diff options
Diffstat (limited to 'branches/sca-java-20080910/modules/extension-helper')
23 files changed, 2464 insertions, 0 deletions
diff --git a/branches/sca-java-20080910/modules/extension-helper/LICENSE b/branches/sca-java-20080910/modules/extension-helper/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + + + diff --git a/branches/sca-java-20080910/modules/extension-helper/NOTICE b/branches/sca-java-20080910/modules/extension-helper/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/branches/sca-java-20080910/modules/extension-helper/pom.xml b/branches/sca-java-20080910/modules/extension-helper/pom.xml new file mode 100644 index 0000000000..e35504caab --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/pom.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-modules</artifactId> + <version>1.4-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tuscany-extension-helper</artifactId> + <name>Apache Tuscany SCA Extension Helper</name> + + <dependencies> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-extensibility</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-host-embedded</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-impl</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-databinding</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <version>2.2</version> + <scope>test</scope> + </dependency> + + </dependencies> + + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + + <configuration> + <instructions> + <Bundle-Version>${tuscany.version}</Bundle-Version> + <Bundle-SymbolicName>org.apache.tuscany.sca.extension.helper</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.extension*</Export-Package> + <DynamicImport-Package>org.apache.tuscany.sca.host.http</DynamicImport-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/BindingActivator.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/BindingActivator.java new file mode 100644 index 0000000000..e117e952c7 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/BindingActivator.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.sca.extension.helper; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * A BindingActivator adds an SCA binding type to the Tuscany runtime. + * + * The SCDL XML used for the binding is derived from the name of the + * class returned from the getBindingClass method - the package name and + * any trailing "Binding" string is removed, leading upper case characters + * are converted to lowercase, and the suffix "binding." is added. + * For example if getBindingClass returns a class named "mypkg.FooBinding" + * then the SCDL for the binding will be <binding.foo>. + * + * Attributes of the <binding.foo> SCDL are based on the getters/setters of + * the binding class. So if FooBinding had getBar/setBar then there + * would be an attribute name 'bar', for example, <binding.foo bar="xxx">. + * + * BindingActivator implementations may use constructor arguments to have + * Tuscany ExtensionPointRegistry objects passed in on their constructor. + * For example: + * + * public class MyBindingActivator implements BindingActivator { + * ServletHost servletHost; + * public MyBindingActivator(ServletHost servletHost) { + * this.servletHost = servletHost; + * } + * ... + * } + * + * BindingActivator implementations are discovered by the Tuscany runtime + * using the J2SE jar file extensions for service provider discovery. All + * that means is packaging the new binding type in a jar which contains a + * file META-INF/services/org.apache.tuscany.sca.extension.helper.BindingActivator and + * that file lists the BindingActivator implementation class name. + * + * @version $Rev$ $Date$ + */ +public interface BindingActivator<B> { + + Class<B> getBindingClass(); + + InvokerFactory createInvokerFactory(RuntimeComponent rc, RuntimeComponentReference rcr, Binding b, B pojoBinding); + + ComponentLifecycle createService(RuntimeComponent rc, RuntimeComponentService rcs, Binding b, B pojoBinding); + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ComponentLifecycle.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ComponentLifecycle.java new file mode 100644 index 0000000000..92b6e4191f --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ComponentLifecycle.java @@ -0,0 +1,32 @@ +/* + * 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.extension.helper; + +/** + * Interface that defines the Component Lifecycle methods. + * + * @version $Rev$ $Date$ + */ +public interface ComponentLifecycle { + + void start(); + void stop(); + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ImplementationActivator.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ImplementationActivator.java new file mode 100644 index 0000000000..7d2a9c3d2d --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/ImplementationActivator.java @@ -0,0 +1,64 @@ +/* + * 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.extension.helper; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * An ImplementationActivator adds an SCA implementation type to the Tuscany runtime. + * + * The SCDL XML used for the implementation is derived from the name of the + * class returned from the getImplementationClass method - the package name and + * any trailing "Implementation" string is removed, leading upper case characters + * are converted to lowercase, and the suffix "implementation." is added. For + * example if getImplementationClass returns a class named "mypkg.FooImplementation" + * then the SCDL for the implementation will be <implementation.foo>. + * + * Attributes of the <implementation.foo> SCDL are based on the getters/setters of + * the Implementation class. So if FooImplementation had getBar/setBar then there + * would be an attribute name 'bar', for example, <implementation.foo bar="xxx">. + * + * BindingActivator implementations may use constructor arguments to have + * Tuscany ExtensionPointRegistry objects passed in on their constructor. + * For example: + * + * public class MyImplementationActivator implements ImplementationActivator { + * ServletHost servletHost; + * public MyImplementationActivator(ServletHost servletHost) { + * this.servletHost = servletHost; + * } + * ... + * } + * + * ImplementationActivator implementations are discovered by the Tuscany runtime + * using the J2SE jar file extensions for service provider discovery. All + * that means is packaging the new binding type in a jar which contains a + * file META-INF/services/org.apache.tuscany.sca.extension.helper.ImplementationActivator and + * that file lists the ImplementationActivator implementation class name. + * + * @version $Rev$ $Date$ + */ +public interface ImplementationActivator<T> { + + Class<T> getImplementationClass(); + + InvokerFactory createInvokerFactory(RuntimeComponent rc, ComponentType ct, T implementation); +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/InvokerFactory.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/InvokerFactory.java new file mode 100644 index 0000000000..c51a7267cc --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/InvokerFactory.java @@ -0,0 +1,34 @@ +/* + * 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.extension.helper; + +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; + +/** + * Interface that defines the methods for an Invoker Factory. + * + * @version $Rev$ $Date$ + */ +public interface InvokerFactory { + + Invoker createInvoker(Operation operation); + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingSCDLProcessor.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingSCDLProcessor.java new file mode 100644 index 0000000000..8a83f630e9 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingSCDLProcessor.java @@ -0,0 +1,194 @@ +/* + * 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.extension.helper.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.NamespaceContext; +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.extension.helper.utils.AbstractBinding; + +/** + * An SCDL ArtifactProcessor which uses the Binding class getters/setters + * to define the SCDL attributes. + * + * TODO: merge this with SCDLProcessor + * + * @version $Rev$ $Date$ + */ +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 getModelType() { + //FIXME Having two different bindings, PojoBinding wrapping + // the real binding is pretty confusing, looks like if you don't return + // PojoBinding here, the write and resolve methods will never be + // called, returning PojoBinding.class seems to fix that issue without + // breaking anything else + return PojoBinding.class; + } + + 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 writer) throws ContributionWriteException, XMLStreamException { + + //FIXME: none of the attributes of Binding seem to be working with PojoBinding + // For now at least write the binding URI + + // Find a namespace prefix and write the element + String prefix = writer.getPrefix(scdlQName.getNamespaceURI()); + if (prefix == null) { + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, scdlQName.getNamespaceURI()); + } + writer.writeStartElement(scdlQName.getNamespaceURI(), scdlQName.getLocalPart()); + + // Write the binding URI attribute + String uri; + try { + uri = (String)model.getClass().getMethod("getURI").invoke(model); + } catch (Exception e) { + uri = null; + } + if (uri != null) { + writer.writeAttribute("uri", uri); + } + + writer.writeEndElement(); + + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingsActivator.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingsActivator.java new file mode 100644 index 0000000000..bca1dac0ed --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/BindingsActivator.java @@ -0,0 +1,262 @@ +/* + * 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.extension.helper.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.ModelFactoryExtensionPoint; +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.ModuleActivator; +import org.apache.tuscany.sca.extension.helper.BindingActivator; +import org.apache.tuscany.sca.extension.helper.ComponentLifecycle; +import org.apache.tuscany.sca.extension.helper.InvokerFactory; +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; + +/** + * + * @version $Rev$ $Date$ + */ +public class BindingsActivator implements ModuleActivator { + + protected List<BindingActivator> bindingActivators; + protected AssemblyFactory assemblyFactory; + protected Map<Class, BindingActivator> bindingActivatorMap = new HashMap<Class, BindingActivator>(); + + public void start(ExtensionPointRegistry registry) { + + ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class); + this.assemblyFactory = factories.getFactory(AssemblyFactory.class); + + + this.bindingActivators = + DiscoveryUtils.discoverActivators(BindingActivator.class, registry); + + StAXArtifactProcessorExtensionPoint staxProcessors = + registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + + ProviderFactoryExtensionPoint providerFactories = + registry.getExtensionPoint(ProviderFactoryExtensionPoint.class); + + for (final BindingActivator bindingActivator : bindingActivators) { + Class bindingClass = bindingActivator.getBindingClass(); + bindingActivatorMap.put(bindingClass, bindingActivator); + QName scdlQName = getBindingQName(bindingClass); + staxProcessors.addArtifactProcessor(new BindingSCDLProcessor(scdlQName, bindingClass)); + + // Check if the binding extends from Binding interface + if (Binding.class.isAssignableFrom(bindingClass)) { + // Add provider factory against the binding class + providerFactories.addProviderFactory(new DelegatingBindingProviderFactory(bindingClass)); + } + + } + + // Add a generic provider factory against PojoBinding.class + providerFactories.addProviderFactory(new DelegatingBindingProviderFactory(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); + } + } + } + if (providerFactories != null) { + ProviderFactory factory = providerFactories.getProviderFactory(PojoBinding.class); + 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_TUSCANY_NS, "binding." + sb.toString()); + } + + private final class DelegatingBindingProviderFactory implements BindingProviderFactory { + private Class modelType; + + public DelegatingBindingProviderFactory(Class modelType) { + super(); + this.modelType = modelType; + } + + public ReferenceBindingProvider createReferenceBindingProvider(final RuntimeComponent rc, + final RuntimeComponentReference rcr, + final Binding b) { + final Object realBinding; + if (b instanceof PojoBinding) { + realBinding = ((PojoBinding)b).getUserBinding(); + } else { + realBinding = b; + } + final BindingActivator bindingActivator = bindingActivatorMap.get(realBinding.getClass()); + return new ReferenceBindingProvider() { + List<InvokerProxy> invokers = new ArrayList<InvokerProxy>(); + private InvokerFactory factory; + + public Invoker createInvoker(Operation operation) { + InvokerProxy invoker = new InvokerProxy(factory, operation); + invokers.add(invoker); + return invoker; + } + + public boolean supportsOneWayInvocation() { + return false; + } + + 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 != null) && (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 realBinding; + if (b instanceof PojoBinding) { + realBinding = ((PojoBinding)b).getUserBinding(); + } else { + realBinding = b; + } + final BindingActivator bindingActivator = bindingActivatorMap.get(realBinding.getClass()); + return new ServiceBindingProvider() { + ComponentLifecycle listener = bindingActivator.createService(rc, rcs, b, realBinding); + + public InterfaceContract getBindingInterfaceContract() { + return null; + } + + public boolean supportsOneWayInvocation() { + return false; + } + + public void start() { + listener.start(); + } + + public void stop() { + listener.stop(); + } + }; + } + + public Class getModelType() { + return modelType; + } + } + +} + +class InvokerProxy implements Invoker { + InvokerFactory factory; + Invoker invoker; + Operation op; + + InvokerProxy(InvokerFactory factory, Operation op) { + this.factory = factory; + this.op = op; + this.invoker = factory.createInvoker(op); + } + + public Message invoke(Message arg0) { + return invoker.invoke(arg0); + } + +// public void start(InvokerFactory factory) { +// invoker = factory.createInvoker(op); +// } +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java new file mode 100644 index 0000000000..720d409a44 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/DiscoveryUtils.java @@ -0,0 +1,113 @@ +/* + * 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.extension.helper.impl; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Discovers Activators in the classpath using the J2SE + * jar file extensions for Service Provider discovery + * + * @version $Rev$ $Date$ + */ +public class DiscoveryUtils { + + @SuppressWarnings("unchecked") + public static <T> List<T> discoverActivators(Class<T> activatorClass, ExtensionPointRegistry registry) { + List<T> activators; + try { + Set<ServiceDeclaration> activatorClasses = + ServiceDiscovery.getInstance().getServiceDeclarations(activatorClass); + activators = new ArrayList<T>(); + for (ServiceDeclaration declaration : activatorClasses) { + try { + Class<T> c = (Class<T>)declaration.loadClass(); + activators.add(c.cast(instantiateActivator(c, registry))); + } catch (Throwable e) { + e.printStackTrace(); // TODO: log + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + 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++) { + if ("org.apache.tuscany.sca.host.http.ServletHost".equals(paramTypes[i].getName())) { + extensions[i] = getServletHost(registry); + } else { + extensions[i] = registry.getExtensionPoint(paramTypes[i]); + } + } + + try { + + return cs[0].newInstance(extensions); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static Object getServletHost(ExtensionPointRegistry registry) { + try { + + Class<?> servletHostEPClass = Class.forName("org.apache.tuscany.sca.host.http.ServletHostExtensionPoint"); + Object servletHostEP = registry.getExtensionPoint(servletHostEPClass); + Class<?> extensibleServletHost = Class.forName("org.apache.tuscany.sca.host.http.ExtensibleServletHost"); + return extensibleServletHost.getConstructor(new Class[] {servletHostEPClass}).newInstance(servletHostEP); + + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/ImplementationImplementationProvider.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/ImplementationImplementationProvider.java new file mode 100644 index 0000000000..f7c65acb3d --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/ImplementationImplementationProvider.java @@ -0,0 +1,99 @@ +/* + * 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.extension.helper.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.extension.helper.ImplementationActivator; +import org.apache.tuscany.sca.extension.helper.InvokerFactory; +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; + +/** + * 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. + * + * @version $Rev$ $Date$ + */ +public class ImplementationImplementationProvider implements ImplementationProvider { + + ImplementationActivator implementationActivator; + RuntimeComponent runtimeComponent; + Implementation impl; + Object userImpl; + InvokerFactory factory; + + 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); + return invoker; + } + + public boolean supportsOneWayInvocation() { + return false; + } + + public void start() { + factory = implementationActivator.createInvokerFactory(runtimeComponent, impl, userImpl); + } + + public void stop() { + } + + class InvokerProxy implements Invoker { + Invoker invoker; + Operation op; + + InvokerProxy(Operation op) { + this.op = op; + } + + public Message invoke(Message msg) { + init(); + return invoker.invoke(msg); + } + + public synchronized void init() { + if (invoker == null) { + invoker = factory.createInvoker(op); + } + } + } +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/ImplementationsActivator.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/ImplementationsActivator.java new file mode 100644 index 0000000000..d156d835ad --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/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.extension.helper.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.ModelFactoryExtensionPoint; +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.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.extension.helper.ImplementationActivator; +import org.apache.tuscany.sca.extension.helper.utils.DefaultPropertyValueObjectFactory; +import org.apache.tuscany.sca.extension.helper.utils.PropertyValueObjectFactory; +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; + +/** + * A Tuscany ModuleActivator which activates all the ImplementationActivators + * + * @version $Rev$ $Date$ + */ +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); + + //FIXME Pass this factory differently as it's not an extension point + PropertyValueObjectFactory propertyFactory = new DefaultPropertyValueObjectFactory(mediator); + registry.addExtensionPoint(propertyFactory); + + this.implementationActivators = DiscoveryUtils.discoverActivators(ImplementationActivator.class, 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_TUSCANY_NS, "implementation." + sb.toString()); + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoBinding.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoBinding.java new file mode 100644 index 0000000000..de9a5bfbb1 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoBinding.java @@ -0,0 +1,40 @@ +/* + * 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.extension.helper.impl; + +import org.apache.tuscany.sca.extension.helper.utils.AbstractBinding; + +/** + * + * @version $Rev$ $Date$ + */ +public class PojoBinding extends AbstractBinding { + + Object userBinding; + + public PojoBinding(Object userImpl) { + this.userBinding = userImpl; + } + + public Object getUserBinding() { + return userBinding; + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoImplementation.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoImplementation.java new file mode 100644 index 0000000000..a59733aced --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/PojoImplementation.java @@ -0,0 +1,58 @@ +/* + * 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.extension.helper.impl; + +import java.lang.reflect.Method; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.extension.helper.utils.DynamicImplementation; + +/** + * Enables Implementation extensions to use a simple POJO + * for the implementation object instead of requiring + * implementing the Implementation interface. + * + * @version $Rev$ $Date$ + */ +public class PojoImplementation<Implementation> extends DynamicImplementation { + + Object userImpl; + + public PojoImplementation(Object userImpl) { + this.userImpl = userImpl; + } + + public Object getUserImpl() { + return userImpl; + } + + public void resolve(ModelResolver resolver) { + + try { + Method resolveMethod; + if (userImpl != null && + (resolveMethod = userImpl.getClass().getMethod("resolve", ModelResolver.class)) != null) { + resolveMethod.invoke(userImpl, resolver); + } + } catch (Exception e) { + } + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/SCDLProcessor.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/SCDLProcessor.java new file mode 100644 index 0000000000..c91618c24d --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/impl/SCDLProcessor.java @@ -0,0 +1,248 @@ +/* + * 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.extension.helper.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.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +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.extension.helper.utils.AbstractStAXArtifactProcessor; +import org.apache.tuscany.sca.extension.helper.utils.DynamicImplementation; +import org.osoa.sca.ServiceRuntimeException; + +/** + * An SCDL ArtifactProcessor which uses the Implementation class getters/setters + * to define the SCDL attributes. + * + * @version $Rev$ $Date$ + */ +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 { + } + + @Override + 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()); + } + } + } + + ComponentType getComponentType(ModelResolver resolver, Implementation impl) throws IllegalArgumentException, IllegalAccessException, + InvocationTargetException { + for (Method m : getGetters()) { + Object io; + if (impl instanceof PojoImplementation) { + io = ((PojoImplementation) impl).getUserImpl(); + } else { + io = impl; + } + String value = (String) m.invoke(io, new Object[] {}); + if (value != null) { + value = value.substring(0, value.lastIndexOf('.')); + ComponentType componentType = assemblyFactory.createComponentType(); + componentType.setUnresolved(true); + componentType.setURI(value + ".componentType"); + componentType = resolver.resolveModel(ComponentType.class, componentType); + if (!componentType.isUnresolved()) { + return componentType; + } + } + } + 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; + } +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractBinding.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractBinding.java new file mode 100644 index 0000000000..112fb09f2a --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractBinding.java @@ -0,0 +1,72 @@ +/* + * 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.extension.helper.utils; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Binding; + +/** + * Helper for implementing Bindings, implements all the + * standard getters and setters on the binding interface. + * + * @version $Rev$ $Date$ + */ +public class AbstractBinding implements Binding { + + private String name; + private String uri; + private List<Object> extensions; + private boolean unresolved; + + public String getName() { + return name; + } + + public String getURI() { + return uri; + } + + public void setName(String name) { + this.name = name; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public List<Object> getExtensions() { + return extensions; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractImplementation.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractImplementation.java new file mode 100644 index 0000000000..0e658cfd1e --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractImplementation.java @@ -0,0 +1,153 @@ +/* + * 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.extension.helper.utils; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.ConfiguredOperation; +import org.apache.tuscany.sca.assembly.ConstrainingType; +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.policy.Intent; +import org.apache.tuscany.sca.policy.IntentAttachPointType; +import org.apache.tuscany.sca.policy.PolicySet; + +/** + * Helper for implementing Implementations, implements all the + * standard getters and setters on the Implementation interface. + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractImplementation implements Implementation { + + private List<Service> services = new ArrayList<Service>(); + private List<Reference> references = new ArrayList<Reference>(); + private List<Property> properties = new ArrayList<Property>(); + private ConstrainingType constrainingType; + private String uri; + private boolean unresolved = true; + private List<ConfiguredOperation> configuredOperations = new ArrayList<ConfiguredOperation>(); + private List<PolicySet> applicablePolicySets = new ArrayList<PolicySet>(); + private List<PolicySet> policySets = new ArrayList<PolicySet>(); + private List<Intent> requiredIntents = new ArrayList<Intent>(); + private IntentAttachPointType type = null; + + public AbstractImplementation() { + } + + public List<Property> getProperties() { + return properties; + } + + public List<Reference> getReferences() { + return references; + } + + public List<Service> getServices() { + return services; + } + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public ConstrainingType getConstrainingType() { + return constrainingType; + } + + public void setConstrainingType(ConstrainingType constrainingType) { + this.constrainingType = constrainingType; + } + + public List<Object> getExtensions() { + // TODO what is this for? + return null; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public Service getService(String name) { + for (Service service : getServices()) { + if (service.getName().equals(name)) { + return service; + } + } + return null; + } + + public Reference getReference(String name) { + for (Reference reference : getReferences()) { + if (reference.getName().equals(name)) { + return reference; + } + } + return null; + } + + public Property getProptery(String name) { + for (Property property : getProperties()) { + if (property.getName().equals(name)) { + return property; + } + } + return null; + } + + public List<ConfiguredOperation> getConfiguredOperations() { + return configuredOperations; + } + + // public void setConfiguredOperations(List<ConfiguredOperation> configuredOperations) { + // this.configuredOperations = configuredOperations; + // } + + public List<PolicySet> getApplicablePolicySets() { + return applicablePolicySets; + } + + public List<PolicySet> getPolicySets() { + return policySets; + } + + public List<Intent> getRequiredIntents() { + return requiredIntents; + } + + public IntentAttachPointType getType() { + return type; + } + + public void setType(IntentAttachPointType type) { + this.type = type; + } +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractStAXArtifactProcessor.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractStAXArtifactProcessor.java new file mode 100644 index 0000000000..9a521b5b79 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/AbstractStAXArtifactProcessor.java @@ -0,0 +1,132 @@ +/* + * 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.extension.helper.utils; + +import java.lang.reflect.Method; + +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.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +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.impl.InterfaceContractImpl; +import org.apache.tuscany.sca.interfacedef.impl.InterfaceImpl; +import org.apache.tuscany.sca.interfacedef.impl.OperationImpl; + +/** + * TODO: couldn't something like this class be provided by the runtime? + * Each impl shouldn't have to have their own .componentType merging code + * + * @version $Rev$ $Date$ + */ +public abstract class AbstractStAXArtifactProcessor<I extends Implementation> implements StAXArtifactProcessor<I> { + + protected AssemblyFactory assemblyFactory; + + public AbstractStAXArtifactProcessor(AssemblyFactory assemblyFactory) { + this.assemblyFactory = assemblyFactory; + } + + public void resolve(I model, ModelResolver resolver) throws ContributionResolveException { + + addSideFileComponentType(model.getURI(), model, resolver); + + if (model instanceof DynamicImplementation) { + // if no services have been defined then add a dynamic one + if (model.getServices().size() < 1) { + Service dynamicService = createDynamicService(); + model.getServices().add(dynamicService); + } + } + + // Allow implementation classes to resolve themselves + try { + Method resolveMethod; + if ((resolveMethod = model.getClass().getMethod("resolve", ModelResolver.class)) != null) { + resolveMethod.invoke(model, resolver); + } + } catch (Exception e) { + } + + model.setUnresolved(false); + } + + protected void addSideFileComponentType(String name, Implementation impl, ModelResolver resolver) { + if (name == null) { + return; + } + int lastDot = name.lastIndexOf('.'); + if (lastDot < 0) { + return; + } + String sideFileName = name.substring(0, lastDot) + ".componentType"; + + ComponentType componentType = assemblyFactory.createComponentType(); + componentType.setURI(sideFileName); + componentType.setUnresolved(true); + + componentType = resolver.resolveModel(ComponentType.class, componentType); + + if (!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()); + } + } + } + + protected Service createDynamicService() { + Service dynamicService = assemblyFactory.createService(); + dynamicService.setName("$dynamic$"); + InterfaceContract dynamicInterfaceContract = new InterfaceContractImpl() {}; + Interface dynamicInterface = new DynamicInterfaceImpl(); + Operation dynamicOperation = new OperationImpl(); + dynamicOperation.setDynamic(true); + dynamicInterface.getOperations().add(dynamicOperation); + dynamicInterfaceContract.setInterface(dynamicInterface); + dynamicService.setInterfaceContract(dynamicInterfaceContract); + + return dynamicService; + } + + private static class DynamicInterfaceImpl extends InterfaceImpl { + @Override + public boolean isDynamic() { + return true; + } + + } + +}
\ No newline at end of file diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DefaultPropertyValueObjectFactory.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DefaultPropertyValueObjectFactory.java new file mode 100644 index 0000000000..550498d7b1 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DefaultPropertyValueObjectFactory.java @@ -0,0 +1,231 @@ +/* + * 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.extension.helper.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.core.factory.ObjectCreationException; +import org.apache.tuscany.sca.core.factory.ObjectFactory; +import org.apache.tuscany.sca.databinding.Mediator; +import org.apache.tuscany.sca.databinding.SimpleTypeMapper; +import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * TODO: Shouldn't this class be provided by the runtime? + * + * @version $Rev$ $Date$ + */ +public class DefaultPropertyValueObjectFactory implements PropertyValueObjectFactory { + // protected DataBindingRegistry dbRegistry = new DataBindingRegistryImpl(); + protected Mediator mediator = null; + protected SimpleTypeMapper simpleTypeMapper = new SimpleTypeMapperImpl(); + boolean isSimpleType; + + public DefaultPropertyValueObjectFactory(Mediator mediator) { + this.mediator = mediator; + } + + /* (non-Javadoc) + * @see org.apache.tuscany.sca.extension.helper.utils.PVOF#createValueFactory(org.apache.tuscany.sca.assembly.Property) + */ + public ObjectFactory createValueFactory(Property property) { + isSimpleType = isSimpleType(property); + Document doc = (Document)property.getValue(); + Element rootElement = doc.getDocumentElement(); + + //FIXME : since scripts use dynamic types we need to generate a dynamic java type using the + //XML structure of the property value. Should this be done in the JavaBeansDataBinding... + Class javaType = null; + + if (property.isMany()) { + if (isSimpleType) { + String value = ""; + if (rootElement.getChildNodes().getLength() > 0) { + value = rootElement.getChildNodes().item(0).getTextContent(); + } + List<String> values = + getSimplePropertyValues(value, javaType); + return new ListObjectFactoryImpl(property, + values, + isSimpleType, + javaType); + } else { + return new ListObjectFactoryImpl(property, + getComplexPropertyValues(doc), + isSimpleType, + javaType); + } + } else { + if (isSimpleType) { + String value = ""; + if (rootElement.getChildNodes().getLength() > 0) { + value = rootElement.getChildNodes().item(0).getTextContent(); + } + return new ObjectFactoryImpl(property, + value, + isSimpleType, + javaType); + } else { + Object value = getComplexPropertyValues(doc).get(0); + return new ObjectFactoryImpl(property, + value, + isSimpleType, + javaType); + } + + } + } + + private boolean isSimpleType(Property property) { + if (property.getXSDType() != null) { + return SimpleTypeMapperImpl.isSimpleXSDType(property.getXSDType()); + } else { + if (property instanceof Document) { + Document doc = (Document)property; + Element element = doc.getDocumentElement(); + if (element.getChildNodes().getLength() == 1 && + element.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE) { + return true; + } + } + } + return false; + } + + private List<String> getSimplePropertyValues(String concatenatedValue, Class javaType) { + List<String> propValues = new ArrayList<String>(); + StringTokenizer st = null; + if ( javaType.getName().equals("java.lang.String")) { + st = new StringTokenizer(concatenatedValue, "\""); + } else { + st = new StringTokenizer(concatenatedValue); + } + String aToken = null; + while (st.hasMoreTokens()) { + aToken = st.nextToken(); + if (aToken.trim().length() > 0) { + propValues.add(aToken); + } + } + return propValues; + } + + private List<Node> getComplexPropertyValues(Document document) { + Element rootElement = document.getDocumentElement(); + List<Node> propValues = new ArrayList<Node>(); + for (int count = 0 ; count < rootElement.getChildNodes().getLength() ; ++count) { + if (rootElement.getChildNodes().item(count).getNodeType() == Node.ELEMENT_NODE) { + propValues.add(rootElement.getChildNodes().item(count)); + } + } + return propValues; + } + + public abstract class ObjectFactoryImplBase implements ObjectFactory { + protected SimpleTypeMapper simpleTypeMapper = new SimpleTypeMapperImpl(); + protected Property property; + protected Object propertyValue; + protected Class javaType; + protected DataType<XMLType> sourceDataType; + protected DataType<?> targetDataType; + boolean isSimpleType; + + public ObjectFactoryImplBase(Property property, Object propertyValue, boolean isSimpleType, Class javaType) { + + this.isSimpleType = isSimpleType; + this.property = property; + this.propertyValue = propertyValue; + this.javaType = javaType; + //FIXME : fix this when we have managed to generate dynamic java types + /*sourceDataType = + new DataTypeImpl<XMLType>(DOMDataBinding.NAME, Node.class, + new XMLType(null, this.property.getXSDType())); + TypeInfo typeInfo = null; + if (this.property.getXSDType() != null) { + if (SimpleTypeMapperExtension.isSimpleXSDType(this.property.getXSDType())) { + typeInfo = new TypeInfo(property.getXSDType(), true, null); + } else { + typeInfo = new TypeInfo(property.getXSDType(), false, null); + } + } else { + typeInfo = new TypeInfo(property.getXSDType(), false, null); + } + + XMLType xmlType = new XMLType(typeInfo); + String dataBinding = null; //(String)property.getExtensions().get(DataBinding.class.getName()); + if (dataBinding != null) { + targetDataType = new DataTypeImpl<XMLType>(dataBinding, javaType, xmlType); + } else { + targetDataType = new DataTypeImpl<XMLType>(dataBinding, javaType, xmlType); + mediator.getDataBindingRegistry().introspectType(targetDataType, null); + }*/ + } + } + + public class ObjectFactoryImpl extends ObjectFactoryImplBase { + public ObjectFactoryImpl(Property property, Object propertyValue, boolean isSimpleType, Class javaType) { + super(property, propertyValue, isSimpleType, javaType); + } + + @SuppressWarnings("unchecked") + public Object getInstance() throws ObjectCreationException { + if (isSimpleType) { + return simpleTypeMapper.toJavaObject(property.getXSDType(), (String)propertyValue, null); + } else { + return mediator.mediate(propertyValue, sourceDataType, targetDataType, null); + //return null; + } + } + } + + public class ListObjectFactoryImpl extends ObjectFactoryImplBase { + public ListObjectFactoryImpl(Property property, List<?>propertyValues, boolean isSimpleType, Class javaType) { + super(property, propertyValues, isSimpleType, javaType); + } + + @SuppressWarnings("unchecked") + public List<?> getInstance() throws ObjectCreationException { + if (isSimpleType) { + List<Object> values = new ArrayList<Object>(); + for (String aValue : (List<String>)propertyValue) { + values.add(simpleTypeMapper.toJavaObject(property.getXSDType(), aValue, null)); + } + return values; + } else { + List instances = new ArrayList(); + for (Node aValue : (List<Node>)propertyValue) { + instances.add(mediator.mediate(aValue, + sourceDataType, + targetDataType, + null)); + } + return instances; + } + } + } +} +
\ No newline at end of file diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DynamicImplementation.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DynamicImplementation.java new file mode 100644 index 0000000000..dbfb9d089f --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/DynamicImplementation.java @@ -0,0 +1,96 @@ +/* + * 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.extension.helper.utils; + +import org.apache.tuscany.sca.assembly.Component; +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.assembly.builder.ComponentPreProcessor; +import org.apache.tuscany.sca.runtime.RuntimeComponent; + +/** + * + * @version $Rev$ $Date$ + */ +public class DynamicImplementation extends AbstractImplementation implements ComponentPreProcessor { + + public void preProcess(Component component) { + RuntimeComponent rtc = (RuntimeComponent) component; + + for (Service service : rtc.getServices()) { + if (getService(service.getName()) == null) { + getServices().add(createService(service)); + } + } + + Service dynamicService = getService("$dynamic$"); + if (dynamicService != null && getServices().size() > 1) { + getServices().remove(dynamicService); + dynamicService = null; + } + + for (Reference reference : rtc.getReferences()) { + if (getReference(reference.getName()) == null) { + getReferences().add(createReference(reference)); + } + } + + for (Property property : rtc.getProperties()) { + if (getProptery(property.getName()) == null) { + getProperties().add(createProperty(property)); + } + } + + // TODO: support properties + } + + protected Service createService(Service service) { + Service newService; + try { + newService = (Service)service.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // should not ever happen + } + + return newService; + } + + protected Reference createReference(Reference reference) { + Reference newReference; + try { + newReference = (Reference)reference.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // should not ever happen + } + return newReference; + } + + protected Property createProperty(Property property) { + Property newProperty; + try { + newProperty = (Property)property.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // should not ever happen + } + return newProperty; + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/PropertyValueObjectFactory.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/PropertyValueObjectFactory.java new file mode 100644 index 0000000000..f209825679 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/PropertyValueObjectFactory.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.sca.extension.helper.utils; + +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.core.factory.ObjectFactory; + +/** + * + * @version $Rev$ $Date$ + */ +public interface PropertyValueObjectFactory { + + ObjectFactory createValueFactory(Property property); + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/ResourceHelper.java b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/ResourceHelper.java new file mode 100644 index 0000000000..4e7965ce60 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/java/org/apache/tuscany/sca/extension/helper/utils/ResourceHelper.java @@ -0,0 +1,70 @@ +/* + * 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.extension.helper.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; + +/** + * TODO: Shouldn't this be using the contribution service? + * + * @version $Rev$ $Date$ + */ +public class ResourceHelper { + + public static String readResource(URL scriptSrcUrl) { + + InputStream is; + try { + URLConnection connection = scriptSrcUrl.openConnection(); + connection.setUseCaches(false); + is = connection.getInputStream(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + try { + + Reader reader = new InputStreamReader(is, "UTF-8"); + char[] buffer = new char[1024]; + StringBuilder source = new StringBuilder(); + int count; + while ((count = reader.read(buffer)) > 0) { + source.append(buffer, 0, count); + } + + return source.toString(); + + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } + +} diff --git a/branches/sca-java-20080910/modules/extension-helper/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator b/branches/sca-java-20080910/modules/extension-helper/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator new file mode 100644 index 0000000000..a408b0d061 --- /dev/null +++ b/branches/sca-java-20080910/modules/extension-helper/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator @@ -0,0 +1,20 @@ +# 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.
+
+# Implementation class for the ExtensionActivator
+org.apache.tuscany.sca.extension.helper.impl.ImplementationsActivator
+org.apache.tuscany.sca.extension.helper.impl.BindingsActivator
|