Package org.apache.tuscany.sca.implementation.xquery.xml

Source Code of org.apache.tuscany.sca.implementation.xquery.xml.XQueryIntrospector

/*
* 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.sca.implementation.xquery.xml;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
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.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.resolver.ClassReference;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
import org.apache.tuscany.sca.implementation.xquery.XQueryImplementation;
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: 601501 $ $Date: 2007-12-05 20:23:21 +0000 (Wed, 05 Dec 2007) $
*/
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;

    public XQueryIntrospector(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
        super();
        this.assemblyFactory = assemblyFactory;
        this.javaFactory = javaFactory;
    }

    public boolean introspect(XQueryImplementation xqueryImplementation, ModelResolver resolver) throws ContributionResolveException {
       
        String xqExpression = null;
        try {
            xqExpression = loadXQExpression(xqueryImplementation.getLocationURL());
        } 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, resolver);
        } 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(URL locationURL) throws FileNotFoundException, IOException {
     
        InputStream xqResourceStream = locationURL.openStream();

        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;
    }
   
    private Class<?> resolveClass(ModelResolver resolver, String className) throws ClassNotFoundException {
        ClassReference classReference = new ClassReference(className);
        classReference = resolver.resolveModel(ClassReference.class, classReference);
        Class<?> javaClass = classReference.getJavaClass();
        if (javaClass == null) {
            throw new ClassNotFoundException(className);
        } else {
            return javaClass;
        }
    }

    /**
     * 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, ModelResolver resolver)
        throws ClassNotFoundException, InvalidInterfaceException {
        NamespaceResolver namespaceResolver = exp.getStaticContext().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 = resolveClass(resolver, 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 = resolveClass(resolver, 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 = resolveClass(resolver, 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();
    }
}
TOP

Related Classes of org.apache.tuscany.sca.implementation.xquery.xml.XQueryIntrospector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.