How to import globaltransitions.xml in myflow.xml? - spring-webflow

I want import global transitions as a separate xml so that i can import this global transition xml from all the flow xmls. globaltransitions.xml looks as follows, so how can i import this from flow xml ?
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
>
<global-transitions>
<transition on="login" to="login" />
<transition on="error" to="error" />
</global-transitions>
</flow>
Any idea on this?

You can use the globaltransitions.xml as parent flow, so all your flows should extend it. In order to get a flow extending the parent flow, use "parent" attribute.
First, define both parent and child flows in flow-registry:
<flow:flow-registry id="flowRegistry" ...>
<flow:flow-location id="globalTransitions" path="globaltransitions.xml"/>
<flow:flow-location id="childFlow" path="childflow.xml"/>
</flow:flow-registry>
Finally, implement parent flow as you described and child flow as follows:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
start-state="start" parent="globalTransitions">
...
</flow>
Now all global transitions defined in globaltransitions.xml are imported into childflow.
Hope this helps.

Related

How to use the input/output elements in webflow?

I'm trying to understand how the input and output elements are used in webflow. The documentation suggests that flow input/output mapping is similar to calling a method with a signature, but I don't understand what passes the flow the input value or what the flow returns output to. How do I use these elements?
I've been reading the documentation found here, but there are no examples of the elements in action that I can find. This is an example from the documentation.
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow.xsd">
<input name="hotelId" />
<on-start>
<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"
result="flowScope.booking" />
</on-start>
<view-state id="enterBookingDetails">
<transition on="submit" to="reviewBooking" />
</view-state>
<view-state id="reviewBooking">
<transition on="confirm" to="bookingConfirmed" />
<transition on="revise" to="enterBookingDetails" />
<transition on="cancel" to="bookingCancelled" />
</view-state>
<end-state id="bookingConfirmed" />
<end-state id="bookingCancelled" />
In this code, where does the value assigned to "hotelId" come from? Does the input come from the URL? If so, does <input/> behavior change in subflows?
In this code, hotelId will be automatically mapped from the URL if you call /myFlow?hotelId=3 (assuming your flow is called "myFlow")
but you can also set the input directly when calling the flow from another flow, i.e. using:
<subflow-state id="mySubflow" subflow="myFlow">
<input name="hotelId" value="3"/>
</subflow-state>

ActionScript creating custom component to hold two other spark components

I'm fairly new to ActionScript/Flex so I'm not entirely sure if this is even possible.
Basically I have the following block repeating several times in my code:
<s:TextInput .. \>
<s:BitmapImage .. \>
What I'm trying to do is create an ActionScript custom component so I can replace the above block everywhere in my code with:
<MyBlock\>
My best guess is I have to do this by extending spark.application?
What I have so far:
package MyPackage
{
import spark.components.Application;
public class MyBlock extends Application
{
..
}
..
}
I am completely at a loss as to how to combine two existing components into a new custom one, if it is even possible.
How exactly should I proceed next? Any help would be appreciated.
Thanks,
It is so much easier than that: for this use case you should simply extend Group. And to make things easier, write your composed component in MXML.
Create a new file MyBlock.mxml (for instance in com/mydomain/components) and add the following code:
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:TextInput .. />
<s:BitmapImage .. />
</s:Group>
Now simply use this component:
<c:MyBlock />
where the c namespace is defined as xmlns:c="com.mydomain.components.*" at the root node of your document using this class. For example:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:c="com.mydomain.components.*">
<c:MyBlock />
</s:Application>
Now suppose you want to have a different text in each block, you'll have to expose a property. To do this, lets add a label property to MyBlock:
<fx:Declarations>
<fx:String id="label" />
</fx:Declarations>
To make the TextInput show what's in that variable whenever it changes, we use binding like so:
<s:TextInput text="{label}" />
The final component would look something like this:
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<fx:String id="label" />
</fx:Declarations>
<s:TextInput text="{label}" .. />
<s:BitmapImage .. />
</s:Group>
Now you can create multiple MyBlock instances with different texts:
<c:MyBlock label="hello" />
<c:MyBlock label="world" />
Note that if your regular use of MyBlock is more in a list-like fashion, you may want to consider using a List component with a custom ItemRenderer, rather then using MyBlock over and over again.

Spring web flow, create subflow with input field

