craigmcc 01/08/19 22:25:19 Modified: workflow/src/java/org/apache/commons/workflow/core GetStep.java PutStep.java Added: workflow/src/test/org/apache/commons/workflow/core TestBean.java Log: Add "xpath" properties to GetStep and PutStep as alternatives to the name/scope based bean access methods. NOTE: According to the JPath documentation, you cannot currently use xpath expressions in PutStep to create a new bean -- only to modify a bean property of an existing bean. Add a test bean that will be used in unit tests of the "core" Step implementations. Revision Changes Path 1.2 +43 -14 jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/GetStep.java Index: GetStep.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/GetStep.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- GetStep.java 2001/08/13 21:16:22 1.1 +++ GetStep.java 2001/08/20 05:25:19 1.2 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/GetStep.java,v 1.1 2001/08/13 21:16:22 craigmcc Exp $ - * $Revision: 1.1 $ - * $Date: 2001/08/13 21:16:22 $ + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/GetStep.java,v 1.2 2001/08/20 05:25:19 craigmcc Exp $ + * $Revision: 1.2 $ + * $Date: 2001/08/20 05:25:19 $ * * ==================================================================== * @@ -62,6 +62,7 @@ package org.apache.commons.workflow.core; +import org.apache.commons.jpath.JPathContext; import org.apache.commons.workflow.Context; import org.apache.commons.workflow.StepException; import org.apache.commons.workflow.base.BaseStep; @@ -69,7 +70,9 @@ /** * <p>Make a copy of the specified bean in the specified scope, and push - * it on to the evaluation stack.</p> + * it on to the evaluation stack. The bean can be referenced by either the + * <code>name</code> and <code>scope</code> properties, or by the + * <code>xpath</code> property.</p> * * <p>Supported Attributes:</p> * <ul> @@ -77,9 +80,12 @@ * in the specified scope.</li> * <li><strong>scope</strong> - Name of the scope in which to search for * this bean, or omitted to search for the bean in any scope.</li> + * <li><strong>xpath</strong> - XPath expression identifying the specified + * bean or bean property, relative to the local Scope of our execution + * Context.</li> * </ul> * - * @version $Revision: 1.1 $ $Date: 2001/08/13 21:16:22 $ + * @version $Revision: 1.2 $ $Date: 2001/08/20 05:25:19 $ * @author Craig R. McClanahan */ @@ -106,7 +112,7 @@ /** * The scope containing the bean to be copied. */ - public String scope = null; + protected String scope = null; public String getScope() { return (this.scope); @@ -117,6 +123,20 @@ } + /** + * The XPath expression identifying the specified bean. + */ + protected String xpath = null; + + public String getXpath() { + return (this.xpath); + } + + public void setXPath(String xpath) { + this.xpath = xpath; + } + + // --------------------------------------------------------- Public Methods @@ -132,15 +152,24 @@ // Retrieve the specified bean value Object value = null; - if (scope == null) - value = context.get(name); - int scopeId = context.getScopeId(scope); - if (scopeId < 0) - throw new StepException("Cannot find scope '" + scope + "'", this); - else - value = context.get(name, scopeId); + if (xpath != null) { + JPathContext jpc = context.getJPathContext(); + value = jpc.getValue("local/" + xpath); + } else { + if (scope == null) { + value = context.get(name); + } else { + int scopeId = context.getScopeId(scope); + if (scopeId < 0) + throw new StepException + ("Cannot find scope '" + scope + "'", this); + value = context.get(name, scopeId); + } + } if (value == null) - throw new StepException("Cannot find bean '" + name + "'", this); + throw new StepException("Cannot find bean '" + + (xpath != null ? xpath : name) + "'", + this); // Push the value onto the evaluation stack context.push(value); 1.2 +39 -5 jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/PutStep.java Index: PutStep.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/PutStep.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- PutStep.java 2001/08/13 21:16:22 1.1 +++ PutStep.java 2001/08/20 05:25:19 1.2 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/PutStep.java,v 1.1 2001/08/13 21:16:22 craigmcc Exp $ - * $Revision: 1.1 $ - * $Date: 2001/08/13 21:16:22 $ + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/PutStep.java,v 1.2 2001/08/20 05:25:19 craigmcc Exp $ + * $Revision: 1.2 $ + * $Date: 2001/08/20 05:25:19 $ * * ==================================================================== * @@ -63,6 +63,7 @@ import java.util.EmptyStackException; +import org.apache.commons.jpath.JPathContext; import org.apache.commons.workflow.Context; import org.apache.commons.workflow.StepException; import org.apache.commons.workflow.base.BaseStep; @@ -71,7 +72,7 @@ /** * <p>Pop the top value from the evaluation stack and store it under the * specified name in the specified scope (replacing any previous value - * stored under that name).</p> + * stored under that name), or via the specified xpath expression.</p> * * <p>Supported Attributes:</p> * <ul> @@ -79,9 +80,17 @@ * in the specified scope.</li> * <li><strong>scope</strong> - Name of the scope in which to store * this bean, or omitted for storage in local scope.</li> + * <li><strong>xpath</strong> - XPath expression identifying the specified + * bean property, relative to the local Scope of our execution + * Context.</li> * </ul> * - * @version $Revision: 1.1 $ $Date: 2001/08/13 21:16:22 $ + * <p><strong>WARNING</strong> - Due to current limitations in the JPath + * implementation, you cannot use an <code>xpath</code> expression to create + * a new bean in an appropriate Scope. Such an expression can only be used + * to set a bean property of an existing bean.</p> + * + * @version $Revision: 1.2 $ $Date: 2001/08/20 05:25:19 $ * @author Craig R. McClanahan */ @@ -119,6 +128,20 @@ } + /** + * The XPath expression identifying the specified bean or property. + */ + protected String xpath = null; + + public String getXpath() { + return (this.xpath); + } + + public void setXPath(String xpath) { + this.xpath = xpath; + } + + // --------------------------------------------------------- Public Methods @@ -138,6 +161,17 @@ value = context.pop(); } catch (EmptyStackException e) { throw new StepException("Evaluation stack is empty", e, this); + } + + // Use the XPath expression if specified + if (xpath != null) { + JPathContext jpc = context.getJPathContext(); + try { + jpc.setValue("local/" + xpath, value); + } catch (Throwable t) { + throw new StepException("Cannot put '" + xpath + "'", + t, this); + } } // Identify the scope we are interested in 1.1 jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/core/TestBean.java Index: TestBean.java =================================================================== /* * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/core/TestBean.java,v 1.1 2001/08/20 05:25:19 craigmcc Exp $ * $Revision: 1.1 $ * $Date: 2001/08/20 05:25:19 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.workflow.core; /** * General purpose test bean for core <code>Step</code> implementation tests. * * @author Craig R. McClanahan * @version $Revision: 1.1 $ $Date: 2001/08/20 05:25:19 $ */ public class TestBean { // ------------------------------------------------------------- Properties /** * A boolean property whose initial value is true. */ private boolean booleanProperty = true; public boolean getBooleanProperty() { return (booleanProperty); } public void setBooleanProperty(boolean booleanProperty) { this.booleanProperty = booleanProperty; } /** * A double property. */ private double doubleProperty = 321.0; public double getDoubleProperty() { return (this.doubleProperty); } public void setDoubleProperty(double doubleProperty) { this.doubleProperty = doubleProperty; } /** * A boolean property whose initial value is false */ private boolean falseProperty = false; public boolean getFalseProperty() { return (falseProperty); } public void setFalseProperty(boolean falseProperty) { this.falseProperty = falseProperty; } /** * A float property. */ private float floatProperty = (float) 123.0; public float getFloatProperty() { return (this.floatProperty); } public void setFloatProperty(float floatProperty) { this.floatProperty = floatProperty; } /** * Integer arrays that are accessed as an array as well as indexed. */ private int intArray[] = { 0, 10, 20, 30, 40 }; public int[] getIntArray() { return (this.intArray); } public void setIntArray(int intArray[]) { this.intArray = intArray; } private int intIndexed[] = { 0, 10, 20, 30, 40 }; public int getIntIndexed(int index) { return (intIndexed[index]); } public void setIntIndexed(int index, int value) { intIndexed[index] = value; } private int intMultibox[] = new int[0]; public int[] getIntMultibox() { return (this.intMultibox); } public void setIntMultibox(int intMultibox[]) { this.intMultibox = intMultibox; } /** * An integer property. */ private int intProperty = 123; public int getIntProperty() { return (this.intProperty); } public void setIntProperty(int intProperty) { this.intProperty = intProperty; } /** * A long property. */ private long longProperty = 321; public long getLongProperty() { return (this.longProperty); } public void setLongProperty(long longProperty) { this.longProperty = longProperty; } /** * A multiple-String SELECT element. */ private String[] multipleSelect = { "Multiple 3", "Multiple 5", "Multiple 7" }; public String[] getMultipleSelect() { return (this.multipleSelect); } public void setMultipleSelect(String multipleSelect[]) { this.multipleSelect = multipleSelect; } /** * A nested reference to another test bean (populated as needed). */ private TestBean nested = null; public TestBean getNested() { if (nested == null) nested = new TestBean(); return (nested); } /** * A String property with an initial value of null. */ private String nullProperty = null; public String getNullProperty() { return (this.nullProperty); } public void setNullProperty(String nullProperty) { this.nullProperty = nullProperty; } /** * A short property. */ private short shortProperty = (short) 987; public short getShortProperty() { return (this.shortProperty); } public void setShortProperty(short shortProperty) { this.shortProperty = shortProperty; } /** * A single-String value for a SELECT element. */ private String singleSelect = "Single 5"; public String getSingleSelect() { return (this.singleSelect); } public void setSingleSelect(String singleSelect) { this.singleSelect = singleSelect; } /** * String arrays that are accessed as an array as well as indexed. */ private String stringArray[] = { "String 0", "String 1", "String 2", "String 3", "String 4" }; public String[] getStringArray() { return (this.stringArray); } public void setStringArray(String stringArray[]) { this.stringArray = stringArray; } private String stringIndexed[] = { "String 0", "String 1", "String 2", "String 3", "String 4" }; public String getStringIndexed(int index) { return (stringIndexed[index]); } public void setStringIndexed(int index, String value) { stringIndexed[index] = value; } /** * A String property. */ private String stringProperty = "This is a string"; public String getStringProperty() { return (this.stringProperty); } public void setStringProperty(String stringProperty) { this.stringProperty = stringProperty; } /** * An empty String property. */ private String emptyStringProperty = ""; public String getEmptyStringProperty() { return (this.emptyStringProperty); } public void setEmptyStringProperty(String emptyStringProperty) { this.emptyStringProperty = emptyStringProperty; } }