Package org.apache.tuscany.sca.assembly.xml

Source Code of org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor

/*
* 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.assembly.xml;

import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import org.apache.tuscany.sca.assembly.Base;
import org.apache.tuscany.sca.assembly.ComponentType;
import org.apache.tuscany.sca.assembly.Implementation;
import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.policy.PolicySubject;

/**
* Default Model Processor for beans.
*
* @version $Rev: 921293 $ $Date: 2010-03-10 10:40:26 +0000 (Wed, 10 Mar 2010) $
*/
public class DefaultBeanModelProcessor<T> extends BaseAssemblyProcessor implements StAXArtifactProcessor<T> {

    private QName artifactType;
    private Class<T> modelClass;
    private Object modelFactory;
    private Method factoryMethod;
    private Map<String, Method> setterMethods = new HashMap<String, Method>();
    private Map<String, Method> getterMethods = new HashMap<String, Method>();

    public DefaultBeanModelProcessor(FactoryExtensionPoint modeFactories,
                                     QName artifactType,
                                     Class<T> modelClass,
                                     Object modelFactory) {
        super(modeFactories, null);
        this.artifactType = artifactType;
        this.modelClass = modelClass;
        this.modelFactory = modelFactory;

        // Introspect the factory class and bean model class
        if (modelFactory != null) {

            // Find the model create method
            for (Method method: modelFactory.getClass().getMethods()) {
                if (method.getName().startsWith("create") && method.getReturnType() == modelClass) {
                    factoryMethod = method;
                    break;
                }
            }
        }

        // Index the bean's setter methods
        for (Method method: modelClass.getMethods()) {
            Method getter;
            String name = method.getName();
            if (name.startsWith("set") && name.length() > 3) {

                // Get the corresponding getter method
                try {
                    getter = modelClass.getMethod("get" + name.substring(3));
                } catch (Exception e) {
                    getter = null;
                    continue;
                }

                // Get the property name
                name = name.substring(3);
                if (name.length() > 1) {
                    if (!name.toUpperCase().equals(name)) {
                        name = name.substring(0, 1).toLowerCase() + name.substring(1);
                    }
                }
            } else {
                continue;
            }

            // Map an uppercase property name to a lowercase attribute name
            if (name.toUpperCase().equals(name)) {
                name = name.toLowerCase();
            }

            // Trim trailing _ from property names
            if (name.endsWith("_")) {
                name = name.substring(0, name.length()-1);
            }
            setterMethods.put(name, method);
            getterMethods.put(name, getter);
        }
    }

    public T read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {

        // Read an element
        try {

            // Create a new instance of the model
            Object model;
            if (modelFactory != null) {
                // Invoke the factory create method
                model = factoryMethod.invoke(modelFactory);
            } else {
                // Invoke the model bean class default constructor
                model = modelClass.newInstance();
            }

            // Initialize the bean properties with the attributes found in the
            // XML element
            for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
                String attributeName = reader.getAttributeLocalName(i);
                Method setter = setterMethods.get(attributeName);
                if (setter != null) {
                    String value = null;
                    if (attributeName.equals("uri")){
                        value = getURIString(reader, "uri");
                    } else {
                        value = reader.getAttributeValue(i);
                    }
                    setter.invoke(model, value);
                }
            }

            // Read policies
            policyProcessor.readPolicies(model, reader);

            // FIXME read extension elements

            // By default mark the model object unresolved
            if (model instanceof Base) {
                ((Base)model).setUnresolved(true);
            }

            // Skip to end element
            while (reader.hasNext()) {
                if (reader.next() == END_ELEMENT && artifactType.equals(reader.getName())) {
                    break;
                }
            }
            return (T) model;

        } catch (Exception e) {
          ContributionReadException ce = new ContributionReadException(e);
          error(context.getMonitor(), "ContributionReadException", reader, ce);
            throw ce;
        }
    }

    public void write(T bean, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException {
        try {
            // Write the bean properties as attributes
            List<XAttr> attrs = new ArrayList<XAttr>();
            for (Map.Entry<String, Method> entry: getterMethods.entrySet()) {
                if (entry.getValue().getReturnType() == String.class) {
                    String value = (String)entry.getValue().invoke(bean);
                    attrs.add(new XAttr(entry.getKey(), value));
                }
            }

            // Write element
            writeStart(writer, artifactType.getNamespaceURI(), artifactType.getLocalPart(),
                       policyProcessor.writePolicies(bean), new XAttr(null, attrs));

            writeEnd(writer);

        } catch (Exception e) {
          ContributionWriteException ce = new ContributionWriteException(e);
          error(context.getMonitor(), "ContributionWriteException", writer, ce);
            throw ce;
        }
    }

    public void resolve(T bean, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {

        // Resolve and merge the component type associated with an
        // implementation model
        if (bean instanceof Implementation) {
            Implementation implementation = (Implementation)bean;
            String uri = implementation.getURI();
            if (uri != null) {
                int d = uri.lastIndexOf('.');
                if (d != -1) {
                    uri = uri.substring(0, d) + ".componentType";

                    // Resolve the component type
                    ComponentType componentType = assemblyFactory.createComponentType();
                    componentType.setURI(uri);
                    componentType.setUnresolved(true);

                    componentType = resolver.resolveModel(ComponentType.class, componentType, context);
                    if (componentType != null && !componentType.isUnresolved()) {

                        // We found a component type, merge it into the implementation model
                        implementation.getServices().addAll(componentType.getServices());
                        implementation.getReferences().addAll(componentType.getReferences());
                        implementation.getProperties().addAll(componentType.getProperties());

                        if (implementation instanceof PolicySubject &&
                                componentType instanceof PolicySubject ) {
                            PolicySubject policiedImpl = (PolicySubject)implementation;
                            PolicySubject policiedCompType = (PolicySubject)componentType;

                            if ( policiedImpl.getPolicySets() != null) {
                                policiedImpl.getPolicySets().addAll(policiedCompType.getPolicySets());
                            }
                            if (policiedImpl.getRequiredIntents() != null) {
                                policiedImpl.getRequiredIntents().addAll(policiedCompType.getRequiredIntents());
                            }
                        }
                    }
                }
            }
        }

        // Mark the model resolved
        if (bean instanceof Base) {
            ((Base)bean).setUnresolved(false);
        }
    }

    public QName getArtifactType() {
        return artifactType;
    }

    public Class<T> getModelType() {
        return modelClass;
    }

}
TOP

Related Classes of org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor

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.