summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl')
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingSCDLProcessor.java155
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingsActivator.java207
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/DiscoveryUtils.java134
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationImplementationProvider.java91
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationsActivator.java138
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoBinding.java36
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoImplementation.java42
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/SCDLProcessor.java241
8 files changed, 1044 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingSCDLProcessor.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingSCDLProcessor.java
new file mode 100644
index 0000000000..1e430e43e8
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingSCDLProcessor.java
@@ -0,0 +1,155 @@
+/*
+ * 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.spi.impl;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+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.Binding;
+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.spi.utils.AbstractBinding;
+
+/**
+ * An SCDL ArtifactProcessor which uses the Binding class getters/setters
+ * to define the SCDL attributes.
+ *
+ * TODO: merge this with SCDLProcessor
+ */
+public class BindingSCDLProcessor implements StAXArtifactProcessor {
+
+ protected QName scdlQName;
+ protected Class<Binding> bindingClass;
+
+ protected Map<String, Method> attributeSetters;
+ protected Method elementTextSetter;
+
+ public BindingSCDLProcessor(QName scdlQName, Class<Binding> implementationClass) {
+ this.scdlQName = scdlQName;
+ this.bindingClass = implementationClass;
+ initAttributes();
+ }
+
+ protected void initAttributes() {
+ attributeSetters = new HashMap<String, Method>();
+ Set<Method> methods = new HashSet<Method>(Arrays.asList(bindingClass.getMethods()));
+ methods.removeAll(Arrays.asList(AbstractBinding.class.getMethods()));
+ for (Method m : methods) {
+ if ("setElementText".equals(m.getName())) {
+ elementTextSetter = m;
+ } else if ((m.getName().startsWith("set"))) {
+ attributeSetters.put(getFieldName(m), m);
+ }
+ }
+ }
+
+ /**
+ * Remove get/set from method name, set 1st char to lowercase and
+ * remove any trailing underscore character
+ */
+ protected String getFieldName(Method m) {
+ StringBuilder sb = new StringBuilder(m.getName().substring(3));
+ sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
+ String name = sb.toString();
+ if (name.endsWith("_")) {
+ name = name.substring(0,name.length()-1);
+ }
+ return name;
+ }
+
+ public QName getArtifactType() {
+ return scdlQName;
+ }
+
+ public Class<Binding> getModelType() {
+ return bindingClass;
+ }
+
+ public Binding read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+ Object impl;
+ try {
+ impl = bindingClass.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ for (String attribute : attributeSetters.keySet()) {
+ String value = reader.getAttributeValue(null, attribute);
+ if (value != null && value.length() > 0) {
+ try {
+ attributeSetters.get(attribute).invoke(impl, new Object[] {value});
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ //FIXME: none of the attributes of Binding seem to be working with PojoBinding
+ // For now at least read the binding URI
+ String uri = reader.getAttributeValue(null, "uri");
+
+ if (elementTextSetter != null) {
+ try {
+ String value = reader.getElementText();
+ if (value != null && value.length() > 0) {
+ elementTextSetter.invoke(impl, value);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ while (!(reader.getEventType() == END_ELEMENT && scdlQName.equals(reader.getName())) && reader.hasNext()) {
+ reader.next();
+ }
+
+ if (!(impl instanceof Binding)) {
+ impl = new PojoBinding(impl);
+
+ //FIXME: none of the attributes of Binding seem to be working with PojoBinding
+ // For now at least read the binding URI
+ if (uri != null) {
+ ((PojoBinding)impl).setURI(uri);
+ }
+ }
+ return (Binding)impl;
+ }
+
+ public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException {
+ }
+
+ public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException {
+ }
+
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingsActivator.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingsActivator.java
new file mode 100644
index 0000000000..d2de4b6769
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/BindingsActivator.java
@@ -0,0 +1,207 @@
+/*
+ * 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.spi.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.provider.BindingProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.spi.BindingActivator;
+import org.apache.tuscany.sca.spi.ComponentLifecycle;
+import org.apache.tuscany.sca.spi.InvokerFactory;
+
+public class BindingsActivator implements ModuleActivator {
+
+ protected List<BindingActivator> bindingActivators;
+ protected AssemblyFactory assemblyFactory;
+
+ public void start(ExtensionPointRegistry registry) {
+
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+
+ this.bindingActivators = DiscoveryUtils.discoverActivators(BindingActivator.class, getClass().getClassLoader(), registry);
+
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ for (final BindingActivator bindingActivator : bindingActivators) {
+
+ QName scdlQName = getBindingQName(bindingActivator.getBindingClass());
+ staxProcessors.addArtifactProcessor(new BindingSCDLProcessor(scdlQName, bindingActivator.getBindingClass()));
+
+ if (bindingActivator.getBindingClass() != null) {
+ // Add a ProviderFactory
+ ProviderFactoryExtensionPoint providerFactories =
+ registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ providerFactories.addProviderFactory(new BindingProviderFactory() {
+ public ReferenceBindingProvider createReferenceBindingProvider(final RuntimeComponent rc,
+ final RuntimeComponentReference rcr,
+ final Binding b) {
+ return new ReferenceBindingProvider() {
+ List<InvokerProxy> invokers = new ArrayList<InvokerProxy>();
+ private InvokerFactory factory;
+ public Invoker createInvoker(Operation operation, boolean isCallback) {
+ InvokerProxy invoker = new InvokerProxy(operation);
+ invokers.add(invoker);
+ return invoker;
+ }
+ public InterfaceContract getBindingInterfaceContract() {
+ return null;
+ }
+ public void start() {
+ if (b instanceof PojoBinding) {
+ factory = bindingActivator.createInvokerFactory(rc, rcr, b, ((PojoBinding)b).getUserBinding());
+ } else {
+ factory = bindingActivator.createInvokerFactory(rc, rcr, b, b);
+ }
+ if (factory instanceof ComponentLifecycle) {
+ ((ComponentLifecycle)factory).start();
+ }
+ for (InvokerProxy invoker : invokers) {
+ invoker.start(factory);
+ }
+ }
+ public void stop() {
+ if (factory instanceof ComponentLifecycle) {
+ ((ComponentLifecycle)factory).stop();
+ }
+ }};
+ }
+
+ public ServiceBindingProvider createServiceBindingProvider(final RuntimeComponent rc,
+ final RuntimeComponentService rcs,
+ final Binding b) {
+ final Object pojoBinding;
+ if (b instanceof PojoBinding) {
+ pojoBinding = ((PojoBinding)b).getUserBinding();
+ } else {
+ pojoBinding = b;
+ }
+ return new ServiceBindingProvider(){
+ ComponentLifecycle listener = bindingActivator.createService(rc, rcs, b, pojoBinding);
+ public InterfaceContract getBindingInterfaceContract() {
+ return null;
+ }
+ public void start() {
+ listener.start();
+ }
+ public void stop() {
+ listener.stop();
+ }};
+ }
+
+ public Class getModelType() {
+ Class c = bindingActivator.getBindingClass();
+ if (Binding.class.isAssignableFrom(c)) {
+ return c;
+ } else {
+ return PojoBinding.class;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ ProviderFactoryExtensionPoint providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ for (final BindingActivator bindingActivator : bindingActivators) {
+
+ // Remove the binding SCDL processor from the runtime
+ if (staxProcessors != null) {
+ StAXArtifactProcessor processor = staxProcessors.getProcessor(getBindingQName(bindingActivator.getBindingClass()));
+ if (processor != null) {
+ staxProcessors.removeArtifactProcessor(processor);
+ }
+ }
+
+ // Remove the ProviderFactory from the runtime
+ if (providerFactories != null && bindingActivator.getBindingClass() != null) {
+ ProviderFactory factory = providerFactories.getProviderFactory(bindingActivator.getBindingClass());
+ if (factory != null) {
+ providerFactories.removeProviderFactory(factory);
+ }
+ }
+ }
+ }
+
+ protected QName getBindingQName(Class bindingClass) {
+ String localName = bindingClass.getName();
+ if (localName.lastIndexOf('.') > -1) {
+ localName = localName.substring(localName.lastIndexOf('.') + 1);
+ }
+ if (localName.endsWith("Binding")) {
+ localName = localName.substring(0, localName.length()-7);
+ }
+ StringBuilder sb = new StringBuilder(localName);
+ for (int i=0; i<sb.length(); i++) {
+ if (Character.isUpperCase(sb.charAt(i))) {
+ sb.setCharAt(i, Character.toLowerCase(sb.charAt(i)));
+ } else {
+ break;
+ }
+ }
+ return new QName(Constants.SCA10_NS, "binding." + sb.toString());
+ }
+
+
+ public Object[] getExtensionPoints() {
+ return null; // not used by binding or implementation extensions
+ }
+
+}
+class InvokerProxy implements Invoker {
+ Invoker invoker;
+ Operation op;
+ InvokerProxy(Operation op) {
+ this.op = op;
+ }
+ public Message invoke(Message arg0) {
+ return invoker.invoke(arg0);
+ }
+ public void start(InvokerFactory factory) {
+ invoker = factory.createInvoker(op);
+ }
+ }
+
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/DiscoveryUtils.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/DiscoveryUtils.java
new file mode 100644
index 0000000000..adf69caf59
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/DiscoveryUtils.java
@@ -0,0 +1,134 @@
+/*
+ * 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.spi.impl;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+
+/**
+ * Discovers Activators in the classpath using the J2SE
+ * jar file extensions for Service Provider discovery
+ */
+public class DiscoveryUtils {
+
+ public static <T> List<T> discoverActivators(Class<T> activatorClass, ClassLoader classLoader, ExtensionPointRegistry registry) {
+ Set<Class> activatorClasses = getServiceClasses(classLoader, activatorClass);
+ List<T> activators = new ArrayList<T>();
+ for (Class<T> c : activatorClasses) {
+ try {
+ activators.add(c.cast(instantiateActivator(c, registry)));
+ } catch (Throwable e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ return activators;
+ }
+
+ static Object instantiateActivator(Class activator, ExtensionPointRegistry registry) {
+ Constructor[] cs = activator.getConstructors();
+ if (cs.length != 1) {
+ throw new RuntimeException("Activator must have only one constructors");
+ }
+
+ Class<?>[] paramTypes = cs[0].getParameterTypes();
+ Object[] extensions = new Object[paramTypes.length];
+
+ for (int i=0; i< paramTypes.length; i++) {
+ extensions[i] = registry.getExtensionPoint(paramTypes[i]);
+ }
+
+ try {
+
+ return cs[0].newInstance(extensions);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Set<Class> getServiceClasses(ClassLoader classLoader, Class name) {
+ try {
+
+ Set<Class> set = new HashSet<Class>();
+ Enumeration<URL> urls = classLoader.getResources("META-INF/services/" + name.getName());
+ while (urls.hasMoreElements()) {
+ URL url = urls.nextElement();
+ Set<String> services = getServiceClassNames(url);
+ if (services != null) {
+ for (String className : services) {
+ try {
+ set.add(Class.forName(className, true, classLoader));
+ } catch (Throwable e) {
+ // TODO: log
+ }
+ }
+ }
+ }
+ return set;
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Set<String> getServiceClassNames(URL url) throws IOException {
+ Set<String> names = new HashSet<String>();
+ InputStream is = url.openStream();
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(is));
+ while (true) {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ line = line.trim();
+ if (!line.startsWith("#") && !"".equals(line)) {
+ names.add(line.trim());
+ }
+ }
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+
+ if (is != null){
+ try {
+ is.close();
+ } catch( IOException ioe) {
+ //ignore
+ }
+ }
+ }
+ return names;
+ }
+
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationImplementationProvider.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationImplementationProvider.java
new file mode 100644
index 0000000000..99e2d0fd88
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationImplementationProvider.java
@@ -0,0 +1,91 @@
+/*
+ * 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.spi.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.spi.ImplementationActivator;
+import org.apache.tuscany.sca.spi.InvokerFactory;
+
+/**
+ * The ImplementationProvider createInvoker method is called before the start method
+ * but the runtime isn't properly setup until the start method is called. This means
+ * that Invoker's can't initialize things like the services, references and properties
+ * until start is called. This class tries to get around that by using an Invoker
+ * proxy that delays creating the real Invoker till start is called.
+ */
+public class ImplementationImplementationProvider implements ImplementationProvider {
+
+ ImplementationActivator implementationActivator;
+ RuntimeComponent runtimeComponent;
+ Implementation impl;
+ Object userImpl;
+
+ List<InvokerProxy> invokers = new ArrayList<InvokerProxy>();
+
+ public ImplementationImplementationProvider(ImplementationActivator implementationActivator, RuntimeComponent rc, Implementation impl, Object userImpl) {
+ this.implementationActivator = implementationActivator;
+ this.runtimeComponent = rc;
+ this.impl = impl;
+ this.userImpl = userImpl;
+ }
+
+ public Invoker createInvoker(RuntimeComponentService arg0, final Operation op) {
+ InvokerProxy invoker = new InvokerProxy(op);
+ invokers.add(invoker);
+ return invoker;
+ }
+
+ public Invoker createCallbackInvoker(Operation operation) {
+ throw new RuntimeException("TODO: callbacks not yet implemented");
+ }
+
+ public void start() {
+ InvokerFactory factory = implementationActivator.createInvokerFactory(runtimeComponent, impl, userImpl);
+ for (InvokerProxy invoker : invokers) {
+ invoker.start(factory);
+ }
+ }
+
+ public void stop() {
+ }
+
+ class InvokerProxy implements Invoker {
+ Invoker invoker;
+ Operation op;
+ InvokerProxy(Operation op) {
+ this.op = op;
+ }
+ public Message invoke(Message arg0) {
+ return invoker.invoke(arg0);
+ }
+ public void start(InvokerFactory factory) {
+ invoker = factory.createInvoker(op);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationsActivator.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationsActivator.java
new file mode 100644
index 0000000000..6285738a40
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/ImplementationsActivator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.spi.impl;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModelFactoryExtensionPoint;
+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.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.spi.ImplementationActivator;
+import org.apache.tuscany.sca.spi.utils.DefaultPropertyValueObjectFactory;
+import org.apache.tuscany.sca.spi.utils.PropertyValueObjectFactory;
+
+/**
+ * A Tuscany ModuleActivator which acitvates all the ImplementationActivators
+ */
+public class ImplementationsActivator implements ModuleActivator {
+
+ protected List<ImplementationActivator> implementationActivators;
+
+ public void start(ExtensionPointRegistry registry) {
+
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ AssemblyFactory assemblyFactory = factories.getFactory(AssemblyFactory.class);
+
+ DataBindingExtensionPoint dataBindings = registry.getExtensionPoint(DataBindingExtensionPoint.class);
+ TransformerExtensionPoint transformers = registry.getExtensionPoint(TransformerExtensionPoint.class);
+ MediatorImpl mediator = new MediatorImpl(dataBindings, transformers);
+ PropertyValueObjectFactory propertyFactory = new DefaultPropertyValueObjectFactory(mediator);
+ registry.addExtensionPoint(propertyFactory);
+
+ this.implementationActivators = DiscoveryUtils.discoverActivators(ImplementationActivator.class, getClass().getClassLoader(), registry);
+
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ ProviderFactoryExtensionPoint providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ for (final ImplementationActivator implementationActivator : implementationActivators) {
+
+ Class<Implementation> implClass = implementationActivator.getImplementationClass();
+ QName scdlQName = getSCDLQName(implClass);
+ staxProcessors.addArtifactProcessor(new SCDLProcessor(assemblyFactory, scdlQName, implClass, registry, factories));
+
+ if (implementationActivator.getImplementationClass() != null && providerFactories != null) {
+ addImplementationProvider(implementationActivator, providerFactories);
+ }
+ }
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ for (final ImplementationActivator implementationActivator : implementationActivators) {
+ if (staxProcessors != null) {
+ StAXArtifactProcessor processor = staxProcessors.getProcessor(getSCDLQName(implementationActivator.getImplementationClass()));
+ if (processor != null) {
+ staxProcessors.removeArtifactProcessor(processor);
+ }
+ }
+ }
+ }
+
+ private void addImplementationProvider(final ImplementationActivator implementationActivator, ProviderFactoryExtensionPoint providerFactories) {
+
+ providerFactories.addProviderFactory(new ImplementationProviderFactory() {
+ public ImplementationProvider createImplementationProvider(final RuntimeComponent rc, final Implementation impl) {
+ if (impl instanceof PojoImplementation) {
+ return new ImplementationImplementationProvider(implementationActivator, rc, impl, ((PojoImplementation)impl).getUserImpl());
+ } else {
+ return new ImplementationImplementationProvider(implementationActivator, rc, impl, impl);
+ }
+ }
+ public Class getModelType() {
+ Class c = implementationActivator.getImplementationClass();
+
+ if (Implementation.class.isAssignableFrom(c)) {
+ return c;
+ } else {
+ return PojoImplementation.class;
+ }
+ }
+ });
+ }
+
+ protected QName getSCDLQName(Class implementationClass) {
+ String localName = implementationClass.getName();
+ if (localName.lastIndexOf('.') > -1) {
+ localName = localName.substring(localName.lastIndexOf('.') + 1);
+ }
+ if (localName.endsWith("Implementation")) {
+ localName = localName.substring(0, localName.length() - 14);
+ }
+ StringBuilder sb = new StringBuilder(localName);
+ for (int i=0; i<sb.length(); i++) {
+ if (Character.isUpperCase(sb.charAt(i))) {
+ sb.setCharAt(i, Character.toLowerCase(sb.charAt(i)));
+ } else {
+ break;
+ }
+ }
+ return new QName(Constants.SCA10_NS, "implementation." + sb.toString());
+ }
+
+
+ public Object[] getExtensionPoints() {
+ return null;
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoBinding.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoBinding.java
new file mode 100644
index 0000000000..663f4bc037
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoBinding.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.sca.spi.impl;
+
+import org.apache.tuscany.sca.spi.utils.AbstractBinding;
+
+public class PojoBinding extends AbstractBinding {
+
+ Object userBinding;
+
+ public PojoBinding(Object userImpl) {
+ this.userBinding = userImpl;
+ }
+
+ public Object getUserBinding() {
+ return userBinding;
+ }
+
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoImplementation.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoImplementation.java
new file mode 100644
index 0000000000..ff5d0512fc
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/PojoImplementation.java
@@ -0,0 +1,42 @@
+/*
+ * 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.spi.impl;
+
+import org.apache.tuscany.sca.spi.utils.DynamicImplementation;
+
+/**
+ * Enables Implementation extensions to use a simple POJO
+ * for the implementation object instead of requiring
+ * implementing the Implementation interface.
+ */
+public class PojoImplementation<Implementation> extends DynamicImplementation {
+
+ Object userImpl;
+
+ public PojoImplementation(Object userImpl) {
+ this.userImpl = userImpl;
+ }
+
+ public Object getUserImpl() {
+ return userImpl;
+ }
+
+
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/SCDLProcessor.java b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/SCDLProcessor.java
new file mode 100644
index 0000000000..a26ed00920
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/extension-helper/src/main/java/org/apache/tuscany/sca/spi/impl/SCDLProcessor.java
@@ -0,0 +1,241 @@
+/*
+ * 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.spi.impl;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Implementation;
+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.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl;
+import org.apache.tuscany.sca.contribution.service.ContributionReadException;
+import org.apache.tuscany.sca.contribution.service.ContributionWriteException;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.spi.utils.AbstractStAXArtifactProcessor;
+import org.apache.tuscany.sca.spi.utils.DynamicImplementation;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * An SCDL ArtifactProcessor which uses the Implementation class getters/setters
+ * to define the SCDL attributes.
+ */
+public class SCDLProcessor extends AbstractStAXArtifactProcessor<Implementation> {
+
+ protected QName scdlQName;
+ protected Class<Implementation> implementationClass;
+ protected ExtensionPointRegistry registry;
+ protected ModelFactoryExtensionPoint factories;
+
+ protected Map<String, Method> attributeSetters;
+ protected Method elementTextSetter;
+
+ public SCDLProcessor(AssemblyFactory assemblyFactory, QName scdlQName, Class<Implementation> implementationClass, ExtensionPointRegistry registry, ModelFactoryExtensionPoint factories) {
+ super(assemblyFactory);
+ this.scdlQName = scdlQName;
+ this.implementationClass = implementationClass;
+ this.registry = registry;
+ this.factories = factories;
+ initAttributes();
+ }
+
+ protected void initAttributes() {
+ attributeSetters = new HashMap<String, Method>();
+ Set<Method> methods = new HashSet<Method>(Arrays.asList(implementationClass.getMethods()));
+ methods.removeAll(Arrays.asList(DynamicImplementation.class.getMethods()));
+ for (Method m : methods) {
+ if ("setElementText".equals(m.getName())) {
+ elementTextSetter = m;
+ } else if ((m.getName().startsWith("set"))) {
+ attributeSetters.put(getFieldName(m), m);
+ }
+ }
+ }
+
+ /**
+ * Remove get/set from method name, set 1st char to lowercase and
+ * remove any trailing underscore character
+ */
+ protected String getFieldName(Method m) {
+ StringBuilder sb = new StringBuilder(m.getName().substring(3));
+ sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
+ String name = sb.toString();
+ if (name.endsWith("_")) {
+ name = name.substring(0,name.length()-1);
+ }
+ return name;
+ }
+
+ private Object[] getImplConstrArgs() {
+ Constructor[] cs = implementationClass.getConstructors();
+ if (cs.length != 1) {
+ throw new IllegalArgumentException("Implementation class must have a single constructor: "+ implementationClass.getName());
+ }
+ List args = new ArrayList();
+ for (Class c : cs[0].getParameterTypes()) {
+ Object o = factories.getFactory(c);
+ if (o == null) {
+ o = registry.getExtensionPoint(c);
+ }
+ args.add(o);
+ }
+ return args.toArray();
+ }
+
+
+ public QName getArtifactType() {
+ return scdlQName;
+ }
+
+ public Class<Implementation> getModelType() {
+ Class clazz;
+ if (Implementation.class.isAssignableFrom(implementationClass)) {
+ clazz = implementationClass;
+ } else {
+ clazz = PojoImplementation.class;
+ }
+ return clazz;
+ }
+
+ public Implementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+ Object impl;
+ try {
+ impl = implementationClass.getConstructors()[0].newInstance(getImplConstrArgs());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ for (String attribute : attributeSetters.keySet()) {
+ String value = reader.getAttributeValue(null, attribute);
+ if (value != null && value.length() > 0) {
+ try {
+ attributeSetters.get(attribute).invoke(impl, new Object[] {value});
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ if (elementTextSetter != null) {
+ try {
+ String value = reader.getElementText();
+ if (value != null && value.length() > 0) {
+ elementTextSetter.invoke(impl, value);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ while (!(reader.getEventType() == END_ELEMENT && scdlQName.equals(reader.getName())) && reader.hasNext()) {
+ reader.next();
+ }
+
+ if (!(impl instanceof Implementation)) {
+ impl = new PojoImplementation(impl);
+ }
+
+ return (Implementation)impl;
+ }
+
+ public void write(Implementation arg0, XMLStreamWriter arg1) throws ContributionWriteException, XMLStreamException {
+ }
+
+ protected void addSideFileComponentType(String name, Implementation impl, ModelResolver resolver) {
+// protected void addSideFileComponentType(Implementation impl, ModelResolver resolver) {
+
+ ComponentType componentType;
+ try {
+ componentType = getComponentType(resolver, impl);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+
+ if (componentType != null && !componentType.isUnresolved()) {
+ for (Reference reference : componentType.getReferences()) {
+ impl.getReferences().add(reference);
+ }
+ for (Service service : componentType.getServices()) {
+ impl.getServices().add(service);
+ }
+ for (Property property : componentType.getProperties()) {
+ impl.getProperties().add(property);
+ }
+ if (componentType.getConstrainingType() != null) {
+ impl.setConstrainingType(componentType.getConstrainingType());
+ }
+ }
+ }
+
+ private ComponentType getComponentType(ModelResolver resolver, Implementation impl) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ for (Object o :((ModelResolverImpl)resolver).getModels()) {
+ if (o instanceof ComponentType) {
+ ComponentType ct = (ComponentType)o;
+ String uri = ct.getURI();
+ if (uri != null && uri.endsWith(".componentType")) {
+ String name = uri.substring(0, uri.lastIndexOf('.'));
+ for (Method m : getGetters()) {
+ String value = (String) m.invoke(impl, new Object[]{});
+ if (value != null && name.endsWith(value.substring(0, value.lastIndexOf('.')))) {
+ return ct;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private List<Method> getGetters() {
+ List<Method> ms = new ArrayList<Method>();
+ for (Method setter : attributeSetters.values()) {
+ String s = getFieldName(setter);
+ for (Method m : implementationClass.getMethods()) {
+ String name = m.getName();
+ if (name.length() > 3 && name.startsWith("get")) {
+ if (s.endsWith(name.substring(4))) {
+ ms.add(m);
+ }
+ }
+ }
+ }
+ return ms;
+ }
+}