I am starting with spring web flow, reading and following the documentation. I have created a new flow:
test-flow.xml
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="testName" class="com.project.TestView" />
<view-state id="test">
<on-entry>
<set name="flowScope.name" value="testName.name" />
</on-entry>
<transition on="test" to="saveName"/>
</view-state>
<subflow-state id="subTest" subflow="testSub-flow">
<input name="nameVar" value="name" />
<transition to="error" />
</subflow-state>
<view-state id="error" />
<end-state id="finish" />
</flow>
And I am trying to create a testSub-flow.xml
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<input type="String" name="nameVar" />
<on-start>
<evaluate expression="com.project.TestView.printSomething(nameVar)" result="flowScope.testPrint" />
</on-start>
<view-state id="printTest" >
<transition on="restart" to="endSub" />
</view-state>
<end-state id="endSub" />
</flow>
The method called is:
#Transactional(readOnly = true)
public String printSomething(String text){
System.out.print(text + " this is a test");
return text + " this is a test";
}
I get some exception in the browser when it is loading the main flow, test-flow.xml
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [AnnotatedAction#6ca837 targetAction = [EvaluateAction#7aed3a expression = com.project.TestView.printSomething(nameVar), resultExpression = flowScope.testPrint], attributes = map[[empty]]] in state 'null' of flow 'test' -- action execution attributes were 'map[[empty]]'
What could be the problem?? Thanks in advance.
At first sight, it seems that it can not find any start-state. Try adding start-state attribute in flow tag:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
start-state="test">
If that does not fix the problem, it could be that flow builder can not find a state named "saveName". The problem could be in this line:
<transition on="test" to="saveName"/>
If you want to invoke the subflow when "test" event occurs, you write "subTest" instead of "saveName" in order to call the subflow.
So, that line should be:
<transition on="test" to="subTest"/>
Also, note that you are not specifying any view for those view-states.
Hope this helps.

Flex mobile using Parsley

I'm using Parsley in my flex mobile project. I have multiple destination services but I can't find more resources on how to add another destination service to config.xml file. The file is as below:
<objects
xmlns="http://www.spicefactory.org/parsley"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.spicefactory.org/parsley
http://www.spicefactory.org/parsley/schema/2.4/parsley-core.xsd">
<object type="mx.rpc.remoting.RemoteObject" id="genBUS">
<property name="destination" value="genBUS"/>
<property name="endpoint" value="http://localhost:8080/ClinASM/messagebroker/amf" />
</object>
</object>
In the case when I create another
<object type="mx.rpc.remoting.RemoteObject" id="anotherBUS"></objects>
and do
[Inject(id='genBUS')]
public var genBUS:RemoteObject;
it complains that I have defined multiple remote objects. How does it work? How can I inject another destination service? That would be great to gain more knowledge about Parsley...
UPDATE: config.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Object
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="http://www.spicefactory.org/parsley">
<Object id="genBUS" type="mx.rpc.remoting.RemoteObject">
<Property name="destination" value="genBUS" />
<Property name="endpoint" value="http://localhost:8080/ClinASM/messagebroker/amf" />
</Object>
<Object id="karBUS" type="mx.rpc.remoting.RemoteObject">
<Property name="destination" value="karBUS" />
<Property name="endpoint" value="http://localhost:8080/ClinASM/messagebroker/amf" />
</Object>
</mx:Object>
Injecting by ID is not considerer to be good practice because you create a name-based dependency. Change the name, or make a typo, and your application breaks and it's hard to debug that.
So as a general rule you should try to avoid it. The Parsley docs explain how to do this. I'll just add a simple example to show you how you'd use that technique with your multiple RemoteObjects.
<fx:Object xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:p="http://www.spicefactory.org/parsley">
<fx:Script>
import path.to.service.GenBusDelegate;
import path.to.service.KarBusDelegate;
</fx:Script>
<fx:Declarations>
<fx:String id="gateway">http://localhost:8080/ClinASM/messagebroker/amf</fx:String>
<s:RemoteObject id="genBus" destination="genBus" endpoint="{gateway}" />
<s:RemoteObject id="karBus" destination="karBus" endpoint="{gateway}" />
<p:Object type="{GenBusDelegate}">
<p:ConstructorArgs>
<p:ObjectRef idRef="genBus" />
</p:ConstructorArgs>
</p:Object>
<p:Object type="{KarBusDelegate}">
<p:ConstructorArgs>
<p:ObjectRef idRef="karBus" />
</p:ConstructorArgs>
</p:Object>
</fx:Declarations>
</fx:Object>
or if you don't want to use constructor arguments:
<p:Object type="{GenBusDelegate}">
<Property name="remoteObject" idRef="genBus"/>
</p:Object>

When using blazeDS's proxy-config throw faultDetail="Connection refused: connect"

I have created a XML file directly under the webroot, named index.jsp, the contents are as follow:
<%# page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<product>
<name>Product 1</name>
<description>Product 1 is good</description>
<price>5</price>
</product>
<product>
<name>Product 2</name>
<description>Product 2 is good</description>
<price>15</price>
</product>
<product>
<name>Product 2</name>
<description>Product 2 is good</description>
<price>25</price>
</product>
</catalog>
And in proxy-config.xml under the WEB-INF/flex:
<destination id="getXML">
<properties>
<url>http://localhost:8080/FlexTest/index.jsp</url>
</properties>
</destination>
In the main.mxml, the httpservice as follow:
<mx:HTTPService id="httpService" destination="getXML" useProxy="true" />
Corresponding DataGrid:
<mx:DataGrid dataProvider="{httpService.lastResult.catalog.product}" x="405" y="130" width="329" height="166"/>
But when I click the button to execute httpService.send(), some errors has been thrown up as follow:
[RPC Fault faultString="Error sending request" faultCode="Server.Proxy.Request.Failed" faultDetail="Connection refused: connect"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:290]
at mx.rpc::Responder/fault()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\Responder.as:58]
at mx.rpc::AsyncRequest/fault()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:103]
at NetConnectionMessageResponder/statusHandler()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\messaging\channels\NetConnectionChannel.as:581]
at mx.messaging::MessageResponder/status()[C:\autobuild\3.5.0\frameworks\projects\rpc\src\mx\messaging\MessageResponder.as:222]
I hope someone could help me solve it out, thanks a lot.
Maybe you have to give to your HTTPService an url, like
<mx:HTTPService id="httpService" url="http://localhost:8080/FlexTest/index.jsp" destination="getXML" useProxy="true"/>

Resources