summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java257
1 files changed, 257 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java
new file mode 100644
index 0000000000..e6e172a44b
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java
@@ -0,0 +1,257 @@
+/*
+ * 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$ $Date$
+ */
+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;
+ }
+
+}