summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:06:58 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:06:58 +0000
commit3dd7e2c4da9c80b8182a2d04dc129a67aa7910df (patch)
tree71b970aa1c5987564405511d3912044387118fd4 /sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java
parent0f3f9b59b310833f31ba234ee4aefa808649833c (diff)
Moving 1.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835121 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java')
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementation.java69
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationFactory.java31
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProvider.java165
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProviderFactory.java47
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvokationException.java33
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvoker.java277
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryModuleActivator.java80
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationFactoryImpl.java36
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationImpl.java92
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryArtifactProcessor.java127
-rw-r--r--sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryIntrospector.java305
11 files changed, 1262 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementation.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementation.java
new file mode 100644
index 0000000000..b061cad70d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementation.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import net.sf.saxon.query.XQueryExpression;
+
+import org.apache.tuscany.sca.assembly.Implementation;
+
+/**
+ * Class representing the XQuery implementation type
+ * @version $Rev$ $Date$
+ */
+public interface XQueryImplementation extends Implementation {
+
+ /**
+ * Location of the xquery implementation file
+ * @return
+ */
+ public String getLocation();
+ public void setLocation(String location);
+
+ /**
+ * The XQuery expression that is loaded from the xquery implementation file
+ * @return
+ */
+ public String getXqExpression();
+ public void setXqExpression(String expression);
+
+ /**
+ * The XQuery expression should be extended for with additional
+ * script, which provides the external variables needed to invoke
+ * a function. In this way for each function that is defined in the
+ * original XQuery expression additional expression is defined, which
+ * can invoke this function, using external variables as input.
+ * These expression extensions are stored in this map. It provides for
+ * each method of a service interface that is implemented by this component
+ * type corresponding expression extension
+ * @return
+ */
+ public Map<Method, String> getXqExpressionExtensionsMap();
+
+ /**
+ * This map is a kind of cache for function invokations. If a given
+ * xquery function of this implementation has been invoked already
+ * its compiled expression can be reused. In this manner the preformance
+ * can be increased
+ * @return
+ */
+ public Map<String, XQueryExpression> getCompiledExpressionsCache();
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationFactory.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationFactory.java
new file mode 100644
index 0000000000..d04b5372ac
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import org.apache.tuscany.implementation.xquery.impl.XQueryImplementationFactoryImpl;
+
+/**
+ * Provides instances of XQueryImplementation classes
+ * @version $Rev$ $Date$
+ */
+public interface XQueryImplementationFactory {
+
+ public XQueryImplementationFactory INSTANCE = new XQueryImplementationFactoryImpl();
+ XQueryImplementation createXQueryImplementation();
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProvider.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProvider.java
new file mode 100644
index 0000000000..a9397db42e
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProvider.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.core.factory.ObjectFactory;
+import org.apache.tuscany.sca.databinding.saxon.SaxonNodeDataBinding;
+import org.apache.tuscany.sca.databinding.saxon.SaxonValueDataBinding;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Provides the runtime configuration of xquery-typed component.
+ * @version $Rev$ $Date$
+ *
+ * Generally the following is done:
+ * 1. During constructuion all services and references are provided
+ * with the saxon data binding, which is the one required by the
+ * XQueryInvoker
+ *
+ * 2. During startup:
+ * - a proxy is created for each reference and it is kept in the referenceProxies
+ * map, which is used later by the invoker to configure the saxon parser;
+ * - each property value is read and put into the properties map. This is
+ * again used by the invoker to configure the saxon parser
+ */
+public class XQueryImplementationProvider implements ImplementationProvider {
+
+ private RuntimeComponent component;
+ private XQueryImplementation implementation;
+ private Map<String, Object> referenceProxies = new HashMap<String, Object>();
+ private Map<String, Object> properties = new HashMap<String, Object>();
+ private JavaPropertyValueObjectFactory javaFactory;
+
+ public XQueryImplementationProvider(RuntimeComponent component, XQueryImplementation implementation,
+ JavaPropertyValueObjectFactory factory) {
+ this.component = component;
+ this.implementation = implementation;
+ this.javaFactory = factory;
+ init();
+ }
+
+ private void init() {
+ List<ComponentService> services = component.getServices();
+ for(ComponentService sevice : services) {
+ InterfaceContract interfaceContract = sevice.getInterfaceContract();
+ //interfaceContract.getInterface().setDefaultDataBinding(ValueRepresentation.class.getName());
+ setDataBinding(interfaceContract.getInterface(), false);
+ }
+
+ List<ComponentReference> references = component.getReferences();
+ for(ComponentReference reference : references) {
+ InterfaceContract interfaceContract = reference.getInterfaceContract();
+ //interfaceContract.getInterface().setDefaultDataBinding(ValueRepresentation.class.getName());
+ setDataBinding(interfaceContract.getInterface(), true);
+ }
+ }
+
+ public Invoker createCallbackInvoker(Operation operation) {
+ return new XQueryInvoker(null, operation, implementation, referenceProxies, properties);
+ }
+
+ public Invoker createInvoker(RuntimeComponentService service,
+ Operation operation) {
+ return new XQueryInvoker(service, operation, implementation, referenceProxies, properties);
+ }
+
+ public void start() {
+
+ for(Reference reference : component.getReferences()) {
+ String refName = reference.getName();
+ if(refName.startsWith("$self$.")) {
+ continue;
+ }
+ Class interfaze = ((JavaInterface)reference.getInterfaceContract().getInterface()).getJavaClass();
+ Object refProxy = component.getComponentContext().getService(interfaze, refName);
+ referenceProxies.put(refName, refProxy);
+ }
+
+ for(ComponentProperty property : component.getProperties()) {
+ String propName = property.getName();
+ QName xmlType = property.getXSDType();
+ Class clazz = JavaXMLMapper.getJavaType(xmlType);
+
+ Object propertyValue = null;
+ if(clazz == null || java.lang.Object.class.equals(clazz)) {
+ propertyValue = property.getValue();
+ } else {
+ ObjectFactory objfactory = javaFactory.createValueFactory(property, property.getValue(), clazz);
+ propertyValue = objfactory.getInstance();
+ }
+ properties.put(propName, propertyValue);
+ }
+ }
+
+ private void setDataBinding(Interface interfaze, boolean isReference) {
+ interfaze.setDefaultDataBinding(SaxonNodeDataBinding.NAME);
+ List<Operation> operations = interfaze.getOperations();
+ for(Operation operation : operations) {
+ DataType<List<DataType>> inputType = operation.getInputType();
+ if(inputType != null) {
+ List<DataType> logical = inputType.getLogical();
+ for(DataType inArg : logical) {
+ if(inArg.getPhysical().isPrimitive() || inArg.getPhysical() == java.lang.String.class) {
+ if(!isReference) {
+ inArg.setDataBinding(SaxonValueDataBinding.NAME);
+ }
+ } else {
+ inArg.setDataBinding(SaxonNodeDataBinding.NAME);
+ }
+ }
+ }
+ DataType outputType = operation.getOutputType();
+ if(outputType != null) {
+ if(outputType.getPhysical().isPrimitive() || outputType.getPhysical() == java.lang.String.class) {
+ if(!isReference) {
+ outputType.setDataBinding(SaxonValueDataBinding.NAME);
+ }
+ } else {
+ outputType.setDataBinding(SaxonNodeDataBinding.NAME);
+ }
+ }
+ }
+ }
+
+ public void stop() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProviderFactory.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProviderFactory.java
new file mode 100644
index 0000000000..91e8074654
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryImplementationProviderFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * A factory for xquery implementation providers
+ * @version $Rev$ $Date$
+ */
+public class XQueryImplementationProviderFactory implements
+ ImplementationProviderFactory<XQueryImplementation> {
+
+ private JavaPropertyValueObjectFactory javaFactory;
+ public XQueryImplementationProviderFactory(JavaPropertyValueObjectFactory javaFactory) {
+ this.javaFactory = javaFactory;
+ }
+
+ public ImplementationProvider createImplementationProvider(
+ RuntimeComponent component, XQueryImplementation implementation) {
+ return new XQueryImplementationProvider(component, implementation, javaFactory);
+ }
+
+ public Class<XQueryImplementation> getModelType() {
+ return XQueryImplementation.class;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvokationException.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvokationException.java
new file mode 100644
index 0000000000..e9b8d7b775
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvokationException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+/**
+ * Exception class used by the XQueryInvoker to report problems in
+ * xquery script invokaion
+ * @version $Rev$ $Date$
+ */
+public class XQueryInvokationException extends Exception {
+
+ private static final long serialVersionUID = -2674411654705699541L;
+
+ public XQueryInvokationException( String msg ) {
+ super( msg );
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvoker.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvoker.java
new file mode 100644
index 0000000000..cdf8f03581
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryInvoker.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import net.sf.saxon.Configuration;
+import net.sf.saxon.om.DocumentInfo;
+import net.sf.saxon.om.Item;
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.om.SequenceIterator;
+import net.sf.saxon.query.DynamicQueryContext;
+import net.sf.saxon.query.QueryResult;
+import net.sf.saxon.query.StaticQueryContext;
+import net.sf.saxon.query.XQueryExpression;
+import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.value.Value;
+
+import org.apache.tuscany.sca.databinding.saxon.SaxonDataBindingHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Performs the invokation of a requested xquery function
+ * @version $Rev$ $Date$
+ */
+public class XQueryInvoker implements Invoker {
+
+ private RuntimeComponentService service;
+ private Operation operation;
+ private Method theMethod;
+ private XQueryImplementation implementation;
+ private Map<String, Object> referenceProxies;
+ private Map<String, Object> properties;
+
+ /**
+ * Constructs a new instance of the xquery invoker.
+ * Also performs a search of java.lang.Method instance
+ * that corresponds to the invoked operation
+ */
+ public XQueryInvoker(RuntimeComponentService service, Operation operation,
+ XQueryImplementation implementation,
+ Map<String, Object> referenceProxies,
+ Map<String, Object> properties) {
+ this.service = service;
+ this.operation = operation;
+ this.implementation = implementation;
+ this.referenceProxies = referenceProxies;
+ this.properties = properties;
+
+ findMatchingMethod();
+ }
+
+ /**
+ * This mehtod contains the XQuery invokation logic
+ * The following steps are performed:
+ * 1. XQuery expression is produced by combining the original expression
+ * and the function invokation extension (See XQueryImplementation.getXqExpressionExtensionsMap()
+ * for details)
+ * 2. A check is performed if this expression has been invoked already. If yes -
+ * it is taken from the cache
+ * 3. Configuration for the execution is either created or retrieved from
+ * the cached expression
+ * 4. The input parameters of the operation to be invoked are taken from the
+ * payload and transformed to ones that are built with the current
+ * configuration.
+ * NOTE: This is unnecessary overhead - can the Configuration
+ * object be attached in some way to the invokation request?
+ * 5. All parameters, reference proxies and property values are mapped
+ * to external variables of the XQuery script
+ * 6. The query is executed and the result is returned depending on its type
+ * (i.e. it could be either a node NodeInfo or Value object). Currently
+ * no collections are supported, i.e. if there is more then one element
+ * in the result ony the first one will be returned
+ *
+ * NOTE: During execution of the XQuery a static variable is set with
+ * the current configuration. This variable is used by the NodeInfo transformers
+ * to produce the correct NodeInfo for all Output2Output tranformations, which
+ * happen as result of the XQuery component invoking some reference components
+ * The old state of the static configuraton is preserved and in this way allowing
+ * to nest XQuery component invokations (i.e. one XQuery component invokes another
+ * one)
+ */
+ private Object doInvoke(Object payload) throws XQueryInvokationException, XPathException {
+ if(theMethod == null) {
+ throw new XQueryInvokationException("No java method for operation: "+operation.getName());
+ }
+ String xqExpression = implementation.getXqExpression() +
+ implementation.getXqExpressionExtensionsMap().get(theMethod);
+
+ Configuration config = null;
+ Properties props = new Properties();
+ props.setProperty(OutputKeys.METHOD, "xml");
+ props.setProperty(OutputKeys.INDENT, "yes");
+
+ XQueryExpression exp = implementation.getCompiledExpressionsCache().get(xqExpression);
+ if(exp == null) {
+ config = new Configuration();
+ StaticQueryContext sqc = new StaticQueryContext(config);
+ exp = sqc.compileQuery(xqExpression);
+ implementation.getCompiledExpressionsCache().put(xqExpression, exp);
+ } else {
+ config = exp.getStaticContext().getConfiguration();
+ }
+
+ Object [] params = prepareParameters(payload, config, props);
+
+ DynamicQueryContext dynamicContext = new DynamicQueryContext(config);
+
+ // Setting the parameters for function invokation
+ String methodName = theMethod.getName();
+ for(int i=0; i<params.length; i++) {
+ dynamicContext.setParameter(methodName+"_"+i, params[i]);
+ }
+
+ // Setting references
+ for(Map.Entry<String, Object> entry : referenceProxies.entrySet()) {
+ dynamicContext.setParameter(entry.getKey(), entry.getValue());
+ }
+
+ // Setting properties
+ for(Map.Entry<String, Object> entry : properties.entrySet()) {
+ dynamicContext.setParameter(entry.getKey(), transformProperty(entry.getValue(), config));
+ }
+
+ SequenceIterator iterator = null;
+ Configuration oldConfigValue = SaxonDataBindingHelper.CURR_EXECUTING_CONFIG;
+ SaxonDataBindingHelper.CURR_EXECUTING_CONFIG = config;
+ try {
+ iterator = exp.iterator(dynamicContext);
+ } finally {
+ SaxonDataBindingHelper.CURR_EXECUTING_CONFIG = oldConfigValue;
+ }
+ Item item = iterator.next();
+ if(item == null) {
+ return null;
+ }
+ if(item instanceof NodeInfo) {
+ return item;
+ } else {
+ return Value.asValue(item);
+ }
+ }
+
+ public Message invoke(Message msg) {
+ try {
+ Object resp = doInvoke(msg.getBody());
+ msg.setBody(resp);
+ } catch (XQueryInvokationException e) {
+ msg.setFaultBody(e.getCause());
+ } catch (XPathException e) {
+ msg.setFaultBody(e.getCause());
+ }
+ return msg;
+ }
+
+ private void findMatchingMethod() {
+ Class<?> interfaze = ((JavaInterface)service.getInterfaceContract().getInterface()).getJavaClass();
+
+ for(Method method : interfaze.getMethods()) {
+ if(match(operation, method)) {
+ theMethod = method;
+ }
+ }
+ }
+
+ private static boolean match(Operation operation, Method method) {
+ Class<?>[] params = method.getParameterTypes();
+ DataType<List<DataType>> inputType = operation.getInputType();
+ List<DataType> types = inputType.getLogical();
+ boolean matched = true;
+ if (types.size() == params.length && method.getName().equals(operation.getName())) {
+ for (int i = 0; i < params.length; i++) {
+ Class<?> clazz = params[i];
+ if (!clazz.equals(operation.getInputType().getLogical().get(i).getPhysical())) {
+ matched = false;
+ }
+ }
+ } else {
+ matched = false;
+ }
+ return matched;
+
+ }
+
+ private Object [] prepareParameters(Object payload, Configuration configuration, Properties props) {
+ if(payload == null) {
+ return new Object[0];
+ }
+ Object [] inputArguments = null;
+ if(payload.getClass().isArray()) {
+ inputArguments = (Object [])payload;
+ } else {
+ inputArguments = new Object[1];
+ inputArguments[0] = payload;
+ }
+
+ Object [] parameters = new Object[inputArguments.length];
+
+ for(int i=0; i<inputArguments.length; i++) {
+ if(inputArguments[i] instanceof NodeInfo) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ StreamResult sw = new StreamResult(baos);
+ try {
+ QueryResult.serialize((NodeInfo)inputArguments[i], sw, props);
+ baos.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ StreamSource ss = new StreamSource(bais);
+ parameters[i] = configuration.buildDocument(ss);
+ } catch (Exception e) {
+ e.printStackTrace();
+ parameters[i] = null;
+ }
+ } else {
+ parameters[i] = inputArguments[i];
+ }
+ }
+
+ return parameters;
+ }
+
+ private Object transformProperty(Object argument, Configuration configuration) {
+ Object parameter = argument;
+ if(argument instanceof Document) {
+ try {
+ Document doc = (Document)argument;
+ Document cloneDoc = (Document)doc.cloneNode(false);
+ Node valueNode = doc.getFirstChild();
+ if(valueNode instanceof Element && valueNode.getNodeName().equals("value")) {
+ SaxonDataBindingHelper.setNamespacesAndPrefixesReq(valueNode, cloneDoc, cloneDoc, "", null);
+ } else {
+ SaxonDataBindingHelper.setNamespacesAndPrefixesReq(doc, cloneDoc, cloneDoc, "", null);
+ }
+ DocumentInfo docInfo = configuration.buildDocument(new DOMSource(cloneDoc));
+ parameter = docInfo;
+ } catch (XPathException e) {
+ e.printStackTrace();
+ return parameter;
+ }
+ }
+
+ return parameter;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryModuleActivator.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryModuleActivator.java
new file mode 100644
index 0000000000..d5c655e9ba
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/XQueryModuleActivator.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery;
+
+import org.apache.tuscany.implementation.xquery.xml.XQueryArtifactProcessor;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.TransformerExtensionPoint;
+import org.apache.tuscany.sca.databinding.impl.MediatorImpl;
+import org.apache.tuscany.sca.implementation.java.injection.JavaPropertyValueObjectFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+
+/**
+ * This class activates the xquery implementation module
+ * @version $Rev$ $Date$
+ * The following contributions are prvided: XQueryArtifactProcessor and XQueryImplementationProviderFactory
+ */
+public class XQueryModuleActivator implements ModuleActivator {
+
+ private XQueryArtifactProcessor xqueryArtifactProcessor;
+
+ public XQueryModuleActivator() {
+ }
+
+ public Object[] getExtensionPoints() {
+ return null;
+ }
+
+ public void start(ExtensionPointRegistry registry) {
+
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+
+ DataBindingExtensionPoint dataBindings = registry.getExtensionPoint(DataBindingExtensionPoint.class);
+ TransformerExtensionPoint transformers = registry.getExtensionPoint(TransformerExtensionPoint.class);
+
+ // Tools for Java interface handling
+ AssemblyFactory assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ JavaInterfaceFactory javaFactory = factories.getFactory(JavaInterfaceFactory.class);
+ // Create the artifact processor for XQuery artifacts and add to artifact processors
+ xqueryArtifactProcessor = new XQueryArtifactProcessor(assemblyFactory, javaFactory);
+
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessors.addArtifactProcessor(xqueryArtifactProcessor);
+
+ // Create XQueryImplementationProviderFactory and add to provider factories
+ MediatorImpl mediator =new MediatorImpl(dataBindings, transformers);
+ JavaPropertyValueObjectFactory javaPropertyValueObjectFactory = new JavaPropertyValueObjectFactory(mediator);
+ XQueryImplementationProviderFactory factory = new XQueryImplementationProviderFactory(javaPropertyValueObjectFactory);
+
+ ProviderFactoryExtensionPoint providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+ providerFactories.addProviderFactory(factory);
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessors.removeArtifactProcessor(xqueryArtifactProcessor);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationFactoryImpl.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationFactoryImpl.java
new file mode 100644
index 0000000000..7cf55a1692
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationFactoryImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery.impl;
+
+import org.apache.tuscany.implementation.xquery.XQueryImplementation;
+import org.apache.tuscany.implementation.xquery.XQueryImplementationFactory;
+
+/**
+ * Actual implementation of the XQuery implementation factory
+ * @version $Rev$ $Date$
+ */
+public class XQueryImplementationFactoryImpl implements
+ XQueryImplementationFactory {
+
+ public XQueryImplementation createXQueryImplementation() {
+ XQueryImplementation implementation = new XQueryImplementationImpl();
+ return implementation;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationImpl.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationImpl.java
new file mode 100644
index 0000000000..af837204b7
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/impl/XQueryImplementationImpl.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery.impl;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.saxon.query.XQueryExpression;
+
+import org.apache.tuscany.implementation.xquery.XQueryImplementation;
+import org.apache.tuscany.sca.assembly.impl.ComponentTypeImpl;
+
+/**
+ * Actual implementation of the XQuery implementation
+ * @version $Rev$ $Date$
+ */
+public class XQueryImplementationImpl extends ComponentTypeImpl implements
+ XQueryImplementation {
+
+ private String location;
+ private String xqExpression;
+
+ private Map<String, XQueryExpression> compiledExpressionsCache = new HashMap<String, XQueryExpression>();
+ private Map<Method, String> xqExpressionExtensionsMap = new HashMap<Method, String>();
+
+ public XQueryImplementationImpl () {
+ setUnresolved(true);
+ }
+
+ public String getLocation() {
+ return location;
+ }
+ public void setLocation(String location) {
+ this.location = location;
+ }
+ public String getXqExpression() {
+ return xqExpression;
+ }
+ public void setXqExpression(String xqExpression) {
+ this.xqExpression = xqExpression;
+ }
+
+ public Map<String, XQueryExpression> getCompiledExpressionsCache() {
+ return compiledExpressionsCache;
+ }
+
+ public Map<Method, String> getXqExpressionExtensionsMap() {
+ return xqExpressionExtensionsMap;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = super.hashCode();
+ result = PRIME * result + ((location == null) ? 0 : location.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (getClass() != obj.getClass())
+ return false;
+ final XQueryImplementationImpl other = (XQueryImplementationImpl) obj;
+ if (location == null) {
+ if (other.location != null)
+ return false;
+ } else if (!location.equals(other.location))
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryArtifactProcessor.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryArtifactProcessor.java
new file mode 100644
index 0000000000..7877e84dab
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryArtifactProcessor.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.implementation.xquery.XQueryImplementation;
+import org.apache.tuscany.implementation.xquery.XQueryImplementationFactory;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.service.ContributionReadException;
+import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.service.ContributionWriteException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+/**
+ * Processor for the xquery implementation type artifact
+ * @version $Rev$ $Date$
+ */
+public class XQueryArtifactProcessor implements StAXArtifactProcessor<XQueryImplementation> {
+
+ private static final String LOCATION = "location";
+ private static final String IMPLEMENTATION_XQUERY = "implementation.xquery";
+ private static final QName IMPLEMENTATION_XQUERY_QNAME =
+ new QName(Constants.SCA10_NS, IMPLEMENTATION_XQUERY);
+ private static final String MSG_LOCATION_MISSING = "Reading implementation.xquery - location attribute missing";
+
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+
+ public XQueryArtifactProcessor (AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaFactory) {
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ }
+
+ public QName getArtifactType() {
+ return IMPLEMENTATION_XQUERY_QNAME;
+ }
+
+ /**
+ * Reads from the stream and sets the location attribute of the implementation correspondingly
+ */
+ public XQueryImplementation read(XMLStreamReader inputSource) throws ContributionReadException, XMLStreamException {
+ try {
+ /* Read the location attribute for the xquery implementation */
+ String xqueryLocation = inputSource.getAttributeValue(null, LOCATION);
+ if (xqueryLocation == null) {
+ throw new ContributionReadException( MSG_LOCATION_MISSING );
+ }
+ /* Create the XQuery implementation and set the location into it */
+ XQueryImplementation xqueryImplementation = XQueryImplementationFactory.INSTANCE.createXQueryImplementation();
+ xqueryImplementation.setLocation( xqueryLocation );
+
+ // Skip to end element
+ while (inputSource.hasNext()) {
+ if (inputSource.next() == END_ELEMENT && IMPLEMENTATION_XQUERY_QNAME.equals(inputSource.getName())) {
+ break;
+ }
+ } // end while
+
+ xqueryImplementation.setUnresolved(true);
+
+ return xqueryImplementation;
+
+ } catch (XMLStreamException e) {
+ throw new ContributionReadException(e);
+ }
+ }
+
+ public void write(XQueryImplementation xqueryImplementation, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException {
+ try {
+
+ outputSource.writeStartElement(Constants.SCA10_NS, IMPLEMENTATION_XQUERY);
+ if (xqueryImplementation.getLocation() != null) {
+ outputSource.writeAttribute(LOCATION, xqueryImplementation.getLocation());
+ }
+ outputSource.writeEndElement();
+
+ } catch (XMLStreamException e) {
+ throw new ContributionWriteException(e);
+ }
+ }
+
+ public Class<XQueryImplementation> getModelType() {
+ return XQueryImplementation.class;
+ }
+
+ /**
+ * Resolves the implementation: its services and references, by invoking the xquery
+ * introspector
+ */
+ public void resolve(XQueryImplementation xqueryImplementation, ModelResolver resolver) throws ContributionResolveException {
+
+ XQueryIntrospector introspector = new XQueryIntrospector(assemblyFactory, javaFactory);
+
+ boolean success = introspector.introspect( xqueryImplementation );
+
+ if(success) {
+ xqueryImplementation.setUnresolved(false);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryIntrospector.java b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryIntrospector.java
new file mode 100644
index 0000000000..2e3da7d61c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-0.99/modules/implementation-xquery/src/main/java/org/apache/tuscany/implementation/xquery/xml/XQueryIntrospector.java
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.tuscany.implementation.xquery.xml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
+import net.sf.saxon.Configuration;
+import net.sf.saxon.om.NamespaceResolver;
+import net.sf.saxon.query.StaticQueryContext;
+import net.sf.saxon.query.XQueryExpression;
+import net.sf.saxon.trans.XPathException;
+
+import org.apache.tuscany.implementation.xquery.XQueryImplementation;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
+
+/**
+ * This class introspects an XQuery file and extrats out of it
+ * all implemented service, references and properties
+ * It also creates expression extensions for each operation
+ * in the implemented services
+ * @version $Rev$ $Date$
+ */
+public class XQueryIntrospector {
+
+ private static final String SCA_SERVICE_PREFIX = "scaservice:java/";
+ private static final String SCA_REFERENCE_PREFIX = "scareference:java/";
+ private static final String SCA_PROPERTY_JAVA_PREFIX = "scaproperty:java/";
+ private static final String SCA_PROPERTY_XML_PREFIX = "scaproperty:xml/";
+
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+ private ClassLoader cl;
+
+ public XQueryIntrospector(AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaFactory) {
+ super();
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ }
+
+ public boolean introspect(XQueryImplementation xqueryImplementation) throws ContributionResolveException {
+ cl = Thread.currentThread().getContextClassLoader();
+
+ String xqExpression = null;
+ try {
+ xqExpression = loadXQExpression(xqueryImplementation.getLocation(), cl);
+ } catch (FileNotFoundException e) {
+ throw new ContributionResolveException(e);
+ } catch (IOException e) {
+ throw new ContributionResolveException(e);
+ }
+
+ if(xqExpression == null) {
+ return false;
+ }
+
+ xqueryImplementation.setXqExpression(xqExpression);
+
+ xqExpression += "\r\n<dummy></dummy>";
+
+ Configuration config = new Configuration();
+ StaticQueryContext sqc = new StaticQueryContext(config);
+ XQueryExpression exp = null;
+ try {
+ exp = sqc.compileQuery(xqExpression);
+ } catch (XPathException e) {
+ throw new ContributionResolveException(e);
+ }
+
+ if(exp == null) {
+ return false;
+ }
+ xqueryImplementation.getCompiledExpressionsCache().put(xqExpression, exp);
+
+ try {
+ introspectServicesAndReferences(xqueryImplementation, exp);
+ } catch (ClassNotFoundException e) {
+ throw new ContributionResolveException(e);
+ } catch (InvalidInterfaceException e) {
+ throw new ContributionResolveException(e);
+ }
+
+ fillExpressionExtensions(xqueryImplementation);
+
+ return true;
+ }
+
+ /**
+ * Loads the xquery expression from the location that is provided with the implementation
+ */
+ private String loadXQExpression(String location, ClassLoader cl) throws FileNotFoundException, IOException {
+ File locationFile = new File(location);
+ InputStream xqResourceStream = null;
+ if(locationFile.exists()) {
+ xqResourceStream = new FileInputStream(locationFile);
+ } else {
+ xqResourceStream = cl.getResourceAsStream(location);
+ }
+
+ if(xqResourceStream == null) {
+ return null;
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int i=0;
+ while((i=xqResourceStream.read()) >= 0) {
+ baos.write(i);
+ }
+ xqResourceStream.close();
+ baos.flush();
+ baos.close();
+
+ String xqExpression = baos.toString();
+
+ return xqExpression;
+ }
+
+ /**
+ * From the compiled xquery expression get all namespaces and see if they
+ * are services, references or properties declaraions
+ */
+ private void introspectServicesAndReferences(XQueryImplementation xqueryImplementation, XQueryExpression exp) throws ClassNotFoundException, InvalidInterfaceException {
+ StaticQueryContext compiledSqc = exp.getStaticContext();
+ NamespaceResolver namespaceResolver = compiledSqc.getNamespaceResolver();
+ Iterator declaredPrefixesIterator = namespaceResolver.iteratePrefixes();
+ while(declaredPrefixesIterator.hasNext()) {
+ String prefix = (String)declaredPrefixesIterator.next();
+ String uri = namespaceResolver.getURIForPrefix(prefix, false);
+ if(uri.startsWith(SCA_SERVICE_PREFIX)) {
+ String serviceName = prefix;
+ String className = uri.substring(SCA_SERVICE_PREFIX.length());
+ Class<?> interfaze = cl.loadClass( className );
+ Service theService = createService(interfaze, serviceName);
+ xqueryImplementation.getServices().add(theService);
+ } else if(uri.startsWith(SCA_REFERENCE_PREFIX)) {
+ String referenceName = prefix;
+ String className = uri.substring(SCA_REFERENCE_PREFIX.length());
+ Class<?> interfaze = cl.loadClass( className );
+ Reference theReference = createReference(interfaze, referenceName);
+ xqueryImplementation.getReferences().add(theReference);
+ } else if(uri.startsWith(SCA_PROPERTY_JAVA_PREFIX)) {
+ String propertyName = prefix;
+ String className = uri.substring(SCA_PROPERTY_JAVA_PREFIX.length());
+ Class<?> clazz = cl.loadClass( className );
+ QName xmlType = JavaXMLMapper.getXMLType(clazz);
+ Property theProperty = createProperty(xmlType, propertyName);
+ xqueryImplementation.getProperties().add(theProperty);
+ } else if(uri.startsWith(SCA_PROPERTY_XML_PREFIX)) {
+ String propertyName = prefix;
+ String namespaceAndLocalname = uri.substring(SCA_PROPERTY_XML_PREFIX.length());
+ int localNameDelimiterPostition = namespaceAndLocalname.lastIndexOf(':');
+ String localName = null;
+ String namespace = null;
+ if(localNameDelimiterPostition < 0) {
+ localName = namespaceAndLocalname;
+ namespace = "";
+ } else {
+ namespace = namespaceAndLocalname.substring(0, localNameDelimiterPostition);
+ localName = namespaceAndLocalname.substring(localNameDelimiterPostition+1);
+ }
+ QName xmlType = new QName(namespace, localName);
+ Property theProperty = createProperty(xmlType, propertyName);
+ xqueryImplementation.getProperties().add(theProperty);
+ }
+ }
+ }
+
+ /**
+ * Creates a Service for the component type based on its name and Java interface
+ */
+ private Service createService( Class<?> interfaze, String name )
+ throws InvalidInterfaceException {
+ Service service = assemblyFactory.createService();
+ JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract();
+ service.setInterfaceContract(interfaceContract);
+
+ // Set the name for the service
+ service.setName( name );
+
+ // Set the call interface and, if present, the callback interface
+ JavaInterface callInterface = javaFactory.createJavaInterface(interfaze);
+ //setDataBindingForInterface(callInterface, DataObject.class.getName());
+ service.getInterfaceContract().setInterface(callInterface);
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface = javaFactory.createJavaInterface(callInterface.getCallbackClass());
+ //setDataBindingForInterface(callbackInterface, DataObject.class.getName());
+ service.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+ return service;
+ } // end method createService
+
+ protected Property createProperty(QName type, String name) {
+
+ Property property = assemblyFactory.createProperty();
+ property.setName(name);
+ property.setXSDType(type);
+
+ property.setMany(false);
+ return property;
+
+ }
+
+ /**
+ * Creates a Reference for the component type based on its name and Java interface
+ */
+ private Reference createReference( Class<?> interfaze, String name )
+ throws InvalidInterfaceException {
+ Reference reference = assemblyFactory.createReference();
+ JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract();
+ reference.setInterfaceContract(interfaceContract);
+
+ // Set the name of the reference to the supplied name and the multiplicity of the reference
+ // to 1..1 - for XQuery implementations, this is the only multiplicity supported
+ reference.setName(name);
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+
+ // Set the call interface and, if present, the callback interface
+ JavaInterface callInterface = javaFactory.createJavaInterface( interfaze );
+ reference.getInterfaceContract().setInterface( callInterface );
+ if (callInterface.getCallbackClass() != null) {
+ JavaInterface callbackInterface =
+ javaFactory.createJavaInterface(callInterface.getCallbackClass());
+ reference.getInterfaceContract().setCallbackInterface(callbackInterface);
+ }
+
+ return reference;
+ }
+
+ /**
+ * For the methods of each implemented service corresponding expression extension
+ * is generated
+ * @param xqueryImplementation
+ */
+ private void fillExpressionExtensions(XQueryImplementation xqueryImplementation) {
+ for(Service service : xqueryImplementation.getServices()) {
+ Class<?> interfaze = ((JavaInterface)service.getInterfaceContract().getInterface()).getJavaClass();
+
+ // For each of the methods
+ for(Method method : interfaze.getMethods()) {
+ String expressionExtension = createExpressionExtension(method, interfaze, service.getName());
+ xqueryImplementation.getXqExpressionExtensionsMap().put(method, expressionExtension);
+ }
+ }
+ }
+
+ private String createExpressionExtension(Method method, Class<?> interfaze, String serviceName) {
+ StringBuffer exprBuf = new StringBuffer();
+
+ exprBuf.append("\r\n");
+
+ String methodName = method.getName();
+
+ // For each of the declared parameters
+ for(int i=0; i<method.getParameterTypes().length; i++) {
+ exprBuf.append("declare variable $"+methodName+"_"+i+" external;\r\n");
+ }
+
+ exprBuf.append(serviceName+":"+methodName+"(");
+
+ for(int i=0; i<method.getParameterTypes().length; i++) {
+ exprBuf.append("$"+methodName+"_"+i);
+ if(i != method.getParameterTypes().length-1) {
+ exprBuf.append(", ");
+ }
+ }
+ exprBuf.append(")");
+
+ return exprBuf.toString();
+ }
+}