Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/interaction/document/operations/SetTextValueOperation.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/interaction/document/operations/SetTextValueOperation.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/interaction/document/operations/SetTextValueOperation.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/interaction/document/operations/SetTextValueOperation.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,60 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.interaction.document.operations; + +import java.io.Serializable; + +import org.apache.ode.capi.ContentException; +import org.w3c.dom.Node; + +public class SetTextValueOperation extends DocumentOperation +implements Serializable +{ + static final long serialVersionUID = 7046905920497670266L; + + public SetTextValueOperation( ) + { + super( true ); + } + + protected Object execute(Object iQueryResult, Object iParameters, + String xpath) throws ContentException + { + String stringValue = null; + + if (iParameters instanceof String) + { + stringValue = (String) iParameters; + } else + { + stringValue = iParameters.toString(); + } + + Node node = (Node) (iQueryResult); + + DOMUtil.setTextValue(node, stringValue); + + return null; + } + + public boolean isMutator() + { + return true; + } + + + +}
Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/MasterQueryFactory.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/MasterQueryFactory.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/MasterQueryFactory.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/MasterQueryFactory.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,79 @@ +package org.apache.ode.capi.impl.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.ode.capi.ContentException; +import org.apache.ode.capi.Query; +import org.apache.ode.capi.QueryFactory; +import org.apache.ode.capi.impl.query.jaxen.JaxenQueryFactory; + +public class MasterQueryFactory implements QueryFactory { + + static final long serialVersionUID = 3229334691771274257L; + + private List<QueryFactory> factoryList; + private static MasterQueryFactory MasterInstance = null; + + private MasterQueryFactory() + { + // default factories + factoryList = new ArrayList<QueryFactory>(); + factoryList.add(new JaxenQueryFactory()); + } + + + public void addQueryFactories( List<QueryFactory> factories ) + { + factoryList.addAll(0, factories ); + } + + public Query createQuery(String expression, HashMap namespaceMap) throws ContentException { + return createQuery(Query.DEFAULT_QUERY_LANGUAGE,expression,namespaceMap); + } + + private static synchronized MasterQueryFactory CreateMasterInstance() + { + if ( MasterInstance == null ) + { + MasterInstance = new MasterQueryFactory(); + } + return MasterInstance; + } + + + public boolean supportsQuery(String queryLanguage) { + for ( QueryFactory f : factoryList ) + { + if ( f.supportsQuery(queryLanguage) ) + { + return true; + } + } + return false; + } + + public Query createQuery(String queryLanguage, String expression, HashMap namespaceMap) + throws ContentException { + for ( QueryFactory f : factoryList ) + { + if ( f.supportsQuery(queryLanguage) ) + { + return f.createQuery(queryLanguage,expression,namespaceMap); + } + } + throw new UnsupportedOperationException(); + } + + public static MasterQueryFactory newInstance() + { + if ( MasterInstance == null ) + { + return CreateMasterInstance(); + } + return MasterInstance; + + } + +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/DocumentQuery.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/DocumentQuery.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/DocumentQuery.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/DocumentQuery.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,32 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import org.apache.ode.capi.ContentException; +import org.apache.ode.capi.Query; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + + +public interface DocumentQuery extends Query +{ + Object runQuery( Document iDocument ) + throws ContentException; + + Node buildQueriedNode( Document iDocument ) + throws ContentException; + +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenNodeBuilder.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenNodeBuilder.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenNodeBuilder.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenNodeBuilder.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,118 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; + +import org.apache.ode.capi.ContentException; +import org.apache.ode.capi.impl.interaction.document.operations.DOMUtil; +import org.jaxen.JaxenException; +import org.jaxen.SimpleNamespaceContext; +import org.jaxen.XPathFunctionContext; +import org.jaxen.dom.DOMXPath; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +public class JaxenNodeBuilder implements NodeBuilder, Serializable +{ + static final long serialVersionUID = 9183764444392953826L; + + + private XPathParser XPathParser; + private LinkedList<Object[]> subQueries = new LinkedList<Object[]>(); + private SimpleNamespaceContext namespaceContext = null; + + public JaxenNodeBuilder() + { + } + + public JaxenNodeBuilder(HashMap iURIMap, String iExpression ) throws JaxenException + { + namespaceContext = new SimpleNamespaceContext( iURIMap ); + XPathParser = new XPathParser( iURIMap, iExpression ); + buildSubQueries(); + } + + private void buildSubQueries() throws JaxenException + { + subQueries.clear(); + Iterator iter = XPathParser.getNodeDescriptors().iterator(); + DOMXPath currentQuery = null; + String currentQueryString = ""; + while( iter.hasNext() ) + { + NodeDescriptor nodeDescriptor = + ( NodeDescriptor )( iter.next() ); + + currentQueryString = currentQueryString + "/" + + nodeDescriptor.getName(); + + currentQuery = new DOMXPath( currentQueryString ); + currentQuery.setNamespaceContext(namespaceContext); + currentQuery.setFunctionContext(new XPathFunctionContext()); + + if ( currentQuery != null ) + { + subQueries.addFirst( new Object[]{ currentQuery, nodeDescriptor }); + } + + } + } + + + + public Node buildNode(Document iDocument) throws ContentException + { + LinkedList<NodeDescriptor> nodesToBuild = new LinkedList<NodeDescriptor>(); + Node returnNode = null; + for ( Object[] nextPair : subQueries ) + { + DOMXPath query = ( DOMXPath )( nextPair[0] ); + NodeDescriptor descriptor = ( NodeDescriptor )( nextPair[1] ); + + Object resultObject = + JaxenXPathSingleNodeQuery.runSingleNodeQuery( + query, iDocument, query.getRootExpr().getText() ); + + if (( resultObject == null )|| + ((resultObject instanceof java.util.List) && (((java.util.List)resultObject).isEmpty()))) + { + if ( !descriptor.canBuild() ) + { + if ( !descriptor.getName().equals("*") ) + { + throw new ContentException("CAN_NOT_BUILD"); + } + } + nodesToBuild.addFirst( descriptor ); + } + else + { + returnNode = DOMUtil.buildNodes( ( Node ) resultObject, nodesToBuild ); + break; + } + + } + if ( returnNode == null ) + { + returnNode = DOMUtil.buildNodes( iDocument, nodesToBuild ); + } + return returnNode; + } +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenQueryFactory.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenQueryFactory.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenQueryFactory.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenQueryFactory.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,26 @@ +package org.apache.ode.capi.impl.query.jaxen; + +import java.util.HashMap; + +import org.apache.ode.capi.ContentException; +import org.apache.ode.capi.Query; +import org.apache.ode.capi.QueryFactory; + +public class JaxenQueryFactory implements QueryFactory { + + public Query createQuery(String queryLanguage, String expression, + HashMap namespaceMap) throws ContentException { + + if ( supportsQuery(queryLanguage)) { + return new JaxenXPathSingleNodeQuery(expression,namespaceMap); + } else { + throw new UnsupportedOperationException(); + } + + } + + public boolean supportsQuery(String queryLanguage) { + return queryLanguage.equals(Query.DEFAULT_QUERY_LANGUAGE); + } + +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenXPathSingleNodeQuery.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenXPathSingleNodeQuery.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenXPathSingleNodeQuery.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/JaxenXPathSingleNodeQuery.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,225 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.ode.capi.ContentException; +import org.apache.ode.capi.Query; +import org.jaxen.JaxenException; +import org.jaxen.NamespaceContext; +import org.jaxen.SimpleNamespaceContext; +import org.jaxen.XPathFunctionContext; +import org.jaxen.dom.DOMXPath; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +public class JaxenXPathSingleNodeQuery implements DocumentQuery, +Serializable +{ + + static final long serialVersionUID = 8007784523598625657L; + private HashMap namespaceMap = null; + private SimpleNamespaceContext namespaceContext = null; + private transient Map<Thread,DOMXPath> DOMXPathHM; + private String expression; + private boolean shouldCreateNode = false; + private NodeBuilder nodeBuilder = null; + + public JaxenXPathSingleNodeQuery() + { + super(); + } + + public JaxenXPathSingleNodeQuery( + String iXPathExpression, + HashMap iNamespaceMap) + throws ContentException + { + setNamespaceMap(iNamespaceMap); + setXPathExpression(iXPathExpression); + + } + + public JaxenXPathSingleNodeQuery( + String XPathExpression, + HashMap namespaceMap, + DOMXPath locator ) throws Exception + { + setNamespaceMap( namespaceMap ); + setXPathExpression( XPathExpression ); + setLocator( locator ); + } + + public void setLocator( DOMXPath locator ) + { + locator.setFunctionContext(new XPathFunctionContext()); + if ( DOMXPathHM == null ) { + DOMXPathHM = Collections.synchronizedMap(new HashMap<Thread,DOMXPath>()); + } + DOMXPathHM.put(Thread.currentThread(),locator); + } + + public DOMXPath createLocator() throws ContentException + { + if ( DOMXPathHM == null ) { + DOMXPathHM = Collections.synchronizedMap(new HashMap<Thread,DOMXPath>()); + } + DOMXPath locator = (DOMXPath)DOMXPathHM.get(Thread.currentThread()); + if (locator == null) + { + if ((expression != null) && (namespaceMap != null)) + { + try { + locator = new DOMXPath(this.getXPathExpression()); + } catch (Exception e) { + throw new ContentException("NATIVE_EXCEPTION",e); + } + locator.setNamespaceContext(createNamespaceContext()); + locator.setFunctionContext(new XPathFunctionContext()); + DOMXPathHM.put(Thread.currentThread(),locator); + } + } + return locator; + } + + public String getXPathExpression() throws Exception + { + return expression; + } + + public void setXPathExpression(String iExpression) throws ContentException + { + expression = iExpression; + createLocator(); + } + + public void setShouldCreateNode(boolean iShouldCreateNode) + { + shouldCreateNode = iShouldCreateNode; + } + + public boolean getShouldCreateNode() + { + return shouldCreateNode; + } + + public NamespaceContext createNamespaceContext() + { + if (namespaceContext == null) + { + namespaceContext = new SimpleNamespaceContext(namespaceMap); + } + + return namespaceContext; + } + + public void setNamespaceMap(HashMap iNamespaceMap) throws ContentException + { + namespaceMap = iNamespaceMap; + createNamespaceContext(); + createLocator(); + } + + public HashMap getNamespaceMap() + { + return namespaceMap; + } + + public static Object runSingleNodeQuery( + DOMXPath iQuery, + Document iDocument, + String xpath) + throws ContentException + { + + Object result; + try { + result = iQuery.evaluate(iDocument); + } catch (JaxenException e) { + throw new ContentException("NATIVE_EXCEPTION",e); + } + Object resultObject = null; + + if (result instanceof ArrayList) + { + + ArrayList arrayList = (ArrayList) (result); + if (arrayList.size() > 1) + { + throw new ContentException("AMBIGUOUS_NODE"); + } + + Iterator iterator = arrayList.iterator(); + if (iterator.hasNext()) + { + resultObject = (iterator.next()); + } + } else if (result.equals(Collections.EMPTY_LIST)) + { + resultObject = null; + }else + { + resultObject = result; + } + return resultObject; + } + + public Object runQuery(Document iDocument) throws ContentException + { + DOMXPath xpath = createLocator(); + return runSingleNodeQuery(xpath, iDocument, expression); + + } + + synchronized private void createNodeBuilder() throws JaxenException + { + if ( nodeBuilder == null ) + { + nodeBuilder = new JaxenNodeBuilder( namespaceMap, + this.expression ); + } + } + + public Node buildQueriedNode(Document iDocument) throws ContentException + { + if ( nodeBuilder == null ) + { + try { + createNodeBuilder(); + } catch (JaxenException e) { + throw new ContentException("NATIVE_EXCEPTION",e); + } + } + return nodeBuilder.buildNode(iDocument); + } + + public String getExpression() { + return expression; + } + + public String getQueryLanguage() { + + return Query.DEFAULT_QUERY_LANGUAGE; + } + + +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeBuilder.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeBuilder.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeBuilder.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeBuilder.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,25 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import org.apache.ode.capi.ContentException; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +public interface NodeBuilder +{ + public Node buildNode( Document iDocument) throws ContentException; +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeDescriptor.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeDescriptor.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeDescriptor.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/NodeDescriptor.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,122 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Serializable; +import java.util.HashMap; + +import org.apache.xml.utils.XMLChar; + +public class NodeDescriptor implements Serializable +{ + + static final long serialVersionUID = -7444717200424355396L; + + private String nodeDescriptorString; + private String namespacePrefix; + private String localName; + private String URI; + private boolean canBuild; + + public NodeDescriptor( HashMap iURIMap, String iNodeDescriptorString ) + { + nodeDescriptorString = iNodeDescriptorString; + analyze( iURIMap ); + } + + public String getName() + { + return nodeDescriptorString; + } + + public String getLocalname() + { + return localName; + } + + public String getPrefix() + { + return namespacePrefix; + } + + public String getNamespaceURI() + { + return URI; + } + + private void analyze( HashMap iURIMap ) + { + int length = nodeDescriptorString.length(); + int currentIndex = 0; + int currentChar = 0; + localName = nodeDescriptorString; + namespacePrefix = ""; + canBuild = true; + while( currentIndex < length ) + { + currentChar = nodeDescriptorString.charAt( currentIndex ); + if ( currentChar == XPathParser.COLON ) + { + namespacePrefix = + nodeDescriptorString.substring( 0, currentIndex ); + URI = (String)iURIMap.get(namespacePrefix); + localName = + nodeDescriptorString.substring( currentIndex + 1, length ); + } + else if ( !( XMLChar.isName( currentChar ) ) ) + { + //If the node is not simply an element name + //then we can't build it. + canBuild = false; + localName = null; + URI = null; + namespacePrefix=null; + + break; + } + currentIndex++; + } + + } + + public String toString() + { + return nodeDescriptorString; + } + + public void dump( OutputStream iOutputStream ) + { + PrintStream printStream = new PrintStream( iOutputStream ); + printStream.println( "Name = " + wrap(nodeDescriptorString) ); + printStream.println( "prefix = " + wrap(namespacePrefix) ); + printStream.println( "localName = " + wrap(localName) ); + printStream.println( "namespaceURI = " + wrap(URI)); + printStream.println( "canBuild = " + canBuild ); + } + + private String wrap( String iString ) + { + return "<"+iString+">"; + } + + public boolean canBuild() + { + return canBuild; + } + +} Added: incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/XPathParser.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/XPathParser.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/XPathParser.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/main/java/org/apache/ode/capi/impl/query/jaxen/XPathParser.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,188 @@ +/* + * Copyright 2006 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. +*/ +package org.apache.ode.capi.impl.query.jaxen; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.LinkedList; + + +public class XPathParser implements Serializable +{ + static final long serialVersionUID = -8922198154683798177L; + + private LinkedList<NodeDescriptor> nodeDescriptors = null; + private String expression = null; + private HashMap uriMap = null; + + private int expressionLength; + private int currentIndex; + private boolean parseActive; + + static final int QUOTE = '"'; + static final int TICK = '\''; + static final int LEFT_BRACKET = '['; + static final int RIGHT_BRACKET = ']'; + static final int COLON = ':'; + static final int FORWARD_SLASH = '/'; + + public XPathParser() + { + } + + public XPathParser(HashMap iURIMap, String iXPathExpression) + { + setURIMap( iURIMap ); + setXPathExpression(iXPathExpression); + } + + private synchronized void parseExpression() + { + if ( nodeDescriptors != null ) + { + return; + } + expressionLength = expression.length(); + currentIndex = 0; + parseActive = true; + nodeDescriptors = new LinkedList<NodeDescriptor>(); + + while ( parseActive && ( currentIndex < expressionLength ) ) + { + parseNodeDescriptor(); + } + parseActive = false; + } + + private void parseNodeDescriptor() + { + int startIndex = currentIndex; + int stopIndex = 0; + + while (true) + { + if ( currentIndex >= expressionLength ) + { + stopIndex = expressionLength; + break; + } + + int currentChar = expression.charAt(currentIndex); + // Skip past any literals contained in the expression. + if (currentChar == QUOTE || currentChar == TICK) + { + int closeIndex = + expression.indexOf(currentChar, currentIndex + 1); + if (closeIndex >= 0) + { + currentIndex = closeIndex + 1; + } + else + { + parseActive = false; + break; + } + } + else if ( currentChar == LEFT_BRACKET ) + { + int closeIndex = + expression.indexOf(RIGHT_BRACKET, currentIndex + 1); + + if (closeIndex >= 0) + { + currentIndex = closeIndex + 1; + } + else + { + parseActive = false; + break; + } + } + else if ( currentChar == FORWARD_SLASH ) + { + stopIndex = currentIndex; + currentIndex++; + break; + + } + else + { + currentIndex++; + } + + } + + String nodeDescriptorString = expression.substring( startIndex, stopIndex ); + if ( nodeDescriptorString.length() > 0) + { + addNodeDescriptor( nodeDescriptorString ); + } + } + + private void addNodeDescriptor( String iDescriptorString ) + { + NodeDescriptor nodeDescriptor = new NodeDescriptor( getURIMap(), iDescriptorString ); + nodeDescriptors.addLast( nodeDescriptor ); + } + + public void setXPathExpression(String iExpression) + { + expression = iExpression; + } + + public String getXPathExpression() + { + return expression; + } + + public void setURIMap( HashMap iHashMap ) + { + uriMap = iHashMap; + } + + public HashMap getURIMap() + { + return uriMap; + } + + public void dump( OutputStream iOutputStream ) + { + PrintStream printStream = new PrintStream( iOutputStream ); + printStream.println( "XPathExpression = " + expression); + printStream.println( "Node Descriptors:" ); + LinkedList<NodeDescriptor> nodeDescriptors = getNodeDescriptors(); + int count = 0; + for ( NodeDescriptor nodeDescriptor : nodeDescriptors ) + { + count++; + printStream.println( count + ")" ); + nodeDescriptor.dump(iOutputStream ); + } + + + } + + public LinkedList<NodeDescriptor> getNodeDescriptors() + { + if ( nodeDescriptors == null ) + { + parseExpression(); + } + return nodeDescriptors; + } +} Added: incubator/ode/scratch/ode/bpel-content/src/test/java/org/apache/ode/capi/ContentTest.java URL: http://svn.apache.org/viewvc/incubator/ode/scratch/ode/bpel-content/src/test/java/org/apache/ode/capi/ContentTest.java?rev=416172&view=auto ============================================================================== --- incubator/ode/scratch/ode/bpel-content/src/test/java/org/apache/ode/capi/ContentTest.java (added) +++ incubator/ode/scratch/ode/bpel-content/src/test/java/org/apache/ode/capi/ContentTest.java Wed Jun 21 16:28:38 2006 @@ -0,0 +1,320 @@ +package org.apache.ode.capi; + +import java.util.HashMap; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.apache.ode.capi.DescribedContent; +import org.apache.ode.capi.FormattableContent; +import org.apache.ode.capi.Interaction; +import org.apache.ode.capi.InteractionFactory; +import org.apache.ode.capi.Query; +import org.apache.ode.capi.QueryFactory; +import org.apache.ode.capi.impl.interaction.MasterInteractionFactory; +import org.apache.ode.capi.impl.query.MasterQueryFactory; + +/** + * Unit test for simple App. + */ +public class ContentTest + extends TestCase +{ + InteractionFactory masterInteractionFactory; + QueryFactory masterQueryFactory; + /** + * Create the test case + * + * @param testName name of the test case + */ + public ContentTest( String testName ) + { + super( testName ); + masterInteractionFactory = MasterInteractionFactory.newInstance(); + masterQueryFactory = MasterQueryFactory.newInstance(); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ContentTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testCopyFragToNode() throws Exception + { + + /* + * Something like this BPEL + * + * <assign> + * <copy> + * <from xmlns:ns2="http://ns2">$var.part2/ns2:x</from> + * <to xmlns:ns1="http://ns1">var.part1/ns1:a/ns1:b/ns1:c</to> + * </copy> + * </assign> + * + */ + + // deployer will parse the bpel and create the needed query objects + Query queryTo = null; + Query queryFrom = null; + if ( masterQueryFactory.supportsQuery("urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0")) { + HashMap<String,String> namespaceMap = new HashMap<String,String>(); + namespaceMap.put("ns1","http://ns1"); + namespaceMap.put("ns2","http://ns2"); + queryTo = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/ns1:a/ns1:b/ns1:c",namespaceMap); + queryFrom = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/ns2:x",namespaceMap); + } + + // integration layer builds described content for the message parts and sends it in + DescribedContent dc1 = + new DescribedContent( + "<ns1:a xmlns:ns1=\"http://ns1\">" + + "<ns1:b>" + + "<ns1:c/>" + + "</ns1:b>" + + "</ns1:a>", + "http://www.w3.org/TR/REC-xml"); + DescribedContent dc2 = + new DescribedContent("" + + "<ns2:x xmlns:ns2=\"http://ns2\">" + + "<ns2:y>" + + "<ns2:z/>" + + "</ns2:y>" + + "</ns2:x>", + "http://www.w3.org/TR/REC-xml"); + + // engine creates interactions for the assign + Interaction interaction1 = null; + Interaction interaction2 = null; + if ( masterInteractionFactory.supportsInteraction(dc1)) { + interaction1 = masterInteractionFactory.createInteraction(dc1); + } + if ( masterInteractionFactory.supportsInteraction(dc2)) { + interaction2 = masterInteractionFactory.createInteraction(dc2); + } + + + // engine executes bpel assign action + if ( interaction1.supportsCopySubElements(queryTo,interaction2.getValue()) && + interaction2.supportsGetComplexValue(queryFrom) ) { + interaction1.copySubElements(queryTo,interaction2.getComplexValue(queryFrom)); + } + + // engine sends formattable content back to integration layer through + // invoke or reply + FormattableContent fv = interaction1.getValue(); + + // integration layer can get the value as a supported type + byte[] ba = null; + if ( fv.supportsGetValueAs(byte[].class)) { + ba = (byte[])fv.getValueAs(byte[].class); + } + + assertEquals(new String(ba), + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<ns1:a xmlns:ns1=\"http://ns1\">" + + "<ns1:b>" + + "<ns1:c>" + + "<ns2:y xmlns:ns2=\"http://ns2\">" + + "<ns2:z/>" + + "</ns2:y>" + + "</ns1:c>" + + "</ns1:b>" + + "</ns1:a>"); + } + + public void testCopyAttributeToNode() throws Exception { + + /* + * Something like this BPEL + * + * <assign> + * <copy> + * <from>$var.part2/x/@attr</from> + * <to>var.part1/a/b/c</to> + * </copy> + * </assign> + * + */ + + // deployer will parse the bpel and create the needed query objects + Query queryTo = null; + Query queryFrom = null; + if ( masterQueryFactory.supportsQuery("urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0")) { + HashMap<String,String> namespaceMap = new HashMap<String,String>(); + queryTo = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/a/b/c",namespaceMap); + queryFrom = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/x/@attr",namespaceMap); + } + + // integration layer builds described content for the message parts and sends it in + DescribedContent dc1 = + new DescribedContent("<a><b><c/></b></a>", + "http://www.w3.org/TR/REC-xml"); + DescribedContent dc2 = + new DescribedContent("<x attr=\"stuff\"><y><z/></y></x>", + "http://www.w3.org/TR/REC-xml"); + + // engine creates interactions for the assign + Interaction interaction1 = null; + Interaction interaction2 = null; + if ( masterInteractionFactory.supportsInteraction(dc1)) { + interaction1 = masterInteractionFactory.createInteraction(dc1); + } + if ( masterInteractionFactory.supportsInteraction(dc2)) { + interaction2 = masterInteractionFactory.createInteraction(dc2); + } + + + // engine executes bpel assign action + if ( interaction1.supportsSetSimpleValue(queryTo,interaction2.getValue()) && + interaction2.supportsGetSimpleValue(queryFrom) ) { + interaction1.setSimpleValue(queryTo,interaction2.getSimpleValue(queryFrom)); + } + + // engine sends formattable content back to integration layer through + // invoke or reply + FormattableContent fv = interaction1.getValue(); + + // integration layer can get the value as a supported type + byte[] ba = null; + if ( fv.supportsGetValueAs(byte[].class)) { + ba = (byte[])fv.getValueAs(byte[].class); + } + + assertEquals(new String(ba), + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<a><b><c>stuff</c></b></a>"); + + } + + public void testCopyAtomicToNode() throws Exception { + /* + * Something like this BPEL where var.part2 is not XML + * + * <assign> + * <copy> + * <from>$var.part2</from> + * <to>var.part1/a/b/c</to> + * </copy> + * </assign> + * + */ + + // deployer will parse the bpel and create the needed query objects + Query queryTo = null; + if ( masterQueryFactory.supportsQuery("urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0")) { + HashMap<String,String> namespaceMap = new HashMap<String,String>(); + queryTo = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/a/b/c",namespaceMap); + } + + // integration layer builds described content for the message parts and sends it in + DescribedContent dc1 = + new DescribedContent("<a><b><c/></b></a>", + "http://www.w3.org/TR/REC-xml"); + DescribedContent dc2 = + new DescribedContent("stuff","ATOMIC"); + + // engine creates interactions for the assign + Interaction interaction1 = null; + Interaction interaction2 = null; + if ( masterInteractionFactory.supportsInteraction(dc1)) { + interaction1 = masterInteractionFactory.createInteraction(dc1); + } + if ( masterInteractionFactory.supportsInteraction(dc2)) { + interaction2 = masterInteractionFactory.createInteraction(dc2); + } + + + // engine executes bpel assign action + if ( interaction1.supportsSetSimpleValue(queryTo,interaction2.getValue())) { + interaction1.setSimpleValue(queryTo,interaction2.getValue()); + } + + // engine sends formattable content back to integration layer through + // invoke or reply + FormattableContent fv = interaction1.getValue(); + + // integration layer can get the value as a supported type + byte[] ba = null; + if ( fv.supportsGetValueAs(byte[].class)) { + ba = (byte[])fv.getValueAs(byte[].class); + } + + assertEquals(new String(ba), + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<a><b><c>stuff</c></b></a>"); + } + + + public void testCopyAtomicToAttribute() throws Exception { + /* + * Something like this BPEL where var.part2 is not XML + * + * <assign> + * <copy> + * <from>$var.part2</from> + * <to>var.part1/a/b/c/@attr</to> + * </copy> + * </assign> + * + */ + + // deployer will parse the bpel and create the needed query objects + Query queryTo = null; + if ( masterQueryFactory.supportsQuery("urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0")) { + HashMap<String,String> namespaceMap = new HashMap<String,String>(); + queryTo = masterQueryFactory.createQuery( + "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0","/a/b/c/@attr",namespaceMap); + } + + // integration layer builds described content for the message parts and sends it in + DescribedContent dc1 = + new DescribedContent("<a><b><c attr=\"junk\"/></b></a>", + "http://www.w3.org/TR/REC-xml"); + DescribedContent dc2 = + new DescribedContent("stuff","ATOMIC"); + + // engine creates interactions for the assign + Interaction interaction1 = null; + Interaction interaction2 = null; + if ( masterInteractionFactory.supportsInteraction(dc1)) { + interaction1 = masterInteractionFactory.createInteraction(dc1); + } + if ( masterInteractionFactory.supportsInteraction(dc2)) { + interaction2 = masterInteractionFactory.createInteraction(dc2); + } + + + // engine executes bpel assign action + if ( interaction1.supportsSetSimpleValue(queryTo,interaction2.getValue())) { + interaction1.setSimpleValue(queryTo,interaction2.getValue()); + } + + // engine sends formattable content back to integration layer through + // invoke or reply + FormattableContent fv = interaction1.getValue(); + + // integration layer can get the value as a supported type + byte[] ba = null; + if ( fv.supportsGetValueAs(byte[].class)) { + ba = (byte[])fv.getValueAs(byte[].class); + } + + assertEquals(new String(ba), + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<a><b><c attr=\"stuff\"/></b></a>"); + } + +}
