![]() | w i z a r d 4 j |
| Overview |
| Flowcharts |
| Xml Language |
| Reference |
| Dia |
| Examples |
| Try It |
| Engine |
| Getting Started |
| Tuning |
| JavaDoc |
| Mailing Lists |
| Download |
| License |
Before a flowchart can be used in the wizard4j engine or session it needs to be validated. The result of this validation is the creation of a Flowchart object (in case the validation was ok).
If the flowchart xml description is available as a String, the validation code is:
WizardValidator validator = WizardFactory.newWizardValidator();
StringReader flowchartReader = new StringReader(flowchartXml);
InputSource flowchartSource = new InputSource(flowchartReader);
try {
Flowchart flowchart = wv.validateFlowchart(flowchartSource);
} catch (ValidationException e) {
// invalid flowchart
}
If the flowchart xml description is available in a file, the validation code is:
WizardValidator validator = WizardFactory.newWizardValidator();
InputSource flowchartSource = new InputSource(flowchartXmlFileName);
try {
Flowchart flowchart = wv.validateFlowchart(flowchartSource);
} catch (ValidationException e) {
// invalid flowchart
}
An engine is created with a single parameter: the session timeout that will be used for its managed sessions (in seconds).
One can obtain either a non-managed session or a managed session. In the former case the caller gets a FlowchartSession and is responsible for the lifecycle of the session, in the latter case a flowchartSessionId is returned and the engine will manage the lifecycle of the session (using the timeout).
FlowchartEngine flowchartEngine = WizardFactory.newFlowchartEngine(3600); // create and start a non-managed session FlowchartSession flowchartSession = flowchartEngine.createSession(flowchart); FlowchartResponse flowchartResponse = flowchartSession.start(); // create and start a managed session String flowchartSessionId = flowchartEngine.createManagedSession(flowchart); flowchartResponse = flowchartEngine.start(flowchartSessionId);
The next code fragment shows the code required for a flowchart run. We assume a managed session is created and we assume a method response2Request() is developed that creates an appropriate FlowchartRequest on the FlowchartResponse generated by the session.
while (!flowchartResponse.hasFlowchartEnded()) {
FlowchartRequest flowchartRequest = response2Request(flowchartResponse);
flowchartResponse = flowchartEngine.next(flowchartSessionId, flowchartRequest);
}
The next code fragment shows how the result of the flowchart execution, can be obtained and used to generate a presentation.
ResultNode rootResultNode = flowchartEngine.getResult(flowchartSessionId);
// generate a built-in presentation
String builtInPresentation = rootResultNode.getBuiltInPresentation(EBuiltInResultPresentationMode.SVG);
// generate a presentation using a velocity template test.vtl in the directory test
VelocityEngine engine = VelocityFactory.getEngine("test/");
VelocityContext context = VelocityFactory.getContext();
context.put("root", rootResultNode);
Template template = engine.getTemplate("test.vtl");
StringWriter sw = new StringWriter();
template.merge(context, sw);
String aVelocityPresentation = sw.toString();
// generate a presentation using a freemarker template test.ftl in the directory test
Configuration configuration = FreemarkerFactory.getConfiguration("test");
Template template = configuration.getTemplate("test.ftl");
StringWriter sw = new StringWriter();
template.process(rootResultNode, sw);
String aFreemarkerPresentation = sw.toString();
The result of a flowchart run is stored in a tree structure as well. It is the tree obtained by expanding the flowchart tree, i.e. fragmentPointers are replaced by the real fragments and the loop iterations are explicitly indicated by branches (similar to how branches are already used in switches). These nodes in the result tree can be accessed directly by Velocity and Freemarker. Consider e.g. example HelloWorld3: the value of the firstname in the french branch of the language switch can be address in Velocity as ${root.language.french.firstname} and in Freemarker as ${language.french.firstname}.
The next code can be used (e.g. inside a servlet) to start a flowchart. Again we use a managed session. The HtmlWrapper requires 3 parameters:
WizardValidator validator = WizardFactory.newWizardValidator(); Flowchart flowchart = validator.validateFlowchart(flowchartSource); HtmlWrapper htmlWrapper = WizardFactory.newHtmlWrapper(timeout, servletPath, false); String flowchartSessionId = htmlWrapper.createManagedSession(flowchart); String htmlCode = htmlWrapper.first(flowchartSessionId);
Or using a ticket:
WizardValidator validator = WizardFactory.newWizardValidator(); Flowchart flowchart = validator.validateFlowchart(flowchartSource); HtmlWrapper htmlWrapper = WizardFactory.newHtmlWrapper(timeout, servletPath, true); String flowchartSessionId = htmlWrapper.createManagedSession(flowchart); String ticket = htmlWrapper.first(flowchartSessionId); ... String htmlCode = htmlWrapper.getHtml(ticket); ...
A typical parsing of the user input inside a servlet is shown in the next fragment. The result of the current form is forwarded to the HtmlWrapper via the parameterMap and the HtmlWrapper will return the next form.
String htmlCode = htmlWrapper.request(httpServletRequest.getParameterMap());
The Restful Wrapper requires that the developer implements a WizardRepository (by extending the WizardRepositoryBase class). The wrapper accesses the flowcharts, presentations and results via this interface. The provided commands are:
baseUri/repositories => list repositories
baseUri/repositories/{repository} => show repository
baseUri/repositories/{repository}/flowcharts => list flowcharts
baseUri/repositories/{repository}/flowcharts/{flowchart} => show flowchart (builtin presentations)
baseUri/repositories/{repository}/flowcharts/{flowchart}/start => first interaction
baseUri/repositories/{repository}/flowcharts/{flowchart}/{action}?state=..&input1=.. => interaction
baseUri/repositories/{repository}/flowcharts/{flowchart}/presentations => list presentations
baseUri/repositories/{repository}/flowcharts/{flowchart}/presentations/{presentation} => presentation description
baseUri/repositories/{repository}/flowcharts/{flowchart}/presentations/{presentation}?state=... => presentation
baseUri/repositories/{repository}/flowcharts/{flowchart}/results => list results
baseUri/repositories/{repository}/flowcharts/{flowchart}/results/{result} => result (builtin presentations)
The next 'conversation' gives an impression on how a wizard4j restful client-server interaction works:
Client:Show me your flowcharts [baseUri/repositories/{repository}/flowcharts]
Server:Here's a list of all the flowcharts you can run at this shop.
Client:Good, okay, I'd like to run flowchart X [baseUri/repositories/{repository}/flowcharts/X/start]
Server:Okay, here is your current flowchart state and your input options
Client:I would like to execute following request on this flowchart state [baseUri/repositories/{repository}/flowcharts/X/action?state=..&input=...]
Server:Okay, request executed, here is your current flowchart state and your input options
Client:Actually I didn't really want to send my previous request, here is my previous state with a new request
Server:Okay, request executed, here is your current flowchart state and your input options
Client:I would like to execute following request on this flowchart state
Server:Okay, flowchart terminated, here is your current flowchart state
Client:Show me your presentations for flowchart X [baseUri/repositories/{repository}/flowcharts/X/presentations]
Server:Here's a list of all the presentations for flowchart X
Client:Give me the result for presentation Y with the current flowchart state [baseUri/repositories/{repository}/flowcharts/X/presentations/Y?state=...]
The class org.wizard4j.wrapper.restful.ClientUtil provides some methods to help in constructing the request urls.
The classes org.wizard4j.test.TestRestful and org.wizard4j.test.WizardRepositoryDummy of the junit tests might help to understand how the restful wrapper works.
The wizard4j-all distribution contains the source code of the junit tests. Some code fragments in these junit tests might be useful to illustrate the wizard4j usage.