You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by ne...@apache.org on 2006/10/27 19:44:56 UTC
svn commit: r468474 - in /lenya/trunk/src:
modules-core/usecase/java/src/org/apache/lenya/cms/usecase/
modules/bxe/config/cocoon-xconf/ modules/cforms/
modules/cforms/config/cocoon-xconf/ modules/cforms/flow/
modules/cforms/java/ modules/cforms/java/sr...
Author: nettings
Date: Fri Oct 27 10:44:55 2006
New Revision: 468474
URL: http://svn.apache.org/viewvc?view=rev&rev=468474
Log:
usecase handler cleanup.
[1] remove all cforms-specific code from usecases.js and
UsecaseView.java
[2] split usecases.js into maintainable chunks
[3] introduce a mechanism to add custom flow code (see javadocs in
UsecaseView.java and read usecases.js for details)
[4] remove DummyCFormsUsecase.java and cforms-specific usecases-utils.js
from global code
[5] add CForms.java usecase to cforms module
[6] add custom flow to cforms module to restore functionality
[7] tweak bxe usecases to not create continuations (this restores their
original behaviour which was changed by the previous revision of
usecases.js)
HEADSUP: cforms saving is currently broken, and there is instrumentation
code left in modules/cforms/flow/customFlow.js.
Added:
lenya/trunk/src/modules/cforms/flow/
lenya/trunk/src/modules/cforms/flow/customFlow.js (with props)
lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js (with props)
lenya/trunk/src/modules/cforms/java/
lenya/trunk/src/modules/cforms/java/src/
lenya/trunk/src/modules/cforms/java/src/org/
lenya/trunk/src/modules/cforms/java/src/org/apache/
lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/
lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/
lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/
lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/
lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/CForms.java
- copied, changed from r468313, lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/DummyCFormsUsecase.java
Removed:
lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/DummyCFormsUsecase.java
lenya/trunk/src/webapp/lenya/usecases/usecases-util.js
Modified:
lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/UsecaseView.java
lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe-close.xconf
lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe.xconf
lenya/trunk/src/modules/cforms/config/cocoon-xconf/usecase-edit.xconf
lenya/trunk/src/modules/cforms/module.xml
lenya/trunk/src/webapp/lenya/usecases/usecase.xmap
lenya/trunk/src/webapp/lenya/usecases/usecases.js
Modified: lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/UsecaseView.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/UsecaseView.java?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/UsecaseView.java (original)
+++ lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/UsecaseView.java Fri Oct 27 10:44:55 2006
@@ -32,36 +32,100 @@
* Information about a usecase view.
*
* @version $Id$
+ *
+ * Example configuration:
+ * <code><view uri="/modules/foo/usecases/foo-mogrify.jx"
+ * customFlow="/modules/foo/flow/myflow.js"
+ * menu="false|true"
+ * createContinuation="false|true"
+ * >
+ * <tab group="foo" name="bar"/> // optional
+ * <parameter name="foo" value="bar/> // optional
+ * </view></code>
+ * <p>
+ * <code>uri</code> is the relative URL of the page to be sent back to the client. If the URI
+ * starts with a slash, it is resolved starting at the root sitemap, otherwise it
+ * is resolved relative to the current sitemap. The URI should not contain a
+ * scheme (such as cocoon:).
+ * </p>
+ * <p>
+ * <code>menu</code> is a boolean that governs whether the Lenya GUI menu is displayed while
+ * the usecase is running. The displaying of the menu is handled by the usecase.xmap sitemap;
+ * hence this option is only functional if <code>uri</code> does <em>not</em> start with a slash
+ * (or if you implement it yourself based on the <code>showMenu()</code> method of this object).<br>
+ * Default is <em>false</em>.
+ * </p>
+ * <p>
+ * <code>customFlow</code> is a javascript file where you can provide custom methods that will override
+ * those in the default usecase handler (<code>webapp/lenya/usecases/usecases.js</code>).
+ * Currently, it provides support for "customLoopFlow" and "customSubmitFlow". Refer to the default handler
+ * for function prototypes and more information.
+ * NB: the "menu" and "createContinuation" attributes will have no effect when you use custom flow code, unless
+ * you check for them and implement the respective functions yourself.
+ * </p>
+ * <p>
+ * <code>createContinuation</code> can be set to false, in which case the generic flowscript
+ * uses "sendPage" instead of "sendPageAndWait" and terminates after the view has been sent.
+ * When <code>createContinuation</code> is false, you must not specify <code>submitFlow</code>
+ * or <code>loopFlow</code>.<br>
+ * Default is <em>true</em>.
+ * </p>
+ * <p>
+ * For tabbed usecases, you can optionally specify a tab group and name. Additional custom
+ * configuration can be passed via the generic "parameter" element.
+ * </p>
+ * <p>
+ * For backwards compatibility with existing usecases, the constructor looks for a <code>template</code>
+ * attribute if no <code>uri</code> is present. It is mapped to the same field, viewUri, internally.
+ * </p>
*/
public class UsecaseView implements Configurable, Serviceable {
- protected static final String ATTRIBUTE_TEMPLATE_URI = "template";
+ protected static final String ATTRIBUTE_URI = "uri";
+ protected static final String ATTRIBUTE_TEMPLATE = "template"; // backwards compatibility, mapped to "uri"
+
+ protected static final String ATTRIBUTE_CUSTOM_FLOW = "customFlow";
protected static final String ATTRIBUTE_SHOW_MENU = "menu";
+ protected static final String ATTRIBUTE_CREATE_CONT = "createContinuation";
+
+ // additional parameters:
protected static final String ELEMENT_PARAMETER = "parameter";
protected static final String ATTRIBUTE_NAME = "name";
protected static final String ATTRIBUTE_VALUE = "value";
-
- protected static final String ATTRIBUTE_TYPE = "type";
- protected static final String VIEW_CFORM = "cforms";
-
- protected static final String ELEMENT_CFORM_DEFINITION = "definition";
- protected static final String ELEMENT_CFORM_BINDING = "binding";
- protected static final String ELEMENT_CFORM_OUTRO = "outro";
- protected static final String ELEMENT_CFORM_INTRO = "intro";
-
- protected static final String ATTRIBUTE_URI = "uri";
- protected static final String ATTRIBUTE_GROUP = "group";
+
+ // tabbed usecases:
+ protected static final String ATTRIBUTE_GROUP = "group";
protected static final String ELEMENT_TAB = "tab";
+
private Map parameters = new HashMap();
+ private ServiceManager manager;
+ private String viewUri;
+ private String customFlow;
+
+ private boolean showMenu;
+ private boolean createContinuation;
+ private Tab tab;
+
+
+
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
public void configure(Configuration config) throws ConfigurationException {
- this.templateUri = config.getAttribute(ATTRIBUTE_TEMPLATE_URI, null);
- this.viewUri = config.getAttribute(ATTRIBUTE_URI, null);
-
+ // get <view> attributes:
+ this.viewUri = config.getAttribute(ATTRIBUTE_URI, "");
+ if (this.viewUri == "") {
+ // fall back to "template" attribute for backwards compatibility (rip out eventually).
+ this.viewUri = config.getAttribute(ATTRIBUTE_TEMPLATE, "");
+ }
+ this.showMenu = config.getAttributeAsBoolean(ATTRIBUTE_SHOW_MENU, false);
+ this.customFlow = config.getAttribute(ATTRIBUTE_CUSTOM_FLOW, "");
+ this.createContinuation = config.getAttributeAsBoolean(ATTRIBUTE_CREATE_CONT, true);
+
+
+ // get <tab/> configuration:
Configuration tabConfig = config.getChild(ELEMENT_TAB, false);
if (tabConfig != null) {
String tabName = tabConfig.getAttribute(ATTRIBUTE_NAME);
@@ -79,54 +143,18 @@
}
}
- if (this.viewUri == null && this.templateUri == null) {
- throw new ConfigurationException("Either uri or template attribute must be declared!");
- }
-
- this.showMenu = config.getAttributeAsBoolean(ATTRIBUTE_SHOW_MENU, false);
-
- this.viewType = config.getAttribute(ATTRIBUTE_TYPE, null);
-
- if (this.viewType!=null && this.viewType.equals(VIEW_CFORM)){
- Configuration cformIntroConfig = config.getChild(ELEMENT_CFORM_INTRO, false);
- if (cformIntroConfig!=null){
- this.cformIntro = cformIntroConfig.getValue(null);
- }
- Configuration cformDefinitionConfig = config.getChild(ELEMENT_CFORM_DEFINITION, false);
- if (cformDefinitionConfig!=null){
- this.cformDefinition = cformDefinitionConfig.getAttribute(ATTRIBUTE_TEMPLATE_URI, null);
- this.cformDefinitionBody = cformDefinitionConfig.getValue(null);
- }
- Configuration cformBindingConfig = config.getChild(ELEMENT_CFORM_BINDING, false);
- if (cformBindingConfig!=null){
- this.cformBinding = cformBindingConfig.getAttribute(ATTRIBUTE_TEMPLATE_URI, null);
- this.cformBindingBody = cformBindingConfig.getValue(null);
- }
- Configuration cformOutroConfig = config.getChild(ELEMENT_CFORM_OUTRO, false);
- if (cformOutroConfig!=null){
- this.cformOutro = cformOutroConfig.getValue(null);
- }
- }
-
+ // get <parameter/> configuration
Configuration[] parameterConfigs = config.getChildren(ELEMENT_PARAMETER);
for (int i = 0; i < parameterConfigs.length; i++) {
String name = parameterConfigs[i].getAttribute(ATTRIBUTE_NAME);
String value = parameterConfigs[i].getAttribute(ATTRIBUTE_VALUE);
this.parameters.put(name, value);
}
- }
- private String templateUri;
+ checkConfig();
- /**
- * @return The URI of the JX template;
- */
- public String getTemplateURI() {
- return this.templateUri;
}
- private String viewUri;
-
/**
* @return The URI of the JX template;
*/
@@ -134,16 +162,28 @@
return this.viewUri;
}
- private boolean showMenu;
-
/**
- * @return If the menubar should be visible on usecase screens.
+ * @return whether the menubar should be visible on usecase screens.
*/
public boolean showMenu() {
return this.showMenu;
}
/**
+ * @return whether a continuation should be created.
+ */
+ public boolean createContinuation() {
+ return this.createContinuation;
+ }
+
+ /**
+ * @return the Flowscript snippet to be executed during the usecase view loop.
+ */
+ public String getCustomFlow() {
+ return this.customFlow;
+ }
+
+ /**
* @param name The parameter name.
* @return The parameter value.
*/
@@ -151,8 +191,6 @@
return (String) this.parameters.get(name);
}
- private Tab tab;
-
/**
* @return The tab the usecase belongs to or <code>null</code>.
*/
@@ -181,8 +219,6 @@
}
}
- private ServiceManager manager;
-
/**
* @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
*/
@@ -190,117 +226,9 @@
this.manager = manager;
}
- private String cformDefinition =null;
-
- /**
- * @return Returns the cformDefinition.
- */
- public String getCformDefinition() {
- return cformDefinition;
- }
-
- /**
- * @param cformDefinition The cformDefinition to set.
- */
- public void setCformDefinition(String cformDefinition) {
- this.cformDefinition = cformDefinition;
- }
-
-
- private String cformBinding =null;
-
- private String cformOutro=null;
-
- private String cformIntro=null;
-
- private String cformDefinitionBody=null;
-
- private String cformBindingBody=null;
-
- /**
- * @return Returns the cformBinding.
- */
- public String getCformBinding() {
- return cformBinding;
- }
-
- /**
- * @param cformBinding The cformBinding to set.
- */
- public void setCformBinding(String cformBinding) {
- this.cformBinding = cformBinding;
- }
-
- private String viewType;
-
- /**
- * @return Returns the viewType.
- */
- public String getViewType() {
- return viewType;
- }
-
- /**
- * @param viewType The viewType to set.
- */
- public void setViewType(String viewType) {
- this.viewType = viewType;
- }
-
- /**
- * @return Returns the cformOutro.
- */
- public String getCformOutro() {
- return cformOutro;
- }
-
- /**
- * @param cformOutro The cformOutro to set.
- */
- public void setCformOutro(String cformOutro) {
- this.cformOutro = cformOutro;
- }
-
- /**
- * @return Returns the cformIntro.
- */
- public String getCformIntro() {
- return cformIntro;
- }
-
- /**
- * @param cformIntro The cformIntro to set.
- */
- public void setCformIntro(String cformIntro) {
- this.cformIntro = cformIntro;
- }
-
- /**
- * @return Returns the cformBindingBody.
- */
- public String getCformBindingBody() {
- return cformBindingBody;
- }
-
- /**
- * @param cformBindingBody The cformBindingBody to set.
- */
- public void setCformBindingBody(String cformBindingBody) {
- this.cformBindingBody = cformBindingBody;
- }
-
- /**
- * @return Returns the cformDefinitionBody.
- */
- public String getCformDefinitionBody() {
- return cformDefinitionBody;
- }
-
- /**
- * @param cformDefinitionBody The cformDefinitionBody to set.
- */
- public void setCformDefinitionBody(String cformDefinitionBody) {
- this.cformDefinitionBody = cformDefinitionBody;
+ private void checkConfig() throws ConfigurationException {
+ if (this.tab != null && this.viewUri == "") {
+ throw new ConfigurationException("When you specify a <tab/>, you must specify a <view uri=\"..\"/> as well!");
+ }
}
-
-}
\ No newline at end of file
+}
Modified: lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe-close.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe-close.xconf?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe-close.xconf (original)
+++ lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe-close.xconf Fri Oct 27 10:44:55 2006
@@ -23,7 +23,7 @@
<component-instance name="bxe.close" logger="lenya.publication"
class="org.apache.lenya.cms.usecase.DummyUsecase">
- <view uri="cocoon://modules/bxe/bxe.close" menu="false"/>
+ <view uri="cocoon://modules/bxe/bxe.close" menu="false" createContinuation="false"/>
</component-instance>
</xconf>
Modified: lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe.xconf?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe.xconf (original)
+++ lenya/trunk/src/modules/bxe/config/cocoon-xconf/usecase-bxe.xconf Fri Oct 27 10:44:55 2006
@@ -23,7 +23,7 @@
<component-instance name="bxe.edit" logger="lenya.publication"
class="org.apache.lenya.cms.workflow.usecases.CheckWorkflow">
- <view uri="cocoon://modules/bxe/bxe.open" menu="false"/>
+ <view uri="cocoon://modules/bxe/bxe.open" menu="false" createContinuation="false"/>
<event id="edit"/>
</component-instance>
Modified: lenya/trunk/src/modules/cforms/config/cocoon-xconf/usecase-edit.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/cforms/config/cocoon-xconf/usecase-edit.xconf?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/modules/cforms/config/cocoon-xconf/usecase-edit.xconf (original)
+++ lenya/trunk/src/modules/cforms/config/cocoon-xconf/usecase-edit.xconf Fri Oct 27 10:44:55 2006
@@ -3,23 +3,11 @@
<xconf xpath="/cocoon/usecases" unless="/cocoon/usecases/component-instance[@name = 'cforms.edit']">
<component-instance name="cforms.edit"
logger="lenya.site"
- class="org.apache.lenya.cms.usecase.DummyCFormsUsecase">
- <view template="modules/cforms/usecases/dynamicrepeater_template.xml" type="cforms">
- <intro/>
- <definition template="modules/cforms/usecases/dynamicrepeater.xml">
- form.setAttribute("counter", new java.lang.Integer(0));
- </definition>
- <binding template="modules/cforms/usecases/dynamicrepeater_binding.xml">
- generic.doc = loadDocument(generic.proxy.getParameter('sourceUri'));
- form.load(generic.doc);
- </binding>
- <outro>
- form.save(generic.doc);
- var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
- flowHelper.triggerWorkflow(cocoon, 'edit');
- saveDocument(generic.doc, generic.proxy.getParameter('sourceUri'));
- </outro>
- </view>
+ class="org.apache.lenya.cms.editors.cforms.CForms">
+ <view
+ uri="modules/cforms/usecases/dynamicrepeater_template.xml"
+ customFlow="fallback://lenya/modules/cforms/flow/customFlow.js"
+ />
</component-instance>
</xconf>
Added: lenya/trunk/src/modules/cforms/flow/customFlow.js
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/cforms/flow/customFlow.js?view=auto&rev=468474
==============================================================================
--- lenya/trunk/src/modules/cforms/flow/customFlow.js (added)
+++ lenya/trunk/src/modules/cforms/flow/customFlow.js Fri Oct 27 10:44:55 2006
@@ -0,0 +1,92 @@
+function customLoopFlow(view,proxy,generic) {
+ // load some helper functions
+ // cocoon.load("fallback://lenya/modules/cforms/flow/lenyadoc-utils.js");
+ try {
+ var formDef = "fallback://lenya/modules/cforms/usecases/dynamicrepeater.xml";
+ var formBind = "fallback://lenya/modules/cforms/usecases/dynamicrepeater_binding.xml";
+ var formView = "usecases-view/menu/modules/cforms/usecases/dynamicrepeater_template.xml";
+ generic.form = new Form(formDef);
+ generic.form.setAttribute("counter", new java.lang.Integer(0));
+ generic.form.createBinding(formBind);
+
+ try {
+ var parser = cocoon.getComponent(Packages.org.apache.excalibur.xml.dom.DOMParser.ROLE);
+ var resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ var source = resolver.resolveURI(proxy.getParameter('sourceUri'));
+ var is = new Packages.org.xml.sax.InputSource(source.getInputStream());
+ is.setSystemId(source.getURI());
+ generic.doc = parser.parseDocument(is);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(parser);
+ cocoon.releaseComponent(resolver);
+ }
+
+ generic.form.load(generic.doc);
+ generic.form.showForm(formView, {"usecase" : proxy});
+ } catch (exception) {
+ // if an exception was thrown by the view, allow the usecase to rollback the transition
+ log("error", "Exception during customLoopFlow: " + exception);
+ throw exception;
+ }
+}
+function customSubmitFlow(usecase, generic) {
+ generic.form.save(generic.doc);
+ var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
+// try {
+ flowHelper.triggerWorkflow(cocoon, 'edit');
+ //saveDocument(generic.doc, usecase.getSourceURL());
+// try {
+ var resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ var source = resolver.resolveURI(usecase.getSourceURL());
+ var tf = Packages.javax.xml.transform.TransformerFactory.newInstance();
+ log("debug", "source instanceof ModifiableSource ? " + (source instanceof Packages.org.apache.excalibur.source.ModifiableSource));
+ log("debug", "tf.getFeature(SAXTransformerFactory.FEATURE): " + tf.getFeature(Packages.javax.xml.transform.sax.SAXTransformerFactory.FEATURE));
+ if (source instanceof Packages.org.apache.excalibur.source.ModifiableSource
+ && tf.getFeature(Packages.javax.xml.transform.sax.SAXTransformerFactory.FEATURE)) {
+ var outputStream = source.getOutputStream();
+ var transformerHandler = tf.newTransformerHandler();
+ var transformer = transformerHandler.getTransformer();
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.INDENT, "true");
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.METHOD, "xml");
+ transformerHandler.setResult(new Packages.javax.xml.transform.stream.StreamResult(outputStream));
+
+ var streamer = new Packages.org.apache.cocoon.xml.dom.DOMStreamer(transformerHandler);
+ streamer.stream(generic.doc);
+ } else {
+ throw new Packages.org.apache.cocoon.ProcessingException("Cannot write to source " + usecase.getSourceURL());
+ }
+/* } catch (exception) {
+ log("error", "Something went wrong during saving: " + exception, usecase.getName());
+ log("debug", "usecase.getSourceURL(): " + usecase.getSourceURL(), usecase.getName());
+ log("debug", "source: " + source, usecase.getName());
+ log("debug", "tf: " + tf, usecase.getName());
+ log("debug", "generic.doc: " + generic.doc, usecase.getName());
+ log("debug", "outputStream: " + outputStream, usecase.getName());
+ //log("debug", "streamer.stream(generic.doc): " + streamer.stream(generic.doc), usecase.getName());
+ throw exception;
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(resolver);
+ if (outputStream != null) {
+ try {
+ outputStream.flush();
+ outputStream.close();
+ } catch (exception) {
+ log("error", "Could not flush/close outputstream: " + exception, usecase.getName());
+ throw exception;
+ }
+ }
+ }
+
+ } catch (exception) {
+ log("error", "Exception during customSubmitFlow: " + exception, usecase.getName());
+ throw exception;
+ } finally {
+ cocoon.releaseComponent(flowHelper);
+ }
+*/
+ return "success";
+}
Propchange: lenya/trunk/src/modules/cforms/flow/customFlow.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js?view=auto&rev=468474
==============================================================================
--- lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js (added)
+++ lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js Fri Oct 27 10:44:55 2006
@@ -0,0 +1,162 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/* $Id: usecases.js 265544 2005-08-31 18:40:31Z thorsten $ */
+
+var loadDocument;
+
+function loadDocument(uri) {
+ var parser = null;
+ var source = null;
+ var resolver = null;
+ try {
+ parser = cocoon.getComponent(Packages.org.apache.excalibur.xml.dom.DOMParser.ROLE);
+ resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+ var is = new Packages.org.xml.sax.InputSource(source.getInputStream());
+ is.setSystemId(source.getURI());
+ return parser.parseDocument(is);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(parser);
+ cocoon.releaseComponent(resolver);
+ }
+}
+
+var saveDocument;
+
+function saveDocument(document, uri) {
+ var source = null;
+ var resolver = null;
+ var outputStream = null;
+ try {
+ resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+
+ var tf = Packages.javax.xml.transform.TransformerFactory.newInstance();
+
+ if (source instanceof Packages.org.apache.excalibur.source.ModifiableSource
+ && tf.getFeature(Packages.javax.xml.transform.sax.SAXTransformerFactory.FEATURE)) {
+
+ outputStream = source.getOutputStream();
+ var transformerHandler = tf.newTransformerHandler();
+ var transformer = transformerHandler.getTransformer();
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.INDENT, "true");
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.METHOD, "xml");
+ transformerHandler.setResult(new Packages.javax.xml.transform.stream.StreamResult(outputStream));
+
+ var streamer = new Packages.org.apache.cocoon.xml.dom.DOMStreamer(transformerHandler);
+ streamer.stream(document);
+ } else {
+ throw new Packages.org.apache.cocoon.ProcessingException("Cannot write to source " + uri);
+ }
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(resolver);
+ if (outputStream != null) {
+ try {
+ outputStream.flush();
+ outputStream.close();
+ } catch (error) {
+ cocoon.log.error("Could not flush/close outputstream: " + error);
+ }
+ }
+ }
+}
+/*
+ * Copyright 1999-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/* $Id: usecases.js 265544 2005-08-31 18:40:31Z thorsten $ */
+
+var loadDocument;
+
+function loadDocument(uri) {
+ var parser = null;
+ var source = null;
+ var resolver = null;
+ try {
+ parser = cocoon.getComponent(Packages.org.apache.excalibur.xml.dom.DOMParser.ROLE);
+ resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+ var is = new Packages.org.xml.sax.InputSource(source.getInputStream());
+ is.setSystemId(source.getURI());
+ return parser.parseDocument(is);
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(parser);
+ cocoon.releaseComponent(resolver);
+ }
+}
+
+var saveDocument;
+
+function saveDocument(document, uri) {
+ var source = null;
+ var resolver = null;
+ var outputStream = null;
+ try {
+ resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
+ source = resolver.resolveURI(uri);
+
+ var tf = Packages.javax.xml.transform.TransformerFactory.newInstance();
+
+ if (source instanceof Packages.org.apache.excalibur.source.ModifiableSource
+ && tf.getFeature(Packages.javax.xml.transform.sax.SAXTransformerFactory.FEATURE)) {
+
+ outputStream = source.getOutputStream();
+ var transformerHandler = tf.newTransformerHandler();
+ var transformer = transformerHandler.getTransformer();
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.INDENT, "true");
+ transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.METHOD, "xml");
+ transformerHandler.setResult(new Packages.javax.xml.transform.stream.StreamResult(outputStream));
+
+ var streamer = new Packages.org.apache.cocoon.xml.dom.DOMStreamer(transformerHandler);
+ streamer.stream(document);
+ } else {
+ throw new Packages.org.apache.cocoon.ProcessingException("Cannot write to source " + uri);
+ }
+ } finally {
+ if (source != null)
+ resolver.release(source);
+ cocoon.releaseComponent(resolver);
+ if (outputStream != null) {
+ try {
+ outputStream.flush();
+ outputStream.close();
+ } catch (error) {
+ cocoon.log.error("Could not flush/close outputstream: " + error);
+ }
+ }
+ }
+}
Propchange: lenya/trunk/src/modules/cforms/flow/lenyadoc-utils.js
------------------------------------------------------------------------------
svn:eol-style = native
Copied: lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/CForms.java (from r468313, lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/DummyCFormsUsecase.java)
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/CForms.java?view=diff&rev=468474&p1=lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/DummyCFormsUsecase.java&r1=468313&p2=lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/CForms.java&r2=468474
==============================================================================
--- lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/DummyCFormsUsecase.java (original)
+++ lenya/trunk/src/modules/cforms/java/src/org/apache/lenya/cms/editors/cforms/CForms.java Fri Oct 27 10:44:55 2006
@@ -13,7 +13,7 @@
* limitations under the License.
*
*/
-package org.apache.lenya.cms.usecase;
+package org.apache.lenya.cms.editors.cforms;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.lenya.cms.publication.Document;
@@ -25,7 +25,7 @@
/**
* Dummy CForms usecase.
*/
-public class DummyCFormsUsecase extends DocumentUsecase {
+public class CForms extends DocumentUsecase {
/**
* @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
Modified: lenya/trunk/src/modules/cforms/module.xml
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/cforms/module.xml?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/modules/cforms/module.xml (original)
+++ lenya/trunk/src/modules/cforms/module.xml Fri Oct 27 10:44:55 2006
@@ -19,6 +19,7 @@
<module xmlns="http://apache.org/lenya/module/1.0">
<id>org.apache.lenya.modules.cforms</id>
+ <depends module="org.apache.lenya.modules.usecase"/>
<package>org.apache.lenya.modules</package>
<version>0.1-dev</version>
<name>CForms Editor</name>
Modified: lenya/trunk/src/webapp/lenya/usecases/usecase.xmap
URL: http://svn.apache.org/viewvc/lenya/trunk/src/webapp/lenya/usecases/usecase.xmap?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/webapp/lenya/usecases/usecase.xmap (original)
+++ lenya/trunk/src/webapp/lenya/usecases/usecase.xmap Fri Oct 27 10:44:55 2006
@@ -23,12 +23,12 @@
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
- <map:components>
- <map:transformers default="xslt">
- <map:transformer name="browser-update" src="org.apache.cocoon.ajax.BrowserUpdateTransformer"/>
- </map:transformers>
- <map:selectors>
- <map:selector name="ajax-request" src="org.apache.cocoon.ajax.AjaxRequestSelector"/>
+ <map:components>
+ <map:transformers default="xslt">
+ <map:transformer name="browser-update" src="org.apache.cocoon.ajax.BrowserUpdateTransformer"/>
+ </map:transformers>
+ <map:selectors>
+ <map:selector name="ajax-request" src="org.apache.cocoon.ajax.AjaxRequestSelector"/>
</map:selectors>
</map:components>
@@ -48,7 +48,7 @@
executeUsecase() flowscript has completed and issued a redirect,
which is matched here.
-->
- <map:match pattern="view/*/**" internal-only="true">
+ <map:match pattern="usecases-view/*/**" internal-only="true">
<map:generate type="jx" src="fallback://lenya/{2}"/>
<map:transform type="browser-update"/>
@@ -64,12 +64,12 @@
<map:parameter name="resources-uri" value="{page-envelope:context-prefix}/cforms"/>
</map:transform>
<map:transform src="fallback://lenya/xslt/cforms/add-xhtml-namespace.xsl"/>
- <map:match pattern="view/menu/**">
+ <map:match pattern="usecases-view/menu/**">
<map:transform src="cocoon://lenya-page/{page-envelope:publication-id}/{page-envelope:area}/default.xml"/>
</map:match>
- <map:select type="ajax-request">
- <map:when test="true">
- <map:serialize type="xml"/>
+ <map:select type="ajax-request">
+ <map:when test="true">
+ <map:serialize type="xml"/>
</map:when>
</map:select>
<map:select type="request-parameter">
Modified: lenya/trunk/src/webapp/lenya/usecases/usecases.js
URL: http://svn.apache.org/viewvc/lenya/trunk/src/webapp/lenya/usecases/usecases.js?view=diff&rev=468474&r1=468473&r2=468474
==============================================================================
--- lenya/trunk/src/webapp/lenya/usecases/usecases.js (original)
+++ lenya/trunk/src/webapp/lenya/usecases/usecases.js Fri Oct 27 10:44:55 2006
@@ -16,299 +16,347 @@
*/
/* $Id$ */
- cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");
- cocoon.load("fallback://lenya/usecases/usecases-util.js");
+cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");
-/* Helper method to add all request parameters to a usecase */
-function passRequestParameters(flowHelper, usecase) {
+//placeholders for custom flow code:
+var customLoopFlow = undefined;
+var customSubmitFlow = undefined;
+
+/**
+ * Get the current usecase.
+ *
+ * @param the name of the usecase
+ * @return a org.apache.lenya.cms.usecase.Usecase object
+ */
+function getUsecase(usecaseName) {
+ var flowHelper;
+ var request;
+ var sourceUrl;
+ var usecaseResolver;
+ var usecase;
+ try {
+ flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
+ request = flowHelper.getRequest(cocoon);
+ sourceUrl = Packages.org.apache.lenya.util.ServletHelper.getWebappURI(request);
+ usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
+ usecase = usecaseResolver.resolve(sourceUrl, usecaseName);
+ usecase.setSourceURL(sourceUrl);
+ usecase.setName(usecaseName);
+ } catch (exception) {
+ log("error", "Error in getUsecase(): " + exception);
+ log("debug", "usecaseName = " + usecaseName);
+ log("debug", "flowHelper = " + flowHelper);
+ log("debug", "request = " + request);
+ log("debug", "sourceUrl = " + sourceUrl);
+ log("debug", "usecaseResolver = " + usecaseResolver);
+ log("debug", "usecase = " + usecase);
+
+ throw exception;
+ } finally {
+ cocoon.releaseComponent(flowHelper);
+ cocoon.releaseComponent(usecaseResolver);
+ }
+ return usecase;
+}
+
+/**
+ * Release a usecase. Since usecases are Avalon Components, they must
+ * be released before a continuation is created.
+ *
+ * @param a org.apache.lenya.cms.usecase.Usecase object
+ */
+function releaseUsecase(usecase) {
+ var usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
+ try {
+ usecaseResolver.release(usecase);
+ } finally {
+ cocoon.releaseComponent(usecaseResolver);
+ }
+}
+
+/**
+ * Pass all parameters from the current request to a usecase
+ * (except lenya.usecase, lenya.continuation and submit).
+ *
+ * @param a org.apache.lenya.cms.usecase.Usecase object
+ */
+function passRequestParameters(usecase) {
+ var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
var names = cocoon.request.getParameterNames();
while (names.hasMoreElements()) {
var name = names.nextElement();
- if (!name.equals("lenya.usecase")
- && !name.equals("lenya.continuation")
- && !name.equals("submit")) {
-
+ // some parameters are handled elsewhere:
+ if (!name.equals("lenya.usecase")
+ && !name.equals("lenya.continuation")
+ && !name.equals("submit")) {
+ // pass the rest on:
var value = flowHelper.getRequest(cocoon).get(name);
-
var string = new Packages.java.lang.String();
var vector = new Packages.java.util.Vector();
if (string.getClass().isInstance(value) || vector.getClass().isInstance(value)) {
// use getParameters() to avoid character encoding problems
var values = flowHelper.getRequest(cocoon).getParameterValues(name);
- if (values.length < 2) {
+ if (values.length < 2) {
usecase.setParameter(name, values[0]);
- } else {
- usecase.setParameter(name, values);
- }
- }
- else {
+ } else {
+ usecase.setParameter(name, values);
+ }
+ } else {
usecase.setPart(name, value);
}
-
}
}
+ cocoon.releaseComponent(flowHelper);
}
+/**
+ * Load the custom flow functions as provided in the view
+ * configuration, if any.
+ *
+ * @param a org.apache.lenya.cms.usecase.UsecaseView object
+ */
+function loadCustomFlow(view) {
+ var flowUri = view.getCustomFlow();
+ if (flowUri != null && flowUri != "") { // for some reason, flowUri is not correctly cast into a Boolean, so "if (flowUri)" does not work
+ log("debug", "customFlow uri: [" + flowUri + "]");
+ //loopFlow = new Function(prepareCustomFlow(flowUri));
+ cocoon.load(flowUri);
+ }
+}
-/*
- * Main function to execute a usecase.
+
+/**
+ * Log messages via cocoon.log.
*
- * Uses request parameter "lenya.usecase" to determine what
- * usecase to execute.
+ * @param level, one of ("debug"|"warn"|"error")
+ * @param message (a string).
+ * @param usecaseName (a string).
+ */
+function log(level, message, usecaseName) {
+ var msg = "usecases.js::executeUsecase() "
+ + (usecaseName ? "with lenya.usecase=[" + usecaseName + "]" : "")
+ + ": "
+ + message;
+ switch (level) {
+ case "debug":
+ if (cocoon.log.isDebugEnabled())
+ cocoon.log.debug(msg);
+ break;
+ case "info":
+ cocoon.log.info(msg);
+ break;
+ case "warn":
+ cocoon.log.warn(msg);
+ break;
+ case "error":
+ cocoon.log.error(msg);
+ break;
+ default:
+ cocoon.log.error(msg + "[Unknown log level " + level + "]");
+ break;
+ }
+}
+
+/**
+ * The Loop stage of the flow, in which a view is displayed.
+ * <em>Note:</em> All Avalon components should be released before calling
+ * this function! This means especially that you cannot hold a usecase object,
+ * hence the proxy.
*
+ * @param a org.apache.lenya.cms.usecase.UsecaseView object
+ * @param a org.apache.lenya.cms.usecase.UsecaseProxy object
+ * @param a generic Javascript object for custom flow code to preserve state information (not used by default)
+ *
+ * This function invokes customLoopFlow if it exists.
+ * Otherwise it falls back to defaultLoopFlow.
*/
-function executeUsecase() {
+function loopFlow(view, proxy, generic) {
+ if (customLoopFlow != undefined) {
+ log("info", "Using customLoopFlow function", proxy.getName());
+ return customLoopFlow(view, proxy, generic);
+ } else{
+ return defaultLoopFlow(view, proxy);
+ }
+}
- var usecaseName = cocoon.parameters["usecaseName"];
- var view;
- var proxy;
- var menu = "nomenu";
-
- var usecaseResolver;
- var usecase;
- var sourceUrl;
-
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase() called, parameter lenya.usecase = [" + usecaseName + "]");
-
- try {
+/**
+ * The Submit stage of the flow, in which a user interaction is processed.
+ * and the usecase is advanced. If the user has submitted, the usecase is executed.
+ *
+ * @param a org.apache.lenya.cms.usecase.Usecase object
+ * @param a generic Javascript object for custom flow code to preserve state information (not used by default)
+ * @return a string with the return state ("success"|"cancel"|"continue").
+ *
+ * This function invokes customSubmitFlow if it exists.
+ * Otherwise it falls back to defaultSubmitFlow.
+ */
+function submitFlow(usecase, generic) {
+ if (customSubmitFlow != null) {
+ log("info", "Using customSubmitFlow function", usecase.getName());
+ return customSubmitFlow(usecase, generic);
+ } else{
- var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
- var request = flowHelper.getRequest(cocoon);
- sourceUrl = Packages.org.apache.lenya.util.ServletHelper.getWebappURI(request);
+ return defaultSubmitFlow(usecase);
+ }
+}
- usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
- usecase = usecaseResolver.resolve(sourceUrl, usecaseName);
- usecase.setSourceURL(sourceUrl);
- usecase.setName(usecaseName);
- view = usecase.getView();
- if (view && view.showMenu()) {
- menu = "menu";
+/**
+ * @see loopFlow.
+ */
+function defaultLoopFlow(view, proxy) {
+ var viewUri = view.getViewURI();
+ // we used to allow a cocoon:/ prefix (which sendPageXXX does not handle),
+ // but it is now deprecated!
+ if (viewUri.startsWith("cocoon:/")) {
+ viewUri = viewUri.substring(new Packages.java.lang.String("cocoon:/").length());
+ log("warn", "The use of the cocoon:/ protocol prefix in the <view uri=\"...\"> attribute is deprecated!");
+ }
+ if (! viewUri.startsWith("/")) {
+ // a local URI must be handled by usecase.xmap, which assumes a prefix "usecases-view/[menu|nomenu]/
+ // that determines whether the menu is to be displayed. this mechanism is used by most lenya core usecases.
+ viewUri = "usecases-view/"
+ + (view.showMenu() ? "menu" : "nomenu")
+ + "/" + viewUri;
+ }
+ if (view.createContinuation()) {
+ log("debug", "Creating view and continuation, calling Cocoon with viewUri = [" + viewUri + "]");
+ cocoon.sendPageAndWait(viewUri, { "usecase" : proxy });
+ } else {
+ log("debug", "Creating view without continuation (!), calling Cocoon with viewUri = [" + viewUri + "]");
+ cocoon.sendPage(viewUri, { "usecase" : proxy});
+ cocoon.exit(); // we're done.
+ }
+}
+
+/**
+ * @see submitFlow
+ */
+function defaultSubmitFlow(usecase) {
+ usecase.advance();
+ if (cocoon.request.getParameter("submit")||cocoon.request.getParameter("lenya.submit")=="ok") {
+ usecase.checkExecutionConditions();
+ if (! usecase.hasErrors()) {
+ return executeFlow(usecase);
}
+ } else if (cocoon.request.getParameter("cancel")) {
+ usecase.cancel();
+ return "cancel";
+ }
+ return "continue"
+}
- passRequestParameters(flowHelper, usecase);
+/**
+ * The Execute stage of the flow, in which the usecase is finally executed.
+ *
+ * @param a org.apache.lenya.cms.usecase.Usecase object
+ * @return a string with the return state ("success"|"continue").
+ */
+function executeFlow(usecase) {
+ usecase.execute();
+ if (! usecase.hasErrors()) {
+ usecase.checkPostconditions();
+ if (! usecase.hasErrors()) {
+ return "success";
+ }
+ }
+ return "continue";
+}
+
+/**
+ * Redirect to target URL after finishing the usecase.
+ *
+ * @param the target URL
+ */
+function redirect(targetUrl) {
+ var flowHelper = cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");
+ var contextPath = flowHelper.getRequest(cocoon).getContextPath();
+ cocoon.releaseComponent(flowHelper);
+ cocoon.redirectTo(contextPath + targetUrl, true);
+}
+
+
+
+/**
+ * Main function to execute a usecase. This is called from <map:flow/>.
+ *
+ * Uses request parameter "lenya.usecase" to determine what
+ * usecase to execute.
+ *
+ * Since "usecase" and "flowHelper" are avalon components,
+ * they must be released before a continuation is created.
+ * In order to preserve state information, a "proxy" object
+ * is used.
+ */
+function executeUsecase() {
+
+ var usecaseName;
+ var usecase; // the Usecase object
+ var proxy; // a UsecaseProxy to make the usecase state persistent across continuations
+ var view; // the UsecaseView object that belongs to our usecase.
+ var state; // the state of the usecase ("continue"|"success"|"cancel");
+ var targetUrl; // URL to redirect to after completion.
+ var generic = new Object; // a generic helper object for custom flow code to preserve state information.
+
+ try {
+ usecaseName = cocoon.parameters["usecaseName"];
+ usecase = getUsecase(usecaseName);
+ passRequestParameters(usecase);
usecase.checkPreconditions();
usecase.lockInvolvedObjects();
+ // create proxy object to save usecase state
proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
+ view = usecase.getView();
+ log("debug", "Successfully prepared usecase.", usecaseName);
+ } catch (exception) {
+ log("error", "Could not prepare usecase: " + exception, usecaseName);
+ throw exception;
+ } finally {
+ releaseUsecase(usecase);
}
- finally {
- /* done with usecase component, tell usecaseResolver to release it */
- if (usecaseResolver != null) {
- if (usecase != null) {
- usecaseResolver.release(usecase);
- usecase = undefined;
- }
- cocoon.releaseComponent(usecaseResolver);
- }
- }
-
- var success = false;
- var targetUrl;
- var form;
- var scriptString;
- var evalFunc;
- var generic;
-
- /*
- * If the usecase has a view, this means we want to display something
- * to the user before proceeding. This also means the usecase consists
- * several steps; repeated until the user chooses to submit or cancel.
- *
- * If the usecase does not have a view, it is simply executed.
- */
-
- if (view) {
- var ready = false;
- while (!ready) {
-
+ loadCustomFlow(view);
+ if (view.getViewURI()) {
+ // If the usecase has a view uri, this means we want to display something
+ // to the user before proceeding. This also means the usecase can consist
+ // of several steps; repeated until the user chooses to submit or cancel.
+ do {
+ // show the view:
try {
- var templateUri = view.getTemplateURI();
- if (templateUri) {
- var viewUri = "view/" + menu + "/" + view.getTemplateURI();
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", creating view, calling Cocoon with viewUri = [" + viewUri + "]");
- if (view.getViewType()=="cforms"){
- /*
- * var generic - Generic object that can be used in all custom flow code
- * that is added by usecases. Right now it focus on document opertations
- * but the properties should be extended through user/dev feedback.
- * The intention of this var is to provide a generic global flow object
- * (like in lots of cocoon examples) that can be accessed through out the different flow stages.
- * Alternatively one can use the invoking java class by providing bean properties methods
- * (getter/setter methods) in this class and use them within the extensions (see usecase doc).
- *
- * FIXME: Add cforms integration howto to the documentation.
- */
- generic={proxy:proxy,uri:null,doc:null,generic:null};
- var viewDef = "fallback://lenya/"+ view.getCformDefinition();
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase()::cforms in usecase " + usecaseName + ", preparing formDefinition, calling Cocoon with viewUri = [" + viewDef + "]");
-
- // custom flowscript
- if (view.getCformIntro()!=null){
- scriptString= view.getCformIntro();
- evalFunc = new Function (scriptString);
- evalFunc();
- }
-
- // form definition
- form = new Form(viewDef);
-
- // custom flowscript
- if (view.getCformDefinitionBody()!=null){
- scriptString= view.getCformDefinitionBody();
- evalFunc = new Function ("form","generic",scriptString);
- evalFunc(form,generic);
- }
-
- // form binding
- if (view.getCformBinding() != null){
- var viewBind = "fallback://lenya/"+ view.getCformBinding();
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase()::cforms in usecase " + usecaseName + ", preparing formDefinition, calling Cocoon with viewUri = [" + viewBind + "]");
-
- // form binding
- form.createBinding(viewBind);
-
- // custom flowscript
- if (view.getCformBindingBody()!=null){
- scriptString= view.getCformBindingBody();
- evalFunc = new Function ("form","generic",scriptString);
- evalFunc(form,generic);
- }
- }
- // form template
- form.showForm(viewUri, {"usecase" : proxy});
-//DEBUG ajax="true"
-// print("form.showForm after");
- }
- else{
- cocoon.sendPageAndWait(viewUri, {
- "usecase" : proxy
- });
- }
- }
- else {
- var viewUri = view.getViewURI();
- if (viewUri.startsWith("cocoon:/")) {
- viewUri = viewUri.substring(new Packages.java.lang.String("cocoon:/").length());
- }
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", creating view, calling Cocoon with viewUri = [" + viewUri + "]");
-
- cocoon.sendPageAndWait(viewUri, {
- "usecase" : proxy
- });
- }
- }
- catch (exception) {
- /* if an exception was thrown by the view, allow the usecase to rollback the transition */
+ loopFlow(view, proxy, generic); //usecase must be released here!
+ } catch (exception) {
+ // if something went wrong, try and rollback the usecase:
+ log("error", "Exception during loopFlow(): " + exception, usecaseName);
try {
- usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
- usecase = usecaseResolver.resolve(sourceUrl, usecaseName);
+ usecase = getUsecase(usecaseName);
proxy.setup(usecase);
usecase.cancel();
throw exception;
+ } finally {
+ releaseUsecase(usecase);
}
- finally {
- if (usecaseResolver != null) {
- if (usecase != null) {
- usecaseResolver.release(usecase);
- usecase = undefined;
- }
- cocoon.releaseComponent(usecaseResolver);
- }
- }
- }
-
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", after view, now advancing in usecase");
-
- try {
- usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
- usecase = usecaseResolver.resolve(sourceUrl, usecaseName);
- proxy.setup(usecase);
-
- passRequestParameters(flowHelper, usecase);
- usecase.advance();
- //HEADSUP: Cform do not allow id="submit" anymore. Use id="ok" for now (till it is settled on cocoon-dev).
- if (cocoon.request.getParameter("submit")||cocoon.request.getParameter("lenya.submit")=="ok") {
- usecase.checkExecutionConditions();
- if (! usecase.hasErrors()) {
- if (view.getViewType()=="cforms"){
- // custom flowscript
- if (view.getCformOutro()!=null){
- scriptString= view.getCformOutro();
- evalFunc = new Function ("form","generic",scriptString);
- evalFunc(form,generic);
- }
- }
- usecase.execute();
- if (! usecase.hasErrors()) {
- usecase.checkPostconditions();
- if (! usecase.hasErrors()) {
- ready = true;
- success = true;
- }
- }
- }
- }
- else if (cocoon.request.getParameter("cancel")) {
- usecase.cancel();
- ready = true;
- }
- if (!ready) {
- proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
- }
- targetUrl = usecase.getTargetURL(success);
}
- catch (exception) {
- /* allow usecase to rollback the transition */
- usecase.cancel();
- throw exception;
- }
- finally {
- if (usecaseResolver != null) {
- if (usecase != null) {
- usecaseResolver.release(usecase);
- usecase = undefined;
- }
- cocoon.releaseComponent(usecaseResolver);
- }
- }
- }
- }
- else {
- try {
- usecaseResolver = cocoon.getComponent("org.apache.lenya.cms.usecase.UsecaseResolver");
- usecase = usecaseResolver.resolve(sourceUrl, usecaseName);
+ log("debug", "Advancing in usecase.", usecaseName);
+ // restore the usecase state and handle the user input:
+ usecase = getUsecase(usecaseName);
proxy.setup(usecase);
-
- usecase.execute();
- if (! usecase.hasErrors()) {
- usecase.checkPostconditions();
- if (! usecase.hasErrors()) {
- success = true;
- }
- }
- targetUrl = usecase.getTargetURL(success);
- }
- catch (exception) {
- /* allow usecase to rollback the transition */
- usecase.cancel();
- throw exception;
- }
- finally {
- usecaseResolver.release(usecase);
- usecase = undefined;
- cocoon.releaseComponent(usecaseResolver);
- }
+ passRequestParameters(usecase);
+ state = submitFlow(usecase, generic);
+ // create a new proxy with the updated usecase state
+ proxy = new Packages.org.apache.lenya.cms.usecase.UsecaseProxy(usecase);
+ releaseUsecase(usecase);
+ } while (state == "continue");
+ // If the usecase does not have a view uri, we can directly jump to
+ // executeFlow().
+ } else {
+ usecase = getUsecase(usecaseName);
+ proxy.setup(usecase);
+ passRequestParameters(usecase);
+ state = executeFlow(usecase);
+ releaseUsecase(usecase);
}
- var url = flowHelper.getRequest(cocoon).getContextPath() + targetUrl;
-
- if (cocoon.log.isDebugEnabled())
- cocoon.log.debug("usecases.js::executeUsecase() in usecase " + usecaseName + ", completed, redirecting to url = [" + url + "]");
- cocoon.redirectTo(url, true);
-
-}
+ //getTargetURL takes a boolean that is true on success:
+ targetUrl = usecase.getTargetURL(state == "success");
+ log("debug", "Completed, redirecting to url = [context:/" + targetUrl + "]", usecaseName);
+ // jump to the appropriate URL:
+ redirect(targetUrl);
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org