You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/08/26 07:46:58 UTC

svn commit: r240168 [5/30] - in /struts/sandbox/trunk/ti: ./ core/src/java/org/apache/ti/ core/src/java/org/apache/ti/config/ core/src/java/org/apache/ti/config/mapper/ core/src/java/org/apache/ti/core/ core/src/java/org/apache/ti/core/factory/ core/sr...

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalOutputFormTypeException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalOutputFormTypeException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalOutputFormTypeException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalOutputFormTypeException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception that occurs when the first output form for a {@link Forward} resolves to a
+ * {@link org.apache.ti.pageflow.annotations.ti.forward @ti.forward} annotation whose
+ * {@link org.apache.ti.pageflow.annotations.ti.forward#outputFormBean outputFormBean} or
+ * {@link org.apache.ti.pageflow.annotations.ti.forward#outputFormBeanType outputFormBeanType}
+ * attribute demands a different form type.
+ *
+ * @see Forward#addOutputForm
+ */
+public class IllegalOutputFormTypeException extends IllegalOutputFormException {
+
+    private String _requiredType;
+
+
+    /**
+     * @param forwardName    the name of the relevant {@link Forward}.
+     * @param flowController the current {@link FlowController} instance.
+     * @param outputFormType the type name of the relevant output form.
+     * @param requiredType   the name of the required form type.
+     */
+    public IllegalOutputFormTypeException(String forwardName, FlowController flowController,
+                                          String outputFormType, String requiredType) {
+        super(forwardName, flowController, outputFormType);
+        _requiredType = requiredType;
+    }
+
+    /**
+     * Get the name of the required form type.
+     *
+     * @return a String that is the name of the required form type.
+     */
+    public String getRequiredType() {
+        return _requiredType;
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{getForwardName(), getActionName(), getFlowControllerURI(), getOutputFormType(),
+                            _requiredType};
+    }
+
+    public String[] getMessageParts() {
+        return new String[]
+        {
+            "The forward \"", "\" on action ", " in page flow ", " has a first output form of type ",
+            ", but is declared to require type ", "."
+        };
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalPageInputException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalPageInputException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalPageInputException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalPageInputException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception that occurs when a action output has been added to a forward that resolves to a
+ * {@link org.apache.ti.pageflow.annotations.ti.forward @ti.forward} annotation marked with
+ * <code>{@link org.apache.ti.pageflow.annotations.ti.forward#redirect redirect}=true</code>.
+ * action outputs may not be used on redirect forwards.
+ *
+ * @deprecated Use {@link IllegalActionOutputException} instead.
+ */
+public class IllegalPageInputException extends IllegalActionOutputException {
+
+    /**
+     * Constructor.
+     *
+     * @param forwardName      the name of the relevant {@link Forward}.
+     * @param flowController   the current {@link FlowController} instance.
+     * @param actionOutputName the name of the relevant action output.
+     */
+    public IllegalPageInputException(String forwardName, FlowController flowController, String actionOutputName) {
+        super(forwardName, flowController, actionOutputName);
+    }
+
+    /**
+     * Get the name of the relevant action output.
+     *
+     * @return a String that is the name of the relevant action output.
+     */
+    public String getPageInputName() {
+        return getActionOutputName();
+    }
+
+    /**
+     * Set the name of the relevant action output.
+     *
+     * @param actionOutputName a String that is the name of the relevant action output.
+     */
+    public void setPageInputName(String actionOutputName) {
+        setActionOutputName(actionOutputName);
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalRedirectOutputFormException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalRedirectOutputFormException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalRedirectOutputFormException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/IllegalRedirectOutputFormException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception that occurs when an output form has been added to a forward that resolves to a
+ * {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward} annotation marked with
+ * <code>{@link org.apache.ti.pageflow.annotations.ti.forward#redirect redirect}=true</code>.
+ * Output forms may not be used on redirect forwards.
+ *
+ * @see Forward#addOutputForm
+ */
+public class IllegalRedirectOutputFormException extends IllegalOutputFormException {
+
+    /**
+     * @param forwardName    the name of the relevant {@link Forward}.
+     * @param flowController the current {@link FlowController} instance.
+     * @param outputFormType the type name of the relevant output form.
+     */
+    public IllegalRedirectOutputFormException(String forwardName, FlowController flowController, String outputFormType) {
+        super(forwardName, flowController, outputFormType);
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{getForwardName(), getActionName(), getFlowControllerURI(), getOutputFormType()};
+    }
+
+    public String[] getMessageParts() {
+        return new String[]
+        {
+            "The forward \"", "\" on action ", " in page flow ", " has at least one output form (type ",
+            "), but is set to redirect=\"true\". Output forms may not be used on redirect forwards."
+        };
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/InfiniteReturnToActionException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/InfiniteReturnToActionException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/InfiniteReturnToActionException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/InfiniteReturnToActionException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception that occurs when the
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#previousAction previousAction}</code>
+ * attribute is used on a {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward}, a
+ * {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction}, or a
+ * {@link org.apache.ti.pageflow.annotations.ti.conditionalForward &#64;ti.conditionalForward},
+ * but the previous action was the same as the current action (an infinite loop).
+ */
+public class InfiniteReturnToActionException extends FlowControllerException {
+
+    public InfiniteReturnToActionException(FlowController fc) {
+        super(fc);
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{getActionName(), getFlowControllerURI()};
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]
+        {
+            "Infinite loop of returnTo=\"action\" for action ",
+            " in Page Flow ",
+            "."
+        };
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>false</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return false;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/LoginExpiredException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/LoginExpiredException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/LoginExpiredException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/LoginExpiredException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception thrown when {@link NotLoggedInException} would be thrown, <i>and</i> when the
+ * current HttpServletRequest refers to a session that no longer exists.
+ */
+public class LoginExpiredException
+        extends NotLoggedInException {
+
+    public LoginExpiredException(FlowController fc) {
+        super(fc);
+    }
+
+    public String[] getMessageParts() {
+        return new String[]
+        {
+            "action ",
+            " on Page Flow ",
+            " requires a current user, but there is no logged-in user.  This may be due to an expired session."
+        };
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MismatchedActionOutputException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MismatchedActionOutputException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MismatchedActionOutputException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MismatchedActionOutputException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+/**
+ * Exception that occurs in iterative development mode when an action output attached to a {@link Forward} is of a
+ * different type than was declared.
+ */
+public class MismatchedActionOutputException extends FlowControllerException {
+
+    private String _actionOutputName;
+    private String _expectedType;
+    private String _actualType;
+    private String _forwardName;
+
+    public MismatchedActionOutputException(FlowController flowController, String actionOutputName,
+                                           String forwardName, String expectedType, String actualType) {
+        super(flowController);
+        _actionOutputName = actionOutputName;
+        _expectedType = expectedType;
+        _actualType = actualType;
+        _forwardName = forwardName;
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{_actionOutputName, _forwardName, getActionName(), getFlowControllerURI(), _actualType,
+                            _expectedType};
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]{"The action output \"", "\" on forward \"", "\" (action ", " in Page Flow ", ") is of type ",
+                            ", but was declared to expect type ", "."};
+    }
+
+    public String getActionOutputName() {
+        return _actionOutputName;
+    }
+
+    public String getForwardName() {
+        return _forwardName;
+    }
+
+    public String getExpectedType() {
+        return _expectedType;
+    }
+
+    public String getActualType() {
+        return _actualType;
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>false</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return false;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MissingActionOutputException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MissingActionOutputException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MissingActionOutputException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/MissingActionOutputException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+/**
+ * Exception that occurs when a required action output is missing from a {@link Forward}.
+ */
+public class MissingActionOutputException
+        extends FlowControllerException {
+
+    private String _actionOutputName;
+    private String _forwardName;
+
+    public MissingActionOutputException(FlowController flowController, String actionOutputName,
+                                        String forwardName) {
+        super(flowController);
+        _actionOutputName = actionOutputName;
+        _forwardName = forwardName;
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{_actionOutputName, _forwardName, getActionName(), getFlowControllerURI()};
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]{"The required action output \"", "\" was not present on forward \"",
+                            "\" (action ", " in Page Flow ", ")."};
+    }
+
+    public String getActionOutputName() {
+        return _actionOutputName;
+    }
+
+    public String getForwardName() {
+        return _forwardName;
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>false</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return false;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfig.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfig.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfig.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfig.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import com.opensymphony.xwork.config.entities.ActionConfig;
+import com.opensymphony.xwork.config.entities.ResultConfig;
+import org.apache.ti.pageflow.internal.InternalConstants;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ModuleConfig {
+
+    private boolean _isNestedFlow;
+    private boolean _isLongLivedFlow;
+    private String _controllerClassName;
+    private String _namespace;
+    private boolean _isReturnToPageDisabled;
+    private boolean _isReturnToActionDisabled;
+    private LinkedHashMap/*<String, String>*/ _referencedSharedFlowTypes;
+    private boolean _isSharedFlow;
+    private String _overrideMultipartClass = null;
+    private String _overrideMemFileSize = null;
+    private boolean _forceMultipartDisabled = false;
+    private Map/*<String, ActionConfig>*/ _actionConfigs;
+    private Map/*<String, List>*/ _formBeanTypeToAttrs;
+    private Map/*<String, String>*/ _formBeanAttrToType;
+
+
+    protected ModuleConfig() {
+    }
+
+    public ModuleConfig(String namespace, ActionConfig moduleMetadata, Map actionConfigs) {
+        _namespace = namespace;
+        _actionConfigs = actionConfigs;
+        Map params = moduleMetadata.getParams();
+        _controllerClassName = (String) params.get("controllerClassName");
+        assert _controllerClassName != null : "No controllerClassName for module " + namespace;
+        _isNestedFlow = Boolean.valueOf((String) params.get("nestedFlow")).booleanValue();
+        _isLongLivedFlow = Boolean.valueOf((String) params.get("longLivedFlow")).booleanValue();
+        _isSharedFlow = Boolean.valueOf((String) params.get("sharedFlow")).booleanValue();
+        _isReturnToPageDisabled = Boolean.valueOf((String) params.get("returnToPageDisabled")).booleanValue();
+        _isReturnToActionDisabled = Boolean.valueOf((String) params.get("returnToActionDisabled")).booleanValue();
+        // TODO: parse shared flow references
+        // TODO: parse multipart params
+        
+        // Cache:
+        //     - a Map of type name (String) -> list of form bean attribute names (List).
+        //     - a Map of form bean attribute (String) -> form bean type name (String)
+        HashMap formBeanTypeToAttrs = new HashMap();
+        HashMap formBeanAttrToType = new HashMap();
+        for (Iterator i = getActionConfigs().entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            String actionName = (String) entry.getKey();
+            ActionConfig actionConfig = (ActionConfig) entry.getValue();
+            Map actionParams = actionConfig.getParams();
+            String formBeanAttr = (String) actionParams.get(InternalConstants.FORM_BEAN_ATTR_PARAM);
+
+            if (formBeanAttr != null) {
+                String formBeanType = (String) actionParams.get(InternalConstants.FORM_BEAN_TYPE_PARAM);
+                assert formBeanType != null : "No form bean type for attr " + formBeanAttr + " on action " + actionName;
+                List attrNames = (List) formBeanTypeToAttrs.get(formBeanType);
+                if (attrNames == null) {
+                    attrNames = new ArrayList();
+                    formBeanTypeToAttrs.put(formBeanType, attrNames);
+                }
+                attrNames.add(formBeanAttr);
+
+                assert !formBeanAttrToType.containsKey(formBeanAttr)
+                        || formBeanAttrToType.get(formBeanAttr).equals(formBeanType)
+                        : "Duplicate entry for attr \"" + formBeanAttr + "\": " + formBeanAttrToType.get(formBeanAttr)
+                        + ", " + formBeanType;
+                formBeanAttrToType.put(formBeanAttr, formBeanType);
+            }
+        }
+
+        _formBeanTypeToAttrs = Collections.unmodifiableMap(formBeanTypeToAttrs);
+        _formBeanAttrToType = Collections.unmodifiableMap(formBeanAttrToType);
+    }
+
+    public String getNamespace() {
+        return _namespace;
+    }
+
+    public void setNestedFlow(boolean nestedFlow) {
+        _isNestedFlow = nestedFlow;
+    }
+
+    public boolean isNestedFlow() {
+        return _isNestedFlow;
+    }
+
+    public boolean isLongLivedFlow() {
+        return _isLongLivedFlow;
+    }
+
+    public void setLongLivedFlow(boolean longLivedFlow) {
+        _isLongLivedFlow = longLivedFlow;
+    }
+
+    public String getControllerClassName() {
+        return _controllerClassName;
+    }
+
+    public void setControllerClassName(String controllerClassName) {
+        _controllerClassName = controllerClassName;
+    }
+
+    public ActionConfig findActionConfig(String actionName) {
+        return (ActionConfig) getActionConfigs().get(actionName);
+    }
+
+    /**
+     * @return a Map of action-name (String) to action-config ({@link ActionConfig}).
+     */
+    public Map getActionConfigs() {
+        // TODO: we could also get this with:
+        //     ConfigurationManager.getConfiguration().getRuntimeConfiguration().getActionConfigs().get(getNamespace());
+        //     Is there any disadvantage to holding onto them?
+        return _actionConfigs;
+    }
+
+    public ResultConfig findGlobalResult(String resultName) {
+        throw new UnsupportedOperationException("NYI"); // TODO: NYI        
+    }
+
+    /**
+     * @return a Map of type name (String) -> list of form bean attribute names (List).
+     */
+    public Map getFormBeanAttributeNames() {
+        return _formBeanTypeToAttrs;
+    }
+
+    /**
+     * @return a Map of form bean attribute (String) -> form bean type name (String)
+     */
+    public Map getFormBeans() {
+        return _formBeanAttrToType;
+    }
+
+    public boolean isReturnToActionDisabled() {
+        return _isReturnToActionDisabled;
+    }
+
+    public void setReturnToActionDisabled(boolean returnToActionDisabled) {
+        _isReturnToActionDisabled = returnToActionDisabled;
+    }
+
+    public boolean isReturnToPageDisabled() {
+        return _isReturnToPageDisabled;
+    }
+
+    public void setReturnToPageDisabled(boolean returnToPageDisabled) {
+        _isReturnToPageDisabled = returnToPageDisabled;
+    }
+
+    public boolean isSharedFlow() {
+        return _isSharedFlow;
+    }
+
+    public void setSharedFlow(boolean sharedFlow) {
+        _isSharedFlow = sharedFlow;
+    }
+
+    public String getOverrideMultipartClass() {
+        return _overrideMultipartClass;
+    }
+
+    public void setOverrideMultipartClass(String overrideMultipartClass) {
+        _overrideMultipartClass = overrideMultipartClass;
+    }
+
+    public String getOverrideMemFileSize() {
+        return _overrideMemFileSize;
+    }
+
+    public void setOverrideMemFileSize(String overrideMemFileSize) {
+        _overrideMemFileSize = overrideMemFileSize;
+    }
+
+    public boolean isForceMultipartDisabled() {
+        return _forceMultipartDisabled;
+    }
+
+    public void setForceMultipartDisabled(boolean forceMultipartDisabled) {
+        _forceMultipartDisabled = forceMultipartDisabled;
+    }
+
+    /**
+     * @return a Map of shared-flow-name (String) -> shared-flow-typename (String)
+     */
+    public Map/*<String, String>*/ getSharedFlowTypes() {
+        return _referencedSharedFlowTypes;
+    }
+
+    public String findExceptionHandler(Class exceptionType) {
+        do {
+            String handlerName = exceptionType.getName();
+            if (findActionConfig(handlerName) != null) return handlerName;
+            exceptionType = exceptionType.getSuperclass();
+        } while (exceptionType != null);
+
+        return null;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfigLocator.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfigLocator.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfigLocator.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/ModuleConfigLocator.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+/**
+ * Interface for specifying alternate locations for auto-registered Struts modules.
+ *
+ * @see org.apache.ti.pageflow.internal.DefaultModuleRegistrationHandler#getDefaultModuleConfigLocators
+ */
+public interface ModuleConfigLocator {
+
+    /**
+     * Get the resource path to a module config file, based on the module name.
+     *
+     * @param namespace the namespace of the module, e.g., "someModule" or "some/other/module".
+     * @return the webapp-relative path the the Struts module config file.
+     */
+    public String getModuleResourcePath(String namespace);
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoCurrentPageFlowException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoCurrentPageFlowException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoCurrentPageFlowException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoCurrentPageFlowException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.pageflow.internal.NavigateToException;
+import org.apache.ti.pageflow.xwork.NavigateToResult;
+
+
+/**
+ * Exception that occurs when the
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#previousAction previousAction}</code>,
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#currentPage currentPage}</code>, or
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#previousPage previousPage}</code>
+ * attribute is used on a {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward}, a
+ * {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction}, or a
+ * {@link org.apache.ti.pageflow.annotations.ti.conditionalForward &#64;ti.conditionalForward},
+ * but there is no current page flow.  This may happen when the user session expires, or when the web application has
+ * been redeployed.
+ */
+public class NoCurrentPageFlowException extends NavigateToException {
+
+    public NoCurrentPageFlowException(NavigateToResult result) {
+        super(result, null);
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]{"No current page flow for navigateTo=", " on action ", "."};
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>true</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return true;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoMatchingActionMethodException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoMatchingActionMethodException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoMatchingActionMethodException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoMatchingActionMethodException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.util.Bundle;
+
+
+/**
+ * Exception that occurs when the current action method does not accept the type of form bean passed in the
+ * {@link Forward} to the action.  This may happen when control is returned from a nested page flow, with a specified
+ * form bean type
+ * (<code>outputFormBean</code> or <code>outputFormBeanType</code> set on
+ * {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward},
+ * {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction}, or
+ * {@link org.apache.ti.pageflow.annotations.ti.conditionalForward &#64;ti.conditionalForward})
+ * but no action in the calling page flow accepts that form bean type.
+ */
+public class NoMatchingActionMethodException extends FlowControllerException {
+
+    private String _formClassName;
+
+
+    public NoMatchingActionMethodException(Object form, FlowController fc) {
+        super(fc);
+        _formClassName =
+                form != null ? form.getClass().getName() : Bundle.getString("PageFlow_NoFormString");
+    }
+
+    public String getFormClassName() {
+        return _formClassName;
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{getActionName(), _formClassName, getFlowControllerURI()};
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]
+        {
+            "Could not find matching action method for action=", ", form=", " on Page Flow ", "."
+        };
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>false</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return false;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousActionException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousActionException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousActionException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousActionException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.pageflow.internal.NavigateToException;
+import org.apache.ti.pageflow.xwork.NavigateToResult;
+
+
+/**
+ * Exception that occurs when the
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#previousAction previousAction}</code>
+ * attribute is used on a {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward}, a
+ * {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction}, or a
+ * {@link org.apache.ti.pageflow.annotations.ti.conditionalForward &#64;ti.conditionalForward},
+ * but thethere is no previously-run action in the page flow.
+ */
+public class NoPreviousActionException extends NavigateToException {
+
+    public NoPreviousActionException(NavigateToResult result, FlowController fc) {
+        super(result, fc);
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]{"No previous action for navigateTo=", " on action ", " in page flow ", "."};
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousPageException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousPageException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousPageException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NoPreviousPageException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.pageflow.internal.NavigateToException;
+import org.apache.ti.pageflow.xwork.NavigateToResult;
+
+
+/**
+ * Exception that occurs when the
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#previousPage previousPage}</code>
+ * or
+ * <code>navigateTo={@link org.apache.ti.pageflow.annotations.ti.NavigateTo#currentPage currentPage}</code>
+ * attribute is used on a {@link org.apache.ti.pageflow.annotations.ti.forward &#64;ti.forward}, a
+ * {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction}, or a
+ * {@link org.apache.ti.pageflow.annotations.ti.conditionalForward &#64;ti.conditionalForward},
+ * but there is no previously-shown page in the current page flow.
+ */
+public class NoPreviousPageException extends NavigateToException {
+
+    public NoPreviousPageException(NavigateToResult result, FlowController fc) {
+        super(result, fc);
+    }
+
+    protected String[] getMessageParts() {
+        return new String[]{"No previous page for navigateTo=", " on action ", " in page flow ", "."};
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NotLoggedInException.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NotLoggedInException.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NotLoggedInException.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/NotLoggedInException.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+/**
+ * Exception thrown when:
+ * <ul>
+ * <li>
+ * An action ({@link org.apache.ti.pageflow.annotations.ti.action &#64;ti.action}
+ * or {@link org.apache.ti.pageflow.annotations.ti.simpleAction &#64;ti.simpleAction})
+ * marked with <code>loginRequired=true</code> is hit when there is no logged-in user, or,
+ * </li>
+ * <li>
+ * An action marked with <code>rolesAllowed="</code><i>list of roles</i><code>"</code> is hit when there is
+ * no logged-in user.
+ * </li>
+ * </ul>
+ * If the requested session-ID is different than the current session-ID, the {@link LoginExpiredException}
+ * will be thrown instead of the <code>NotLoggedInException</code>.
+ */
+public class NotLoggedInException
+        extends FlowControllerException
+        implements ResponseErrorCodeSender {
+
+    public NotLoggedInException(FlowController fc) {
+        super(fc);
+    }
+
+    protected Object[] getMessageArgs() {
+        return new Object[]{getActionName(), getFlowControllerURI()};
+    }
+
+    public String[] getMessageParts() {
+        return new String[]
+        {
+            "action ", " on page flow ", " requires a current user, but there is no logged-in user."
+        };
+    }
+
+    public void sendResponseErrorCode(HttpServletResponse response) throws IOException {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST, getLocalizedMessage());
+    }
+
+    /**
+     * Tell whether the root cause may be session expiration in cases where the requested session ID is different than
+     * the actual session ID.  In this case, the answer is <code>true</code>.
+     */
+    public boolean causeMayBeSessionExpiration() {
+        return true;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowActionServlet.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowActionServlet.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowActionServlet.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowActionServlet.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,550 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.util.internal.InternalStringBuilder;
+
+import org.apache.ti.pageflow.internal.InternalConstants;
+import org.apache.ti.pageflow.internal.InternalUtils;
+import org.apache.ti.pageflow.handler.Handlers;
+import org.apache.ti.pageflow.handler.ForwardRedirectHandler;
+import org.apache.ti.pageflow.httpservlet.PageFlowContextListener;
+import org.apache.ti.util.internal.ServletUtils;
+import org.apache.ti.util.logging.Logger;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.action.RequestProcessor;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.List;
+import java.util.Collection;
+
+
+
+/**
+ * ActionServlet that dynamically registers modules based on naming/location conventions for Struts
+ * configuration files that are generated by the Page Flow compiler.  These files are located in
+ * /WEB-INF/.pageflow-struts-generated, and are named jpf-struts-config-<i>module-name</i>.xml.
+ * For auto-registration of config files in other locations, the user may specify additional
+ * {@link ModuleConfigLocator} classes in /WEB-INF/beehive-netui-config.xml using the
+ * <code>&lt;module-config-locators&gt;</code> element. 
+ */
+public class PageFlowActionServlet extends AutoRegisterActionServlet
+{
+    private static final Logger _log = Logger.getInstance( PageFlowActionServlet.class );
+    
+    private Handlers _handlers;
+    
+    private static final ModuleConfigLocator[] DEFAULT_MODULE_CONFIG_LOCATORS =
+            {
+                new DefaultModuleConfigLocator(),
+                new LegacyModuleConfigLocator()
+            };
+    
+    
+    /**
+     * Get the base list of ModuleConfigLocators, to specify locations for auto-registered Struts modules.  By default,
+     * this ActionServlet auto-registers Struts modules whose configuration files are located at
+     * "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>".  Overriding this method allows
+     * alternate locations to be specified.  When an unrecognized Struts module is requested, each registered
+     * ModuleConfigLocator is queried for a possible path to the configuration file for the module.  If the
+     * configuration file is found, the module is auto-registered against the file.
+     */
+    protected ModuleConfigLocator[] getDefaultModuleConfigLocators()
+    {
+        return DEFAULT_MODULE_CONFIG_LOCATORS;
+    }
+    
+    /**
+     * Default ModuleConfigLocator that looks for Struts module configuration files according to the pattern
+     * "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>".  An instance of this class
+     * is registered by default.
+     * 
+     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
+     */ 
+    public static class DefaultModuleConfigLocator implements ModuleConfigLocator, Serializable
+    {
+        public String getModuleConfigPath( String moduleName )
+        {
+            InternalStringBuilder moduleConfPath = new InternalStringBuilder( getGenDir() );
+            moduleConfPath.append( '/' ).append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_PREFIX );
+            
+            if ( moduleName.length() > 1 )
+            {
+                moduleConfPath.append( moduleName.replace( '/', '-' ) );
+            }
+            
+            moduleConfPath.append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_EXTENSION );
+            return moduleConfPath.toString();
+        }
+        
+        protected String getGenDir()
+        {
+            return PageFlowConstants.PAGEFLOW_MODULE_CONFIG_GEN_DIR;
+        }
+    }
+    
+    /**
+     * ModuleConfigLocator that looks for legacy Struts module configuration files according to the pattern
+     * "/WEB-INF/jpf-struts-config-<i>&lt;module&gt;</i>".  An instance of this class is registered by default.
+     * 
+     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
+     */ 
+    protected static class LegacyModuleConfigLocator extends DefaultModuleConfigLocator
+    {
+        protected String getGenDir()
+        {
+            return InternalConstants.WEBINF_DIR;
+        }
+    }
+
+    public void init()
+            throws ServletException
+    {
+        //
+        // Ensure that PageFlowContextListener gets to do its initializations, even if it's not registered in web.xml.
+        //
+        ServletContext servletContext = getServletContext();
+        
+        if ( ! PageFlowContextListener.isInit( servletContext ) )
+        {
+            PageFlowContextListener.performInitializations( servletContext );
+        }
+        
+        _handlers = Handlers.get( servletContext );
+        
+        super.init();
+    }
+
+    protected void process( HttpServletRequest request, HttpServletResponse response )
+            throws IOException, ServletException
+    {
+        // If this is a direct request for a shared flow (.jpfs) or a Faces backing bean (.jsfb), return a 404 status.
+        // These are not web-addressable.
+        String servletPath = InternalUtils.getRequestPath( request );
+        if ( servletPath.endsWith( InternalConstants.SHARED_FLOW_EXTENSION ) ||
+             servletPath.endsWith( InternalConstants.FACES_BACKING_EXTENSION ) )
+        {
+            if ( _log.isDebugEnabled() )
+            {
+                _log.debug( "Attempt to hit restricted URI " + servletPath + "; 404 error returned." );
+            }
+            
+            response.sendError( HttpServletResponse.SC_NOT_FOUND );
+            return;
+        }
+        
+        // First, reinitialize the page flow classloader, for reloading when recompile occurs in dev mode.
+        _handlers.getReloadableClassHandler().reloadClasses( );
+        
+        super.process( request, response );
+    }
+
+    /**
+     * Get the webapp-relative path to the Struts module configration file for a given module path.  By default,
+     * this is "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>", but alternate
+     * locations can be specified by adding {@link ModuleConfigLocator}s.  
+     * 
+     * @param modulePath the Struts module path.
+     * @return a String that is the path to the Struts configuration file, relative to the web application root.
+     * @see #getDefaultModuleConfigLocators
+     */ 
+    public String getModuleConfPath( String modulePath )
+    {
+        return super.getModuleConfPath( modulePath );
+    }
+    
+    /**
+     * Struts keeps track of the action servlet URL pattern (e.g., *.do) so it can construct action
+     * URIs.  We want to prevent it from noticing *.jpf so it doesn't use that to construct the URIs.
+     * 
+     * @exclude
+     */ 
+    public void addServletMapping( String servletName, String urlPattern )
+    {
+        if ( ! urlPattern.endsWith( PageFlowConstants.JPF_EXTENSION ) )
+        {
+            super.addServletMapping( servletName, urlPattern );
+        }
+    }
+    
+    /**
+     * Tell whether the given module can handle the given path.  If this is the root module (path=="") and it's a 
+     * Page Flow module, then it shouldn't try to handle any path that has a slash in it -- it only handles local
+     * actions.
+     */ 
+    protected boolean moduleCanHandlePath( ModuleConfig moduleConfig, RequestProcessor rp, String servletPath )
+    {
+        if ( moduleConfig.getPrefix().equals( "" ) && servletPath.lastIndexOf( '/' ) > 0
+             && rp instanceof PageFlowRequestProcessor )
+        {
+            return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Last chance to handle an unhandled action URI.
+     * @return <code>true</code> if this method handled it (by forwarding somewhere or writing to the response).
+     */ 
+    protected boolean processUnhandledAction( HttpServletRequest request, HttpServletResponse response, String uri )
+        throws IOException, ServletException
+    {
+        //
+        // First check to see if we're already in a forwarded fallback request.  If so, just bail.
+        //
+        PageFlowRequestWrapper rw = PageFlowRequestWrapper.get( request );
+        if ( rw.getOriginalServletPath() != null ) return false;       
+        
+        SharedFlowController sharedFlowToTry = null;
+        String uriBaseName = ServletUtils.getBaseName( uri );
+        int firstDot = uriBaseName.indexOf( '.' );
+        int lastDot = uriBaseName.lastIndexOf( '.' );
+        
+        if ( firstDot != -1 && firstDot != lastDot )
+        {
+            String sharedFlowName = uriBaseName.substring( 0, firstDot );
+            
+            try
+            {
+                RequestContext rc = new RequestContext( request, response );
+                Map defaultSharedFlows = FlowControllerFactory.get( getServletContext() ).getDefaultSharedFlows( rc );
+                
+                if ( defaultSharedFlows != null )
+                {
+                    sharedFlowToTry = ( SharedFlowController ) defaultSharedFlows.get( sharedFlowName );
+                    uriBaseName = uriBaseName.substring( firstDot + 1 );
+                }
+            }
+            catch ( ClassNotFoundException e )
+            {
+                throw new ServletException( e );
+            }
+            catch ( InstantiationException e )
+            {
+                throw new ServletException( e );
+            }
+            catch ( IllegalAccessException e )
+            {
+                throw new ServletException( e );
+            }
+        }
+        else
+        {
+            sharedFlowToTry = FlowControllerFactory.getGlobalApp( request, response, getServletContext() );
+        }
+        
+        //
+        // If we couldn't find an appropriate module, try raising the action on the (deprecated) Global.app.
+        //
+        
+        if ( sharedFlowToTry != null )
+        {
+            InternalStringBuilder sfActionURI = new InternalStringBuilder( sharedFlowToTry.getModulePath() );
+            sfActionURI.append( '/' );
+            sfActionURI.append( uriBaseName );
+            rw.setOriginalServletPath( uri );
+            ForwardRedirectHandler frh = _handlers.getForwardRedirectHandler();
+            frh.forward( sfActionURI.toString() );
+            return true;
+        }
+        
+        return false;
+    }
+}
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+import org.apache.ti.util.internal.InternalStringBuilder;
+
+import org.apache.ti.pageflow.internal.InternalConstants;
+import org.apache.ti.pageflow.internal.InternalUtils;
+import org.apache.ti.pageflow.handler.Handlers;
+import org.apache.ti.pageflow.handler.ForwardRedirectHandler;
+import org.apache.ti.pageflow.httpservlet.PageFlowContextListener;
+import org.apache.ti.util.internal.ServletUtils;
+import org.apache.ti.util.logging.Logger;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.action.RequestProcessor;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.List;
+import java.util.Collection;
+
+
+
+/**
+ * ActionServlet that dynamically registers modules based on naming/location conventions for Struts
+ * configuration files that are generated by the Page Flow compiler.  These files are located in
+ * /WEB-INF/.pageflow-struts-generated, and are named jpf-struts-config-<i>module-name</i>.xml.
+ * For auto-registration of config files in other locations, the user may specify additional
+ * {@link ModuleConfigLocator} classes in /WEB-INF/beehive-netui-config.xml using the
+ * <code>&lt;module-config-locators&gt;</code> element. 
+ */
+public class PageFlowActionServlet extends AutoRegisterActionServlet
+{
+    private static final Logger _log = Logger.getInstance( PageFlowActionServlet.class );
+    
+    private Handlers _handlers;
+    
+    private static final ModuleConfigLocator[] DEFAULT_MODULE_CONFIG_LOCATORS =
+            {
+                new DefaultModuleConfigLocator(),
+                new LegacyModuleConfigLocator()
+            };
+    
+    
+    /**
+     * Get the base list of ModuleConfigLocators, to specify locations for auto-registered Struts modules.  By default,
+     * this ActionServlet auto-registers Struts modules whose configuration files are located at
+     * "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>".  Overriding this method allows
+     * alternate locations to be specified.  When an unrecognized Struts module is requested, each registered
+     * ModuleConfigLocator is queried for a possible path to the configuration file for the module.  If the
+     * configuration file is found, the module is auto-registered against the file.
+     */
+    protected ModuleConfigLocator[] getDefaultModuleConfigLocators()
+    {
+        return DEFAULT_MODULE_CONFIG_LOCATORS;
+    }
+    
+    /**
+     * Default ModuleConfigLocator that looks for Struts module configuration files according to the pattern
+     * "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>".  An instance of this class
+     * is registered by default.
+     * 
+     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
+     */ 
+    public static class DefaultModuleConfigLocator implements ModuleConfigLocator, Serializable
+    {
+        public String getModuleConfigPath( String moduleName )
+        {
+            InternalStringBuilder moduleConfPath = new InternalStringBuilder( getGenDir() );
+            moduleConfPath.append( '/' ).append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_PREFIX );
+            
+            if ( moduleName.length() > 1 )
+            {
+                moduleConfPath.append( moduleName.replace( '/', '-' ) );
+            }
+            
+            moduleConfPath.append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_EXTENSION );
+            return moduleConfPath.toString();
+        }
+        
+        protected String getGenDir()
+        {
+            return PageFlowConstants.PAGEFLOW_MODULE_CONFIG_GEN_DIR;
+        }
+    }
+    
+    /**
+     * ModuleConfigLocator that looks for legacy Struts module configuration files according to the pattern
+     * "/WEB-INF/jpf-struts-config-<i>&lt;module&gt;</i>".  An instance of this class is registered by default.
+     * 
+     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
+     */ 
+    protected static class LegacyModuleConfigLocator extends DefaultModuleConfigLocator
+    {
+        protected String getGenDir()
+        {
+            return InternalConstants.WEBINF_DIR;
+        }
+    }
+
+    public void init()
+            throws ServletException
+    {
+        //
+        // Ensure that PageFlowContextListener gets to do its initializations, even if it's not registered in web.xml.
+        //
+        ServletContext servletContext = getServletContext();
+        
+        if ( ! PageFlowContextListener.isInit( servletContext ) )
+        {
+            PageFlowContextListener.performInitializations( servletContext );
+        }
+        
+        _handlers = Handlers.get( servletContext );
+        
+        super.init();
+    }
+
+    protected void process( HttpServletRequest request, HttpServletResponse response )
+            throws IOException, ServletException
+    {
+        // If this is a direct request for a shared flow (.jpfs) or a Faces backing bean (.jsfb), return a 404 status.
+        // These are not web-addressable.
+        String servletPath = InternalUtils.getRequestPath( request );
+        if ( servletPath.endsWith( InternalConstants.SHARED_FLOW_EXTENSION ) ||
+             servletPath.endsWith( InternalConstants.FACES_BACKING_EXTENSION ) )
+        {
+            if ( _log.isDebugEnabled() )
+            {
+                _log.debug( "Attempt to hit restricted URI " + servletPath + "; 404 error returned." );
+            }
+            
+            response.sendError( HttpServletResponse.SC_NOT_FOUND );
+            return;
+        }
+        
+        // First, reinitialize the page flow classloader, for reloading when recompile occurs in dev mode.
+        _handlers.getReloadableClassHandler().reloadClasses( );
+        
+        super.process( request, response );
+    }
+
+    /**
+     * Get the webapp-relative path to the Struts module configration file for a given module path.  By default,
+     * this is "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-<i>&lt;module&gt;</i>", but alternate
+     * locations can be specified by adding {@link ModuleConfigLocator}s.  
+     * 
+     * @param modulePath the Struts module path.
+     * @return a String that is the path to the Struts configuration file, relative to the web application root.
+     * @see #getDefaultModuleConfigLocators
+     */ 
+    public String getModuleConfPath( String modulePath )
+    {
+        return super.getModuleConfPath( modulePath );
+    }
+    
+    /**
+     * Struts keeps track of the action servlet URL pattern (e.g., *.do) so it can construct action
+     * URIs.  We want to prevent it from noticing *.jpf so it doesn't use that to construct the URIs.
+     * 
+     * @exclude
+     */ 
+    public void addServletMapping( String servletName, String urlPattern )
+    {
+        if ( ! urlPattern.endsWith( PageFlowConstants.JPF_EXTENSION ) )
+        {
+            super.addServletMapping( servletName, urlPattern );
+        }
+    }
+    
+    /**
+     * Tell whether the given module can handle the given path.  If this is the root module (path=="") and it's a 
+     * Page Flow module, then it shouldn't try to handle any path that has a slash in it -- it only handles local
+     * actions.
+     */ 
+    protected boolean moduleCanHandlePath( ModuleConfig moduleConfig, RequestProcessor rp, String servletPath )
+    {
+        if ( moduleConfig.getPrefix().equals( "" ) && servletPath.lastIndexOf( '/' ) > 0
+             && rp instanceof PageFlowRequestProcessor )
+        {
+            return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Last chance to handle an unhandled action URI.
+     * @return <code>true</code> if this method handled it (by forwarding somewhere or writing to the response).
+     */ 
+    protected boolean processUnhandledAction( HttpServletRequest request, HttpServletResponse response, String uri )
+        throws IOException, ServletException
+    {
+        //
+        // First check to see if we're already in a forwarded fallback request.  If so, just bail.
+        //
+        PageFlowRequestWrapper rw = PageFlowRequestWrapper.get( request );
+        if ( rw.getOriginalServletPath() != null ) return false;       
+        
+        SharedFlowController sharedFlowToTry = null;
+        String uriBaseName = ServletUtils.getBaseName( uri );
+        int firstDot = uriBaseName.indexOf( '.' );
+        int lastDot = uriBaseName.lastIndexOf( '.' );
+        
+        if ( firstDot != -1 && firstDot != lastDot )
+        {
+            String sharedFlowName = uriBaseName.substring( 0, firstDot );
+            
+            try
+            {
+                RequestContext rc = new RequestContext( request, response );
+                Map defaultSharedFlows = FlowControllerFactory.get( getServletContext() ).getDefaultSharedFlows( rc );
+                
+                if ( defaultSharedFlows != null )
+                {
+                    sharedFlowToTry = ( SharedFlowController ) defaultSharedFlows.get( sharedFlowName );
+                    uriBaseName = uriBaseName.substring( firstDot + 1 );
+                }
+            }
+            catch ( ClassNotFoundException e )
+            {
+                throw new ServletException( e );
+            }
+            catch ( InstantiationException e )
+            {
+                throw new ServletException( e );
+            }
+            catch ( IllegalAccessException e )
+            {
+                throw new ServletException( e );
+            }
+        }
+        else
+        {
+            sharedFlowToTry = FlowControllerFactory.getGlobalApp( request, response, getServletContext() );
+        }
+        
+        //
+        // If we couldn't find an appropriate module, try raising the action on the (deprecated) Global.app.
+        //
+        
+        if ( sharedFlowToTry != null )
+        {
+            InternalStringBuilder sfActionURI = new InternalStringBuilder( sharedFlowToTry.getModulePath() );
+            sfActionURI.append( '/' );
+            sfActionURI.append( uriBaseName );
+            rw.setOriginalServletPath( uri );
+            ForwardRedirectHandler frh = _handlers.getForwardRedirectHandler();
+            frh.forward( sfActionURI.toString() );
+            return true;
+        }
+        
+        return false;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowConstants.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowConstants.java?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowConstants.java (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/PageFlowConstants.java Thu Aug 25 22:46:03 2005
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2004 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow;
+
+
+
+/**
+ * Constants related to Page Flow.
+ */
+public interface PageFlowConstants {
+
+    /**
+     * The name of the special action in a user-defined {@link PageFlowController} (.jpf) that is
+     * processed when the URI for the .jpf is accessed.
+     */
+    public static final String BEGIN_ACTION_NAME = "begin";
+
+    /**
+     * The extension used for hitting a {@link PageFlowController} through its URI.
+     */
+    public static final String PAGEFLOW_EXTENSION = ".jpf";
+
+    /**
+     * The extension for Struts action URIs used with page flows.
+     */
+    public static final String ACTION_EXTENSION = ".do";   // TODO: will need to read this from the Servlet mapping
+
+    /**
+     * The filename prefix for Struts module configuration files generated from page flow source files.
+     */
+    public static final String PAGEFLOW_MODULE_CONFIG_PREFIX = "jpf-struts-config";
+
+    /**
+     * The file extensioni for Struts configuration files generated by the Page Flow compiler.
+     */
+    public static final String PAGEFLOW_MODULE_CONFIG_EXTENSION = ".xml";
+
+    /**
+     * The default webapp-relative directory for Struts module configuration files generated by the Page Flow compiler.
+     */
+    public static final String PAGEFLOW_MODULE_CONFIG_GEN_DIR = "_pageflow-config";
+
+    /**
+     * The name of an automatically-generated forward that can be used from <i>any</i> Page Flow action, in situations
+     * where the framework can handle the response itself.  Currently, this happens when a nested page flow returns
+     * after being shown in a popup window.  In the calling page flow, the handler for the return action would return
+     * something like <code>new forward("_auto")</code>, and the framework would write out the correct javascript to
+     * close the popup window.
+     */
+    public static final String AUTO_VIEW_RENDER_FORWARD_NAME = "_auto";
+
+    /**
+     * The prefix for a request parameter that will override the action that would normally be derived from the
+     * request path.
+     */
+    public static final String ACTION_OVERRIDE_PARAM_PREFIX = "actionOverride:";
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org