Announcement Announcement Module
Collapse
No announcement yet.
SWF Basic question 1 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    JIRA created as requested.

    JIRA http://opensource.atlassian.com/proj...browse/SPR-933

    Comment


    • #17
      Can you just use a JSTL fmt tag to lookup the message with the code you want, with the publisher name as an arg?

      If you post the code, post a zip :-)

      Keith

      Comment


      • #18
        l used spring:message tag already , l thing it is similar to jstl fmt tag.
        Code:
        <c&#58;if test="$&#123;!empty message_publisher_added&#125;" >
            <spring&#58;message text="$&#123;message_publisher_added&#125;"/>
            <c&#58;remove var="message_publisher_added"/>
        </c&#58;if>
        messages.properties
        Code:
        publisher.added=The Publisher <strong>&#123;0&#125;</strong> have been added ...
        {0} is the publisher name arg , have to be injected using the code that in controller,
        Code:
        context.getRequestScope&#40;&#41;.setAttribute&#40;"message_publisher_added",
                  getMessageSourceAccessor&#40;&#41;.getMessage&#40;"publisher.added",
                  new Object&#91;&#93; &#123;publisher.getPublisherName&#40;&#41;&#125;&#41;&#41;;
        only controller know when to inject the publisher name arg , if try success , then inject , otherwise catch and throw error message (code above , save method).
        u mean there is other way to do this ?

        How to post a zip to the forum ? l study phpbb forum , can't find a way ..

        moon

        Comment


        • #19
          Right, I see. Your controller knows what the result is, so it's logical he set a result message for display. I like that better.

          You might want to create superclass helper methods that are more concise though -- MessageSourceAccessor is just so many letters to type...

          Maybe something like:

          Code:
             message&#40;"publisher.added", new Object&#91;&#93; &#123; publisher.getName&#40;&#41; &#125;&#41;&#41;;
          That one call could not only resolve the message, but expose it as an attribute in request scope for you.

          Comment


          • #20
            You might want to create superclass helper methods that are more concise though
            may be u can consider adding suppport for this method , then l just call it , because l am a sincere user of SWF ....hihihi

            Regarding my CRUD codes , l do think that it will benefit for those beginners , and fill some docs and basic HOW TOs , specially for those peoples using displaytag. l spend many hours to make it work , it may be trivial for experts , but not for beginners.

            The important thing is don't waste time here , l did it , just copy and paste my codes (complain if it is bad) to play , and then ask more advance question about SWF , make it move faster ..... or save the time for your family... programming is hard ~~~.....hihihi

            How to post zip here ?

            moon

            Comment


            • #21
              If you want to send me an e-mail with your code - I can post it for download. Please include a README.txt with an explanation of how to install your code and how to walk through it's UI.

              Thanks,

              Matt

              Comment


              • #22
                Hi , matt
                l send it to [email protected] , one thing to remind , remember to modify your tomcat server.xml to make UTF-8 work .....
                URIEncoding="UTF-8"

                Code:
                    <Connector port="8080"
                               maxThreads="150"
                               minSpareThreads="25"
                               maxSpareThreads="75"
                               enableLookups="false"
                               redirectPort="8443"
                               acceptCount="100"
                               debug="0"
                               connectionTimeout="20000"
                               disableUploadTimeout="true"
                               URIEncoding="UTF-8" />
                it cost me a lot of time to find out while changing from tomcat 4.0 to tomcat 5.0

                + an original spring MVC version for comparison. (remember to reload the library.sql , minor different for these two versions-->subject have an additional version field)

                moon

                Comment


                • #23
                  Hi , one last question in this thread.

                  Can we make the following code more compact ? because it will growth fast if we have a lot subflows.
                  Code:
                  <bean id="publisher.Search.id.set"
                            class="org.springframework.web.flow.action.EventParameterMapperAction">
                  		<property name="mapping" value="id,java.lang.Long"/>
                  		<property name="targetScopeAsString"><value>flow</value></property>
                  </bean>
                  
                  <bean id="id.attributeMapper"
                           class="org.springframework.web.flow.support.ParameterizableFlowAttributeMapper">
                  		<property name="inputMappings">
                  			<list>
                  				<value>id</value>
                  			</list>
                  		</property>
                  </bean>
                  id,java.lang.Long will be the most frequest use conversion , make it special ?

                  moon

                  Comment


                  • #24
                    Use the new xml syntax...

                    Code:
                    	<subflow-state id="subFlowState2" flow="subFlow2">
                    		<attribute-mapper>
                    			<input name="attribute1"/>
                    			<input name="attribute3" as="attribute2"/>
                    			<output name="attribute2"/>
                    			<output name="attribute1" as="attribute3"/>
                    		</attribute-mapper>
                    		<transition on="event2" to="endState2"/>
                    	</subflow-state>
                    Soon you'll be able to map directly out of event or request scope from here as well, without a need for any action. e.g.

                    Code:
                    	<subflow-state id="subFlowState2" flow="subFlow2">
                    		<attribute-mapper>
                                                         <input value="$&#123;lastEvent.parameter.personId&#125; as="personId"/>
                    		</attribute-mapper>
                    		<transition on="event2" to="endState2"/>
                    	</subflow-state>

                    Comment


                    • #25
                      in the sandbox now ?

                      Comment


                      • #26
                        yes

                        Comment


                        • #27
                          codes break so fast ....
                          Code:
                          context.getOriginating&#40;&#41;
                          have to change to
                          Code:
                          context.getSourceEvent&#40;&#41;
                          if u use the sandbox jar (Preview2~preview3) to test the code above.

                          failed to setup.
                          with exception below ( l tried all the combinations , hihi ..),
                          Code:
                          org.springframework.beans.factory.BeanCreationException&#58; Error creating bean with name 'publisher.Update.Delete.FlowController' defined in ServletContext resource &#91;/WEB-INF/library-servlet.xml&#93;&#58; Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError&#58; org/springframework/web/flow/SubflowState
                          java.lang.NoClassDefFoundError&#58; org/springframework/web/flow/SubflowState
                          ........
                          Here is my working code ,
                          PublisherActions.java instead of PublisherCRUD.java , hihi ..
                          Code:
                          public class PublisherActions extends AbstractLibraryAction &#123;
                          
                          	private static final String PUBLISHER_FORM_OBJECT_NAME = "publisher";
                          
                          	public PublisherActions&#40;&#41; &#123;
                          
                          		setFormObjectName&#40;PUBLISHER_FORM_OBJECT_NAME&#41;;
                          		setFormObjectClass&#40;Publisher.class&#41;;
                          		//setValidator&#40;new PublisherValidator&#40;&#41;&#41;;
                          	&#125;
                          
                           	public Event Save&#40;RequestContext context&#41; throws Exception &#123;
                          
                                          Publisher publisher = &#40;Publisher&#41;context.getRequestScope&#40;&#41;.get&#40;PUBLISHER_FORM_OBJECT_NAME&#41;;
                          
                          		try&#123;
                          		   	getLibrary&#40;&#41;.storePublisher&#40;publisher&#41;;
                          
                          		        context.getRequestScope&#40;&#41;.setAttribute&#40;"message_publisher_added",
                                                          getMessageSourceAccessor&#40;&#41;.getMessage&#40;"publisher.added",
                                                          new Object&#91;&#93; &#123;publisher.getPublisherName&#40;&#41;&#125;&#41;&#41;;
                                                  //context.getRequestScope&#40;&#41;.removeAttribute&#40;"publisher"&#41;;
                          
                          		&#125;
                          		catch&#40;org.springframework.dao.DataIntegrityViolationException eive&#41;&#123;
                          
                                                  Errors errors = new FormObjectAccessor&#40;context&#41;.getFormErrors&#40;&#41;;
                                                  errors.rejectValue&#40;"publisherName","publisher.name.already.exists",
                                                                     "Publisher name already exists ..."&#41;;
                          			return error&#40;&#41;;
                          		&#125;
                          
                          		return success&#40;&#41;;
                          
                                  &#125;
                          
                          	public Event Edit&#40;RequestContext context&#41; throws Exception &#123;
                          
                                          Publisher publisher = &#40;Publisher&#41;context.getRequestScope&#40;&#41;.get&#40;PUBLISHER_FORM_OBJECT_NAME&#41;;
                          
                          		try&#123;
                          		   	getLibrary&#40;&#41;.storePublisher&#40;publisher&#41;;
                          
                          		        context.getRequestScope&#40;&#41;.setAttribute&#40;"message_publisher_edited",
                                                          getMessageSourceAccessor&#40;&#41;.getMessage&#40;"publisher.edited",
                                                          new Object&#91;&#93; &#123;publisher.getPublisherName&#40;&#41;&#125;&#41;&#41;;
                                                  context.getRequestScope&#40;&#41;.removeAttribute&#40;"publisher"&#41;;
                          
                          		&#125;catch&#40;org.springframework.dao.DataIntegrityViolationException eive&#41;&#123;
                          
                                                  //Errors errors = new FormObjectAccessor&#40;context&#41;.getFormErrors&#40;PUBLISHER_FORM_OBJECT_NAME,ScopeType.REQUEST&#41;;
                                                  Errors errors = new FormObjectAccessor&#40;context&#41;.getFormErrors&#40;&#41;;
                                                  errors.rejectValue&#40;"publisherName","publisher.name.already.exists",
                                                                     "Publisher name already exists ..."&#41;;
                          			return error&#40;&#41;;
                          		&#125;
                          
                          		return success&#40;&#41;;
                          
                                  &#125;
                          
                                  public Event Delete&#40;RequestContext context&#41; throws Exception &#123;
                          
                                          Long id = new Long&#40;&#40;String&#41;context.getSourceEvent&#40;&#41;.getParameter&#40;"id"&#41;&#41;;
                                          //Long id = &#40;Long&#41;context.getRequestScope&#40;&#41;.getRequiredAttribute&#40;"id", Long.class&#41;;
                          
                          	   	Publisher publisher = getLibrary&#40;&#41;.loadPublisher&#40;id&#41;;
                          
                                          if &#40;publisher != null&#41; &#123;
                          
                                                  try&#123;
                                                      getLibrary&#40;&#41;.deletePublisher&#40;publisher&#41;;
                          
                          		            context.getRequestScope&#40;&#41;.setAttribute&#40;"message_publisher_deleted",
                                                          getMessageSourceAccessor&#40;&#41;.getMessage&#40;"publisher.deleted",
                                                          new Object&#91;&#93; &#123;publisher.getPublisherName&#40;&#41;&#125;&#41;&#41;;
                                                      //context.getRequestScope&#40;&#41;.removeAttribute&#40;"publisher"&#41;;
                          
                                                  &#125;catch &#40;org.springframework.orm.ObjectOptimisticLockingFailureException eoolfe&#41;&#123;
                          
                                                      Errors errors = new FormObjectAccessor&#40;context&#41;.getFormErrors&#40;&#41;;
                                                      errors.rejectValue&#40;"publisherName","publisher.name.already.updated.or.deleted",
                                                                         "The Publisher Name have been updated or deleted by other user..."&#41;;
                          			    return error&#40;&#41;;
                          
                                                  &#125;
                          
                                                  return success&#40;&#41;;
                                          &#125;
                          
                                          return success&#40;&#41;;
                                  &#125;
                          
                          
                          	public Event SearchByName&#40;RequestContext context&#41; throws Exception &#123;
                          
                                          String publisherName = &#40;String&#41;context.getSourceEvent&#40;&#41;.getParameter&#40;"publisherName"&#41;;
                          
                          		if&#40;publisherName != null&#41;&#123;
                          
                          		   	ArrayList publishers = &#40;ArrayList&#41;getLibrary&#40;&#41;.findPublishersByName&#40;publisherName&#41;;
                          
                                                  if &#40;publishers.size&#40;&#41; < 1&#41; &#123;
                                                     // no publisher found
                                                     context.getRequestScope&#40;&#41;.setAttribute&#40;"message_no_publisher_found",
                                                          getMessageSourceAccessor&#40;&#41;.getMessage&#40;"no.publisher.found"&#41;&#41;;
                          
                                                     return success&#40;&#41;;
                          
                                                  &#125;
                                                  // multiple publishers found
                          		        context.getRequestScope&#40;&#41;.setAttribute&#40;"model_name_publishers", publishers&#41;;
                          
                          		        return success&#40;&#41;;
                          		&#125;
                          		
                          		return success&#40;&#41;;
                          
                                  &#125;
                          
                          	public Event SearchById&#40;RequestContext context&#41; throws Exception &#123;
                          
                                          Long id = &#40;Long&#41;context.getFlowScope&#40;&#41;.getRequiredAttribute&#40;"id", Long.class&#41;;
                          
                          		if&#40;id != null&#41;&#123;
                          
                          		   	Publisher publisher = getLibrary&#40;&#41;.loadPublisher&#40;id&#41;;
                          
                          		        context.getRequestScope&#40;&#41;.setAttribute&#40;"publisher", publisher&#41;;
                          
                          		        return success&#40;&#41;;
                          		&#125;
                          		
                          		return success&#40;&#41;;
                          
                                   &#125;
                          
                          &#125;
                          library-servlet.xml
                          Code:
                          <beans>
                          
                                  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                          		<property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
                          		<property name="requestContextAttribute"><value>rc</value></property>
                          		<property name="prefix"><value>/WEB-INF/jsp/</value></property>
                          		<property name="suffix"><value>.jsp</value></property>
                          	</bean>
                          
                          	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
                          	<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
                          	
                          	<bean id="beanNameUrlMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
                          
                          	<!-- Commons Validator Configuration -->
                          	<bean id="validatorFactory" class="org.springmodules.commons.validator.DefaultValidatorFactory" >
                                          <property name="validationConfigLocations">
                                                  <list>
                                                        <value>/WEB-INF/validator-rules.xml</value>
                                                        <value>/WEB-INF/validation.xml</value>
                                                  </list>
                                          </property>
                                  </bean>
                          
                                  <bean id="beanValidator" class="org.springmodules.commons.validator.DefaultBeanValidator">
                                          <property name="validatorFactory"><ref local="validatorFactory"/></property>
                                  </bean>
                          
                          	<bean id="publisherValidator" class="org.springmodules.commons.validator.ConfigurableBeanValidator">
                                          <property name="validatorFactory"><ref local="validatorFactory"/></property>
                                          <property name="formName"><value>publisher</value></property>
                                  </bean>
                          
                                  <bean id="publisherWithoutIdValidator" class="org.springmodules.commons.validator.ConfigurableBeanValidator">
                                          <property name="validatorFactory"><ref local="validatorFactory"/></property>
                                          <property name="formName"><value>publisherWithoutId</value></property>
                                  </bean>
                          
                          	<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
                                          <property name="exceptionMappings">
                                                    <props>
                                                           <prop key="java.lang.Exception">Error</prop>
                                                           <prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
                          				 <prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop>
                                                  </props>
                                          </property>
                                  </bean>
                          
                                  <bean id="publisherActions" class="org.yourschool.library.web.PublisherActions">
                          	      <property name="library"><ref bean="library"/></property>
                          	      <property name="validator"><ref bean="beanValidator"/></property>
                          	</bean>
                          <!-- ************** -->
                                  <bean id="publisher.Create.Search.FlowController" class="org.springframework.web.flow.mvc.FlowController">
                                        <property name="flow" ref="publisher.Create.Search.Flow"/>
                          	</bean>
                          
                          	<bean id="publisher.Create.Search.Flow" class="org.springframework.web.flow.config.XmlFlowFactoryBean">
                          		<property name="location" value="/WEB-INF/flows/publisher.Create.Search-flow.xml"/>
                          	</bean>
                          <!-- ************** -->
                          	<bean id="publisher.Update.Delete.FlowController" class="org.springframework.web.flow.mvc.FlowController">
                                        <property name="flow" ref="publisher.Update.Delete.Flow"/>
                          	</bean>
                          
                          	<bean id="publisher.Update.Delete.Flow" class="org.springframework.web.flow.config.XmlFlowFactoryBean">
                          		<property name="location" value="/WEB-INF/flows/publisher.Search.for.Update.Delete-flow.xml"/>
                          	</bean>
                          <!-- ************** -->
                          	<bean id="publisher.Update.FlowController" class="org.springframework.web.flow.mvc.FlowController">
                                        <property name="flow" ref="publisher.Update.Flow"/>
                          	</bean>
                          
                          	<bean id="publisher.Update.Flow" class="org.springframework.web.flow.config.XmlFlowFactoryBean">
                          		<property name="location" value="/WEB-INF/flows/publisher.Update-flow.xml"/>
                          	</bean>
                          
                          	<bean id="publisher.Search.id.set" class="org.springframework.web.flow.action.EventParameterMapperAction">
                          		<property name="mapping" value="id,java.lang.Long"/>
                          		<property name="targetScopeAsString"><value>flow</value></property>
                          	</bean>
                          
                          	<bean id="id.attributeMapper" class="org.springframework.web.flow.support.ParameterizableFlowAttributeMapper">
                          		<property name="inputMappings">
                          			<list>
                          				<value>id</value>
                          			</list>
                          		</property>
                          	</bean>
                          
                          	<!-- A type conversion service, a more flexible/threadsafe/lightweight alternative to the PropertyEditor! -->
                          	<bean id="conversion.service" class="org.springframework.binding.convert.support.DefaultConversionService" autowire="byType"/>
                          
                          	<!-- A formatter registry, a thread-safe cache for Formatters&#58; a thread-safe, lighter weight alt. to PropertyEditors! -->
                          	<bean id="formatter.locator" class="org.springframework.binding.format.support.ThreadLocalFormatterLocator" autowire="byType"/>
                          
                          	<!-- A broadcaster that will notify the formatter registry to cleanup all thread locals on app shutdown -->
                          	<bean id="thread.cleanupBroadcaster" class="org.springframework.binding.thread.support.DefaultThreadCleanupBroadcaster"/>
                          
                                  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                                  	<property name="interceptors">
                          			<list>
                          				<ref local="localeChangeInterceptor"/>
                          			</list>
                          		</property>
                          		<property name="mappings">
                          			<props>
                          				<prop key="/admin/index.htm">indexView</prop>
                                                          <prop key="/admin/publisher.Create.Search.htm">publisher.Create.Search.FlowController</prop>
                                                          <prop key="/admin/publisher.Search.for.Update.Delete.htm">publisher.Update.Delete.FlowController</prop>
                                                          <prop key="/admin/publisher.Update.htm">publisher.Update.FlowController</prop>
                           			</props>
                          		</property>
                          	</bean>
                          
                          	<bean name="indexView" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
                          		<property name="viewName"><value>index</value></property>
                          	</bean>
                          
                          </beans>
                          publisher.Search.for.Update.Delete-flow.xml
                          Code:
                          <webflow id="publisher.Update.Delete.Flow" start-state="publisher.Search"> 
                          
                             <view-state id="publisher.Search" view="publisher.Search.for.Update.Delete"> 
                                          <transition on="searchByName" to="SearchByName"/> 
                                          <transition on="delete" to="Delete"/> 
                                          <transition on="searchById" to="publisherId.set"/> 
                             </view-state> 
                              
                             <action-state id="SearchByName"> 
                                     <action bean="publisherActions"/> 
                                <transition on="success" to="publisher.Search"/> 
                                <transition on="error" to="publisher.Search"/> 
                             </action-state> 
                          
                             <action-state id="Delete"> 
                                     <action bean="publisherActions"/> 
                                <transition on="success" to="publisher.Search"/> 
                                <transition on="error" to="publisher.Search"/> 
                             </action-state> 
                          
                             <action-state id="publisherId.set"> 
                                <action bean="publisher.Search.id.set"/> 
                                <transition on="success" to="publisher.Update.Flow"/> 
                                <transition on="error" to="publisher.Search"/> 
                             </action-state> 
                              
                             <subflow-state id="publisher.Update.Flow" flow="publisher.Update.Flow"> 
                                <attribute-mapper bean="id.attributeMapper"/> 
                                <transition on="finish" to="done"/> 
                                <transition on="error" to="publisher.Search"/> 
                             </subflow-state> 
                          
                                  <end-state id="done" view="redirect&#58;/admin/publisher.Search.for.Update.Delete.htm"/> 
                             <end-state id="error" view="publisher.Search"/> 
                              
                          </webflow>
                          l did it this way ,

                          Code:
                          	<subflow-state id="publisher.Update.Flow" flow="publisher.Update.Flow">
                          		<attribute-mapper>
                                             <input name="id" as="id"/>
                                             <output name="id"/>
                          		</attribute-mapper>
                          		<transition on="finish" to="done"/>
                          		<transition on="error" to="publisher.Search"/>
                          	</subflow-state>
                          no luck ....l almost did all the combinations , remove the "not so compact codes" , change this and that ...hihihi
                          this is my final step to CRUD in SWF , otherwise l have to write a lot to pollute my library-servlet.xml ....

                          Comment


                          • #28
                            Yes 'sourceEvent' now used in preference to 'originatingEvent' -- name tweak there. Hopefully that's not used too much by folks...

                            So you're saying the xml attribute mapping is not working, right? The CVS changes including that bugfix probably just haven't synced to the anonymous servers yet.

                            Any other trouble with the PR3 code?

                            Comment


                            • #29
                              Hi Keith ,
                              no luck ..still no working. May be l send u my working code , it is the most efficency way, u can try it yourself ( if u have gmail address ).
                              [email protected]
                              yes , there is other problem , not just PR3 , sometimes PR1 , PR2. Sometimes l got
                              Code:
                              <IOException while loading persisted sessions&#58; java.io.EOFException>
                              , it happened when l use "ant stop" , "ant start" to restart tomcat server while a exception occured ...

                              moon

                              Comment


                              • #30
                                Patience, Moon - it takes up to 24 hours and I just committed the fix last night.

                                That EOFException I don't think is our problem -- our serialization logic is correct. I suspect it to be a tomcat issue, or perhaps it occurs when you switch jars.

                                Comment

                                Working...
                                X