diff options
Diffstat (limited to '')
212 files changed, 18620 insertions, 0 deletions
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/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/tags/java/sca/1.3-RC1a/modules/contribution-groovy/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/NOTICE new file mode 100644 index 0000000000..aeeca5ef8d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/NOTICE @@ -0,0 +1,8 @@ +${pom.name} +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +This product uses Relax WS (http://code.google.com/p/relax-ws/) with the following copyright: + * Copyright 2008 Jason Sando diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/pom.xml new file mode 100644 index 0000000000..31506b90bb --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/pom.xml @@ -0,0 +1,84 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tuscany-contribution-groovy</artifactId> + <name>Apache Tuscany SCA Groovy contributions</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all-minimal</artifactId> + <version>1.5.4</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-host-embedded</artifactId> + <version>1.3</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-implementation-java-runtime</artifactId> + <version>1.3</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.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.contribution.groovy</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.groovy*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifact.java b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifact.java new file mode 100644 index 0000000000..77dab193b9 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifact.java @@ -0,0 +1,41 @@ +/* + * 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.contribution.groovy; + +import java.net.URL; + +/** + * GroovyArtifact holds the URL to the Groovy script. + * + * @version $Rev$ $Date$ + */ +public class GroovyArtifact { + + private URL artifactURL; + + public GroovyArtifact(URL artifactURL) { + this.artifactURL = artifactURL; + } + + public URL getArtifactURL() { + return artifactURL; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifactProcessor.java new file mode 100644 index 0000000000..4b7df4d9f8 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyArtifactProcessor.java @@ -0,0 +1,57 @@ +/* + * 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.contribution.groovy; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +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.monitor.Monitor; + +/** + * A URLArtifactProcessor for Groovy scripts + * + * @version $Rev$ $Date$ + */ +public class GroovyArtifactProcessor implements URLArtifactProcessor<GroovyArtifact> { + + public GroovyArtifactProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + } + + public GroovyArtifact read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException { + return new GroovyArtifact(artifactURL); + } + + public String getArtifactType() { + return ".groovy"; + } + + public Class<GroovyArtifact> getModelType() { + return GroovyArtifact.class; + } + + public void resolve(GroovyArtifact groovyModel, ModelResolver arg1) throws ContributionResolveException { + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyModelResolver.java new file mode 100644 index 0000000000..82fe0326df --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/java/org/apache/tuscany/sca/contribution/groovy/GroovyModelResolver.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.contribution.groovy; + +import groovy.lang.GroovyClassLoader; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A ModelResolver that compiles Groovy scripts into the contribution + * class loader so they can be used just like a regular java class. + * + * @version $Rev$ $Date$ + */ +public class GroovyModelResolver implements ModelResolver { + + protected ModelResolver modelresolver; + protected Contribution contribution; + + public GroovyModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + modelresolver = contribution.getModelResolver(); + this.contribution = contribution; + } + + public void addModel(Object model) { + ClassLoader cl = contribution.getClassLoader(); + if (!(cl instanceof GroovyClassLoader)) { + // replace the contribution class loader with a Groovy one + // If the contribution does not have a ClassLoader, use this ClassLoader as parent + if (cl == null) cl = this.getClass().getClassLoader(); + cl = new GroovyClassLoader(cl); + contribution.setClassLoader(cl); + } + try { + + ((GroovyClassLoader)cl).parseClass(((GroovyArtifact)model).getArtifactURL().openStream()); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object removeModel(Object arg0) { + return null; + } + + public <T> T resolveModel(Class<T> arg0, T arg1) { + return null; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor new file mode 100644 index 0000000000..f9dbee53bb --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor @@ -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 artifact processor extension +org.apache.tuscany.sca.contribution.groovy.GroovyArtifactProcessor;type=.groovy,model=org.apache.tuscany.sca.contribution.groovy.GroovyArtifact + diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..86434ac4bf --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.groovy.GroovyModelResolver;model=org.apache.tuscany.sca.contribution.groovy.GroovyArtifact
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorld.java b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorld.java new file mode 100644 index 0000000000..788c42f07d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorld.java @@ -0,0 +1,31 @@ +/* + * 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.contribution.groovy; + +/** + * HelloWorld Service interface used for testing. + * + * @version $Rev$ $Date$ + */ +public interface HelloWorld { + + String sayHello(String s); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorldTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorldTestCase.java new file mode 100644 index 0000000000..02be3acd23 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/java/org/apache/tuscany/sca/contribution/groovy/HelloWorldTestCase.java @@ -0,0 +1,55 @@ +/* + * 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.contribution.groovy; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.host.embedded.SCADomain; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Runs a distributed domain in a single VM by using and in memory implementation of the distributed domain + * + * @version $Rev$ $Date$ + */ +public class HelloWorldTestCase { + + private static HelloWorld helloWorld; + private static SCADomain scaDomain; + + @BeforeClass + public static void init() throws Exception { + scaDomain = SCADomain.newInstance("org/apache/tuscany/sca/contribution/groovy/helloworld.composite"); + helloWorld = scaDomain.getService(HelloWorld.class, "HelloWolrdComponent"); + } + + @AfterClass + public static void destroy() throws Exception { + if (scaDomain != null) { + scaDomain.close(); + } + } + + @Test + public void testCalculator() throws Exception { + Assert.assertEquals("Hello Petra", helloWorld.sayHello("Petra")); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/HelloWorld.groovy b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/HelloWorld.groovy new file mode 100644 index 0000000000..c172528538 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/HelloWorld.groovy @@ -0,0 +1,27 @@ +/*
+ * 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.contribution.groovy
+
+class HelloWorldImpl implements org.apache.tuscany.sca.contribution.groovy.HelloWorld {
+
+ String sayHello(String you) {
+ return "Hello $you"
+ }
+
+}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/helloworld.composite b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/helloworld.composite new file mode 100644 index 0000000000..0d4c17a15b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-groovy/src/test/resources/org/apache/tuscany/sca/contribution/groovy/helloworld.composite @@ -0,0 +1,29 @@ +<?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.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ targetNamespace="http://sample"
+ xmlns:sample="http://sample"
+ name="HelloWorld">
+
+ <component name="HelloWolrdComponent">
+ <implementation.java class="org.apache.tuscany.sca.contribution.groovy.HelloWorldImpl"/>
+ </component>
+
+</composite>
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-impl/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/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/tags/java/sca/1.3-RC1a/modules/contribution-impl/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-impl/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/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/tags/java/sca/1.3-RC1a/modules/contribution-impl/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-impl/pom.xml new file mode 100644 index 0000000000..ec0ae2190f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/pom.xml @@ -0,0 +1,88 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-impl</artifactId> + <name>Apache Tuscany SCA Contribution Model Implementation</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-xml</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-java</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-namespace</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution-resource</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.impl</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java new file mode 100644 index 0000000000..ab056e3214 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/FolderContributionProcessor.java @@ -0,0 +1,156 @@ +/* + * 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.contribution.processor.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.contribution.PackageType; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; + +/** + * Folder contribution package processor. + * + * @version $Rev$ $Date$ + */ +public class FolderContributionProcessor implements PackageProcessor { + + public FolderContributionProcessor() { + } + + public String getPackageType() { + return PackageType.FOLDER; + } + + /** + * Recursively traverse a root directory + * + * @param fileList + * @param file + * @param root + * @throws IOException + */ + private static void traverse(List<URI> fileList, final File file, final File root) throws IOException { + // Allow privileged access to test file. Requires FilePermissions in security policy file. + Boolean isFile = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return file.isFile(); + } + }); + if (isFile) { + fileList.add(AccessController.doPrivileged(new PrivilegedAction<URI>() { + public URI run() { + return root.toURI().relativize(file.toURI()); + } + })); + } else { + // Allow privileged access to test file. Requires FilePermissions in security policy + // file. + Boolean isDirectory = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return file.isDirectory(); + } + }); + if (isDirectory) { + String uri = AccessController.doPrivileged(new PrivilegedAction<URI>() { + public URI run() { + return root.toURI().relativize(file.toURI()); + } + }).toString(); + + if (uri.endsWith("/")) { + uri = uri.substring(0, uri.length() - 1); + } + fileList.add(URI.create(uri)); + + // Allow privileged access to list files. Requires FilePermission in security + // policy. + File[] files = AccessController.doPrivileged(new PrivilegedAction<File[]>() { + public File[] run() { + return file.listFiles(); + } + }); + for (File f : files) { + if (!f.getName().startsWith(".")) { + traverse(fileList, f, root); + } + } + } + } + } + + public URL getArtifactURL(URL sourceURL, URI artifact) throws MalformedURLException { + return new URL(sourceURL, artifact.toString()); + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, + IOException { + if (packageSourceURL == null) { + throw new IllegalArgumentException("Invalid null package source URL."); + } + + List<URI> artifacts = new ArrayList<URI>(); + + try { + // Assume the root is a jar file + final File rootFolder = new File(packageSourceURL.toURI()); + // Allow privileged access to test file. Requires FilePermissions in security policy + // file. + Boolean isDirectory = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return rootFolder.isDirectory(); + } + }); + if (isDirectory) { + // Allow privileged access to test file. Requires FilePermissions in security policy + // file. + Boolean folderExists = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return rootFolder.exists(); + } + }); + if (!folderExists) { + throw new ContributionReadException(rootFolder.getAbsolutePath()); + } + + // Security consideration. This method gathers URIs of enclosed + // artifacts. The URIs are protected by the policy when a user + // yries to open those URLs. + traverse(artifacts, rootFolder, rootFolder); + } + + } catch (URISyntaxException e) { + throw new ContributionReadException(packageSourceURL.toExternalForm(), e); + } + + return artifacts; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java new file mode 100644 index 0000000000..3df275a7a1 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/JarContributionProcessor.java @@ -0,0 +1,123 @@ +/* + * 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.contribution.processor.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +import org.apache.tuscany.sca.contribution.PackageType; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Jar Contribution package processor. + * + * @version $Rev$ $Date$ + */ +public class JarContributionProcessor implements PackageProcessor { + + public JarContributionProcessor() { + } + + public String getPackageType() { + return PackageType.JAR; + } + + public URL getArtifactURL(URL sourceURL, URI artifact) throws MalformedURLException { + if (sourceURL.toString().startsWith("jar:")) { + return new URL(sourceURL, artifact.toString()); + } else { + return new URL("jar:" + sourceURL.toExternalForm() + "!/" + artifact); + } + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, + IOException { + if (packageSourceURL == null) { + throw new IllegalArgumentException("Invalid null package source URL."); + } + + if (inputStream == null) { + throw new IllegalArgumentException("Invalid null source inputstream."); + } + + // Assume the root is a jar file + JarInputStream jar = new JarInputStream(inputStream); + try { + Set<String> names = new HashSet<String>(); + while (true) { + JarEntry entry = jar.getNextJarEntry(); + if (entry == null) { + // EOF + break; + } + + // FIXME: Maybe we should externalize the filter as a property + String name = entry.getName(); + if (!name.startsWith(".")) { + + // Trim trailing / + if (name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + + // Add the entry name + if (!names.contains(name)) { + names.add(name); + + // Add parent folder names to the list too + for (;;) { + int s = name.lastIndexOf('/'); + if (s == -1) { + name = ""; + } else { + name = name.substring(0, s); + } + if (!names.contains(name)) { + names.add(name); + } else { + break; + } + } + } + } + } + + // Return list of URIs + List<URI> artifacts = new ArrayList<URI>(); + for (String name: names) { + artifacts.add(URI.create(name)); + } + return artifacts; + + } finally { + jar.close(); + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java new file mode 100644 index 0000000000..9375cb917f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionRepositoryImpl.java @@ -0,0 +1,399 @@ +/* + * 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.contribution.service.impl; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * The default implementation of ContributionRepository + * + * @version $Rev$ $Date$ + */ +public class ContributionRepositoryImpl implements ContributionRepository { + private static final String NS = "http://tuscany.apache.org/xmlns/1.0-SNAPSHOT"; + private static final String DOMAIN_INDEX_FILENAME = "sca-domain.xml"; + private final File rootFile; + private Map<String, String> contributionLocations = new HashMap<String, String>(); + + private Map<String, Contribution> contributionMap = new HashMap<String, Contribution>(); + private List<Contribution> contributions = new ArrayList<Contribution>(); + + private URI domain; + private XMLInputFactory factory; + private Monitor monitor; + + /** + * Marshals warnings into the monitor + * + * @param message + * @param model + * @param messageParameters + */ + protected void warning(String message, Object model, String... messageParameters) { + if (monitor != null){ + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-impl-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Marshals errors into the monitor + * + * @param problems + * @param message + * @param model + */ + protected void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-impl-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Marshals exceptions into the monitor + * + * @param problems + * @param message + * @param model + */ + protected void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-impl-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + /** + * Constructor with repository root + * + * @param repository + * @param factory + */ + public ContributionRepositoryImpl(final String repository, XMLInputFactory factory, Monitor monitor) throws IOException { + this.monitor = monitor; + String root = repository; + if (repository == null) { + root = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + // Default to <user.home>/.tuscany/domains/local/ + String userHome = System.getProperty("user.home"); + String slash = File.separator; + return userHome + slash + ".tuscany" + slash + "domains" + slash + "local" + slash; + } + }); + } + + // Allow privileged access to File. Requires FilePermission in security policy file. + final String finalRoot = root; + this.rootFile = AccessController.doPrivileged(new PrivilegedAction<File>() { + public File run() { + return new File(finalRoot); + } + }); + + // Allow privileged access to File. Requires FilePermission in security policy file. + this.domain = AccessController.doPrivileged(new PrivilegedAction<URI>() { + public URI run() { + return rootFile.toURI(); + } + }); + + // Allow privileged access to mkdir. Requires FilePermission in security policy file. + try { + AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { + public Object run() throws IOException { + FileHelper.forceMkdir(rootFile); + return null; + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", rootFile, (IOException)e.getException()); + throw (IOException)e.getException(); + } + + // Allow privileged access to test file. Requires FilePermissions in security policy file. + Boolean notDirectory = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return (!rootFile.exists() || !rootFile.isDirectory() || !rootFile.canRead()); + } + }); + if (notDirectory) { + error("RootNotDirectory", rootFile, repository); + throw new IOException("The root is not a directory: " + repository); + } + this.factory = factory; + } + + public URI getDomain() { + return domain; + } + + /** + * Resolve contribution location in the repository -> root repository / + * contribution file -> contribution group id / artifact id / version + * + * @param contribution + * @return + */ + private File mapToFile(URL sourceURL) { + String fileName = FileHelper.toFile(sourceURL).getName(); + return new File(rootFile, "contributions" + File.separator + fileName); + } + + /** + * Write a specific source InputStream to a file on disk + * + * @param source contents of the file to be written to disk + * @param target file to be written + * @throws IOException + */ + public static void copy(InputStream source, File target) throws IOException { + BufferedOutputStream out = null; + BufferedInputStream in = null; + + try { + out = new BufferedOutputStream(new FileOutputStream(target)); + in = new BufferedInputStream(source); + IOHelper.copy(in, out); + } finally { + IOHelper.closeQuietly(out); + IOHelper.closeQuietly(in); + } + } + + public URL store(final String contribution, URL sourceURL, InputStream contributionStream) throws IOException { + // where the file should be stored in the repository + final File location = mapToFile(sourceURL); + FileHelper.forceMkdir(location.getParentFile()); + + copy(contributionStream, location); + + // add contribution to repositoryContent + // Allow ability to read user.dir property. Requires PropertyPermission in security policy. + URL contributionURL; + try { + contributionURL= AccessController.doPrivileged(new PrivilegedExceptionAction<URL>() { + public URL run() throws IOException { + URL contributionURL = location.toURL(); + URI relative = rootFile.toURI().relativize(location.toURI()); + contributionLocations.put(contribution, relative.toString()); + return contributionURL; + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", location, (IOException)e.getException()); + throw (IOException)e.getException(); + } + saveMap(); + + return contributionURL; + } + + public URL store(String contribution, URL sourceURL) throws IOException { + // where the file should be stored in the repository + File location = mapToFile(sourceURL); + File source = FileHelper.toFile(sourceURL); + if (source == null || source.isFile()) { + URLConnection connection = sourceURL.openConnection(); + connection.setUseCaches(false); + InputStream is = connection.getInputStream(); + try { + return store(contribution, sourceURL, is); + } finally { + IOHelper.closeQuietly(is); + } + } + + FileHelper.forceMkdir(location); + FileHelper.copyDirectory(source, location); + + // add contribution to repositoryContent + URI relative = rootFile.toURI().relativize(location.toURI()); + contributionLocations.put(contribution, relative.toString()); + saveMap(); + + return location.toURL(); + } + + public URL find(String contribution) { + if (contribution == null) { + return null; + } + String location = contributionLocations.get(contribution); + if (location == null) { + return null; + } + try { + return new File(rootFile, location).toURL(); + } catch (MalformedURLException e) { + // Should not happen + error("MalformedURLException", location, new AssertionError(e)); + throw new AssertionError(e); + } + } + + public void remove(String contribution) { + URL contributionURL = this.find(contribution); + if (contributionURL != null) { + // remove + try { + FileHelper.forceDelete(FileHelper.toFile(contributionURL)); + this.contributionLocations.remove(contribution); + saveMap(); + } catch (IOException ioe) { + // handle file could not be removed + } + } + } + + public List<String> list() { + return new ArrayList<String>(contributionLocations.keySet()); + } + + public void init() { + File domainFile = new File(rootFile, "sca-domain.xml"); + if (!domainFile.isFile()) { + return; + } + FileInputStream is; + try { + is = new FileInputStream(domainFile); + } catch (FileNotFoundException e) { + warning("DomainFileNotFound", domainFile, domainFile.getAbsolutePath()); + return; + } + try { + XMLStreamReader reader = factory.createXMLStreamReader(new InputStreamReader(is, "UTF-8")); + while (reader.hasNext()) { + switch (reader.getEventType()) { + case XMLStreamConstants.START_ELEMENT: + String name = reader.getName().getLocalPart(); + if ("domain".equals(name)) { + String uri = reader.getAttributeValue(null, "uri"); + if (uri != null) { + domain = URI.create(uri); + } + } + if ("contribution".equals(name)) { + String uri = reader.getAttributeValue(null, "uri"); + String location = reader.getAttributeValue(null, "location"); + contributionLocations.put(uri, location); + } + break; + default: + break; + } + reader.next(); + } + } catch (Exception e) { + // Ignore + } finally { + IOHelper.closeQuietly(is); + } + } + + private void saveMap() { + File domainFile = new File(rootFile, DOMAIN_INDEX_FILENAME); + FileOutputStream os = null; + try { + os = new FileOutputStream(domainFile); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, "UTF-8")); + writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + writer.println("<domain uri=\"" + getDomain() + "\" xmlns=\"" + NS + "\">"); + for (Map.Entry<String, String> e : contributionLocations.entrySet()) { + writer.println(" <contribution uri=\"" + e.getKey() + "\" location=\"" + e.getValue() + "\"/>"); + } + writer.println("</domain>"); + writer.flush(); + } catch (IOException e) { + IllegalArgumentException ae = new IllegalArgumentException(e); + error("IllegalArgumentException", os, ae); + throw ae; + } finally { + IOHelper.closeQuietly(os); + } + } + + public void destroy() { + } + + public void addContribution(Contribution contribution) { + contributionMap.put(contribution.getURI(), contribution); + contributions.add(contribution); + } + + public void removeContribution(Contribution contribution) { + contributionMap.remove(contribution.getURI()); + contributions.remove(contribution); + } + + public void updateContribution(Contribution contribution) { + Contribution oldContribution = contributionMap.remove(contribution.getURI()); + contributions.remove(oldContribution); + contributionMap.put(contribution.getURI(), contribution); + contributions.add(contribution); + } + + public Contribution getContribution(String uri) { + return contributionMap.get(uri); + } + + public List<Contribution> getContributions() { + return Collections.unmodifiableList(contributions); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java new file mode 100644 index 0000000000..0e39174497 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/ContributionServiceImpl.java @@ -0,0 +1,545 @@ +/* + * 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.contribution.service.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.PackageProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; +import org.apache.tuscany.sca.contribution.service.ContributionService; +import org.apache.tuscany.sca.contribution.service.ExtensibleContributionListener; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; +import org.apache.tuscany.sca.contribution.xml.ContributionMetadataDocumentProcessor; +import org.apache.tuscany.sca.definitions.SCADefinitions; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentAttachPointType; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Service interface that manages artifacts contributed to a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public class ContributionServiceImpl implements ContributionService { + + /** + * Repository where contributions are stored. Usually set by injection. + */ + private ContributionRepository contributionRepository; + + /** + * Registry of available package processors. + */ + private PackageProcessor packageProcessor; + + /** + * Registry of available artifact processors + */ + + private URLArtifactProcessor artifactProcessor; + + /** + * Registry of available StAX processors, + * used for loading contribution metadata in a extensible way + */ + private StAXArtifactProcessor staxProcessor; + + /** + * Event listener for contribution operations + */ + private ExtensibleContributionListener contributionListener; + + /** + * Registry of available model resolvers + */ + + private ModelResolverExtensionPoint modelResolvers; + + /** + * Model factory extension point + */ + + private ModelFactoryExtensionPoint modelFactories; + + /** + * XML factory used to create reader instance to load contribution metadata + */ + private XMLInputFactory xmlFactory; + + /** + * Assembly factory + */ + private AssemblyFactory assemblyFactory; + + /** + * Contribution model factory + */ + private ContributionFactory contributionFactory; + + + private ModelResolver policyDefinitionsResolver; + + private List policyDefinitions; + + private Monitor monitor; + + private String COMPOSITE_FILE_EXTN = ".composite"; + + public ContributionServiceImpl(ContributionRepository repository, + PackageProcessor packageProcessor, + URLArtifactProcessor documentProcessor, + StAXArtifactProcessor staxProcessor, + ExtensibleContributionListener contributionListener, + ModelResolver policyDefinitionsResolver, + ModelResolverExtensionPoint modelResolvers, + ModelFactoryExtensionPoint modelFactories, + AssemblyFactory assemblyFactory, + ContributionFactory contributionFactory, + XMLInputFactory xmlFactory, + List<SCADefinitions> policyDefinitions, + Monitor monitor) { + super(); + this.contributionRepository = repository; + this.packageProcessor = packageProcessor; + this.artifactProcessor = documentProcessor; + this.staxProcessor = staxProcessor; + this.contributionListener = contributionListener; + this.modelResolvers = modelResolvers; + this.modelFactories = modelFactories; + this.xmlFactory = xmlFactory; + this.assemblyFactory = assemblyFactory; + this.contributionFactory = contributionFactory; + this.policyDefinitionsResolver = policyDefinitionsResolver; + this.policyDefinitions = policyDefinitions; + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-impl-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public Contribution contribute(String contributionURI, URL sourceURL, boolean storeInRepository) + throws ContributionException, IOException { + if (contributionURI == null) { + error("ContributionURINull", contributionURI); + throw new IllegalArgumentException("URI for the contribution is null"); + } + if (sourceURL == null) { + error("SourceURLNull", sourceURL); + throw new IllegalArgumentException("Source URL for the contribution is null"); + } + return addContribution(contributionURI, sourceURL, null, null, storeInRepository); + } + + public Contribution contribute(String contributionURI, + URL sourceURL, + ModelResolver modelResolver, + boolean storeInRepository) throws ContributionException, IOException { + if (contributionURI == null) { + error("ContributionURINull", contributionURI); + throw new IllegalArgumentException("URI for the contribution is null"); + } + if (sourceURL == null) { + error("SourceURLNull", sourceURL); + throw new IllegalArgumentException("Source URL for the contribution is null"); + } + + return addContribution(contributionURI, sourceURL, null, modelResolver, storeInRepository); + } + + public Contribution contribute(String contributionURI, URL sourceURL, InputStream input) + throws ContributionException, IOException { + + return addContribution(contributionURI, sourceURL, input, null, true); + } + + public Contribution contribute(String contributionURI, URL sourceURL, InputStream input, ModelResolver modelResolver) + throws ContributionException, IOException { + + return addContribution(contributionURI, sourceURL, input, modelResolver, true); + } + + public Contribution getContribution(String uri) { + return this.contributionRepository.getContribution(uri); + } + + /** + * Remove a contribution and notify listener that contribution was removed + */ + public void remove(String uri) throws ContributionException { + Contribution contribution = contributionRepository.getContribution(uri); + this.contributionRepository.removeContribution(contribution); + this.contributionListener.contributionRemoved(this.contributionRepository, contribution); + } + + /** + * Add a composite model to the contribution + */ + public void addDeploymentComposite(Contribution contribution, Composite composite) throws ContributionException { + Artifact artifact = this.contributionFactory.createArtifact(); + artifact.setURI(composite.getURI()); + artifact.setModel(composite); + + contribution.getArtifacts().add(artifact); + + contribution.getDeployables().add(composite); + } + + /** + * Utility/Helper methods for contribution service + */ + + /** + * Perform read of the contribution metadata loader (sca-contribution.xml and sca-contribution-generated.xml) + * When the two metadata files are available, the information provided are merged, and the sca-contribution has priorities + * + * @param sourceURL + * @return Contribution + * @throws ContributionException + */ + private Contribution readContributionMetadata(URL sourceURL) throws ContributionException { + Contribution contributionMetadata = contributionFactory.createContribution(); + + ContributionMetadataDocumentProcessor metadataDocumentProcessor = + new ContributionMetadataDocumentProcessor(modelFactories, staxProcessor, monitor); + + final URL[] urls = {sourceURL}; + // Allow access to create classloader. Requires RuntimePermission in security policy. + URLClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() { + public URLClassLoader run() { + return new URLClassLoader(urls, null); + } + }); + for (String path: new String[]{ + Contribution.SCA_CONTRIBUTION_GENERATED_META, + Contribution.SCA_CONTRIBUTION_META}) { + URL url = cl.getResource(path); + if (url != null) { + ContributionMetadata contribution = metadataDocumentProcessor.read(sourceURL, URI.create(path), url); + contributionMetadata.getImports().addAll(contribution.getImports()); + contributionMetadata.getExports().addAll(contribution.getExports()); + contributionMetadata.getDeployables().addAll(contribution.getDeployables()); + } + } + + // For debugging purposes, write it back to XML + // if (contributionMetadata != null) { + // try { + // ByteArrayOutputStream bos = new ByteArrayOutputStream(); + // XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); + // outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); + // staxProcessor.write(contributionMetadata, outputFactory.createXMLStreamWriter(bos)); + // Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray())); + // OutputFormat format = new OutputFormat(); + // format.setIndenting(true); + // format.setIndent(2); + // XMLSerializer serializer = new XMLSerializer(System.out, format); + // serializer.serialize(document); + // } catch (Exception e) { + // e.printStackTrace(); + // } + // } + + return contributionMetadata; + } + + /** + * Note: + * + * @param contributionURI ContributionID + * @param sourceURL contribution location + * @param contributionStream contribution content + * @param storeInRepository flag if we store the contribution into the + * repository or not + * @return the contribution model representing the contribution + * @throws IOException + * @throws DeploymentException + */ + private Contribution addContribution(String contributionURI, + URL sourceURL, + InputStream contributionStream, + ModelResolver modelResolver, + boolean storeInRepository) throws IOException, ContributionException { + + if (contributionStream == null && sourceURL == null) { + error("ContributionContentNull", contributionStream); + throw new IllegalArgumentException("The content of the contribution is null."); + } + + // store the contribution in the contribution repository + URL locationURL = sourceURL; + if (contributionRepository != null && storeInRepository) { + if (contributionStream == null) { + locationURL = contributionRepository.store(contributionURI, sourceURL); + } else { + locationURL = contributionRepository.store(contributionURI, sourceURL, contributionStream); + } + } + + //initialize contribution based on it's metadata if available + Contribution contribution = readContributionMetadata(locationURL); + + // Create contribution model resolver + if (modelResolver == null) { + //FIXME Remove this domain resolver, visibility of policy declarations should be handled by + // the contribution import/export mechanism instead of this domainResolver hack. + modelResolver = new ExtensibleModelResolver(contribution, modelResolvers, modelFactories, policyDefinitionsResolver); + } + + //set contribution initial information + contribution.setURI(contributionURI); + contribution.setLocation(locationURL.toString()); + contribution.setModelResolver(modelResolver); + + List<URI> contributionArtifacts = null; + + //NOTE: if a contribution is stored on the repository + //the stream would be consumed at this point + if (storeInRepository || contributionStream == null) { + URLConnection connection = sourceURL.openConnection(); + connection.setUseCaches(false); + // Allow access to open URL stream. Add FilePermission to added to security policy file. + final URLConnection finalConnection = connection; + try { + contributionStream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() { + public InputStream run() throws IOException { + return finalConnection.getInputStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + + try { + // process the contribution + contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream); + } finally { + IOHelper.closeQuietly(contributionStream); + contributionStream = null; + } + } else { + // process the contribution + contributionArtifacts = this.packageProcessor.getArtifacts(locationURL, contributionStream); + } + + // Read all artifacts in the contribution + try { + // Allow access to read system properties. Requires PropertyPermission in security policy. + // Any security exceptions are caught and wrapped as ContributionException. + processReadPhase(contribution, contributionArtifacts); + } catch ( Exception e ) { + throw new ContributionException(e); + } + + // + this.contributionListener.contributionAdded(this.contributionRepository, contribution); + + // Resolve them + processResolvePhase(contribution); + + // Add all composites under META-INF/sca-deployables to the + // list of deployables + String prefix = Contribution.SCA_CONTRIBUTION_DEPLOYABLES; + for (Artifact artifact : contribution.getArtifacts()) { + if (artifact.getModel() instanceof Composite) { + if (artifact.getURI().startsWith(prefix)) { + Composite composite = (Composite)artifact.getModel(); + if (!contribution.getDeployables().contains(composite)) { + contribution.getDeployables().add(composite); + } + } + } + } + + // store the contribution on the registry + this.contributionRepository.addContribution(contribution); + + return contribution; + } + + /** + * This utility method process each artifact and delegates to proper + * artifactProcessor to read the model and generate the in-memory representation + * + * @param contribution + * @param artifacts + * @throws ContributionException + * @throws MalformedURLException + */ + private void processReadPhase(Contribution contribution, List<URI> artifacts) throws ContributionException, + MalformedURLException, XMLStreamException { + + ModelResolver modelResolver = contribution.getModelResolver(); + URL contributionURL = new URL(contribution.getLocation()); + + List<URI> compositeUris = new ArrayList<URI>(); + + Object model = null; + for (URI anArtifactUri : artifacts) { + if ( anArtifactUri.toString().endsWith(COMPOSITE_FILE_EXTN)) { + compositeUris.add(anArtifactUri); + } else { + URL artifactURL = packageProcessor.getArtifactURL(new URL(contribution.getLocation()), anArtifactUri); + + // Add the deployed artifact model to the resolver + Artifact artifact = this.contributionFactory.createArtifact(); + artifact.setURI(anArtifactUri.toString()); + artifact.setLocation(artifactURL.toString()); + contribution.getArtifacts().add(artifact); + modelResolver.addModel(artifact); + + model = this.artifactProcessor.read(contributionURL, anArtifactUri, artifactURL); + + if (model != null) { + artifact.setModel(model); + + // Add the loaded model to the model resolver + modelResolver.addModel(model); + + // Add policy definitions to the list of policy definitions + if (model instanceof SCADefinitions) { + policyDefinitions.add(model); + + SCADefinitions definitions = (SCADefinitions)model; + for (Intent intent : definitions.getPolicyIntents() ) { + policyDefinitionsResolver.addModel(intent); + } + + for (PolicySet policySet : definitions.getPolicySets() ) { + policyDefinitionsResolver.addModel(policySet); + } + + for (IntentAttachPointType attachPointType : definitions.getBindingTypes() ) { + policyDefinitionsResolver.addModel(attachPointType); + } + + for (IntentAttachPointType attachPointType : definitions.getImplementationTypes() ) { + policyDefinitionsResolver.addModel(attachPointType); + } + } + } + } + } + + for (URI anArtifactUri : compositeUris) { + URL artifactURL = packageProcessor.getArtifactURL(new URL(contribution.getLocation()), anArtifactUri); + + // Add the deployed artifact model to the resolver + Artifact artifact = this.contributionFactory.createArtifact(); + artifact.setURI(anArtifactUri.toString()); + artifact.setLocation(artifactURL.toString()); + contribution.getArtifacts().add(artifact); + modelResolver.addModel(artifact); + + model = this.artifactProcessor.read(contributionURL, anArtifactUri, artifactURL); + if (model != null) { + artifact.setModel(model); + // Add the loaded model to the model resolver + modelResolver.addModel(model); + } + } + } + + /** + * This utility method process each artifact and delegates to proper + * artifactProcessor to resolve the model references + * + * @param contribution + * @throws ContributionException + */ + @SuppressWarnings("unchecked") + private void processResolvePhase(Contribution contribution) throws ContributionException { + List<Artifact> composites = new ArrayList<Artifact>(); + + // for each artifact that was processed on the contribution + for (Artifact artifact : contribution.getArtifacts()) { + //leave the composites to be resolved at the end + if (artifact.getURI().endsWith(".composite")) { + composites.add(artifact); + } else { + // resolve the model object + if (artifact.getModel() != null) { + // System.out.println("Processing Resolve Phase : " + artifact.getURI()); + this.artifactProcessor.resolve(artifact.getModel(), contribution.getModelResolver()); + } + } + } + + //process each composite file + for (Artifact artifact : composites) { + // resolve the model object + if (artifact.getModel() != null) { + this.artifactProcessor.resolve(artifact.getModel(), contribution.getModelResolver()); + } + } + + //resolve deployables from contribution metadata + List<Composite> resolvedDeployables = new ArrayList<Composite>(); + for (Composite deployableComposite : contribution.getDeployables()) { + Composite resolvedDeployable = + contribution.getModelResolver().resolveModel(Composite.class, deployableComposite); + + resolvedDeployables.add(resolvedDeployable); + } + contribution.getDeployables().clear(); + contribution.getDeployables().addAll(resolvedDeployables); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java new file mode 100644 index 0000000000..9f04c4af27 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/impl/PackageTypeDescriberImpl.java @@ -0,0 +1,120 @@ +/* + * 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.contribution.service.impl; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.PackageType; +import org.apache.tuscany.sca.contribution.service.TypeDescriber; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +/** + * Implementation of the content describer for contribution packages + * + * @version $Rev$ $Date$ + */ +public class PackageTypeDescriberImpl implements TypeDescriber { + private final Map<String, String> contentTypeRegistry = new HashMap<String, String>(); + + public PackageTypeDescriberImpl() { + super(); + init(); + } + + /** + * Initialize contentType registry with know types based on known file extensions + */ + private void init() { + contentTypeRegistry.put("JAR", PackageType.JAR); + contentTypeRegistry.put("WAR", PackageType.JAR); + } + + protected String resolveContentyTypeByExtension(URL resourceURL) { + String artifactExtension = FileHelper.getExtension(resourceURL.getPath()); + if (artifactExtension == null) { + return null; + } + return contentTypeRegistry.get(artifactExtension.toUpperCase()); + } + + /** + * Build contentType for a specific resource. We first check if the file is a supported one + * (looking into our registry based on resource extension) If not found, we try to check file + * contentType Or we return defaultContentType provided + * + * @param resourceURL The artifact URL + * @param defaultContentType The default content type if we can't find the correct one + * @return The content type + */ + public String getType(URL resourceURL, String defaultContentType) { + URLConnection connection = null; + String contentType = defaultContentType; + final String urlProtocol = resourceURL.getProtocol(); + + if (urlProtocol.equals("file")) { + final File fileOrDir = FileHelper.toFile(resourceURL); + // Allow privileged access to test file. Requires FilePermissions in security policy. + Boolean isDirectory = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + return fileOrDir.isDirectory(); + } + }); + if (isDirectory) { + // Special case : contribution is a folder + contentType = PackageType.FOLDER; + } + + String type = resolveContentyTypeByExtension(resourceURL); + if (type != null) { + return type; + } + } else if (urlProtocol.equals("bundle") || urlProtocol.equals("bundleresource")) { + contentType = PackageType.BUNDLE; + } else { + contentType = resolveContentyTypeByExtension(resourceURL); + if (contentType == null) { + try { + connection = resourceURL.openConnection(); + connection.setUseCaches(false); + contentType = connection.getContentType(); + + if (contentType == null || contentType.equals("content/unknown")) { + // here we couldn't figure out from our registry or from URL and it's not a + // special file + // return defaultContentType if provided + contentType = defaultContentType; + } + } catch (IOException io) { + // could not access artifact, just ignore and we will return + // null contentType + } + } + } + return contentType == null ? defaultContentType : contentType; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java new file mode 100644 index 0000000000..cd5e87ca42 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/FileHelper.java @@ -0,0 +1,701 @@ +/* + * 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.contribution.service.util; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.regex.Pattern; + +public class FileHelper { + /** + * The extension separator character. + */ + private static final char EXTENSION_SEPARATOR = '.'; + + /** + * The Unix separator character. + */ + private static final char UNIX_SEPARATOR = '/'; + + /** + * The Windows separator character. + */ + private static final char WINDOWS_SEPARATOR = '\\'; + + /** + * Returns the index of the last directory separator character. + * <p> + * This method will handle a file in either Unix or Windows format. The + * position of the last forward or backslash is returned. + * <p> + * The output will be the same irrespective of the machine that the code is + * running on. + * + * @param filename the filename to find the last path separator in, null + * returns -1 + * @return the index of the last separator character, or -1 if there is no + * such character + */ + public static int indexOfLastSeparator(String filename) { + if (filename == null) { + return -1; + } + int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); + int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); + return Math.max(lastUnixPos, lastWindowsPos); + } + + /** + * Returns the index of the last extension separator character, which is a + * dot. + * <p> + * This method also checks that there is no directory separator after the + * last dot. To do this it uses {@link #indexOfLastSeparator(String)} which + * will handle a file in either Unix or Windows format. + * <p> + * The output will be the same irrespective of the machine that the code is + * running on. + * + * @param filename the filename to find the last path separator in, null + * returns -1 + * @return the index of the last separator character, or -1 if there is no + * such character + */ + public static int indexOfExtension(String filename) { + if (filename == null) { + return -1; + } + int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR); + int lastSeparator = indexOfLastSeparator(filename); + return lastSeparator > extensionPos ? -1 : extensionPos; + } + + /** + * Gets the name minus the path from a full filename. + * <p> + * This method will handle a file in either Unix or Windows format. The text + * after the last forward or backslash is returned. + * + * <pre> + * a/b/c.txt --> c.txt + * a.txt --> a.txt + * a/b/c --> c + * a/b/c/ --> "" + * </pre> + * + * <p> + * The output will be the same irrespective of the machine that the code is + * running on. + * + * @param fileName the filename to query, null returns null + * @return the name of the file without the path, or an empty string if none + * exists + */ + public static String getName(String fileName) { + if (fileName == null) { + return null; + } + int index = indexOfLastSeparator(fileName); + return fileName.substring(index + 1); + } + + /** + * Gets the extension of a filename. + * <p> + * This method returns the textual part of the filename after the last dot. + * There must be no directory separator after the dot. + * + * <pre> + * foo.txt --> "txt" + * a/b/c.jpg --> "jpg" + * a/b.txt/c --> "" + * a/b/c --> "" + * </pre> + * + * <p> + * The output will be the same irrespective of the machine that the code is + * running on. + * + * @param filename the filename to retrieve the extension of. + * @return the extension of the file or an empty string if none exists. + */ + public static String getExtension(String filename) { + if (filename == null) { + return null; + } + int index = indexOfExtension(filename); + if (index == -1) { + return ""; + } else { + return filename.substring(index + 1); + } + } + + /** + * Make a directory, including any necessary but nonexistent parent + * directories. If there already exists a file with specified name or the + * directory cannot be created then an exception is thrown. + * + * @param directory directory to create, not null + * @throws NullPointerException if the directory is null + * @throws IOException if the directory cannot be created + */ + public static void forceMkdir(File directory) throws IOException { + if (directory.exists()) { + if (directory.isFile()) { + String message = + "File " + directory + " exists and is " + "not a directory. Unable to create directory."; + throw new IOException(message); + } + } else { + if (!directory.mkdirs()) { + String message = "Unable to create directory " + directory; + throw new IOException(message); + } + } + } + + /** + * Delete a file. If file is a directory, delete it and all sub-directories. + * <p> + * The difference between File.delete() and this method are: + * <ul> + * <li>A directory to be deleted does not have to be empty.</li> + * <li>You get exceptions when a file or directory cannot be deleted. + * (java.io.File methods returns a boolean)</li> + * </ul> + * + * @param file file or directory to delete, not null + * @throws NullPointerException if the directory is null + * @throws IOException in case deletion is unsuccessful + */ + public static void forceDelete(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + if (!file.exists()) { + throw new FileNotFoundException("File does not exist: " + file); + } + if (!file.delete()) { + String message = "Unable to delete file: " + file; + throw new IOException(message); + } + } + } + + /** + * Convert from a <code>URL</code> to a <code>File</code>. + * <p> + * From version 1.1 this method will decode the URL. Syntax such as + * <code>file:///my%20docs/file.txt</code> will be correctly decoded to + * <code>/my docs/file.txt</code>. + * + * @param url the file URL to convert, null returns null + * @return the equivalent <code>File</code> object, or <code>null</code> + * if the URL's protocol is not <code>file</code> + * @throws IllegalArgumentException if the file is incorrectly encoded + */ + public static File toFile(URL url) { + if (url == null || !url.getProtocol().equals("file")) { + return null; + } else { + String filename = url.getFile().replace('/', File.separatorChar); + int pos = 0; + while ((pos = filename.indexOf('%', pos)) >= 0) { // NOPMD + if (pos + 2 < filename.length()) { + String hexStr = filename.substring(pos + 1, pos + 3); + char ch = (char)Integer.parseInt(hexStr, 16); + filename = filename.substring(0, pos) + ch + filename.substring(pos + 3); + } + } + return new File(filename); + } + } + + public static FileFilter getFileFilter(String regExp, boolean ignoreCase) { + return new RegExpFilter(regExp, ignoreCase); + } + + /** + * A regular-expression based resource filter + */ + public static class RegExpFilter implements FileFilter { + private Pattern pattern; + + public RegExpFilter(Pattern pattern) { + this.pattern = pattern; + } + + public RegExpFilter(String patternStr, boolean ignoreCase) { + this.pattern = Pattern.compile(patternStr, ignoreCase ? Pattern.CASE_INSENSITIVE : 0); + } + + public boolean accept(File file) { + return pattern.matcher(file.getName()).matches(); + } + + /** + * Convert wildcard into a regex pattern + * + * @param str + * @return + */ + public static RegExpFilter getWildcardFilter(String str, boolean ignoreCase) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + if (ch == '?') { + buffer.append('.'); + } else if (ch == '*') { + buffer.append(".*"); + } else { + buffer.append(ch); + } + } + return new RegExpFilter(buffer.toString(), ignoreCase); + } + + } + + /** + * Clean a directory without deleting it. + * + * @param directory directory to clean + * @throws IOException in case cleaning is unsuccessful + */ + public static void cleanDirectory(File directory) throws IOException { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + + IOException exception = null; + for (int i = 0; i < files.length; i++) { + File file = files[i]; + try { + forceDelete(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + /** + * Clean a directory without deleting it. + * + * @param directory directory to clean, must not be <code>null</code> + * @throws NullPointerException if the directory is <code>null</code> + * @throws IOException in case cleaning is unsuccessful + */ + private static void cleanDirectoryOnExit(File directory) throws IOException { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + + IOException exception = null; + for (int i = 0; i < files.length; i++) { + File file = files[i]; + try { + forceDeleteOnExit(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + /** + * Copies a whole directory to a new location preserving the file dates. + * <p> + * This method copies the specified directory and all its child directories + * and files to the specified destination. The destination is the new + * location and name of the directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the new directory, must not be <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir) throws IOException { + copyDirectory(srcDir, destDir, true); + } + + /** + * Copies a whole directory to a new location. + * <p> + * This method copies the contents of the specified source directory to + * within the specified destination directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the new directory, must not be <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcDir.exists()) { + throw new FileNotFoundException("Source '" + srcDir + "' does not exist"); + } + if (!srcDir.isDirectory()) { + throw new IOException("Source '" + srcDir + "' exists but is not a directory"); + } + if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) { + throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same"); + } + doCopyDirectory(srcDir, destDir, preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * Copies a directory to within another directory preserving the file dates. + * <p> + * This method copies the source directory and all its contents to a + * directory of the same name in the specified destination directory. + * <p> + * The destination directory is created if it does not exist. If the + * destination directory did exist, then this method merges the source with + * the destination, with the source taking precedence. + * + * @param srcDir an existing directory to copy, must not be + * <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.2 + */ + public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (!(srcDir.exists() && srcDir.isDirectory())) { + throw new IllegalArgumentException("Source '" + destDir + "' is not a directory"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!(destDir.exists() && destDir.isDirectory())) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyDirectory(srcDir, new File(destDir, srcDir.getName()), true); + } + + /** + * Copies a file to a new location preserving the file date. + * <p> + * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destFile the new file, must not be <code>null</code> + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File) + */ + public static void copyFile(File srcFile, File destFile) throws IOException { + copyFile(srcFile, destFile, true); + } + + /** + * Copies a file to a new location. + * <p> + * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destFile the new file, must not be <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File, boolean) + */ + public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { + if (srcFile == null) { + throw new NullPointerException("Source must not be null"); + } + if (destFile == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcFile.exists()) { + throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); + } + if (srcFile.isDirectory()) { + throw new IOException("Source '" + srcFile + "' exists but is a directory"); + } + if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { + throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); + } + if (!(destFile.getParentFile() != null && destFile.getParentFile().exists())) { + if (!destFile.getParentFile().mkdirs()) { //NOPMD + throw new IOException("Destination '" + destFile + "' directory cannot be created"); + } + } + if (!(destFile.exists() && destFile.canWrite())) { + throw new IOException("Destination '" + destFile + "' exists but is read-only"); + } + doCopyFile(srcFile, destFile, preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * Copies a file to a directory preserving the file date. + * <p> + * This method copies the contents of the specified source file to a file of + * the same name in the specified destination directory. The destination + * directory is created if it does not exist. If the destination file + * exists, then this method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + */ + public static void copyFileToDirectory(File srcFile, File destDir) throws IOException { + copyFileToDirectory(srcFile, destDir, true); + } + + /** + * Copies a file to a directory optionally preserving the file date. + * <p> + * This method copies the contents of the specified source file to a file of + * the same name in the specified destination directory. The destination + * directory is created if it does not exist. If the destination file + * exists, then this method will overwrite it. + * + * @param srcFile an existing file to copy, must not be <code>null</code> + * @param destDir the directory to place the copy in, must not be + * <code>null</code> + * @param preserveFileDate true if the file date of the copy should be the + * same as the original + * @throws NullPointerException if source or destination is + * <code>null</code> + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + * @since Commons IO 1.3 + */ + public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException { + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!(destDir.exists() && destDir.isDirectory())) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate); + } + + // ----------------------------------------------------------------------- + /** + * Recursively delete a directory. + * + * @param directory directory to delete + * @throws IOException in case deletion is unsuccessful + */ + public static void deleteDirectory(File directory) throws IOException { + if (!directory.exists()) { + return; + } + + cleanDirectory(directory); + if (!directory.delete()) { + String message = "Unable to delete directory " + directory + "."; + throw new IOException(message); + } + } + + /** + * Recursively schedule directory for deletion on JVM exit. + * + * @param directory directory to delete, must not be <code>null</code> + * @throws NullPointerException if the directory is <code>null</code> + * @throws IOException in case deletion is unsuccessful + */ + private static void deleteDirectoryOnExit(File directory) throws IOException { + if (!directory.exists()) { + return; + } + + cleanDirectoryOnExit(directory); + directory.deleteOnExit(); + } + + /** + * Internal copy directory method. + * + * @param srcDir the validated source directory, must not be + * <code>null</code> + * @param destDir the validated destination directory, must not be + * <code>null</code> + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + * @since Commons IO 1.1 + */ + private static void doCopyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException { + if (destDir.exists()) { + if (!destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' exists but is not a directory"); + } + } else { + if (!destDir.mkdirs()) { + throw new IOException("Destination '" + destDir + "' directory cannot be created"); + } + if (preserveFileDate) { + destDir.setLastModified(srcDir.lastModified()); + } + } + if (!destDir.canWrite()) { + throw new IOException("Destination '" + destDir + "' cannot be written to"); + } + // recurse + File[] files = srcDir.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + srcDir); + } + for (int i = 0; i < files.length; i++) { + File copiedFile = new File(destDir, files[i].getName()); + if (files[i].isDirectory()) { + doCopyDirectory(files[i], copiedFile, preserveFileDate); + } else { + doCopyFile(files[i], copiedFile, preserveFileDate); + } + } + } + + /** + * Internal copy file method. + * + * @param srcFile the validated source file, must not be <code>null</code> + * @param destFile the validated destination file, must not be + * <code>null</code> + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + */ + private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { + if (destFile.exists() && destFile.isDirectory()) { + throw new IOException("Destination '" + destFile + "' exists but is a directory"); + } + + FileInputStream input = new FileInputStream(srcFile); + try { + FileOutputStream output = new FileOutputStream(destFile); + try { + IOHelper.copy(input, output); + } finally { + IOHelper.closeQuietly(output); + } + } finally { + IOHelper.closeQuietly(input); + } + + if (srcFile.length() != destFile.length()) { + throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); + } + if (preserveFileDate) { + destFile.setLastModified(srcFile.lastModified()); + } + } + + /** + * Schedule a file to be deleted when JVM exits. If file is directory delete + * it and all sub-directories. + * + * @param file file or directory to delete, must not be <code>null</code> + * @throws NullPointerException if the file is <code>null</code> + * @throws IOException in case deletion is unsuccessful + */ + public static void forceDeleteOnExit(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectoryOnExit(file); + } else { + file.deleteOnExit(); + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java new file mode 100644 index 0000000000..630d1f6bf4 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/service/util/IOHelper.java @@ -0,0 +1,190 @@ +/* + * 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.contribution.service.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.jar.JarFile; + +public class IOHelper { + /** + * The default buffer size to use. + */ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + + /** + * Unconditionally close an <code>InputStream</code>. + * <p> + * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + * + * @param input the InputStream to close, may be null or already closed + */ + public static void closeQuietly(InputStream input) { + try { + if (input != null) { + input.close(); + } + } catch (IOException ioe) { + // ignore + } + } + + /** + * Unconditionally close an <code>OutputStream</code>. + * <p> + * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + * + * @param output the OutputStream to close, may be null or already closed + */ + public static void closeQuietly(OutputStream output) { + try { + if (output != null) { + output.close(); + } + } catch (IOException ioe) { + // ignore + } + } + + /** + * Copy bytes from an <code>InputStream</code> to an + * <code>OutputStream</code>. + * <p> + * This method buffers the input internally, so there is no need to use a + * <code>BufferedInputStream</code>. + * + * @param input the <code>InputStream</code> to read from + * @param output the <code>OutputStream</code> to write to + * @return the number of bytes copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static int copy(InputStream input, OutputStream output) throws IOException { + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + int count = 0; + int n = 0; + while (-1 != (n = input.read(buffer))) { // NOPMD + output.write(buffer, 0, n); + count += n; + } + return count; + } + + public static InputStream getInputStream(URL url) throws IOException { + return new SafeURLInputStream(url); + } + + /** + * This class is a workaround for URL stream issue as illustrated below. + * InputStream is=url.getInputStream(); is.close(); // This line doesn't close + * the JAR file if the URL is a jar entry like "jar:file:/a.jar!/my.composite" We + * also need to turn off the JarFile cache. + * + * @see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4950148 + * + * @version $Rev$ $Date$ + */ + public static class SafeURLInputStream extends InputStream { + private JarFile jarFile; + private InputStream is; + + public SafeURLInputStream(URL url) throws IOException { + String protocol = url.getProtocol(); + if (protocol != null && (protocol.equals("jar"))) { + JarURLConnection connection = (JarURLConnection)url.openConnection(); + // We cannot use cache + connection.setUseCaches(false); + try { + is = connection.getInputStream(); + } catch (IOException e) { + throw e; + } + jarFile = connection.getJarFile(); + } else { + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + is = connection.getInputStream(); + } + } + + public SafeURLInputStream(JarURLConnection connection) throws IOException { + // We cannot use cache + connection.setUseCaches(false); + is = connection.getInputStream(); + jarFile = connection.getJarFile(); + } + + @Override + public int available() throws IOException { + return is.available(); + } + + @Override + public void close() throws IOException { + is.close(); + // We need to close the JAR file + if (jarFile != null) { + jarFile.close(); + } + } + + @Override + public synchronized void mark(int readlimit) { + is.mark(readlimit); + } + + @Override + public boolean markSupported() { + return is.markSupported(); + } + + @Override + public int read() throws IOException { + return is.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + return is.read(b, off, len); + } + + @Override + public int read(byte[] b) throws IOException { + return is.read(b); + } + + @Override + public synchronized void reset() throws IOException { + is.reset(); + } + + @Override + public long skip(long n) throws IOException { + return is.skip(n); + } + } +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor new file mode 100644 index 0000000000..b644709266 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor @@ -0,0 +1,19 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.impl.FolderContributionProcessor;type=application/vnd.tuscany.folder
+org.apache.tuscany.sca.contribution.processor.impl.JarContributionProcessor;type=application/x-compressed
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/contribution-impl-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/contribution-impl-validation-messages.properties new file mode 100644 index 0000000000..158ee2102d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/main/resources/contribution-impl-validation-messages.properties @@ -0,0 +1,28 @@ +# +# +# 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. +# +# +ContributionURINull =URI for the contribution is null +SourceURLNull = Source URL for the contribution is null +ContributionContentNull = The content of the contribution is null +PrivilegedActionException = Exception occured due to FilePermissions in security policy file +RootNotDirectory = The root is not a directory {0} +IllegalArgumentException = IllegalArgumentException occured due to : +DomainFileNotFound = Domain file "sca-domain.xml" not found ({0}) +MalformedURLException = MalformedURLException occured due to :
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java new file mode 100644 index 0000000000..c33b31b550 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/FolderContributionPackageProcessorTestCase.java @@ -0,0 +1,46 @@ +/* + * 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.contribution.processor; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.impl.FolderContributionProcessor; + +/** + * Folder Package Processor test case + * Verifies proper handle of File System structured contributions + * + * @version $Rev$ $Date$ + */ +public class FolderContributionPackageProcessorTestCase extends TestCase { + private static final String FOLDER_CONTRIBUTION = "."; + + public final void testProcessPackageArtifacts() throws Exception { + FolderContributionProcessor folderProcessor = new FolderContributionProcessor(); + URL contributionURL = new File(FOLDER_CONTRIBUTION).toURL().toURI().toURL(); + + List<URI> artifacts = folderProcessor.getArtifacts(contributionURL, null); + assertNotNull(artifacts); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java new file mode 100644 index 0000000000..9b3dce7029 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/JarContributionPackageProcessorTestCase.java @@ -0,0 +1,55 @@ +/* + * 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.contribution.processor; + +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.impl.JarContributionProcessor; +import org.apache.tuscany.sca.contribution.service.util.IOHelper; + +/** + * JAR Package Processor test case + * Verifies proper handle of JAR Archives contributions + * + * @version $Rev$ $Date$ + */ + +public class JarContributionPackageProcessorTestCase extends TestCase { + private static final String JAR_CONTRIBUTION = "/repository/sample-calculator.jar"; + + public final void testProcessPackageArtifacts() throws Exception { + JarContributionProcessor jarProcessor = new JarContributionProcessor(); + + URL jarURL = getClass().getResource(JAR_CONTRIBUTION); + InputStream jarStream = jarURL.openStream(); + List<URI> artifacts = null; + try { + artifacts = jarProcessor.getArtifacts(jarURL, jarStream); + } finally { + IOHelper.closeQuietly(jarStream); + } + + assertNotNull(artifacts); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java new file mode 100644 index 0000000000..46b4183380 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/processor/URLartifactProcessorExtensionPointTestCase.java @@ -0,0 +1,114 @@ +/* + * 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.contribution.processor; + +import java.net.URI; +import java.net.URL; + +import junit.framework.TestCase; + +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.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; + + +/** + * URL Artifact Processor Extension Point test case + * Verifies the right registration and lookup for processors that handle filename and file types + * + * @version $Rev$ $Date$ + */ +public class URLartifactProcessorExtensionPointTestCase extends TestCase { + + private URLArtifactProcessorExtensionPoint artifactProcessors; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + artifactProcessors = new DefaultURLArtifactProcessorExtensionPoint(extensionPoints); + artifactProcessors.addArtifactProcessor(new FileTypeArtifactProcessor()); + artifactProcessors.addArtifactProcessor(new FileNameArtifactProcessor()); + } + + + public final void testFileTypeProcessor() { + assertNotNull(artifactProcessors.getProcessor(".m1")); + } + + + public final void testFileNameProcessor() { + assertNotNull(artifactProcessors.getProcessor("file.m2")); + + } + + /** + * Internal mock classes + * + */ + + private class M1 { + } + + private class M2 { + } + + private class FileTypeArtifactProcessor implements URLArtifactProcessor<M1> { + public FileTypeArtifactProcessor() { + } + + public M1 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M1 m1, ModelResolver resolver) throws ContributionResolveException { + } + + public String getArtifactType() { + return ".m1"; + } + + public Class<M1> getModelType() { + return M1.class; + } + } + + private class FileNameArtifactProcessor implements URLArtifactProcessor<M2> { + public FileNameArtifactProcessor() { + } + + public M2 read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + return null; + } + + public void resolve(M2 m2, ModelResolver resolver) throws ContributionResolveException { + } + + public String getArtifactType() { + return "file.m2"; + } + + public Class<M2> getModelType() { + return M2.class; + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.java new file mode 100644 index 0000000000..98852e951c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverTestCase.java @@ -0,0 +1,86 @@ +/* + * 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.contribution.resolver; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultContributionFactory; + +/** + * Test the default model resolver implementation. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolverTestCase extends TestCase { + + private ModelResolver resolver; + private ContributionFactory factory; + + @Override + protected void setUp() throws Exception { + resolver = new DefaultModelResolver(); + factory = new DefaultContributionFactory(); + } + + public void testResolved() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + public void testResolvedArtifact() { + Artifact artifact = factory.createArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + Artifact x = factory.createArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(Artifact.class, x); + assertTrue(x == artifact); + } + + class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.java new file mode 100644 index 0000000000..01083cc6a6 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolverTestCase.java @@ -0,0 +1,126 @@ + /* + * 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.contribution.resolver; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; + +/** + * Test DefaultArtifactResolver. + * + * @version $Rev$ $Date$ + */ +public class ExtensibleModelResolverTestCase extends TestCase { + private ExtensibleModelResolver resolver; + + private ContributionFactory factory; + + @Override + protected void setUp() throws Exception { + + ModelResolverExtensionPoint resolvers = new DefaultModelResolverExtensionPoint(); + resolvers.addResolver(Model.class, TestModelResolver.class); + + ModelFactoryExtensionPoint factories = new DefaultModelFactoryExtensionPoint(); + + resolver = new ExtensibleModelResolver(null, resolvers, factories, null); + + factory = new DefaultContributionFactory(); + } + + public void testResolvedDefault() { + OtherModel a = new OtherModel("a"); + resolver.addModel(a); + OtherModel x = new OtherModel("a"); + x = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == a); + } + + public void testResolvedRegisteredClass() { + Model a = new Model("a"); + resolver.addModel(a); + Model x = new Model("a"); + x = resolver.resolveModel(Model.class, x); + assertTrue(x == a); + } + + public void testUnresolvedDefault() { + OtherModel x = new OtherModel("a"); + OtherModel y = resolver.resolveModel(OtherModel.class, x); + assertTrue(x == y); + } + + public void testUnresolved() { + Model x = new Model("a"); + Model y = resolver.resolveModel(Model.class, x); + assertTrue(x == y); + } + + public void testResolvedArtifact() { + Artifact artifact = factory.createArtifact(); + artifact.setURI("foo/bar"); + resolver.addModel(artifact); + Artifact x = factory.createArtifact(); + x.setURI("foo/bar"); + x = resolver.resolveModel(Artifact.class, x); + assertTrue(x == artifact); + } + + private class Model { + private String name; + + Model(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((Model)obj).name); + } + } + + private class OtherModel { + private String name; + + OtherModel(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return name.equals(((OtherModel)obj).name); + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.java new file mode 100644 index 0000000000..66ecd33da6 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/resolver/TestModelResolver.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.contribution.resolver; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; + +/** + * A test implementation of a model resolver, based on a map. + * + * @version $Rev$ $Date$ + */ +public class TestModelResolver implements ModelResolver { + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + public TestModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + return modelClass.cast(resolved); + } + // Return the unresolved object + return unresolved; + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java new file mode 100644 index 0000000000..2e5354fb96 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/ContributionRepositoryTestCase.java @@ -0,0 +1,81 @@ +/* + * 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.contribution.services; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +import javax.xml.stream.XMLInputFactory; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.service.impl.ContributionRepositoryImpl; +import org.apache.tuscany.sca.contribution.service.util.FileHelper; + +public class ContributionRepositoryTestCase extends TestCase { + private ContributionRepositoryImpl repository; + + @Override + protected void setUp() throws Exception { + // create repository (this should re-create the root directory) + this.repository = new ContributionRepositoryImpl("target/repository/", XMLInputFactory.newInstance(), null); + repository.init(); + } + + public void testStore() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + URL contributionURL = repository.find(contribution); + assertNotNull(contributionURL); + } + + public void testRemove() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + repository.remove(contribution); + URL contributionURL = repository.find(contribution); + assertNull(contributionURL); + } + + public void testList() throws Exception { + String resourceLocation = "/repository/sample-calculator.jar"; + String contribution = "sample-calculator.jar"; + URL contributionLocation = getClass().getResource(resourceLocation); + InputStream contributionStream = getClass().getResourceAsStream(resourceLocation); + repository.store(contribution, contributionLocation, contributionStream); + + assertEquals(1, repository.list().size()); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + FileHelper.deleteDirectory(new File("target/repository")); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java new file mode 100644 index 0000000000..dfb600153e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/services/PackageTypeDescriberImplTestCase.java @@ -0,0 +1,63 @@ +/* + * 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.contribution.services; + +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.PackageType; +import org.apache.tuscany.sca.contribution.service.impl.PackageTypeDescriberImpl; + +public class PackageTypeDescriberImplTestCase extends TestCase { + private PackageTypeDescriberImpl packageTypeDescriber; + + public void testResolveArchivePackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables/sample-calculator.jar"); + assertEquals(PackageType.JAR, this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testResolveFolderPackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables/"); + assertEquals(PackageType.FOLDER, this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testResolveFolder2PackageType() throws Exception { + URL artifactURL = getClass().getResource("/deployables"); + assertEquals(PackageType.FOLDER, this.packageTypeDescriber.getType(artifactURL, null)); + } + + + public void testResolveUnknownPackageType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertNull(this.packageTypeDescriber.getType(artifactURL, null)); + } + + public void testDefaultPackageType() throws Exception { + URL artifactURL = getClass().getResource("/test.ext"); + assertEquals("application/vnd.tuscany.ext", + packageTypeDescriber.getType(artifactURL, "application/vnd.tuscany.ext")); + } + + @Override + protected void setUp() throws Exception { + packageTypeDescriber = new PackageTypeDescriberImpl(); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/deployables/sample-calculator.jar diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..9c46c679d2 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/repository/sample-calculator.jar diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.composite b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.composite new file mode 100644 index 0000000000..1e09549194 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.composite @@ -0,0 +1,22 @@ +<?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.
+-->
+<composite>
+ This file just needs to exist
+</composite>
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.ext b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.ext new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-impl/src/test/resources/test.ext diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-java/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/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/tags/java/sca/1.3-RC1a/modules/contribution-java/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-java/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/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/tags/java/sca/1.3-RC1a/modules/contribution-java/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-java/pom.xml new file mode 100644 index 0000000000..dfe98c7081 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/pom.xml @@ -0,0 +1,71 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-java</artifactId> + <name>Apache Tuscany SCA Java Import/Export Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-core-spi</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.java</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.java*</Export-Package> + <DynamicImport-Package>org.apache.tuscany.sca.contribution.osgi.impl</DynamicImport-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/DefaultJavaImportExportFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/DefaultJavaImportExportFactory.java new file mode 100644 index 0000000000..886c61c00a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/DefaultJavaImportExportFactory.java @@ -0,0 +1,30 @@ +/* + * 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.contribution.java; + +import org.apache.tuscany.sca.contribution.java.impl.JavaImportExportFactoryImpl; + +/** + * Default Java Import/Export Factory implementation + * + * @version $Rev$ $Date$ + */ +public class DefaultJavaImportExportFactory extends JavaImportExportFactoryImpl implements JavaImportExportFactory { +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaExport.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaExport.java new file mode 100644 index 0000000000..41e93ec148 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaExport.java @@ -0,0 +1,43 @@ +/* + * 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.contribution.java; + +import org.apache.tuscany.sca.contribution.Export; + +/** + * Base Java Export model interface + * + * @version $Rev$ $Date$ + */ +public interface JavaExport extends Export { + /** + * Get java package that identifies the import + * + * @return The package name + */ + String getPackage(); + + /** + * Set java package that identifies the import + * + * @param packageName The package name + */ + void setPackage(String packageName); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImport.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImport.java new file mode 100644 index 0000000000..d3568f6283 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImport.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.contribution.java; + +import org.apache.tuscany.sca.contribution.Import; + +/** + * Base Java Import model interface + * + * @version $Rev$ $Date$ + */ +public interface JavaImport extends Import { + + /** + * Get the location used to resolve the definitions for this import + * + * @return The import location + */ + String getLocation(); + + /** + * Set the location used to resolve the definitions for this import + * + * @param location The import location + */ + void setLocation(String location); + + /** + * Get java package that identifies the import + * + * @return The package name + */ + String getPackage(); + + /** + * Set java package that identifies the import + * + * @param packageName The package name + */ + void setPackage(String packageName); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImportExportFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImportExportFactory.java new file mode 100644 index 0000000000..af2ca9cd57 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/JavaImportExportFactory.java @@ -0,0 +1,42 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.java;
+
+/**
+ * Base Java Import/Export model factory
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaImportExportFactory {
+
+ /**
+ * Create a java import model object
+ *
+ * @return The new JavaImport model object
+ */
+ JavaImport createJavaImport();
+
+ /**
+ * Create a java export model object
+ *
+ * @return The new JavaExport model object
+ */
+ JavaExport createJavaExport();
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassLoaderModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassLoaderModelResolver.java new file mode 100644 index 0000000000..d9dde0f8ee --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassLoaderModelResolver.java @@ -0,0 +1,163 @@ +/* + * 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.contribution.java.impl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.DefaultDelegatingModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A Model Resolver for ClassReferences. + * + * @version $Rev$ $Date$ + */ +public class ClassLoaderModelResolver extends URLClassLoader implements ModelResolver { + private Contribution contribution; + private Map<String, ModelResolver> importResolvers = new HashMap<String, ModelResolver>(); + + private static ClassLoader contextClassLoader() { + return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + + public ClassLoaderModelResolver(final Contribution contribution, ModelFactoryExtensionPoint modelFactories) throws MalformedURLException { + super(new URL[] {new URL(contribution.getLocation())}, contextClassLoader()); + this.contribution = contribution; + + // Index Java import resolvers by package name + Map<String, List<ModelResolver>> resolverMap = new HashMap<String, List<ModelResolver>>(); + for (Import import_: this.contribution.getImports()) { + if (import_ instanceof JavaImport) { + JavaImport javaImport = (JavaImport)import_; + List<ModelResolver> resolvers = resolverMap.get(javaImport.getPackage()); + if (resolvers == null) { + resolvers = new ArrayList<ModelResolver>(); + resolverMap.put(javaImport.getPackage(), resolvers); + } + resolvers.add(javaImport.getModelResolver()); + } + } + + // Create a delegating model resolver for each imported package + for (Map.Entry<String, List<ModelResolver>> entry: resolverMap.entrySet()) { + importResolvers.put(entry.getKey(), new DefaultDelegatingModelResolver(entry.getValue())); + } + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + if (!(unresolved instanceof ClassReference)) { + return unresolved; + } + + try { + + // Load the class and return a class reference for it + String className = ((ClassReference)unresolved).getClassName(); + Class<?> clazz = Class.forName(className, true, this); + return modelClass.cast(new ClassReference(clazz)); + + } catch (ClassNotFoundException e) { + return unresolved; + } catch (NoClassDefFoundError e) { + return unresolved; + } + } + + @Override + public URL findResource(String name) { + + //TODO delegate to the Java import resolvers + + URL url = super.findResource(name); + return url; + } + + @Override + public Enumeration<URL> findResources(String name) throws IOException { + + //TODO delegate to the Java import resolvers + //Enumeration<URL> importedResources; + + Enumeration<URL> resources = super.findResources(name); + List<URL> allResources = new ArrayList<URL>(); + //for (; importedResources.hasMoreElements(); ) { + // allResources.add(importedResources.nextElement()); + //} + for (; resources.hasMoreElements(); ) { + allResources.add(resources.nextElement()); + } + return Collections.enumeration(allResources); + } + + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + + // Extract the package name + int d = name.lastIndexOf('.'); + String packageName; + if (d != -1) { + packageName = name.substring(0, d); + } else { + packageName = null; + } + + // First try to load the class using the Java import resolvers + ModelResolver importResolver = importResolvers.get(packageName); + if (importResolver != null) { + ClassReference classReference = importResolver.resolveModel(ClassReference.class, new ClassReference(name)); + if (!classReference.isUnresolved()) { + return classReference.getJavaClass(); + } + } + + // Next, try to load the class from the current contribution + Class<?> clazz = super.findClass(name); + return clazz; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java new file mode 100644 index 0000000000..716abf4602 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java @@ -0,0 +1,156 @@ +/*
+ * 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.contribution.java.impl;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * A Model Resolver for ClassReferences.
+ *
+ * @version $Rev: 557916 $ $Date: 2007-07-20 01:04:40 -0700 (Fri, 20 Jul 2007) $
+ */
+public class ClassReferenceModelResolver implements ModelResolver {
+ private Contribution contribution;
+ private WeakReference<ClassLoader> classLoader;
+ private Map<String, ClassReference> map = new HashMap<String, ClassReference>();
+
+ private ModelResolver osgiResolver;
+
+ public ClassReferenceModelResolver(final Contribution contribution, ModelFactoryExtensionPoint modelFactories) {
+ this.contribution = contribution;
+ if (this.contribution != null) {
+ // Allow privileged access to get ClassLoader. Requires RuntimePermission in security policy.
+ // ClassLoader cl = contribution.getClassLoader();
+ ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return contribution.getClassLoader();
+ }
+ });
+
+ if (cl == null) {
+ // Allow privileged access to get ClassLoader. Requires RuntimePermission in security policy.
+ ClassLoader contextClassLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ cl = new ContributionClassLoader(contribution, contextClassLoader);
+ contribution.setClassLoader(cl);
+ }
+ this.classLoader = new WeakReference<ClassLoader>(cl);
+ } else {
+ // This path should be used only for unit testing.
+ // Allow privileged access to get ClassLoader. Requires RuntimePermission in security policy.
+ // this.classLoader = new WeakReference<ClassLoader>(this.getClass().getClassLoader());
+ ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return this.getClass().getClassLoader();
+ }
+ });
+ this.classLoader = new WeakReference<ClassLoader>( cl );
+ }
+
+ try {
+ Class<?> osgiResolverClass =
+ Class.forName("org.apache.tuscany.sca.contribution.osgi.impl.OSGiClassReferenceModelResolver");
+ if (osgiResolverClass != null) {
+ Constructor constructor =
+ osgiResolverClass.getConstructor(Contribution.class, ModelFactoryExtensionPoint.class);
+ this.osgiResolver = (ModelResolver)constructor.newInstance(contribution, modelFactories);
+ }
+ } catch (Throwable e) {
+ // Ignore error, non-OSGi classloading is used in this case
+ }
+ }
+
+ public void addModel(Object resolved) {
+ ClassReference clazz = (ClassReference)resolved;
+ map.put(clazz.getClassName(), clazz);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(((ClassReference)resolved).getClassName());
+ }
+
+
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+ if (!(unresolved instanceof ClassReference)) {
+ return unresolved;
+ }
+ Object resolved = map.get(((ClassReference)unresolved).getClassName());
+
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+
+ //Load a class on demand
+ Class clazz = null;
+
+ if (osgiResolver != null) {
+ resolved = osgiResolver.resolveModel(modelClass, unresolved);
+ clazz = ((ClassReference)resolved).getJavaClass();
+ }
+
+ if (clazz == null) {
+ try {
+ // Search contribution ClassLoader (which has visibility of classes in the contribution
+ // as well as explicitly imported packages from other contributions)
+ clazz = Class.forName(((ClassReference)unresolved).getClassName(), true, classLoader.get());
+ } catch (ClassNotFoundException e) {
+ } catch (NoClassDefFoundError e) {
+ }
+ }
+
+ if (clazz != null) {
+ //if we load the class
+ // Store a new ClassReference wrapping the loaded class
+ ClassReference classReference = new ClassReference(clazz);
+ map.put(clazz.getName(), classReference);
+
+ // Return the resolved ClassReference
+ return modelClass.cast(classReference);
+ } else {
+ return unresolved;
+ }
+
+ }
+
+
+ /***************
+ * Helper methods
+ ***************/
+
+ private String getPackageName(ClassReference clazz) {
+ int pos = clazz.getClassName().lastIndexOf(".");
+ return clazz.getClassName().substring(0, pos);
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoader.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoader.java new file mode 100644 index 0000000000..60bf7f223b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoader.java @@ -0,0 +1,397 @@ +/*
+ * 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.contribution.java.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+
+
+public class ContributionClassLoader extends URLClassLoader {
+// public class ContributionClassLoader {
+
+ private Contribution contribution;
+ // private b urlClassLoader;
+
+ /**
+ * Constructor for contribution ClassLoader
+ *
+ * @param contribution
+ * @param parent
+ * @throws MalformedURLException
+ */
+ public ContributionClassLoader(Contribution contribution, final ClassLoader parent) {
+ super(new URL[0], parent);
+ // Note that privileged use of getContextClassLoader have been promoted to callers.
+ // super(new URL[0], parent == null?Thread.currentThread().getContextClassLoader(): null);
+ this.contribution = contribution;
+ if (contribution.getLocation() != null) {
+ try {
+ this.addURL(new URL(contribution.getLocation()));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /*
+ * @return the context ClassLoader of the current thread.
+ */
+ protected static ClassLoader getContextClassLoader() {
+ ClassLoader contextClassLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ return contextClassLoader;
+ }
+
+ /*
+ * Return the ClassLoader corresponding to a contribution providing an export
+ * Create a new ClassLoader for the contribution if one does not exist
+ */
+ private ClassLoader getExportClassLoader(Contribution exportingContribution) {
+ ClassLoader cl = exportingContribution.getClassLoader();
+ if (!(cl instanceof ContributionClassLoader)) {
+ if (cl == null) {
+ cl = getContextClassLoader();
+ }
+
+ cl = new ContributionClassLoader(exportingContribution, cl);
+ exportingContribution.setClassLoader(cl);
+ }
+ return cl;
+ }
+
+ /* (non-Javadoc)
+ * @see java.net.URLClassLoader#findClass(java.lang.String)
+ *
+ * Search path for class:
+ * This contribution
+ * Imported contributions
+ */
+ @Override
+ protected Class<?> findClass(String className) throws ClassNotFoundException {
+
+ Class<?> clazz = null;
+ try {
+ clazz = findClassFromContribution(className);
+ } catch (ClassNotFoundException e) {
+
+ for (Import import_ : this.contribution.getImports()) {
+ if (classNameMatchesImport(className, import_)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : ((JavaImportModelResolver)import_.getModelResolver()).getExportContributions()) {
+
+ ClassLoader exportClassLoader = getExportClassLoader(exportingContribution);
+ if (exportClassLoader instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ try {
+ if (import_.match(export)) {
+ clazz = ((ContributionClassLoader)exportClassLoader).findClassFromContribution(className);
+ break;
+ }
+ } catch (ClassNotFoundException e1) {
+ continue;
+ }
+
+ }
+ if (clazz != null) break;
+ }
+ }
+ if (clazz != null) break;
+ }
+ }
+
+ if (clazz == null) throw e;
+ }
+ return clazz;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ *
+ * Search path for class:
+ * Parent ClassLoader
+ * This contribution
+ * Imported contributions
+ *
+ */
+ @Override
+ protected synchronized Class<?> loadClass(String className, boolean resolveClass)
+ throws ClassNotFoundException {
+
+ Class<?> clazz = null;
+ try {
+
+ if (this.getParent() != null)
+ clazz = this.getParent().loadClass(className);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ if (clazz == null)
+ clazz = findClass(className);
+
+
+ if (resolveClass)
+ this.resolveClass(clazz);
+ return clazz;
+
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.net.URLClassLoader#findResource(java.lang.String)
+ */
+ @Override
+ public URL findResource(String name) {
+
+ URL url = findResourceFromContribution(name);
+
+ if (url == null) {
+ for (Import import_ : this.contribution.getImports()) {
+ if (resourceNameMatchesImport(name, import_)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : ((JavaImportModelResolver)import_.getModelResolver()).getExportContributions()) {
+
+ ClassLoader exportClassLoader = getExportClassLoader(exportingContribution);
+ if (exportClassLoader instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ if (import_.match(export)) {
+ url = ((ContributionClassLoader)exportClassLoader).findResourceFromContribution(name);
+ if (url != null) break;
+ }
+ }
+ if (url != null) break;
+ }
+ }
+ if (url != null) break;
+ }
+ }
+
+ }
+ return url;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.net.URLClassLoader#findResources(java.lang.String)
+ */
+ @Override
+ public Enumeration<URL> findResources(String name) throws IOException {
+
+ return Collections.enumeration(findResourceSet(name));
+ }
+
+
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#getResource(java.lang.String)
+ *
+ * Find a resource.
+ * Search path for resource:
+ * Parent ClassLoader
+ * This contribution
+ * Imported contributions
+ */
+ @Override
+ public URL getResource(String resName) {
+
+ URL resource = null;
+
+ if (this.getParent() != null) {
+ resource = this.getParent().getResource(resName);
+ }
+ if (resource == null)
+ resource = findResource(resName);
+
+ return resource;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#getResources(java.lang.String)
+ *
+ * Return list of resources from this contribution, resources
+ * imported through imported contributions and resources from parent
+ * ClassLoader.
+ */
+ @Override
+ public Enumeration<URL> getResources(String resName) throws IOException {
+
+ HashSet<URL> resourceSet = findResourceSet(resName);
+ addEnumerationToCollection(resourceSet, super.getResources(resName));
+
+ return Collections.enumeration(resourceSet);
+ }
+
+
+ /*
+ * Find set of resources
+ */
+ private HashSet<URL> findResourceSet(String name) throws IOException {
+
+ HashSet<URL> resources = new HashSet<URL>();
+
+ addEnumerationToCollection(resources, super.findResources(name));
+
+ for (Import import_ : this.contribution.getImports()) {
+ if (!(import_ instanceof JavaImport)) {
+ continue;
+ }
+ if (resourceNameMatchesImport(name, import_)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : ((JavaImportModelResolver)import_.getModelResolver()).getExportContributions()) {
+
+ ClassLoader exportClassLoader = getExportClassLoader(exportingContribution);
+ if (exportClassLoader instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ if (import_.match(export)) {
+ addEnumerationToCollection(resources,
+ ((ContributionClassLoader)exportClassLoader).findResources(name));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return resources;
+ }
+
+
+ /*
+ * Find class from contribution. If class has already been loaded, return loaded class.
+ */
+ private Class<?> findClassFromContribution(String className) throws ClassNotFoundException {
+
+ Class<?> clazz = findLoadedClass(className);
+ if (clazz == null)
+ clazz = super.findClass(className);
+ return clazz;
+
+ }
+
+ /*
+ * Find resource from contribution.
+ */
+ private URL findResourceFromContribution(String name) {
+
+ return super.findResource(name);
+ }
+
+ /**
+ * Check if a class name matches an import statement.
+ * Class matches if the package name used in <import.java/> matches
+ *
+ * @param name Name of class
+ * @param import_ SCA contribution import
+ * @return true if this is a matching import
+ */
+ private boolean classNameMatchesImport(String name, Import import_) {
+
+ if (import_ instanceof JavaImport && name != null && name.lastIndexOf('.') > 0) {
+ JavaImport javaImport = (JavaImport) import_;
+
+ String packageName = name.substring(0, name.lastIndexOf('.'));
+ if (javaImport.getPackage().endsWith(".*")) {
+ String prefix = javaImport.getPackage().substring(0, javaImport.getPackage().length() -1);
+ if (packageName.startsWith(prefix)) {
+ return true;
+ }
+ } else {
+ return packageName.equals(javaImport.getPackage());
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if a resource name matches an import statement.
+ * Resource matches if package/namespace match the directory of resource.
+ *
+ * @param name Name of resource
+ * @param import_ SCA contribution import
+ * @return true if this is a matching import
+ */
+ private boolean resourceNameMatchesImport(String name, Import import_) {
+
+
+ if (name == null || name.lastIndexOf('/') <= 0)
+ return false;
+ else if (import_ instanceof JavaImport) {
+ JavaImport javaImport = (JavaImport) import_;
+
+ if (javaImport.getPackage().endsWith(".*")) {
+ String packageName = name.substring(0, name.lastIndexOf('/')).replace('/', '.');
+ String prefix = javaImport.getPackage().substring(0, javaImport.getPackage().length() -1);
+ if (packageName.startsWith(prefix)) {
+ return true;
+ }
+ } else {
+ // 'name' is a resource : contains "/" as separators
+ // Get package name from resource name
+ String packageName = name.substring(0, name.lastIndexOf('/'));
+ return packageName.equals(javaImport.getPackage().replaceAll("\\.", "/"));
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Add an enumeration to a Collection
+ */
+ private <T extends Object> void addEnumerationToCollection(Collection<T> collection, Enumeration<T> enumeration) {
+
+ while (enumeration.hasMoreElements())
+ collection.add(enumeration.nextElement());
+ }
+
+
+ @Override
+ public String toString() {
+ return "SCA contribution classloader for : " + contribution.getLocation();
+ }
+
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java new file mode 100644 index 0000000000..f35f35ac4c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.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.contribution.java.impl; + +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * Implementation of a Java Import model + * + * @version $Rev$ $Date$ + */ +public class JavaExportImpl implements JavaExport { + private ModelResolver modelResolver; + + /** + * Java package being exported + */ + private String packageName; + + public JavaExportImpl() { + super(); + } + + public String getPackage() { + return this.packageName; + } + + public void setPackage(String packageName) { + this.packageName = packageName; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportModelResolver.java new file mode 100644 index 0000000000..8d5412f6d7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportModelResolver.java @@ -0,0 +1,76 @@ +/* + * 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.contribution.java.impl; + +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A model resolver for Java exports. + * + * @version $Rev$ $Date$ + */ +public class JavaExportModelResolver implements ModelResolver { + + private JavaExport export; + private ModelResolver resolver; + + public JavaExportModelResolver(JavaExport export, ModelResolver resolver) { + this.export = export; + this.resolver = resolver; + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + if (!(unresolved instanceof ClassReference)) { + return unresolved; + } + + // Filter package name + ClassReference classReference = (ClassReference)unresolved; + String className = classReference.getClassName(); + int d = className.lastIndexOf('.'); + String packageName; + if (d != -1) { + packageName = className.substring(0, d); + } else { + packageName = ""; + } + if (export.getPackage().equals(packageName)) { + + // Package matches the exported package, delegate to the + // contribution's resolver + return resolver.resolveModel(modelClass, unresolved); + } else { + + // Package is not exported, return the unresolved object + return unresolved; + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessor.java new file mode 100644 index 0000000000..9f6ff52289 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessor.java @@ -0,0 +1,143 @@ +/* + * 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.contribution.java.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.java.JavaImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact processor for Java Export + * + * @version $Rev$ $Date$ + */ +public class JavaExportProcessor implements StAXArtifactProcessor<JavaExport> { + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private static final QName EXPORT_JAVA = new QName(SCA10_NS, "export.java"); + + private static final String PACKAGE = "package"; + + private final JavaImportExportFactory factory; + private final Monitor monitor; + + public JavaExportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + super(); + this.factory = modelFactories.getFactory(JavaImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-java-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return EXPORT_JAVA; + } + + public Class<JavaExport> getModelType() { + return JavaExport.class; + } + + /** + * Process <export package=""/> + */ + public JavaExport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + JavaExport javaExport = this.factory.createJavaExport(); + QName element = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <export.java> + if (EXPORT_JAVA.equals(element)) { + String packageName = reader.getAttributeValue(null, PACKAGE); + if (packageName == null) { + error("AttributePackageMissing", reader); + //throw new ContributionReadException("Attribute 'package' is missing"); + } else + javaExport.setPackage(packageName); + } + break; + case XMLStreamConstants.END_ELEMENT: + if (EXPORT_JAVA.equals(reader.getName())) { + return javaExport; + } + break; + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return javaExport; + } + + public void write(JavaExport javaExport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <export.java> + writer.writeStartElement(EXPORT_JAVA.getNamespaceURI(), EXPORT_JAVA.getLocalPart()); + + if (javaExport.getPackage() != null) { + writer.writeAttribute(PACKAGE, javaExport.getPackage()); + } + + writer.writeEndElement(); + } + + public void resolve(JavaExport javaExport, ModelResolver resolver) throws ContributionResolveException { + + if (javaExport.getPackage() != null) + // Initialize the export resolver + javaExport.setModelResolver(new JavaExportModelResolver(javaExport, resolver)); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportFactoryImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportFactoryImpl.java new file mode 100644 index 0000000000..e5dc397f4e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportFactoryImpl.java @@ -0,0 +1,41 @@ +/*
+ * 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.contribution.java.impl;
+
+import org.apache.tuscany.sca.contribution.java.JavaExport;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.java.JavaImportExportFactory;
+
+/**
+ * Java Import/Export Factory implementation
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImportExportFactoryImpl implements JavaImportExportFactory {
+
+ public JavaImport createJavaImport() {
+ return new JavaImportImpl();
+ }
+
+ public JavaExport createJavaExport() {
+ return new JavaExportImpl();
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java new file mode 100644 index 0000000000..47cdc9767b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java @@ -0,0 +1,157 @@ +/*
+ * 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.contribution.java.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.java.JavaExport;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.resolver.DefaultImportAllModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.service.ContributionListener;
+import org.apache.tuscany.sca.contribution.service.ContributionRepository;
+
+/**
+ * Java Import/Export contribution listener
+ * The listener would process all import/export from a given contribution
+ * and initialize the model resolvers properly
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImportExportListener implements ContributionListener {
+
+ private ContributionFactory contributionFactory;
+
+ /**
+ * Constructs a new JavaImportExportListener
+ */
+ public JavaImportExportListener(ModelFactoryExtensionPoint modelFactories) {
+ contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ }
+
+ /**
+ * Initialize the import/export model resolvers
+ * Export model resolvers are same as Contribution model resolver
+ * Import model resolvers are matched to a specific contribution if a location URI is specified,
+ * otherwise it try to resolve against all the other contributions
+ * Also set the exporting contributions used by contribution ClassLoaders to
+ * match import/export for class loading.
+ */
+ public void contributionAdded(ContributionRepository repository, Contribution contribution) {
+
+ // If the contribution does not contain sca-contribution.xml metadata
+ // (for example it's an existing JAR developed before SCA existed)
+ // export all its Java packages
+ ModelResolver modelResolver = contribution.getModelResolver();
+
+ // Look for META-INF/sca-contribution.xml
+ Artifact artifact = contributionFactory.createArtifact();
+ artifact.setURI(Contribution.SCA_CONTRIBUTION_META);
+ artifact = modelResolver.resolveModel(Artifact.class, artifact);
+ if (artifact.getLocation() == null) {
+
+ // Look for META-INF/sca-contribution-generated.xml
+ artifact.setURI(Contribution.SCA_CONTRIBUTION_GENERATED_META);
+ artifact = modelResolver.resolveModel(Artifact.class, artifact);
+ if (artifact.getLocation() == null) {
+
+ // No contribution metadata file was found, default to export all the
+ // Java packages found in the contribution
+ Set<String> packages = new HashSet<String>();
+ for (Artifact a: contribution.getArtifacts()) {
+ String uri = a.getURI();
+ if (uri.endsWith(".class")) {
+ uri = uri.substring(0, uri.length() - 6);
+ int d = uri.lastIndexOf('/');
+ if (d != -1) {
+ packages.add(uri.substring(0, d).replace('/', '.'));
+ }
+ }
+ }
+
+ // Add Java export model objects for all the packages we found
+ for (String pkg: packages) {
+ JavaExport export = new JavaExportImpl();
+ export.setPackage(pkg);
+ contribution.getExports().add(export);
+ }
+ }
+ }
+
+ // Initialize the contribution exports
+ for (Export export: contribution.getExports()) {
+ export.setModelResolver(contribution.getModelResolver());
+ }
+
+ // Initialize the contribution imports
+ for (Import import_: contribution.getImports()) {
+ boolean initialized = false;
+
+ if(import_ instanceof JavaImport) {
+ JavaImport javaImport = (JavaImport) import_;
+
+ //Find a matching contribution
+ if(javaImport.getLocation() != null) {
+ Contribution targetContribution = repository.getContribution(javaImport.getLocation());
+ if (targetContribution != null) {
+
+ // Find a matching contribution export
+ for (Export export: targetContribution.getExports()) {
+ if (export instanceof JavaExport) {
+ JavaExport javaExport = (JavaExport)export;
+ if (javaImport.getPackage().equals(javaExport.getPackage())) {
+ List<Contribution> exportingContributions = new ArrayList<Contribution>();
+ exportingContributions.add(targetContribution);
+ javaImport.setModelResolver(new JavaImportModelResolver(exportingContributions, javaExport.getModelResolver()));
+ initialized = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ //if no location was specified, try to resolve with any contribution
+ if (!initialized) {
+ //Use a resolver that will consider all contributions
+ import_.setModelResolver(new JavaImportModelResolver(repository.getContributions(), new DefaultImportAllModelResolver(import_, repository.getContributions())));
+ }
+ }
+ }
+ }
+
+ public void contributionRemoved(ContributionRepository repository, Contribution contribution) {
+
+ }
+
+ public void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution) {
+
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java new file mode 100644 index 0000000000..cc18d5f798 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java @@ -0,0 +1,110 @@ +/* + * 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.contribution.java.impl; + +import java.util.List; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * Implementation of a Java Import model + * + * @version $Rev$ $Date$ + */ +public class JavaImportImpl implements JavaImport { + private ModelResolver modelResolver; + private List<Contribution> contributions; + /** + * Java package name being imported + */ + private String packageName; + /** + * Contribution URI where the artifact is imported from + */ + private String location; + + public JavaImportImpl() { + super(); + } + + public String getLocation() { + return this.location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getPackage() { + return this.packageName; + } + + public void setPackage(String packageName) { + this.packageName = packageName; + } + + public ModelResolver getModelResolver() { + return this.modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + public List<Contribution> getExportContributions() { + return contributions; + } + + public void setExportContributions(List<Contribution> contributions) { + this.contributions = contributions; + } + + /** + * Match a JavaImport to a given JavaExport based on : + * location is not provided + * import and export packages match + */ + public boolean match(Export export) { + if(export instanceof JavaExport) { + JavaExport javaExport = (JavaExport)export; + String exportedPackage = javaExport.getPackage(); + if (packageName.equals(exportedPackage)) { + return true; + } else { + if (packageName.endsWith(".*")) { + String prefix = packageName.substring(0, packageName.length() - 1); + if (exportedPackage.startsWith(prefix)) { + return true; + } + } + } + } + + return false; + } + + @Override + public String toString() { + return String.valueOf(packageName); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportModelResolver.java new file mode 100644 index 0000000000..484eddd222 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportModelResolver.java @@ -0,0 +1,62 @@ +/* + * 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.contribution.java.impl; + +import java.util.List; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A JavaImport specific model resolver. This model resolver is temporary + * and provides the ContributionClassLoader with the list of exporting + * contributions that it currently needs. + * + * FIXME Remove this class after the ContributionClassLoader is simplified + * and cleaned up. + * + * @version $Rev$ $Date$ + */ +public class JavaImportModelResolver implements ModelResolver { + + private ModelResolver modelResolver; + private List<Contribution> contributions; + + public JavaImportModelResolver(List<Contribution> contributions, ModelResolver modelResolver) { + this.modelResolver = modelResolver; + this.contributions = contributions; + } + + public List<Contribution> getExportContributions() { + return contributions; + } + + public void addModel(Object resolved) { + modelResolver.addModel(resolved); + } + + public Object removeModel(Object resolved) { + return modelResolver.removeModel(resolved); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + return modelResolver.resolveModel(modelClass, unresolved); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessor.java new file mode 100644 index 0000000000..d027d75b32 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessor.java @@ -0,0 +1,148 @@ +/* + * 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.contribution.java.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.java.JavaImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact Processor for Java Imports + * + * @version $Rev$ $Date$ + */ +public class JavaImportProcessor implements StAXArtifactProcessor<JavaImport> { + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private static final QName IMPORT_JAVA = new QName(SCA10_NS, "import.java"); + + private static final String PACKAGE = "package"; + private static final String LOCATION = "location"; + + private final JavaImportExportFactory factory; + private final Monitor monitor; + + public JavaImportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + super(); + this.factory = modelFactories.getFactory(JavaImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-java-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return IMPORT_JAVA; + } + + public Class<JavaImport> getModelType() { + return JavaImport.class; + } + + /** + * Process <import.java package="" location=""/> + */ + public JavaImport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + JavaImport javaImport = this.factory.createJavaImport(); + QName element = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <import.java> + if (IMPORT_JAVA.equals(element)) { + String packageName = reader.getAttributeValue(null, PACKAGE); + if (packageName == null) { + error("AttributePackageMissing", reader); + //throw new ContributionReadException("Attribute 'package' is missing"); + } else + javaImport.setPackage(packageName); + + String location = reader.getAttributeValue(null, LOCATION); + javaImport.setLocation(location); + } + break; + case XMLStreamConstants.END_ELEMENT: + if (IMPORT_JAVA.equals(reader.getName())) { + return javaImport; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return javaImport; + } + + public void write(JavaImport javaImport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <import.java> + writer.writeStartElement(IMPORT_JAVA.getNamespaceURI(), IMPORT_JAVA.getLocalPart()); + + if (javaImport.getPackage() != null) { + writer.writeAttribute(PACKAGE, javaImport.getPackage()); + } + if (javaImport.getLocation() != null) { + writer.writeAttribute(LOCATION, javaImport.getLocation()); + } + + writer.writeEndElement(); + } + + + public void resolve(JavaImport model, ModelResolver resolver) throws ContributionResolveException { + + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.java.JavaImportExportFactory b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.java.JavaImportExportFactory new file mode 100644 index 0000000000..a293330a57 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.java.JavaImportExportFactory @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.java.impl.JavaImportExportFactoryImpl
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..ac1fa9aade --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,19 @@ +# 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. + +org.apache.tuscany.sca.contribution.java.impl.JavaImportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#import.java,model=org.apache.tuscany.sca.contribution.java.JavaImport +org.apache.tuscany.sca.contribution.java.impl.JavaExportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#export.java,model=org.apache.tuscany.sca.contribution.java.JavaExport diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..c69eb40636 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.java.impl.ClassReferenceModelResolver;model=org.apache.tuscany.sca.contribution.resolver.ClassReference
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener new file mode 100644 index 0000000000..7debb3d3c6 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.java.impl.JavaImportExportListener
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/contribution-java-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/contribution-java-validation-messages.properties new file mode 100644 index 0000000000..70b58f75c0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/main/resources/contribution-java-validation-messages.properties @@ -0,0 +1,22 @@ +# +# +# 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. +# +# +AttributePackageMissing = Attribute 'package' is missing + diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceArtifactResolverTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceArtifactResolverTestCase.java new file mode 100644 index 0000000000..1405ad4bd5 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceArtifactResolverTestCase.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.contribution.java.impl;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+
+/**
+ * Test ClassReferenceArtifactResolver.
+ *
+ * @version $Rev: 560435 $ $Date: 2007-07-27 18:26:55 -0700 (Fri, 27 Jul 2007) $
+ */
+public class ClassReferenceArtifactResolverTestCase extends TestCase {
+ private ExtensibleModelResolver resolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+
+ ModelResolverExtensionPoint resolvers = extensionPoints.getExtensionPoint(ModelResolverExtensionPoint.class);
+ resolvers.addResolver(ClassReference.class, ClassReferenceModelResolver.class);
+ ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ resolver = new ExtensibleModelResolver(null, resolvers, modelFactories);
+ }
+
+ /**
+ * Test ClassReference resolution
+ *
+ */
+ public void testResolveClass() {
+ ClassReference ref = new ClassReference(getClass().getName());
+ ClassReference clazz = resolver.resolveModel(ClassReference.class, ref);
+ assertFalse(clazz.isUnresolved());
+ assertTrue(clazz.getJavaClass() == getClass());
+ }
+
+ /**
+ * Test ClassReference resolution of inexistent class
+ *
+ */
+ public void testUnresolvedClass() {
+ ClassReference ref = new ClassReference("NonExistentClass");
+ ClassReference clazz = resolver.resolveModel(ClassReference.class, ref);
+ assertTrue(clazz.isUnresolved());
+ assertTrue(clazz.getJavaClass() == null);
+ }
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoaderTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoaderTestCase.java new file mode 100644 index 0000000000..3ae161642d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/ContributionClassLoaderTestCase.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.contribution.java.impl;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.java.JavaExport;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.java.JavaImportExportFactory;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Test ContributionClassLoader.
+ *
+ */
+public class ContributionClassLoaderTestCase {
+
+ private ContributionFactory contributionFactory;
+ private JavaImportExportFactory javaImportExportFactory;
+
+ @Before
+ public void setUp() throws Exception {
+ ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+ ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ javaImportExportFactory = modelFactories.getFactory(JavaImportExportFactory.class);
+ }
+
+ private Contribution createContribution(String fileName) throws MalformedURLException {
+ Contribution contrib = contributionFactory.createContribution();
+ File contribDir = new File(fileName);
+ contrib.setLocation(contribDir.toURI().toURL().toString());
+ ClassLoader contextClassLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ contrib.setClassLoader(new ContributionClassLoader(contrib, contextClassLoader));
+ return contrib;
+ }
+
+
+ @Test
+ public void testClassLoadingFromContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ // Class present in contribution, also in parent. Class is loaded from parent
+ Class<?> testClassA = contribA.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassA);
+ Assert.assertSame(this.getClass(), testClassA);
+
+ // Class not present in contribution, but present in parent ClassLoader
+ Class<?> testClassB = contribB.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassB);
+ Assert.assertSame(this.getClass(), testClassB);
+
+ // Class present in contribution, but not in parent
+ Class<?> testClassC = contribC.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassC);
+
+ // Class not present in contribution or in parent
+ try {
+ contribA.getClassLoader().loadClass("NonExistent");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+
+
+ }
+
+ @Test
+ public void testResourceLoadingFromContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ // Resource present in contribution, and in parent
+ URL resA = contribA.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resA);
+
+ // Resource not present in contribution, but present in parent ClassLoader
+ URL resB = contribB.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resB);
+
+ // Resource present in contribution, but not in parent
+ URL resC = contribC.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNotNull(resC);
+
+ // Load Java class as resource from parent
+ String classResName = this.getClass().getName().replaceAll("\\.", "/") + ".class";
+ URL classResA = contribA.getClassLoader().getResource(classResName);
+ Assert.assertNotNull(classResA);
+
+ // Non-existent resource
+ URL res = contribA.getClassLoader().getResource("deployables/NonExistent");
+ Assert.assertNull(res);
+
+ }
+
+ private static String getPackageName(Class<?> cls) {
+ String name = cls.getName();
+ int index = name.lastIndexOf('.');
+ return index == -1 ? "" : name.substring(0, index);
+ }
+
+ @Test
+ public void testClassLoadingFromImportedContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+ ArrayList<Contribution> exportContribList = new ArrayList<Contribution>();
+ exportContribList.add(contribA);
+ exportContribList.add(contribC);
+
+ JavaImport import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage(getPackageName(getClass()));
+ import_.setModelResolver(new JavaImportModelResolver(exportContribList, null));
+ contribB.getImports().add(import_);
+ import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage("calculator");
+ import_.setModelResolver(new JavaImportModelResolver(exportContribList, null));
+ contribB.getImports().add(import_);
+
+ JavaExport export = javaImportExportFactory.createJavaExport();
+ export.setPackage(getPackageName(getClass()));
+ contribA.getExports().add(export);
+ export = javaImportExportFactory.createJavaExport();
+ export.setPackage("calculator");
+ contribC.getExports().add(export);
+
+ // Load class from parent, class is also present in imported contribution. Class should
+ // be loaded from parent
+ Class<?> testClassB = contribB.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassB);
+ Assert.assertSame(this.getClass(), testClassB);
+
+ // Load class from parent, class is also present in parent. Class should be loaded
+ // from parent.
+ Class<?> testClassA = contribA.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassA);
+ Assert.assertSame(this.getClass(), testClassA);
+
+ // Imported class should be the same as the one loaded by the exporting contribution
+ Assert.assertSame(testClassA, testClassB);
+
+ // Load class from imported contribution, class is not present in parent
+ Class<?> testClassB1 = contribB.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassB1);
+
+ // Imported class should be the same as the one loaded by the exporting contribution
+ Class<?> testClassC = contribC.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassC);
+ Assert.assertSame(testClassC, testClassB1);
+
+
+ // Try to load class from package which is not explicitly imported - should throw ClassNotFoundException
+ try {
+ contribA.getClassLoader().loadClass("calculator.AddService");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ // Try to load non-existent class from imported package - should throw ClassNotFoundException
+ try {
+ contribB.getClassLoader().loadClass(getPackageName(getClass()) + ".NonExistentClass");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ }
+
+ @Test
+ public void testResourceLoadingFromImportedContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ ArrayList<Contribution> exportContribList = new ArrayList<Contribution>();
+ exportContribList.add(contribA);
+ exportContribList.add(contribC);
+
+ JavaImport import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage(getPackageName(getClass()));
+ import_.setModelResolver(new JavaImportModelResolver(exportContribList, null));
+ contribB.getImports().add(import_);
+ JavaImport import1_ = javaImportExportFactory.createJavaImport();
+ import1_.setPackage("calculator");
+ import1_.setModelResolver(new JavaImportModelResolver(exportContribList, null));
+ contribB.getImports().add(import1_);
+
+ JavaExport export = javaImportExportFactory.createJavaExport();
+ export.setPackage(getPackageName(getClass()));
+ contribA.getExports().add(export);
+ JavaExport export1 = javaImportExportFactory.createJavaExport();
+ export1.setPackage("calculator");
+ contribC.getExports().add(export1);
+
+
+ // Load resource from parent
+ URL resB = contribB.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resB);
+
+ // Load Java class as resource from imported contribution with JavaImport
+ String classResName = this.getClass().getName().replaceAll("\\.", "/") + ".class";
+ URL classResB = contribB.getClassLoader().getResource(classResName);
+ Assert.assertNotNull(classResB);
+
+ // Load Java class as resource from imported contribution with JavaImport
+ URL classResB1 = contribB.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNotNull(classResB1);
+
+ // Try to load resource not explicitly imported by contribution
+ URL classResA1 = contribA.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNull(classResA1);
+
+
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessorTestCase.java new file mode 100644 index 0000000000..0ec5bfba39 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportProcessorTestCase.java @@ -0,0 +1,103 @@ +/* + * 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.contribution.java.impl; + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test JavaExportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class JavaExportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export.java xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" package=\"org.apache.tuscany.sca.contribution.java\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export.java xmlns=\"http://www.osoa.org/xmlns/sca/1.0\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null); + } + + /** + * Test loading a valid export element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + JavaExport javaExport = (JavaExport)staxProcessor.read(reader); + assertEquals("org.apache.tuscany.sca.contribution.java", javaExport.getPackage()); + } + + /** + * Test loading an INVALID export element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributePackageMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessorTestCase.java new file mode 100644 index 0000000000..9e43b744cf --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportProcessorTestCase.java @@ -0,0 +1,105 @@ +/* + * 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.contribution.java.impl; + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test JavaImportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class JavaImportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import.java xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" package=\"org.apache.tuscany.sca.contribution.java\" location=\"sca://contributions/001\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import.java xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" location=\"sca://contributions/001\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null); + } + + /** + * Test loading a valid import element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + JavaImport javaImport = (JavaImport)staxProcessor.read(reader); + + assertEquals("org.apache.tuscany.sca.contribution.java", javaImport.getPackage()); + assertEquals("sca://contributions/001", javaImport.getLocation()); + } + + /** + * Test loading a INVALID import element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributePackageMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/resources/deployables/sample-calculator.jar b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/resources/deployables/sample-calculator.jar Binary files differnew file mode 100644 index 0000000000..0ca3a1b781 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-java/src/test/resources/deployables/sample-calculator.jar diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/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/tags/java/sca/1.3-RC1a/modules/contribution-namespace/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/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/tags/java/sca/1.3-RC1a/modules/contribution-namespace/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/pom.xml new file mode 100644 index 0000000000..40ea8cc386 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/pom.xml @@ -0,0 +1,70 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-namespace</artifactId> + <name>Apache Tuscany SCA Namespace Import/Export Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-core-spi</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.namespace</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.namespace*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/DefaultNamespaceImportExportFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/DefaultNamespaceImportExportFactory.java new file mode 100644 index 0000000000..a71fa61a54 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/DefaultNamespaceImportExportFactory.java @@ -0,0 +1,30 @@ +/* + * 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.contribution.namespace; + +import org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportExportFactoryImpl; + +/** + * Default Namespace Import/Export model factory implementation + * + * @version $Rev$ $Date$ + */ +public class DefaultNamespaceImportExportFactory extends NamespaceImportExportFactoryImpl implements NamespaceImportExportFactory { +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceExport.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceExport.java new file mode 100644 index 0000000000..c68aee8521 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceExport.java @@ -0,0 +1,46 @@ +/* + * 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.contribution.namespace; + +import org.apache.tuscany.sca.contribution.Export; + + +/** + * The representation of an XML namespace export. + * + * @version $Rev$ $Date$ + */ +public interface NamespaceExport extends Export { + + /** + * Get Namespace that identifies the export + * + * @return The exported namespace + */ + String getNamespace(); + + /** + * Set Namespace that identifies the export + * + * @param namespace The exported namespace + */ + void setNamespace(String namespace); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImport.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImport.java new file mode 100644 index 0000000000..8af36d7da0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImport.java @@ -0,0 +1,59 @@ +/* + * 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.contribution.namespace; + +import org.apache.tuscany.sca.contribution.Import; + +/** + * The representation of an XML namespace import. + * + * @version $Rev$ $Date$ + */ +public interface NamespaceImport extends Import { + + /** + * Get the location used to resolve the definitions for this import + * + * @return The import location + */ + String getLocation(); + + /** + * Set the location used to resolve the definitions for this import + * + * @param location The import location + */ + void setLocation(String location); + + /** + * Get Namespace that identifies the import + * + * @return The namespace + */ + String getNamespace(); + + /** + * Set Namespace that identifies the import + * + * @param namespace The namespace + */ + void setNamespace(String namespace); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImportExportFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImportExportFactory.java new file mode 100644 index 0000000000..cfbac8bb1f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/NamespaceImportExportFactory.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.namespace; + +/** + * Base Namespace import/export model factory + * + * @version $Rev$ $Date$ + */ +public interface NamespaceImportExportFactory { + + /** + * Create a namespace import model object + * + * @return The new NamespaceImport model object + */ + NamespaceImport createNamespaceImport(); + + /** + * Create a namespace export model object + * + * @return The new NamespaceExport model object + */ + NamespaceExport createNamespaceExport(); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java new file mode 100644 index 0000000000..8991585d32 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java @@ -0,0 +1,54 @@ +/* + * 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.contribution.namespace.impl; + +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an export for the contribution + * + * @version $Rev$ $Date$ + */ +public class NamespaceExportImpl implements NamespaceExport { + private String namespace; + private ModelResolver modelResolver; + + protected NamespaceExportImpl() { + super(); + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportModelResolver.java new file mode 100644 index 0000000000..5c5ae22f77 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportModelResolver.java @@ -0,0 +1,54 @@ +/* + * 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.contribution.namespace.impl; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A model resolver for namespace exports. + * + * @version $Rev$ $Date$ + */ +public class NamespaceExportModelResolver implements ModelResolver { + + private ModelResolver resolver; + + public NamespaceExportModelResolver(ModelResolver resolver) { + this.resolver = resolver; + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + // Just delegate to the contribution's model resolver, namespace + // based filtering is implemented in the model specific model + // resolver, which know how to get the namespace of the particular + // type of model that they handle + return resolver.resolveModel(modelClass, unresolved); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessor.java new file mode 100644 index 0000000000..64862301c1 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessor.java @@ -0,0 +1,142 @@ +/* + * 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.contribution.namespace.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact processor for Namespace export + * + * @version $Rev$ $Date$ + */ +public class NamespaceExportProcessor implements StAXArtifactProcessor<NamespaceExport> { + + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + private static final QName EXPORT = new QName(SCA10_NS, "export"); + private static final String NAMESPACE = "namespace"; + + private final NamespaceImportExportFactory factory; + private final Monitor monitor; + + public NamespaceExportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + this.factory = modelFactories.getFactory(NamespaceImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-namespace-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return EXPORT; + } + + public Class<NamespaceExport> getModelType() { + return NamespaceExport.class; + } + + /** + * Process <export namespace=""/> + */ + public NamespaceExport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + NamespaceExport namespaceExport = this.factory.createNamespaceExport(); + QName element = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <export> + if (EXPORT.equals(element)) { + String ns = reader.getAttributeValue(null, NAMESPACE); + if (ns == null) { + error("AttributeNameSpaceMissing", reader); + //throw new ContributionReadException("Attribute 'namespace' is missing"); + } else + namespaceExport.setNamespace(ns); + } + + break; + case XMLStreamConstants.END_ELEMENT: + if (EXPORT.equals(reader.getName())) { + return namespaceExport; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return namespaceExport; + } + + public void write(NamespaceExport namespaceExport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <export> + writer.writeStartElement(EXPORT.getNamespaceURI(), EXPORT.getLocalPart()); + + if (namespaceExport.getNamespace() != null) { + writer.writeAttribute(NAMESPACE, namespaceExport.getNamespace()); + } + + writer.writeEndElement(); + } + + public void resolve(NamespaceExport namespaceExport, ModelResolver resolver) throws ContributionResolveException { + + if (namespaceExport.getNamespace() != null) + // Initialize the export's resolver + namespaceExport.setModelResolver(new NamespaceExportModelResolver(resolver)); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportFactoryImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportFactoryImpl.java new file mode 100644 index 0000000000..1146e593a9 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportFactoryImpl.java @@ -0,0 +1,41 @@ +/* + * 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.contribution.namespace.impl; + +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory; + +/** + * Namespace Import/Export model factory implementation + * + * @version $Rev$ $Date$ + */ +public class NamespaceImportExportFactoryImpl implements NamespaceImportExportFactory { + + public NamespaceImport createNamespaceImport() { + return new NamespaceImportImpl(); + } + + public NamespaceExport createNamespaceExport() { + return new NamespaceExportImpl(); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java new file mode 100644 index 0000000000..7ea09a47c7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java @@ -0,0 +1,98 @@ +/* + * 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.contribution.namespace.impl; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.resolver.DefaultImportAllModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionListener; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; + +/** + * Namespace Import/Export contribution listener + * The listener would process all import/export from a given contribution + * and initialize the model resolvers properly + * + * @version $Rev$ $Date$ + */ +public class NamespaceImportExportListener implements ContributionListener { + + /** + * Initialize the import/export model resolvers + * Export model resolvers are same as Contribution model resolver + * Import model resolvers are matched to a specific contribution if a location URI is specified, + * otherwise it try to resolve against all the other contributions + * Also set the exporting contributions used by contribution ClassLoaders to + * match import/export for class loading. + */ + public void contributionAdded(ContributionRepository repository, Contribution contribution) { + // Initialize the contribution exports + for (Export export: contribution.getExports()) { + export.setModelResolver(contribution.getModelResolver()); + } + + // Initialize the contribution imports + for (Import import_: contribution.getImports()) { + boolean initialized = false; + + if (import_ instanceof NamespaceImport) { + NamespaceImport namespaceImport = (NamespaceImport)import_; + + // Find a matching contribution + if (namespaceImport.getLocation() != null) { + Contribution targetContribution = repository.getContribution(namespaceImport.getLocation()); + if (targetContribution != null) { + + // Find a matching contribution export + for (Export export: targetContribution.getExports()) { + if (export instanceof NamespaceExport) { + NamespaceExport namespaceExport = (NamespaceExport)export; + if (namespaceImport.getNamespace().equals(namespaceExport.getNamespace())) { + namespaceImport.setModelResolver(namespaceExport.getModelResolver()); + initialized = true; + break; + } + } + } + } + } + + //if no location was specified, try to resolve with any contribution + if( !initialized ) { + // Use a resolver that will consider all contributions + import_.setModelResolver(new DefaultImportAllModelResolver(import_, repository.getContributions())); + } + } + } + + } + + public void contributionRemoved(ContributionRepository repository, Contribution contribution) { + + } + + public void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution) { + + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java new file mode 100644 index 0000000000..6d2a31f702 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java @@ -0,0 +1,92 @@ +/* + * 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.contribution.namespace.impl; + +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an import for the contribution + * + * @version $Rev$ $Date$ + */ +public class NamespaceImportImpl implements NamespaceImport { + private ModelResolver modelResolver; + + /** + * The namespace to be imported + */ + private String namespace; + /** + * Optional location URI pointing to a Contribution that exports the namespace + */ + private String location; + + + protected NamespaceImportImpl() { + super(); + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + + /** + * Match a NamespaceImport to a given NamespaceExport based on : + * location is not provided + * import and export namespaces match + */ + public boolean match(Export export) { + if (export instanceof NamespaceExport) { + if (this.getNamespace().equals(((NamespaceExport)export).getNamespace())) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return String.valueOf(namespace); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessor.java new file mode 100644 index 0000000000..829e5fa43f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessor.java @@ -0,0 +1,148 @@ +/* + * 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.contribution.namespace.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact processor for Namespace import + * + * @version $Rev$ $Date$ + */ +public class NamespaceImportProcessor implements StAXArtifactProcessor<NamespaceImport> { + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private static final QName IMPORT = new QName(SCA10_NS, "import"); + + private static final String NAMESPACE = "namespace"; + private static final String LOCATION = "location"; + + private final NamespaceImportExportFactory factory; + private final Monitor monitor; + + public NamespaceImportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + this.factory = modelFactories.getFactory(NamespaceImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-namespace-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return IMPORT; + } + + public Class<NamespaceImport> getModelType() { + return NamespaceImport.class; + } + + /** + * Process <import namespace="" location=""/> + */ + public NamespaceImport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + NamespaceImport namespaceImport = this.factory.createNamespaceImport(); + QName element; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <import> + if (IMPORT.equals(element)) { + String ns = reader.getAttributeValue(null, NAMESPACE); + if (ns == null) { + error("AttributeNameSpaceMissing", reader); + //throw new ContributionReadException("Attribute 'namespace' is missing"); + } else + namespaceImport.setNamespace(ns); + + String location = reader.getAttributeValue(null, LOCATION); + if (location != null) { + namespaceImport.setLocation(location); + } + } + break; + case XMLStreamConstants.END_ELEMENT: + if (IMPORT.equals(reader.getName())) { + return namespaceImport; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return namespaceImport; + } + + public void write(NamespaceImport namespaceImport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <import> + writer.writeStartElement(IMPORT.getNamespaceURI(), IMPORT.getLocalPart()); + + if (namespaceImport.getNamespace() != null) { + writer.writeAttribute(NAMESPACE, namespaceImport.getNamespace()); + } + if (namespaceImport.getLocation() != null) { + writer.writeAttribute(LOCATION, namespaceImport.getLocation()); + } + + writer.writeEndElement(); + } + + + public void resolve(NamespaceImport model, ModelResolver resolver) throws ContributionResolveException { + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory new file mode 100644 index 0000000000..095866fb6f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportExportFactoryImpl
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..86f199368b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,19 @@ +# 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. + +org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#import,model=org.apache.tuscany.sca.contribution.namespace.NamespaceImport +org.apache.tuscany.sca.contribution.namespace.impl.NamespaceExportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#export,model=org.apache.tuscany.sca.contribution.namespace.NamespaceExport diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener new file mode 100644 index 0000000000..cdf16a383f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportExportListener
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/contribution-namespace-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/contribution-namespace-validation-messages.properties new file mode 100644 index 0000000000..c7ddba3c3d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/main/resources/contribution-namespace-validation-messages.properties @@ -0,0 +1,22 @@ +# +# +# 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. +# +# +AttributeNameSpaceMissing = Attribute 'namespace' is missing + diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessorTestCase.java new file mode 100644 index 0000000000..1f508d6a4a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportProcessorTestCase.java @@ -0,0 +1,103 @@ +/* + * 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.contribution.namespace.impl; + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.namespace.NamespaceExport; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test NamespaceExportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class NamespaceExportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" namespace=\"http://foo\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, monitor); + } + + /** + * Test loading a valid export element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + NamespaceExport namespaceExport = (NamespaceExport)staxProcessor.read(reader); + assertEquals("http://foo", namespaceExport.getNamespace()); + } + + /** + * Test loading an INVALID export element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributeNameSpaceMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessorTestCase.java new file mode 100644 index 0000000000..71ac33bf68 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-namespace/src/test/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportProcessorTestCase.java @@ -0,0 +1,108 @@ +/* + * 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.contribution.namespace.impl; + + + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test NamespaceImportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class NamespaceImportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" namespace=\"http://foo\" location=\"sca://contributions/001\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" location=\"sca://contributions/001\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, monitor); + } + + /** + * Test loading a valid import element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + NamespaceImport namespaceImport = (NamespaceImport)staxProcessor.read(reader); + + assertEquals("http://foo", namespaceImport.getNamespace()); + assertEquals("sca://contributions/001", namespaceImport.getLocation()); + } + + /** + * Test loading a INVALID import element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributeNameSpaceMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/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/tags/java/sca/1.3-RC1a/modules/contribution-osgi/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/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/tags/java/sca/1.3-RC1a/modules/contribution-osgi/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/pom.xml new file mode 100644 index 0000000000..b2d9ad309c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/pom.xml @@ -0,0 +1,84 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-osgi</artifactId> + <name>Apache Tuscany SCA Contribution Service OSGi </name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-osgi-runtime</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-core-spi</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.main</artifactId> + <version>1.0.4</version> + </dependency> + + + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.osgi</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.osgi*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java new file mode 100644 index 0000000000..0bbb8b707a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java @@ -0,0 +1,161 @@ +/* + * 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.contribution.osgi; + + +/** + * A weak reference to a class, which should be used to register classes + * with an ArtifactResolver and resolve these classes later. + * + * @version $Rev$ $Date$ + */ +public class BundleReference { + + /** + * The bundle. + */ + private Object bundle; + + /** + * The bundle name. + */ + private String bundleName; + + /** + * The bundle version. + */ + private String bundleVersion; + + /** + * The bundle name and version. + */ + private String bundleUniqueName; + + /** + * The bundle relative path. + */ + private String bundleRelativePath; + + /** + * Constructs a new BundleReference. + * + * @param bundle The bundle reference + * @param bundleName The bundle name + * @param bundleVersion The bundle version + * @param bundleRelativePath The relative path for the bundle + */ + public BundleReference(Object bundle, String bundleName, String bundleVersion, String bundleRelativePath) { + this.bundle = bundle; + this.bundleName = bundleName; + this.bundleVersion = bundleVersion; + this.bundleRelativePath = bundleRelativePath; + this.bundleUniqueName = bundleName + "(" + (bundleVersion == null?"0.0.0":bundleVersion) + ")"; + } + + /** + * Constructs a new BundleReference. + * + * @param bundleName The bundle name + * @param bundleVersion The bundle version + */ + public BundleReference(String bundleName, String bundleVersion) { + this.bundleName = bundleName; + this.bundleVersion = bundleVersion; + this.bundleUniqueName = bundleName + "(" + (bundleVersion == null?"0.0.0":bundleVersion) + ")"; + } + + /** + * Get the referenced bundle. + * + * @return The referenced bundle + */ + public Object getBundle() { + return bundle; + } + + /** + * Get the referenced bundle name. + * + * @return The bundle name + */ + public String getBundleName() { + return bundleName; + } + + /** + * Get the referenced bundle version. + * + * @return The bundle version + */ + public String getBundleVersion() { + return bundleVersion; + } + + /** + * Get the referenced bundle name and version. + * + * @return The bundle name + */ + public String getBundleUniqueName() { + return bundleUniqueName; + } + + /** + * Get the relative location of the bundle inside its contribution. + * + * @return The bundle path + */ + public String getBundleRelativePath() { + return bundleRelativePath; + } + + + + /** + * Returns true if the bundle reference is unresolved. + * + * @return Whether or not the bundle has been resolved + */ + public boolean isUnresolved() { + return bundle == null; + } + + @Override + public int hashCode() { + return bundleUniqueName.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof BundleReference) { + BundleReference ref = (BundleReference)obj; + return bundleName.equals(ref.bundleName) && + (bundleVersion == null || ref.bundleVersion == null || + bundleVersion.equals(ref.bundleVersion)); + } else { + return false; + } + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionProcessor.java new file mode 100644 index 0000000000..5033d7eefc --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionProcessor.java @@ -0,0 +1,161 @@ +/*
+ * 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.contribution.osgi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tuscany.sca.contribution.PackageType;
+import org.apache.tuscany.sca.contribution.processor.PackageProcessor;
+import org.apache.tuscany.sca.contribution.service.ContributionException;
+import org.apache.tuscany.sca.osgi.runtime.OSGiRuntime;
+import org.osgi.framework.Bundle;
+
+/**
+ * Bundle Contribution package processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OSGiBundleContributionProcessor implements PackageProcessor {
+
+ public OSGiBundleContributionProcessor() {
+ }
+
+ public String getPackageType() {
+ return PackageType.BUNDLE;
+ }
+
+ public URL getArtifactURL(URL sourceURL, URI artifact) throws MalformedURLException {
+ Bundle bundle = null;
+ try {
+ bundle = OSGiRuntime.findInstalledBundle(sourceURL);
+ if (bundle != null) {
+ URL url = bundle.getResource(artifact.getPath());
+ if (url == null)
+ System.out.println("Could not load resource " + artifact);
+ return url;
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public List<URI> getJarArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException,
+ IOException {
+ if (packageSourceURL == null) {
+ throw new IllegalArgumentException("Invalid null package source URL.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ // Assume the root is a jar file
+ JarInputStream jar = new JarInputStream(inputStream);
+ try {
+ Set<String> names = new HashSet<String>();
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry == null) {
+ // EOF
+ break;
+ }
+
+ // FIXME: Maybe we should externalize the filter as a property
+ String name = entry.getName();
+ if (!name.startsWith(".") && !entry.isDirectory()) {
+
+ // Trim trailing /
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
+ }
+
+ // Add the entry name
+ if (!names.contains(name) && name.length() > 0) {
+ names.add(name);
+
+ }
+ }
+ }
+
+ // Return list of URIs
+ List<URI> artifacts = new ArrayList<URI>();
+ for (String name: names) {
+ artifacts.add(URI.create(name));
+ }
+ return artifacts;
+
+ } finally {
+ jar.close();
+ }
+}
+
+ public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException,
+ IOException {
+
+ Bundle bundle = null;
+ try {
+ bundle = OSGiRuntime.findInstalledBundle(packageSourceURL);
+ } catch (Exception e) {
+ }
+
+ if (bundle == null) {
+ throw new IllegalArgumentException("Could not find OSGi bundle " + packageSourceURL);
+ }
+
+ if (packageSourceURL == null) {
+ throw new IllegalArgumentException("Invalid null package source URL.");
+ }
+
+ List<URI> artifacts = new ArrayList<URI>();
+
+ try {
+ Enumeration entries = bundle.findEntries("/", "*", true);
+ while (entries.hasMoreElements()) {
+ URL entry = (URL)entries.nextElement();
+ String entryName = entry.getPath();
+ if (entryName.startsWith("/"))
+ entryName = entryName.substring(1);
+ artifacts.add(new URI(entryName));
+
+ if (entryName.endsWith(".jar")) {
+
+ URL jarResource = bundle.getResource(entryName);
+ artifacts.addAll(getJarArtifacts(jarResource, jarResource.openStream()));
+ }
+
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return artifacts;
+ }
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java new file mode 100644 index 0000000000..b3c2302f60 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java @@ -0,0 +1,141 @@ +/* + * 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.contribution.osgi.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.osgi.BundleReference; +import org.apache.tuscany.sca.osgi.runtime.OSGiRuntime; + +/** + * OSGi bundle processor + * + * @version $Rev$ $Date$ + */ +public class OSGiBundleProcessor { + + private boolean initializedOSGi; + private OSGiRuntime osgiRuntime; + + public OSGiBundleProcessor() { + } + + public Object installContributionBundle(Contribution contribution) { + + JarInputStream jar = null; + Object bundle = null; + + try { + + URL contribURL = new URL(contribution.getLocation()); + jar = new JarInputStream(contribURL.openStream()); + + Manifest manifest = jar.getManifest(); + if (manifest != null && manifest.getMainAttributes() + .containsKey(new Attributes.Name("Bundle-SymbolicName"))) { + + initialize(); + if (osgiRuntime != null) + bundle = osgiRuntime.installBundle(contribURL.toString(), null); + } + } catch (Exception e) { + // If OSGi cannot process the jar, treat the bundle as a plain jar file. + } finally { + + try { + if (jar != null) + jar.close(); + } catch (IOException e) { + } + } + + return bundle; + } + + public BundleReference installNestedBundle(Contribution contribution, + String bundleSymbolicName, + String bundleVersion) { + + BundleReference bundleReference = null; + + initialize(); + if (osgiRuntime == null) + return null; + + List<Artifact> artifacts = contribution.getArtifacts(); + for (Artifact a : artifacts) { + if (a.getURI().endsWith(".jar")) { + + InputStream stream; + JarInputStream jar = null; + Object name; + Object version; + try { + + URL artifactURL = new URL(a.getLocation()); + stream = artifactURL.openStream(); + jar = new JarInputStream(artifactURL.openStream()); + Manifest manifest = jar.getManifest(); + name = manifest.getMainAttributes().get(new Attributes.Name("Bundle-SymbolicName")); + version = manifest.getMainAttributes().get(new Attributes.Name("Bundle-Version")); + + if (bundleSymbolicName.equals(name) && (bundleVersion == null || version == null || bundleVersion + .equals(version))) { + + Object bundle = osgiRuntime.installBundle(a.getLocation(), stream); + + bundleReference = new BundleReference(bundle, bundleSymbolicName, bundleVersion, a.getURI()); + + break; + } + + } catch (Exception e) { + + // If OSGi cannot process the jar, treat the bundle as a plain jar file. + } finally { + try { + if (jar != null) + jar.close(); + } catch (IOException e) { + } + } + } + } + return bundleReference; + } + + private void initialize() { + try { + if (!initializedOSGi) { + initializedOSGi = true; + osgiRuntime = OSGiRuntime.getRuntime(); + } + } catch (Exception e) { + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java new file mode 100644 index 0000000000..07e80f66f3 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java @@ -0,0 +1,154 @@ +/* + * 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.contribution.osgi.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.osgi.BundleReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.osgi.runtime.OSGiRuntime; +import org.osgi.framework.Bundle; + +/** + * A Model Resolver for BundleReferences. + * + * @version $Rev$ $Date$ + */ +public class OSGiBundleReferenceModelResolver implements ModelResolver { + private Contribution contribution; + private Map<String, BundleReference> map = new HashMap<String, BundleReference>(); + + OSGiRuntime osgiRuntime; + private OSGiBundleProcessor bundleProcessor; + + public OSGiBundleReferenceModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + this.contribution = contribution; + this.bundleProcessor = new OSGiBundleProcessor(); + } + + public void addModel(Object resolved) { + BundleReference bundleRef = (BundleReference)resolved; + map.put(bundleRef.getBundleUniqueName(), bundleRef); + } + + public Object removeModel(Object resolved) { + return map.remove(((BundleReference)resolved).getBundleUniqueName()); + } + + /** + * Handle artifact resolution when the specific class reference is imported from another contribution + * @param unresolved + * @return + */ + private BundleReference resolveImportedModel(BundleReference unresolved) { + BundleReference resolved = unresolved; + + if( this.contribution != null) { + for (Import import_ : this.contribution.getImports()) { + + resolved = import_.getModelResolver().resolveModel(BundleReference.class, unresolved); + if (resolved != unresolved) + break; + } + + } + return resolved; + } + + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + + if (resolved != null ){ + return modelClass.cast(resolved); + } + + try { + if (osgiRuntime == null) + osgiRuntime = OSGiRuntime.getRuntime(); + } catch (Exception e) { + } + if (osgiRuntime == null) + return unresolved; + + //Load a class on demand + Object bundle = null; + String bundleName = ((BundleReference)unresolved).getBundleName(); + String bundleVersion = ((BundleReference)unresolved).getBundleVersion(); + + bundle = osgiRuntime.findBundle(bundleName, bundleVersion); + BundleReference bundleReference; + + if (bundle == null) + bundleReference = bundleProcessor.installNestedBundle(contribution, bundleName, bundleVersion); + else { + bundleReference = new BundleReference(bundle, + ((BundleReference)unresolved).getBundleName(), + bundleVersion, + getBundleFileName(bundle) + ); + } + + + if (bundleReference != null) { + //if we load the class + + map.put(((BundleReference)unresolved).getBundleUniqueName(), bundleReference); + + // Return the resolved BundleReference + return modelClass.cast(bundleReference); + } else { + //delegate resolution of the class + resolved = this.resolveImportedModel((BundleReference)unresolved); + return modelClass.cast(resolved); + } + + + } + + + private String getBundleFileName(Object bundle) { + if (bundle instanceof Bundle) { + String path = ((Bundle)bundle).getLocation(); + if (path.endsWith("/")) + path = path.substring(0, path.length()-1); + if (path.startsWith(contribution.getLocation())) { + if (path.equals(contribution.getLocation())) { + int index = path.lastIndexOf('/'); + if (index > 0 && index < path.length()-1) + path = path.substring(index+1); + } else { + path = path.substring(contribution.getLocation().length()); + if (path.startsWith("/")) + path = path.substring(1); + } + } else if (path.lastIndexOf('/') >= 0) + path = path.substring(path.lastIndexOf('/')+1); + return path; + } + return null; + + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java new file mode 100644 index 0000000000..528a287328 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java @@ -0,0 +1,137 @@ +/* + * 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.contribution.osgi.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.osgi.runtime.OSGiRuntime; +import org.osgi.framework.Bundle; + +/** + * A Model Resolver for ClassReferences. + * + * @version $Rev$ $Date$ + */ +public class OSGiClassReferenceModelResolver implements ModelResolver { + private Contribution contribution; + private Map<String, ClassReference> map = new HashMap<String, ClassReference>(); + private Bundle bundle; + private boolean initialized; + private boolean useOSGi; + + public OSGiClassReferenceModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + this.contribution = contribution; + } + + public void addModel(Object resolved) { + ClassReference clazz = (ClassReference)resolved; + map.put(clazz.getClassName(), clazz); + } + + public Object removeModel(Object resolved) { + return map.remove(((ClassReference)resolved).getClassName()); + } + + /** + * Handle artifact resolution when the specific class reference is imported from another contribution + * @param unresolved + * @return + */ + private ClassReference resolveImportedModel(ClassReference unresolved) { + ClassReference resolved = unresolved; + + if (this.contribution != null) { + for (Import import_ : this.contribution.getImports()) { + + if (resolved == unresolved && bundle != null) { + resolved = import_.getModelResolver().resolveModel(ClassReference.class, unresolved); + if (resolved != unresolved) + break; + } + } + + } + return resolved; + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + + if (resolved != null) { + return modelClass.cast(resolved); + } + initialize(); + if (!useOSGi) + return unresolved; + + //Load a class on demand + Class clazz = null; + if (bundle != null) { + try { + clazz = bundle.loadClass(((ClassReference)unresolved).getClassName()); + } catch (Exception e) { + // we will later try to delegate to imported model resolvers + } + } + + if (clazz != null) { + //if we load the class + // Store a new ClassReference wrapping the loaded class + ClassReference classReference = new ClassReference(clazz); + map.put(getPackageName(classReference), classReference); + + // Return the resolved ClassReference + return modelClass.cast(classReference); + } else { + //delegate resolution of the class + resolved = this.resolveImportedModel((ClassReference)unresolved); + return modelClass.cast(resolved); + } + + } + + /*************** + * Helper methods + ***************/ + + private String getPackageName(ClassReference clazz) { + int pos = clazz.getClassName().lastIndexOf("."); + return clazz.getClassName().substring(0, pos - 1); + } + + private void initialize() { + if (initialized) + return; + + initialized = true; + try { + bundle = OSGiRuntime.findInstalledBundle(contribution.getLocation()); + useOSGi = bundle != null; + } catch (Throwable e) { + // Ignore errors, default to ClassReferenceModelResolver + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiImportExportListener.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiImportExportListener.java new file mode 100644 index 0000000000..15ad0bd948 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiImportExportListener.java @@ -0,0 +1,215 @@ +/* + * 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.contribution.osgi.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.HashSet; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.java.JavaExport; +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.service.ContributionListener; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; +import org.apache.tuscany.sca.osgi.runtime.OSGiRuntime; + +/** + * Namespace Import/Export contribution listener + * The listener would process all import/export from a given contribution + * and initialize the model resolvers properly + * + * @version $Rev$ $Date$ + */ +public class OSGiImportExportListener implements ContributionListener { + + private OSGiBundleProcessor bundleProcessor; + + public OSGiImportExportListener() { + bundleProcessor = new OSGiBundleProcessor(); + } + + /** + * Initialize the import/export model resolvers + * Export model resolvers are same as Contribution model resolver + * Import model resolvers are matched to a specific contribution if a location URI is specified, + * otherwise it try to resolve against all the other contributions + */ + public void contributionAdded(ContributionRepository repository, Contribution contribution) { + + OSGiRuntime osgiRuntime = null; + try { + if (bundleProcessor.installContributionBundle(contribution) == null) { + return; + } else { + osgiRuntime = OSGiRuntime.getRuntime(); + } + } catch (Exception e) { + return; + } + + HashSet<Contribution> bundlesToInstall = new HashSet<Contribution>(); + // Initialize the contribution imports + for (Import import_ : contribution.getImports()) { + boolean initialized = false; + + if (import_ instanceof JavaImport) { + JavaImport javaImport = (JavaImport)import_; + String packageName = javaImport.getPackage(); + + //Find a matching contribution + if (javaImport.getLocation() != null) { + Contribution targetContribution = repository.getContribution(javaImport.getLocation()); + if (targetContribution != null) { + + // Find a matching contribution export + for (Export export : targetContribution.getExports()) { + if (export instanceof JavaExport) { + JavaExport javaExport = (JavaExport)export; + if (packageName.equals(javaExport.getPackage())) { + + if (osgiRuntime.findBundle(targetContribution.getLocation()) == null) + bundlesToInstall.add(targetContribution); + + initialized = true; + + } + } + if (initialized) + break; + } + } + } + } + if (!initialized) { + for (Contribution c : repository.getContributions()) { + + // Go over all exports in the contribution + for (Export export : c.getExports()) { + // If the export matches our namespace, try to the resolve the model object + if (import_.match(export) && osgiRuntime.findBundle(c.getLocation()) == null) { + bundlesToInstall.add(c); + } + } + } + } + } + for (Contribution c : bundlesToInstall) { + try { + installDummyBundle(osgiRuntime, c); + } catch (Exception e) { + } + } + + } + + public void contributionRemoved(ContributionRepository repository, Contribution contribution) { + + } + + public void contributionUpdated(ContributionRepository repository, + Contribution oldContribution, + Contribution contribution) { + + } + + private void installDummyBundle(OSGiRuntime osgiRuntime, Contribution contribution) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + String EOL = System.getProperty("line.separator"); + + String bundleName = contribution.getURI(); + URL contribURL = new URL(contribution.getLocation()); + String contribName = contribURL.getPath(); + if (contribName.endsWith("/")) + contribName = contribName.substring(0, contribName.length()-1); + if (contribName.lastIndexOf("/") >= 0) + contribName = contribName.substring(contribName.lastIndexOf("/")+1); + + StringBuffer exportPackageNames = new StringBuffer(); + for (Export export : contribution.getExports()) { + if (export instanceof JavaExport) { + if (exportPackageNames.length() > 0) + exportPackageNames.append(","); + exportPackageNames.append(((JavaExport)export).getPackage()); + } + } + StringBuffer importPackageNames = new StringBuffer(); + for (Import import_ : contribution.getImports()) { + if (import_ instanceof JavaImport) { + if (importPackageNames.length() > 0) + importPackageNames.append(","); + importPackageNames.append(((JavaImport)import_).getPackage()); + } + } + + String manifestStr = + "Manifest-Version: 1.0" + EOL + + "Bundle-ManifestVersion: 2" + + EOL + + "Bundle-Name: " + + bundleName + + EOL + + "Bundle-SymbolicName: " + + bundleName + + EOL + + "Bundle-Version: " + + "1.0.0" + + EOL + + "Bundle-Localization: plugin" + + EOL; + + StringBuilder manifestBuf = new StringBuilder(); + manifestBuf.append(manifestStr); + manifestBuf.append("Export-Package: " + exportPackageNames + EOL); + manifestBuf.append("Import-Package: " + importPackageNames + EOL); + manifestBuf.append("Bundle-ClassPath: .," + contribName + EOL); + + ByteArrayInputStream manifestStream = new ByteArrayInputStream(manifestBuf.toString().getBytes()); + Manifest manifest = new Manifest(); + manifest.read(manifestStream); + + JarOutputStream jarOut = new JarOutputStream(out, manifest); + + ZipEntry ze = new ZipEntry(contribName); + jarOut.putNextEntry(ze); + InputStream stream = contribURL.openStream(); + + byte[] bytes = new byte[stream.available()]; + stream.read(bytes); + jarOut.write(bytes); + stream.close(); + + jarOut.close(); + out.close(); + + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + + osgiRuntime.installBundle("file://" + bundleName + ".jar", in); + + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiModelResolverImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiModelResolverImpl.java new file mode 100644 index 0000000000..e624b1d3b5 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiModelResolverImpl.java @@ -0,0 +1,119 @@ +/* + * 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.contribution.osgi.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.osgi.BundleReference; +import org.apache.tuscany.sca.contribution.resolver.ClassReference; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.osgi.framework.Bundle; + +/** + * An implementation of an artifact resolver for OSGi bundles. + * + * @version $Rev$ $Date$ + */ +public class OSGiModelResolverImpl implements ModelResolver { + private static final long serialVersionUID = -7826976465762296634L; + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + private Hashtable<String, Bundle> bundles; + public OSGiModelResolverImpl(Hashtable<String, Bundle> bundles) { + this.bundles = bundles; + } + + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + + // Return the resolved object + return modelClass.cast(resolved); + + } else if (unresolved instanceof ClassReference) { + + // Load a class on demand + ClassReference classReference = (ClassReference)unresolved; + Class clazz = null; + for (Bundle bundle : bundles.values()) { + try { + clazz = bundle.loadClass(classReference.getClassName()); + } catch (ClassNotFoundException e) { + continue; + } + break; + } + if (clazz == null) { + + // Return the unresolved object + return unresolved; + } + + // Store a new ClassReference wrapping the loaded class + resolved = new ClassReference(clazz); + map.put(resolved, resolved); + + // Return the resolved ClassReference + return modelClass.cast(resolved); + + } else if (unresolved instanceof BundleReference) { + for (String bundlePath: bundles.keySet()) { + Bundle bundle = bundles.get(bundlePath); + BundleReference bundleRef = (BundleReference)unresolved; + String bundleVersion = (String)bundle.getHeaders().get("Bundle-Version"); + if (bundle.getSymbolicName().equals(bundleRef.getBundleName())&& + (bundleVersion == null || bundleRef.getBundleVersion() == null || + bundleVersion.equals(bundleRef.getBundleVersion()))) { + + resolved = new BundleReference(bundle, + bundle.getSymbolicName(), + bundleVersion, + bundlePath); + map.put(resolved, resolved); + + // Return the resolved BundleReference + return modelClass.cast(resolved); + + } + } + } + + // Return the unresolved object + return unresolved; + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + + public Collection<Object> getModels() { + return map.values(); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor new file mode 100644 index 0000000000..632d135cb5 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessor @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.osgi.impl.OSGiBundleContributionProcessor;type=application/osgi.bundle
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..02e8b411eb --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.osgi.impl.OSGiBundleReferenceModelResolver;model=org.apache.tuscany.sca.contribution.osgi.BundleReference
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener new file mode 100644 index 0000000000..8dec190930 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-osgi/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.osgi.impl.OSGiImportExportListener
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-resource/pom.xml new file mode 100644 index 0000000000..52b33fc564 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/pom.xml @@ -0,0 +1,70 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-resource</artifactId> + <name>Apache Tuscany SCA Resource Import/Export Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-core-spi</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.resource</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.resource*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceExport.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceExport.java new file mode 100644 index 0000000000..0bd30c19dd --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceExport.java @@ -0,0 +1,46 @@ +/* + * 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.contribution.resource; + +import org.apache.tuscany.sca.contribution.Export; + + +/** + * The representation of an resource export. + * + * @version $Rev$ $Date$ + */ +public interface ResourceExport extends Export { + + /** + * Get Resource URI that identifies the export. + * + * @return The exported resource URI + */ + String getURI(); + + /** + * Set Resource URI that identifies the export. + * + * @param uri The exported resource URI + */ + void setURI(String uri); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImport.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImport.java new file mode 100644 index 0000000000..07eac9d843 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImport.java @@ -0,0 +1,59 @@ +/* + * 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.contribution.resource; + +import org.apache.tuscany.sca.contribution.Import; + +/** + * The representation of an resource import. + * + * @version $Rev$ $Date$ + */ +public interface ResourceImport extends Import { + + /** + * Get the location used to resolve the definitions for this import + * + * @return The import location + */ + String getLocation(); + + /** + * Set the location used to resolve the definitions for this import + * + * @param location The import location + */ + void setLocation(String location); + + /** + * Get URI that identifies the resource import + * + * @return The URI + */ + String getURI(); + + /** + * Set URI that identifies the resource import + * + * @param uri The resource URI + */ + void setURI(String uri); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImportExportFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImportExportFactory.java new file mode 100644 index 0000000000..4119c344ce --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/ResourceImportExportFactory.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.resource; + +/** + * Base Resource import/export model factory + * + * @version $Rev$ $Date$ + */ +public interface ResourceImportExportFactory { + + /** + * Create a resource import model object + * + * @return The new ResourceImport model object + */ + ResourceImport createResourceImport(); + + /** + * Create a resource export model object + * + * @return The new ResourceExport model object + */ + ResourceExport createResourceExport(); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ArtifactModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ArtifactModelResolver.java new file mode 100644 index 0000000000..e614b47fc7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ArtifactModelResolver.java @@ -0,0 +1,86 @@ +/* + * 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.contribution.resource.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; + +/** + * A Model Resolver for contribution artifacts. + * + * @version $Rev$ $Date$ + */ +public class ArtifactModelResolver implements ModelResolver { + private Contribution contribution; + private Map<String, Artifact> map = new HashMap<String, Artifact>(); + + public ArtifactModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + this.contribution = contribution; + } + + public void addModel(Object resolved) { + Artifact artifact = (Artifact)resolved; + map.put(artifact.getURI(), artifact); + } + + public Object removeModel(Object resolved) { + return map.remove(((Artifact)resolved).getURI()); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + // Get the artifact URI + String uri = ((Artifact)unresolved).getURI(); + if (uri == null) { + return (T)unresolved; + } + + // Lookup the artifact + Artifact resolved = (Artifact) map.get(uri); + if (resolved != null) { + return modelClass.cast(resolved); + } + + // If not found, delegate the resolution to the imports (in this case based on the resource imports) + for (Import import_ : this.contribution.getImports()) { + if (import_ instanceof ResourceImport) { + ResourceImport resourceImport = (ResourceImport)import_; + //check the import location against the computed package name from the componentType URI + if (resourceImport.getURI().equals(uri)) { + // Delegate the resolution to the import resolver + resolved = resourceImport.getModelResolver().resolveModel(Artifact.class, (Artifact)unresolved); + if (!resolved.isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + } + + return (T)unresolved; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportImpl.java new file mode 100644 index 0000000000..c2d525dfef --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportImpl.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.contribution.resource.impl; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; + +/** + * The representation of an export for the contribution + * + * @version $Rev$ $Date$ + */ +public class ResourceExportImpl implements ResourceExport { + /** + * The resource URI to be exported + */ + private String uri; + + private ModelResolver modelResolver; + + protected ResourceExportImpl() { + super(); + } + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportModelResolver.java new file mode 100644 index 0000000000..fd568e533d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportModelResolver.java @@ -0,0 +1,65 @@ +/* + * 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.contribution.resource.impl; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; + +/** + * A model resolver for resource exports. + * + * @version $Rev$ $Date$ + */ +public class ResourceExportModelResolver implements ModelResolver { + + private ResourceExport export; + private ModelResolver resolver; + + public ResourceExportModelResolver(ResourceExport export, ModelResolver resolver) { + this.export = export; + this.resolver = resolver; + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + // Filter based on the artifact URI + Artifact artifact = (Artifact)unresolved; + if (export.getURI().equals(artifact.getURI())) { + + // The artifact URI matches the exported URI, delegate to the + // contribution's resolver + return resolver.resolveModel(modelClass, unresolved); + } else { + + // The artifact URI is not exported, return the unresolved object + return unresolved; + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessor.java new file mode 100644 index 0000000000..68d5d4761e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessor.java @@ -0,0 +1,142 @@ +/* + * 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.contribution.resource.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; +import org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact processor for Resource export + * + * @version $Rev$ $Date$ + */ +public class ResourceExportProcessor implements StAXArtifactProcessor<ResourceExport> { + + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + private static final QName EXPORT_RESOURCE = new QName(SCA10_NS, "export.resource"); + private static final String URI = "uri"; + + private final ResourceImportExportFactory factory; + private final Monitor monitor; + + public ResourceExportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + this.factory = modelFactories.getFactory(ResourceImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-resource-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return EXPORT_RESOURCE; + } + + public Class<ResourceExport> getModelType() { + return ResourceExport.class; + } + + /** + * Process <export.resource uri=""/> + */ + public ResourceExport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + ResourceExport resourceExport = this.factory.createResourceExport(); + QName element = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <export.resource> + if (EXPORT_RESOURCE.equals(element)) { + String uri = reader.getAttributeValue(null, URI); + if (uri == null) { + error("AttributeURIMissing", reader); + //throw new ContributionReadException("Attribute 'uri' is missing"); + } else + resourceExport.setURI(uri); + } + + break; + case XMLStreamConstants.END_ELEMENT: + if (EXPORT_RESOURCE.equals(reader.getName())) { + return resourceExport; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return resourceExport; + } + + public void write(ResourceExport resourceExport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <export.resource> + writer.writeStartElement(EXPORT_RESOURCE.getNamespaceURI(), EXPORT_RESOURCE.getLocalPart()); + + if (resourceExport.getURI() != null) { + writer.writeAttribute(URI, resourceExport.getURI()); + } + + writer.writeEndElement(); + } + + public void resolve(ResourceExport resourceExport, ModelResolver resolver) throws ContributionResolveException { + + if (resourceExport.getURI() != null) + // Initialize the export's model resolver + resourceExport.setModelResolver(new ResourceExportModelResolver(resourceExport, resolver)); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportFactoryImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportFactoryImpl.java new file mode 100644 index 0000000000..880f5f5786 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportFactoryImpl.java @@ -0,0 +1,41 @@ +/* + * 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.contribution.resource.impl; + +import org.apache.tuscany.sca.contribution.resource.ResourceExport; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; +import org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory; + +/** + * Resource Import/Export model factory implementation + * + * @version $Rev$ $Date$ + */ +public class ResourceImportExportFactoryImpl implements ResourceImportExportFactory { + + public ResourceImport createResourceImport() { + return new ResourceImportImpl(); + } + + public ResourceExport createResourceExport() { + return new ResourceExportImpl(); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportListener.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportListener.java new file mode 100644 index 0000000000..e7aecad786 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportExportListener.java @@ -0,0 +1,97 @@ +/* + * 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.contribution.resource.impl; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.resolver.DefaultImportAllModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; +import org.apache.tuscany.sca.contribution.service.ContributionListener; +import org.apache.tuscany.sca.contribution.service.ContributionRepository; + +/** + * Resource Import/Export contribution listener + * The listener would process all import/export from a given contribution + * and initialize the model resolvers properly + * + * @version $Rev$ $Date$ + */ +public class ResourceImportExportListener implements ContributionListener { + + /** + * Initialize the import/export model resolvers + * Export model resolvers are same as Contribution model resolver + * Import model resolvers are matched to a specific contribution if a location URI is specified, + * otherwise it try to resolve against all the other contributions + * Also set the exporting contributions used by contribution ClassLoaders to + * match import/export for class loading. + */ + public void contributionAdded(ContributionRepository repository, Contribution contribution) { + // Initialize the contribution exports + for (Export export: contribution.getExports()) { + export.setModelResolver(contribution.getModelResolver()); + } + + // Initialize the contribution imports + for (Import import_: contribution.getImports()) { + boolean initialized = false; + + if (import_ instanceof ResourceImport) { + ResourceImport resourceImport = (ResourceImport)import_; + + // Find a matching contribution + if (resourceImport.getLocation() != null) { + Contribution targetContribution = repository.getContribution(resourceImport.getLocation()); + if (targetContribution != null) { + + // Find a matching contribution export + for (Export export: targetContribution.getExports()) { + if (export instanceof ResourceExport) { + ResourceExport resourceExport = (ResourceExport)export; + if (resourceImport.getURI().equals(resourceExport.getURI())) { + resourceImport.setModelResolver(resourceExport.getModelResolver()); + initialized = true; + break; + } + } + } + } + } + + //if no location was specified, try to resolve with any contribution + if( !initialized ) { + // Use a resolver that will consider all contributions + import_.setModelResolver(new DefaultImportAllModelResolver(import_, repository.getContributions())); + } + } + } + } + + public void contributionRemoved(ContributionRepository repository, Contribution contribution) { + + } + + public void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution) { + + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportImpl.java new file mode 100644 index 0000000000..cd33f1290f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportImpl.java @@ -0,0 +1,107 @@ +/* + * 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.contribution.resource.impl; + +import java.util.List; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; + +/** + * The representation of an import for the contribution + * + * @version $Rev$ $Date$ + */ +public class ResourceImportImpl implements ResourceImport { + /** + * The resource URI to be imported + */ + private String uri; + + private ModelResolver modelResolver; + private List<Contribution> exportContributions; + + /** + * Optional location URI pointing to a Contribution that exports the resource + */ + private String location; + + + protected ResourceImportImpl() { + super(); + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + public List<Contribution> getExportContributions() { + return exportContributions; + } + + public void setExportContributions(List<Contribution> contributions) { + this.exportContributions = contributions; + } + + /** + * Match a ResourceImport to a given ResourceExport based on : + * location is not provided + * import and export resource URI match + */ + public boolean match(Export export) { + if (export instanceof ResourceExport) { + if (this.getLocation() == null || this.getLocation().length() == 0) { + if (this.getURI().equals(((ResourceExport)export).getURI())) { + return true; + } + } + + } + return false; + } + + @Override + public String toString() { + return String.valueOf(uri); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessor.java new file mode 100644 index 0000000000..8b2fc44a1c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessor.java @@ -0,0 +1,148 @@ +/* + * 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.contribution.resource.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; +import org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Artifact processor for Namespace import + * + * @version $Rev$ $Date$ + */ +public class ResourceImportProcessor implements StAXArtifactProcessor<ResourceImport> { + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private static final QName IMPORT_RESOURCE = new QName(SCA10_NS, "import.resource"); + + private static final String URI = "uri"; + private static final String LOCATION = "location"; + + private final ResourceImportExportFactory factory; + private final Monitor monitor; + + public ResourceImportProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + this.factory = modelFactories.getFactory(ResourceImportExportFactory.class); + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-resource-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public QName getArtifactType() { + return IMPORT_RESOURCE; + } + + public Class<ResourceImport> getModelType() { + return ResourceImport.class; + } + + /** + * Process <import.resource uri="" location=""/> + */ + public ResourceImport read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + ResourceImport resourceImport = this.factory.createResourceImport(); + QName element; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + element = reader.getName(); + + // Read <import> + if (IMPORT_RESOURCE.equals(element)) { + String uri = reader.getAttributeValue(null, URI); + if (uri == null) { + error("AttributeURIMissing", reader); + //throw new ContributionReadException("Attribute 'uri' is missing"); + } else + resourceImport.setURI(uri); + + String location = reader.getAttributeValue(null, LOCATION); + if (location != null) { + resourceImport.setLocation(location); + } + } + break; + case XMLStreamConstants.END_ELEMENT: + if (IMPORT_RESOURCE.equals(reader.getName())) { + return resourceImport; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return resourceImport; + } + + public void write(ResourceImport resourceImport, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <import> + writer.writeStartElement(IMPORT_RESOURCE.getNamespaceURI(), IMPORT_RESOURCE.getLocalPart()); + + if (resourceImport.getURI() != null) { + writer.writeAttribute(URI, resourceImport.getURI()); + } + if (resourceImport.getLocation() != null) { + writer.writeAttribute(LOCATION, resourceImport.getLocation()); + } + + writer.writeEndElement(); + } + + + public void resolve(ResourceImport model, ModelResolver resolver) throws ContributionResolveException { + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..14eb81546d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,19 @@ +# 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. + +org.apache.tuscany.sca.contribution.resource.impl.ResourceImportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#import.resource,model=org.apache.tuscany.sca.contribution.resource.ResourceImport +org.apache.tuscany.sca.contribution.resource.impl.ResourceExportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#export.resource,model=org.apache.tuscany.sca.contribution.resource.ResourceExport diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..08d2b1c338 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.resource.impl.ArtifactModelResolver;model=org.apache.tuscany.sca.contribution.Artifact
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory new file mode 100644 index 0000000000..d39a5065c2 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resource.ResourceImportExportFactory @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.resource.impl.ResourceImportExportFactoryImpl
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener new file mode 100644 index 0000000000..f4751db9aa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListener @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.resource.impl.ResourceImportExportListener
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/contribution-resource-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/contribution-resource-validation-messages.properties new file mode 100644 index 0000000000..58ee8153f8 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/main/resources/contribution-resource-validation-messages.properties @@ -0,0 +1,22 @@ +# +# +# 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. +# +# +AttributeURIMissing = Attribute 'uri' is missing + diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessorTestCase.java new file mode 100644 index 0000000000..ea44cb506b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceExportProcessorTestCase.java @@ -0,0 +1,104 @@ +/* + * 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.contribution.resource.impl; + + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resource.ResourceExport; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test NamespaceExportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class ResourceExportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export.resource xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" uri=\"helloworld/HelloWorldService.componentType\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<export.resource xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null); + } + + /** + * Test loading a valid export element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + ResourceExport resourceExport = (ResourceExport)staxProcessor.read(reader); + assertEquals("helloworld/HelloWorldService.componentType", resourceExport.getURI()); + } + + /** + * Test loading an INVALID export element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributeURIMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessorTestCase.java new file mode 100644 index 0000000000..1ff931c162 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-resource/src/test/java/org/apache/tuscany/sca/contribution/resource/impl/ResourceImportProcessorTestCase.java @@ -0,0 +1,106 @@ +/* + * 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.contribution.resource.impl; + + + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resource.ResourceImport; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test NamespaceImportProcessorTestCase + * + * @version $Rev$ $Date$ + */ +public class ResourceImportProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import.resource xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" uri=\"helloworld/HelloWorldService.componentType\" location=\"sca://contributions/001\"/>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"ASCII\"?>" + + "<import.resource xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\" location=\"sca://contributions/001\"/>"; + + private XMLInputFactory inputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + inputFactory = XMLInputFactory.newInstance(); + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null); + } + + /** + * Test loading a valid import element from a contribution metadata stream + * @throws Exception + */ + public void testLoad() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + ResourceImport namespaceImport = (ResourceImport)staxProcessor.read(reader); + assertEquals("helloworld/HelloWorldService.componentType", namespaceImport.getURI()); + assertEquals("sca://contributions/001", namespaceImport.getLocation()); + } + + /** + * Test loading a INVALID import element from a contribution metadata stream + * @throws Exception + */ + public void testLoadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("readerException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributeURIMissing", problem.getMessageId()); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution-xml/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/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/tags/java/sca/1.3-RC1a/modules/contribution-xml/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution-xml/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/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/tags/java/sca/1.3-RC1a/modules/contribution-xml/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution-xml/pom.xml new file mode 100644 index 0000000000..97da855e0c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/pom.xml @@ -0,0 +1,64 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution-xml</artifactId> + <name>Apache Tuscany SCA XML Contribution Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.1</version> + <scope>runtime</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.contribution.xml</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution.xml*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java new file mode 100644 index 0000000000..256d50c191 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java @@ -0,0 +1,49 @@ +/* + * 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.contribution.xml; + +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * URLArtifactProcessor that handles sca-contribution-generated.xml files. + * + * @version $Rev$ $Date$ + */ +public class ContributionGeneratedMetadataDocumentProcessor extends ContributionMetadataDocumentProcessor { + + public ContributionGeneratedMetadataDocumentProcessor(XMLInputFactory inputFactory, + StAXArtifactProcessor staxProcessor, + Monitor monitor) { + super(inputFactory, staxProcessor, monitor); + } + + public ContributionGeneratedMetadataDocumentProcessor(ModelFactoryExtensionPoint modelFactories, + StAXArtifactProcessor staxProcessor, + Monitor monitor) { + super(modelFactories, staxProcessor, monitor); + } + + public String getArtifactType() { + return "sca-contribution-generated.xml"; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java new file mode 100644 index 0000000000..e2e97239e0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java @@ -0,0 +1,131 @@ +/* + * 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.contribution.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * URLArtifactProcessor that handles sca-contribution.xml files. + * + * @version $Rev$ $Date$ + */ +public class ContributionMetadataDocumentProcessor implements URLArtifactProcessor<ContributionMetadata>{ + private final StAXArtifactProcessor staxProcessor; + private final XMLInputFactory inputFactory; + private final Monitor monitor; + + public ContributionMetadataDocumentProcessor(XMLInputFactory inputFactory, + StAXArtifactProcessor staxProcessor, + Monitor monitor) { + this.inputFactory = inputFactory; + this.staxProcessor = staxProcessor; + this.monitor = monitor; + } + + public ContributionMetadataDocumentProcessor(ModelFactoryExtensionPoint modelFactories, + StAXArtifactProcessor staxProcessor, + Monitor monitor) { + this.inputFactory = modelFactories.getFactory(XMLInputFactory.class); + this.staxProcessor = staxProcessor; + this.monitor = monitor; + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-xml-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public String getArtifactType() { + return "sca-contribution.xml"; + } + + public Class<ContributionMetadata> getModelType() { + return ContributionMetadata.class; + } + + public ContributionMetadata read(URL contributionURL, URI uri, URL url) throws ContributionReadException { + InputStream urlStream = null; + try { + + // Create a stream reader + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + urlStream = connection.getInputStream(); + XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream); + reader.nextTag(); + + // Read the contribution model + ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader); + + return contribution; + + } catch (XMLStreamException e) { + ContributionReadException ex = new ContributionReadException(e); + error("XMLStreamException", inputFactory, ex); + throw ex; + } catch (IOException e) { + ContributionReadException ex = new ContributionReadException(e); + error("IOException", inputFactory, ex); + throw ex; + } finally { + try { + if (urlStream != null) { + urlStream.close(); + urlStream = null; + } + } catch (IOException ioe) { + //ignore + } + } + } + + public void resolve(ContributionMetadata contribution, ModelResolver resolver) throws ContributionResolveException { + staxProcessor.resolve(contribution, resolver); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java new file mode 100644 index 0000000000..3f5aacb541 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java @@ -0,0 +1,217 @@ +/* + * 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.contribution.xml; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +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.Composite; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Processor for contribution metadata + * + * @version $Rev$ $Date$ + */ +public class ContributionMetadataProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<ContributionMetadata> { + + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private static final QName CONTRIBUTION_QNAME = new QName(SCA10_NS, "contribution"); + private static final QName DEPLOYABLE_QNAME = new QName(SCA10_NS, "deployable"); + + private final AssemblyFactory assemblyFactory; + private final ContributionFactory contributionFactory; + + private final StAXArtifactProcessor<Object> extensionProcessor; + private Monitor monitor; + + public ContributionMetadataProcessor(AssemblyFactory assemblyFactory, + ContributionFactory contributionFactory, + StAXArtifactProcessor<Object> extensionProcessor, + Monitor monitor) { + this.assemblyFactory = assemblyFactory; + this.contributionFactory = contributionFactory; + this.extensionProcessor = extensionProcessor; + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-xml-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public ContributionMetadataProcessor(ModelFactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> extensionProcessor, + Monitor monitor) { + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + this.contributionFactory = modelFactories.getFactory(ContributionFactory.class); + this.extensionProcessor = extensionProcessor; + this.monitor = monitor; + } + + + public QName getArtifactType() { + return CONTRIBUTION_QNAME; + } + + public Class<ContributionMetadata> getModelType() { + return ContributionMetadata.class; + } + + public ContributionMetadata read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + ContributionMetadata contribution = null; + QName name = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + name = reader.getName(); + + if (CONTRIBUTION_QNAME.equals(name)) { + + // Read <contribution> + contribution = this.contributionFactory.createContributionMetadata(); + contribution.setUnresolved(true); + + } else if (DEPLOYABLE_QNAME.equals(name)) { + + // Read <deployable> + QName compositeName = getQName(reader, "composite"); + if (compositeName == null) { + error("AttributeCompositeMissing", reader); + //throw new ContributionReadException("Attribute 'composite' is missing"); + } else { + if (contribution != null) { + Composite composite = assemblyFactory.createComposite(); + composite.setName(compositeName); + composite.setUnresolved(true); + contribution.getDeployables().add(composite); + } + } + } else { + + // Read an extension element + Object extension = extensionProcessor.read(reader); + if (extension != null && contribution != null) { + if (extension instanceof Import) { + contribution.getImports().add((Import)extension); + } else if (extension instanceof Export) { + contribution.getExports().add((Export)extension); + } + } + } + break; + + case XMLStreamConstants.END_ELEMENT: + if (CONTRIBUTION_QNAME.equals(reader.getName())) { + return contribution; + } + break; + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + + return contribution; + } + + public void write(ContributionMetadata contribution, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException { + + // Write <contribution> + writeStartDocument(writer, CONTRIBUTION_QNAME.getNamespaceURI(), CONTRIBUTION_QNAME.getLocalPart()); + + // Write <import> + for (Import imp: contribution.getImports()) { + extensionProcessor.write(imp, writer); + } + + // Write <export> + for (Export export: contribution.getExports()) { + extensionProcessor.write(export, writer); + } + + // Write <deployable> + for (Composite deployable: contribution.getDeployables()) { + writeStart(writer, DEPLOYABLE_QNAME.getNamespaceURI(), DEPLOYABLE_QNAME.getLocalPart(), + new XAttr("composite", deployable.getName())); + writeEnd(writer); + } + + writeEndDocument(writer); + } + + public void resolve(ContributionMetadata contribution, ModelResolver resolver) throws ContributionResolveException { + + // Resolve imports and exports + for (Export export: contribution.getExports()) { + extensionProcessor.resolve(export, resolver); + } + for (Import import_: contribution.getImports()) { + extensionProcessor.resolve(import_, resolver); + } + + // Resolve deployable composites + List<Composite> deployables = contribution.getDeployables(); + for (int i = 0, n = deployables.size(); i < n; i++) { + Composite deployable = deployables.get(i); + Composite resolved = (Composite)resolver.resolveModel(Composite.class, deployable); + if (resolved != deployable) { + deployables.set(i, resolved); + } + } + + contribution.setUnresolved(false); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.java new file mode 100644 index 0000000000..f226dbbee3 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.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.contribution.xml; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A Model Resolver for Contribution models. + * + * @version $Rev$ $Date$ + */ +public class ContributionModelResolver implements ModelResolver { + + private Map<String, Contribution> map = new HashMap<String, Contribution>(); + + public ContributionModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) { + } + + public void addModel(Object resolved) { + Contribution contribution = (Contribution)resolved; + map.put(contribution.getURI(), contribution); + } + + public Object removeModel(Object resolved) { + return map.remove(((Contribution)resolved).getURI()); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + // Lookup a contribution for the given URI + String uri = ((Contribution)unresolved).getURI(); + if (uri != null) { + Contribution resolved = (Contribution) map.get(uri); + if (resolved != null) { + return modelClass.cast(resolved); + } + return unresolved; + } else { + + // If no URI was specified, just return the first contribution + if (!map.isEmpty()) { + Contribution resolved = map.values().iterator().next(); + return modelClass.cast(resolved); + } else { + return unresolved; + } + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..b73c380370 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,19 @@ +# 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 artifact processor extension +org.apache.tuscany.sca.contribution.xml.ContributionMetadataProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#contribution,model=org.apache.tuscany.sca.contribution.ContributionMetadata diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor new file mode 100644 index 0000000000..23adab56b9 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor @@ -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 artifact processor extension +org.apache.tuscany.sca.contribution.xml.ContributionMetadataDocumentProcessor;type=sca-contribution.xml,model=org.apache.tuscany.sca.contribution.ContributionMetadata +org.apache.tuscany.sca.contribution.xml.ContributionGeneratedMetadataDocumentProcessor;type=sca-contribution-generated.xml diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..68030bf6e6 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.xml.ContributionModelResolver;model=org.apache.tuscany.sca.contribution.Contribution
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties new file mode 100644 index 0000000000..3e1a0187fe --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties @@ -0,0 +1,23 @@ +# +# +# 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. +# +# +XMLStreamException = XMLStreamException occured due to: +IOException = IOException occured due to: +AttributeCompositeMissing = Attribute 'composite' is missing
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java new file mode 100644 index 0000000000..8f69f15cd1 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java @@ -0,0 +1,141 @@ +/* + * 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.contribution.xml; + +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl; +import org.apache.tuscany.sca.monitor.impl.DefaultMonitorImpl; + +/** + * Test the contribution metadata processor. + * + * @version $Rev$ $Date$ + */ + +public class ContributionMetadataProcessorTestCase extends TestCase { + + private static final String VALID_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<contribution xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\">" + + "<deployable composite=\"ns:Composite1\"/>" + + "<deployable composite=\"ns:Composite2\"/>" + + "</contribution>"; + + private static final String INVALID_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<contribution xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:ns=\"http://ns\">" + + "<deployable composite=\"ns:Composite1\"/>" + + "<deployable/>" + + "</contribution>"; + + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private StAXArtifactProcessor<Object> staxProcessor; + private Monitor monitor; + + @Override + protected void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + + inputFactory = XMLInputFactory.newInstance(); + outputFactory = XMLOutputFactory.newInstance(); + + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = new DefaultMonitorFactoryImpl(); + if (monitorFactory != null) { + monitor = monitorFactory.createMonitor(); + utilities.addUtility(monitorFactory); + } + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, null); + } + + public void testRead() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader); + assertNotNull(contribution); + assertEquals(2, contribution.getDeployables().size()); + } + + public void testReadInvalid() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML)); + /*try { + staxProcessor.read(reader); + fail("InvalidException should have been thrown"); + } catch (ContributionReadException e) { + assertTrue(true); + }*/ + staxProcessor.read(reader); + Problem problem = ((DefaultMonitorImpl)monitor).getLastLoggedProblem(); + assertNotNull(problem); + assertEquals("AttributeCompositeMissing", problem.getMessageId()); + } + + public void testWrite() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML)); + ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader); + + validateContribution(contribution); + + //write the contribution metadata contents + StringWriter stringWriter = new StringWriter(); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(stringWriter); + staxProcessor.write(contribution, writer); + stringWriter.close(); + + reader = inputFactory.createXMLStreamReader(new StringReader(stringWriter.toString())); + contribution = (ContributionMetadata)staxProcessor.read(reader); + + validateContribution(contribution); + } + + private void validateContribution(ContributionMetadata contribution) { + QName deployable; + + assertNotNull(contribution); + assertEquals(2, contribution.getDeployables().size()); + deployable = new QName("http://ns", "Composite1"); + assertEquals(deployable, contribution.getDeployables().get(0).getName()); + deployable = new QName("http://ns", "Composite2"); + assertEquals(deployable, contribution.getDeployables().get(1).getName()); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/LICENSE b/tags/java/sca/1.3-RC1a/modules/contribution/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/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/tags/java/sca/1.3-RC1a/modules/contribution/NOTICE b/tags/java/sca/1.3-RC1a/modules/contribution/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/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/tags/java/sca/1.3-RC1a/modules/contribution/pom.xml b/tags/java/sca/1.3-RC1a/modules/contribution/pom.xml new file mode 100644 index 0000000000..b4d9b5c009 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/pom.xml @@ -0,0 +1,74 @@ +<?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.3</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-contribution</artifactId> + <name>Apache Tuscany SCA Contribution Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-assembly</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-extensibility</artifactId> + <version>1.3</version> + </dependency> + + <dependency> + <groupId>stax</groupId> + <artifactId>stax-api</artifactId> + <version>1.0.1</version> + </dependency> + <dependency> + <groupId>xml-apis</groupId> + <artifactId>xml-apis</artifactId> + <version>1.3.03</version> + </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.contribution</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.contribution*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java new file mode 100644 index 0000000000..7400501d85 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Artifact.java @@ -0,0 +1,86 @@ +/* + * 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.contribution; + +import org.apache.tuscany.sca.assembly.Base; + + +/** + * Represents an artifact in an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public interface Artifact extends Base { + + /** + * Returns the URI that unique identifies the artifact inside the contribution. + * + * @return The artifact URI + */ + String getURI(); + + /** + * Sets the URI that uniquely identifies the artifact inside the contribution. + * + * @param uri The artifact URI + */ + void setURI(String uri); + + /** + * Returns the location of the artifact. + * + * @return The artifact location + */ + String getLocation(); + + /** + * Set the location of the artifact. + * + * @param location The artifact location + */ + void setLocation(String location); + + + /** + * Returns the in-memory model representing the artifact. + * + * @return The model object + */ + Object getModel(); + + /** + * Sets the in-memory model representing the artifact. + * + * @param model The model object + */ + void setModel(Object model); + + /** + * Returns the contents of the artifact cached here. + * @return the contents of the artifact + */ + byte[] getContents(); + + /** + * Sets the contents of the artifact. + * @param contents the contents of the artifact + */ + void setContents(byte[] contents); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.java new file mode 100644 index 0000000000..81b0b08b9d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContentType.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.contribution; + +/** + * Constants for the main supported contribution package type. + * + * @version $Rev$ $Date$ + */ +@Deprecated +public interface ContentType { + + /** + * Java compressed contribution package + */ + String JAR = "application/x-compressed"; + + /** + * Filesystem folder contribution package + */ + String FOLDER = "application/vnd.tuscany.folder"; + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java new file mode 100644 index 0000000000..743c2356d7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java @@ -0,0 +1,116 @@ +/* + * 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.contribution; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public interface Contribution extends Artifact { + + /** + * Default location of contribution metadata in an SCA contribution. + */ + String SCA_CONTRIBUTION_META = "META-INF/sca-contribution.xml"; + + /** + * Default location of a generated contribution metadata in an SCA contribution. + */ + String SCA_CONTRIBUTION_GENERATED_META = "META-INF/sca-contribution-generated.xml"; + + /** + * Default location of deployable composites in an SCA contribution. + */ + String SCA_CONTRIBUTION_DEPLOYABLES = "META-INF/sca-deployables/"; + + + /** + * Returns a list of exports based on the contribution metadata. + * + * @return The list of exports in this contribution + */ + List<Export> getExports(); + + /** + * Returns a list of imports based on the contribution metadata. + * + * @return The list of imports in this contribution + */ + List<Import> getImports(); + + /** + * Returns the list of deployable composites in the contribution. + * + * @return The list of deployable composites + */ + List<Composite> getDeployables(); + + /** + * Returns the list of artifacts in the contribution. + * + * @return The list of artifacts in the contribution + */ + List<Artifact> getArtifacts(); + + /** + * Returns the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @param modelResolver The model resolver + */ + void setModelResolver(ModelResolver modelResolver); + + /** + * Returns the ClassLoader used to load classes and resources from + * this contribution + * + * FIXME Remove this, the base contribution model should not depend + * on Java ClassLoaders. + * + * @return The contribution ClassLoader + */ + ClassLoader getClassLoader(); + + /** + * Sets the ClassLoader used to load classes and resources from + * this contribution + * + * FIXME Remove this, the base contribution model should not depend + * on Java ClassLoaders. + * + * @param classLoader the contribution class loader + */ + void setClassLoader(ClassLoader classLoader); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java new file mode 100644 index 0000000000..67c9a05a0b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionFactory.java @@ -0,0 +1,73 @@ +/* + * 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.contribution; + + +/** + * A factory for the contribution model. + * + * @version $Rev$ $Date$ + */ +public interface ContributionFactory { + + /** + * Create a contribution model object + * + * @return The new contribution model object + */ + Contribution createContribution(); + + /** + * Create a contribution metadata model object + * + * @return The new contribution metadata model object + */ + ContributionMetadata createContributionMetadata(); + + /** + * Create a deployedArtifact model object + * + * @return The new deployedArtifact model object + */ + @Deprecated + DeployedArtifact createDeployedArtifact(); + + /** + * Create an artifact model object + * + * @return The new artifact model object + */ + Artifact createArtifact(); + + /** + * Create a default import model object. + * + * @return the new default import model object + */ + DefaultImport createDefaultImport(); + + /** + * Create a default export model object. + * + * @return the new default export model object + */ + DefaultExport createDefaultExport(); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java new file mode 100644 index 0000000000..4043fb9eda --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ContributionMetadata.java @@ -0,0 +1,55 @@ +/* + * 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.contribution; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.assembly.Composite; + +/** + * The representation of SCA contribution metadata. + * + * @version $Rev$ $Date$ + */ +public interface ContributionMetadata extends Base { + + /** + * Returns a list of exports based on the contribution metadata. + * + * @return The list of exports + */ + List<Export> getExports(); + + /** + * Returns a list of imports based on the contribution metadata. + * + * @return The list of imports + */ + List<Import> getImports(); + + /** + * Returns the list of deployable based on the contribution metadata. + * + * @return The list of deployable composites + */ + List<Composite> getDeployables(); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.java new file mode 100644 index 0000000000..98954c288a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultContributionFactory.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.contribution; + +import org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl; + + +/** + * Default implementation of a contribution model factory. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionFactory extends ContributionFactoryImpl { + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java new file mode 100644 index 0000000000..b2eddb8336 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultExport.java @@ -0,0 +1,30 @@ +/* + * 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.contribution; + + +/** + * The representation of an export that exports all artifacts in + * a contribution. + * + * @version $Rev$ $Date$ + */ +public interface DefaultExport extends Export { +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java new file mode 100644 index 0000000000..20798dcd17 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultImport.java @@ -0,0 +1,30 @@ +/* + * 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.contribution; + + +/** + * The representation of a default import that imports artifacts from + * all contributions. + * + * @version $Rev$ $Date$ + */ +public interface DefaultImport extends Import { +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.java new file mode 100644 index 0000000000..555d25a2db --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DefaultModelFactoryExtensionPoint.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.contribution; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.HashMap; + +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + + +/** + * Default implementation of a model factory extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelFactoryExtensionPoint implements ModelFactoryExtensionPoint { + + private HashMap<Class<?>, Object> factories = new HashMap<Class<?>, Object>(); + + /** + * Constructs a new DefaultModelFactoryExtensionPoint. + */ + public DefaultModelFactoryExtensionPoint() { + } + + /** + * Add a model factory extension. + * + * @param factory The factory to add + */ + public void addFactory(Object factory) { + Class<?>[] interfaces = factory.getClass().getInterfaces(); + if (interfaces.length == 0) { + Class<?> sc = factory.getClass().getSuperclass(); + if (sc != Object.class) { + factories.put(sc, factory); + } + } else { + for (int i = 0; i<interfaces.length; i++) { + factories.put(interfaces[i], factory); + } + } + } + + /** + * Remove a model factory. + * + * @param factory The factory to remove + */ + public void removeFactory(Object factory) { + Class<?>[] interfaces = factory.getClass().getInterfaces(); + if (interfaces.length == 0) { + Class<?> sc = factory.getClass().getSuperclass(); + if (sc != Object.class) { + factories.remove(sc); + } + } else { + for (int i = 0; i<interfaces.length; i++) { + factories.remove(interfaces[i]); + } + } + } + + /** + * Get a factory implementing the given interface. + * @param factoryInterface The lookup key (factory interface) + * @return The factory + */ + public <T> T getFactory(Class<T> factoryInterface) { + Object factory = factories.get(factoryInterface); + if (factory == null) { + + if (factoryInterface.isInterface()) { + + // Dynamically load a factory class declared under META-INF/services + try { + Class<?> factoryClass = ServiceDiscovery.getInstance().loadFirstServiceClass(factoryInterface); + if (factoryClass != null) { + + try { + // Default empty constructor + Constructor<?> constructor = factoryClass.getConstructor(); + factory = constructor.newInstance(); + } catch (NoSuchMethodException e) { + + // Constructor taking the model factory extension point + Constructor<?> constructor = factoryClass.getConstructor(ModelFactoryExtensionPoint.class); + factory = constructor.newInstance(this); + } + + // Cache the loaded factory + addFactory(factory); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } else { + + // Call the newInstance static method on the factory abstract class + try { + Method newInstanceMethod = factoryInterface.getMethod("newInstance"); + factory = newInstanceMethod.invoke(null); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + + // Cache the factory + addFactory(factory); + } + } + return factoryInterface.cast(factory); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java new file mode 100644 index 0000000000..ffe190132c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/DeployedArtifact.java @@ -0,0 +1,29 @@ +/* + * 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.contribution; + +/** + * Representation of a deployed artifact + * + * @version $Rev$ $Date$ + */ +@Deprecated +public interface DeployedArtifact extends Artifact { +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java new file mode 100644 index 0000000000..bfa16b1ce3 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java @@ -0,0 +1,47 @@ +/* + * 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.contribution; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an export. + * + * @version $Rev$ $Date$ + */ +public interface Export { + + /** + * Returns the model resolver for the models representing artifacts + * made available by this export. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing artifacts + * made available by this export. + * + * @param modelResolver + */ + void setModelResolver(ModelResolver modelResolver); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java new file mode 100644 index 0000000000..35076f55a7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java @@ -0,0 +1,56 @@ +/* + * 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.contribution; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + + +/** + * The representation of an import. + * + * @version $Rev$ $Date$ + */ +public interface Import { + + /** + * Returns the model resolver for the models representing artifacts + * made available by this import. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing artifacts + * made available by this import. + * + * @param modelResolver The model resolver + */ + void setModelResolver(ModelResolver modelResolver); + + /** + * Verify that a specific export actually exports what is being imported. + * + * @param export The Exported being verified + * @return true/false + */ + boolean match(Export export); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java new file mode 100644 index 0000000000..0ada4ebec3 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/ModelFactoryExtensionPoint.java @@ -0,0 +1,54 @@ +/* + * 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.contribution; + +/** + * An extension point for model factories. Model factories are provided to + * abstract the classes that represent artifacts in the assembly model away + * from their creation mechanism. When the runtime needs to extend the model + * as it reads in contributed artifacts it looks up the factory for the + * artifact required in this registry + * + * @version $Rev$ $Date$ + */ +public interface ModelFactoryExtensionPoint { + + /** + * Add a model factory extension. + * + * @param factory The factory to add + */ + void addFactory(Object factory); + + /** + * Remove a model factory extension. + * + * @param factory The factory to remove + */ + void removeFactory(Object factory); + + /** + * Get a factory implementing the given interface. + * @param factoryInterface the lookup key (factory interface) + * @return The factory + */ + <T> T getFactory(Class<T> factoryInterface); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.java new file mode 100644 index 0000000000..c0dd5431d7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/PackageType.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution; + +/** + * Constants for the main supported contribution package types. + * + * @version $Rev$ $Date$ + */ +public interface PackageType { + + /** + * Java compressed contribution package + */ + String JAR = "application/x-compressed"; + + /** + * Filesystem folder contribution package + */ + String FOLDER = "application/vnd.tuscany.folder"; + + + String BUNDLE = "application/osgi.bundle"; + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java new file mode 100644 index 0000000000..881987f622 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ArtifactImpl.java @@ -0,0 +1,103 @@ +/* + * 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.contribution.impl; + +import org.apache.tuscany.sca.contribution.Artifact; + + +/** + * The model representing an artifact in a contribution. + * + * @version $Rev$ $Date$ + */ +class ArtifactImpl implements Artifact { + private String uri; + private String location; + private Object model; + private boolean unresolved; + private byte[] contents; + + ArtifactImpl() { + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public Object getModel() { + return model; + } + + public void setModel(Object model) { + this.model = model; + } + + public byte[] getContents() { + return contents; + } + + public void setContents(byte[] contents) { + this.contents = contents; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof Artifact) { + return uri.equals(((Artifact)obj).getURI()); + } else { + return false; + } + } + } + + @Override + public String toString() { + return "Artifact:" + uri + "\n" + + "at: " + location; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java new file mode 100644 index 0000000000..c678c2eaef --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionFactoryImpl.java @@ -0,0 +1,67 @@ +/* + * 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.contribution.impl; + +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.DefaultImport; +import org.apache.tuscany.sca.contribution.DeployedArtifact; + + +/** + * Default implementation of a contribution model factory. + * + * @version $Rev$ $Date$ + */ +public class ContributionFactoryImpl implements ContributionFactory { + + protected ContributionFactoryImpl() { + } + + public Contribution createContribution() { + return new ContributionImpl(); + } + + public ContributionMetadata createContributionMetadata() { + return new ContributionMetadataImpl(); + } + + public Artifact createArtifact() { + return new ArtifactImpl(); + } + + public DefaultExport createDefaultExport() { + return new DefaultExportImpl(); + } + + public DefaultImport createDefaultImport() { + return new DefaultImportImpl(); + } + + @Deprecated + public DeployedArtifact createDeployedArtifact() { + class DeployedArtifactImpl extends ArtifactImpl implements DeployedArtifact { + } + return new DeployedArtifactImpl(); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java new file mode 100644 index 0000000000..fc9ae607e7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java @@ -0,0 +1,154 @@ +/* + * 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.contribution.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +class ContributionImpl implements Contribution { + private String uri; + private String location; + private Object model; + private byte[] contents; + private boolean unresolved; + private List<Export> exports = new ArrayList<Export>(); + private List<Import> imports = new ArrayList<Import>(); + private List<Composite> deployables = new ArrayList<Composite>(); + private List<Artifact> artifacts = new ArrayList<Artifact>(); + private ModelResolver modelResolver; + + // FIXME remove this dependency on Java ClassLoaders + private ClassLoader classLoader; + + ContributionImpl() { + } + + public String getLocation() { + return this.location; + } + + public void setLocation(String location) { + this.location = location; + } + + //FIXME Remove dependency on Java ClassLoaders + public ClassLoader getClassLoader() { + return classLoader; + } + + //FIXME Remove dependency on Java ClassLoaders + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + + public String getURI() { + return this.uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public Object getModel() { + return model; + } + + public void setModel(Object model) { + this.model = model; + } + + public byte[] getContents() { + return contents; + } + + public void setContents(byte[] contents) { + this.contents = contents; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + public List<Export> getExports() { + return exports; + } + + public List<Import> getImports() { + return imports; + } + + public List<Composite> getDeployables() { + return deployables; + } + + public List<Artifact> getArtifacts() { + return artifacts; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof Artifact) { + return uri.equals(((Artifact)obj).getURI()); + } else { + return false; + } + } + } + + @Override + public String toString() { + return "Contribution : " + uri + " \n" + + "from: " + location; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.java new file mode 100644 index 0000000000..75b12b1260 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionMetadataImpl.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.contribution.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.ContributionMetadata; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; + +/** + * The representation of a deployed contribution + * + * @version $Rev$ $Date$ + */ +class ContributionMetadataImpl implements ContributionMetadata { + private boolean unresolved; + private List<Export> exports = new ArrayList<Export>(); + private List<Import> imports = new ArrayList<Import>(); + private List<Composite> deployables = new ArrayList<Composite>(); + + ContributionMetadataImpl() { + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public List<Export> getExports() { + return exports; + } + + public List<Import> getImports() { + return imports; + } + + public List<Composite> getDeployables() { + return deployables; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java new file mode 100644 index 0000000000..e67395337a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultExportImpl.java @@ -0,0 +1,45 @@ +/* + * 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.contribution.impl; + +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an export for the contribution + * + * @version $Rev$ $Date$ + */ +public class DefaultExportImpl implements DefaultExport { + private ModelResolver modelResolver; + + protected DefaultExportImpl() { + super(); + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java new file mode 100644 index 0000000000..17c09f2cbc --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/impl/DefaultImportImpl.java @@ -0,0 +1,55 @@ +/* + * 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.contribution.impl; + +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.DefaultImport; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * The representation of an import for the contribution + * + * @version $Rev$ $Date$ + */ +public class DefaultImportImpl implements DefaultImport { + private ModelResolver modelResolver; + + protected DefaultImportImpl() { + super(); + } + + public ModelResolver getModelResolver() { + return modelResolver; + } + + public void setModelResolver(ModelResolver modelResolver) { + this.modelResolver = modelResolver; + } + + + public boolean match(Export export) { + if (export instanceof DefaultExport) { + return true; + } + return false; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java new file mode 100644 index 0000000000..b5f536c431 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java @@ -0,0 +1,48 @@ +/* + * 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.contribution.processor; + +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; + +/** + * Base interface for artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactProcessor<M> { + + /** + * Resolve references from this model to other models. For example references + * from a composite to another one, or references from a composite to a WSDL + * model. + * + * @param model The model to resolve + * @param resolver The resolver to use to resolve referenced models + */ + void resolve(M model, ModelResolver resolver) throws ContributionResolveException; + + /** + * Returns the type of model handled by this artifact processor. + * + * @return The type of model handled by this artifact processor + */ + Class<M> getModelType(); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..029df61f0f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessorExtensionPoint.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.contribution.processor; + +/** + * An extension point for artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface ArtifactProcessorExtensionPoint<P extends ArtifactProcessor> { + + /** + * Add an artifact processor. + * + * @param artifactProcessor The artifact processor to add + */ + void addArtifactProcessor(P artifactProcessor); + + /** + * Remove an artifact processor. + * + * @param artifactProcessor The artifact processor to remove + */ + void removeArtifactProcessor(P artifactProcessor); + + /** + * Returns the processor associated with the given artifact type. + * + * @param artifactType An artifact type + * @return The processor associated with the given artifact type + */ + P getProcessor(Object artifactType); + + /** + * Returns the processor associated with the given model type. + * + * @param modelType A model type + * @return The processor associated with the given model type + */ + P getProcessor(Class<?> modelType); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java new file mode 100644 index 0000000000..68a73945c5 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java @@ -0,0 +1,519 @@ +/* + * 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.contribution.processor; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + + +/** + * A base class with utility methods for the other artifact processors in this module. + * + * @version $Rev$ $Date$ + */ +public abstract class BaseStAXArtifactProcessor { + + /** + * Returns a QName from a string. + * @param reader + * @param value + * @return + */ + protected QName getQNameValue(XMLStreamReader reader, String value) { + if (value != null) { + int index = value.indexOf(':'); + String prefix = index == -1 ? "" : value.substring(0, index); + String localName = index == -1 ? value : value.substring(index + 1); + String ns = reader.getNamespaceContext().getNamespaceURI(prefix); + if (ns == null) { + ns = ""; + } + return new QName(ns, localName, prefix); + } else { + return null; + } + } + + /** + * Returns the boolean value of an attribute. + * @param reader + * @param name + * @return + */ + protected boolean getBoolean(XMLStreamReader reader, String name) { + String value = reader.getAttributeValue(null, name); + if (value == null) { + return false; + } + return Boolean.valueOf(value); + } + + /** + * Returns the QName value of an attribute. + * @param reader + * @param name + * @return + */ + protected QName getQName(XMLStreamReader reader, String name) { + String qname = reader.getAttributeValue(null, name); + return getQNameValue(reader, qname); + } + + /** + * Returns the value of an attribute as a list of QNames. + * @param reader + * @param name + * @return + */ + protected List<QName> getQNames(XMLStreamReader reader, String name) { + String value = reader.getAttributeValue(null, name); + if (value != null) { + List<QName> qnames = new ArrayList<QName>(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + qnames.add(getQName(reader, tokens.nextToken())); + } + return qnames; + } else { + return Collections.emptyList(); + } + } + + /** + * Returns the string value of an attribute. + * @param reader + * @param name + * @return + */ + protected String getString(XMLStreamReader reader, String name) { + return reader.getAttributeValue(null, name); + } + + /** + * Test if an attribute is explicitly set + * @param reader + * @param name + * @return + */ + protected boolean isSet(XMLStreamReader reader, String name) { + return reader.getAttributeValue(null, name) != null; + } + + /** + * Returns the value of xsi:type attribute + * @param reader The XML stream reader + * @return The QName of the type, if the attribute is not present, null is + * returned. + */ + protected QName getXSIType(XMLStreamReader reader) { + String qname = reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); + return getQNameValue(reader, qname); + } + + /** + * Parse the next child element. + * @param reader + * @return + * @throws XMLStreamException + */ + protected boolean nextChildElement(XMLStreamReader reader) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); + if (event == END_ELEMENT) { + return false; + } + if (event == START_ELEMENT) { + return true; + } + } + return false; + } + + /** + * Advance the stream to the next END_ELEMENT event skipping any nested + * content. + * @param reader the reader to advance + * @throws XMLStreamException if there was a problem reading the stream + */ + protected void skipToEndElement(XMLStreamReader reader) throws XMLStreamException { + int depth = 0; + while (reader.hasNext()) { + int event = reader.next(); + if (event == XMLStreamConstants.START_ELEMENT) { + depth++; + } else if (event == XMLStreamConstants.END_ELEMENT) { + if (depth == 0) { + return; + } + depth--; + } + } + } + + /** + * + * @param writer + * @param uri + * @throws XMLStreamException + */ + private String writeElementPrefix(XMLStreamWriter writer, String uri) throws XMLStreamException { + if (uri == null) { + return null; + } + String prefix = writer.getPrefix(uri); + if (prefix != null) { + return null; + } else { + + // Find an available prefix and bind it to the given URI + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + return prefix; + } + + } + + /** + * Start an element. + * @param uri + * @param name + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException { + String prefix = writeElementPrefix(writer, uri); + writer.writeStartElement(uri, name); + if (prefix != null){ + writer.writeNamespace(prefix,uri); + } + writeAttributePrefixes(writer, attrs); + writeAttributes(writer, attrs); + } + + /** + * Start an element. + * @param qname + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException { + writeStart(writer, qname.getNamespaceURI(), qname.getLocalPart(), attrs); + } + + /** + * End an element. + * @param writer + * @throws XMLStreamException + */ + protected void writeEnd(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndElement(); + } + + /** + * Start a document. + * @param writer + * @throws XMLStreamException + */ + protected void writeStartDocument(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException { + writer.writeStartDocument(); + writer.setDefaultNamespace(uri); + writeStart(writer, uri, name, attrs); + writer.writeDefaultNamespace(uri); + } + + /** + * Start a document. + * @param writer + * @param qname + * @param attrs + * @throws XMLStreamException + */ + protected void writeStartDocument(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException { + writeStartDocument(writer, qname.getNamespaceURI(), qname.getLocalPart(), attrs); + } + + /** + * End a document. + * @param writer + * @throws XMLStreamException + */ + protected void writeEndDocument(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndDocument(); + } + + /** + * Write attributes to the current element. + * @param writer + * @param attrs + * @throws XMLStreamException + */ + protected void writeAttributes(XMLStreamWriter writer, XAttr... attrs) throws XMLStreamException { + for (XAttr attr : attrs) { + if (attr != null) + attr.write(writer); + } + } + + /** + * Write attribute prefixes to the current element. + * @param writer + * @param attrs + * @throws XMLStreamException + */ + protected void writeAttributePrefixes(XMLStreamWriter writer, XAttr... attrs) throws XMLStreamException { + for (XAttr attr : attrs) { + if (attr != null) + attr.writePrefix(writer); + } + } + + /** + * Represents an XML attribute that needs to be written to a document. + */ + public static class XAttr { + + private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0"; + + private String uri = SCA10_NS; + private String name; + private Object value; + + public XAttr(String uri, String name, String value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, String value) { + this(null, name, value); + } + + public XAttr(String uri, String name, List<?> values) { + this.uri = uri; + this.name = name; + this.value = values; + } + + public XAttr(String name, List<?> values) { + this(null, name, values); + } + + public XAttr(String uri, String name, Boolean value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, Boolean value) { + this(null, name, value); + } + + public XAttr(String uri, String name, QName value) { + this.uri = uri; + this.name = name; + this.value = value; + } + + public XAttr(String name, QName value) { + this(null, name, value); + } + + /** + * Writes a string from a QName and registers a prefix for its namespace. + * @param reader + * @param value + * @return + */ + private String writeQNameValue(XMLStreamWriter writer, QName qname) throws XMLStreamException { + if (qname != null) { + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + prefix = writer.getPrefix(uri); + if (prefix != null) { + + // Use the prefix already bound to the given URI + if (prefix.length() > 0) { + return prefix + ":" + qname.getLocalPart(); + } else { + + // Empty prefix, just return the local part of the given qname + return qname.getLocalPart(); + } + + } else { + + // Find an available prefix and bind it to the given URI + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + writer.writeNamespace(prefix, uri); + return prefix + ":" + qname.getLocalPart(); + } + } else { + return null; + } + } + + /** + * Registers a prefix for the namespace of a QName. + * @param reader + * @param value + * @return + */ + private void writeQNamePrefix(XMLStreamWriter writer, QName qname) throws XMLStreamException { + if (qname != null) { + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + prefix = writer.getPrefix(uri); + if (prefix != null) { + return; + } else { + + // Find an available prefix and bind it to the given URI + NamespaceContext nsc = writer.getNamespaceContext(); + for (int i=1; ; i++) { + prefix = "ns" + i; + if (nsc.getNamespaceURI(prefix) == null) { + break; + } + } + writer.setPrefix(prefix, uri); + writer.writeNamespace(prefix, uri); + } + } + } + + /** + * Write to document + * @param writer + * @throws XMLStreamException + */ + public void write(XMLStreamWriter writer) throws XMLStreamException { + String str; + if (value instanceof QName) { + + // Write a QName + str = writeQNameValue(writer, (QName)value); + + } else if (value instanceof List) { + + // Write a list of values + List<?> values = (List<?>)value; + if (values.isEmpty()) { + return; + } + StringBuffer buffer = new StringBuffer(); + for (Object v: values) { + if (v == null) { + // Skip null values + continue; + } + + if (v instanceof XAttr) { + // Write an XAttr value + ((XAttr)v).write(writer); + continue; + } + + if (buffer.length() != 0) { + buffer.append(' '); + } + if (v instanceof QName) { + // Write a QName value + buffer.append(writeQNameValue(writer, (QName)v)); + } else { + // Write value as a string + buffer.append(String.valueOf(v)); + } + } + str = buffer.toString(); + + } else { + + // Write a string + if (value == null) { + return; + } + str = String.valueOf(value); + } + if (str.length() == 0) { + return; + } + + // Write the attribute + if (uri != null && !uri.equals(SCA10_NS)) { + writer.writeAttribute(uri, name, str); + } else { + writer.writeAttribute(name,str); + } + } + + /** + * Registers a prefix for the namespace of a QName or list of QNames + * @param writer + * @throws XMLStreamException + */ + public void writePrefix(XMLStreamWriter writer) throws XMLStreamException { + if (value instanceof QName) { + + // Write prefix for a single QName value + writeQNamePrefix(writer, (QName)value); + + } else if (value instanceof List) { + + // Write prefixes for a list of values + for (Object v: (List<?>)value) { + if (v instanceof QName) { + // Write prefix for a QName value + writeQNamePrefix(writer, (QName)v); + + } else if (v instanceof XAttr) { + // Write prefix for an XAttr value + ((XAttr)v).writePrefix(writer); + } + } + } + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..3c67a8c550 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java @@ -0,0 +1,66 @@ +/* + * 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.contribution.processor; + +import java.util.HashMap; +import java.util.Map; + +/** + * The default implementation of an artifact processor extension point. + * + * @version $Rev$ $Date$ + */ +abstract class DefaultArtifactProcessorExtensionPoint<P> { + protected final Map<Object, P> processorsByArtifactType = new HashMap<Object, P>(); + protected final Map<Class<?>, P> processorsByModelType = new HashMap<Class<?>, P>(); + + /** + * Constructs a new loader registry. + */ + DefaultArtifactProcessorExtensionPoint() { + } + + /** + * Returns the processor associated with the given artifact type. + * + * @param artifactType An artifact type + * @return The processor associated with the given artifact type + */ + public P getProcessor(Object artifactType) { + return processorsByArtifactType.get(artifactType); + } + + /** + * Returns the processor associated with the given model type. + * + * @param modelType A model type + * @return The processor associated with the given model type + */ + public P getProcessor(Class<?> modelType) { + Class<?>[] classes = modelType.getInterfaces(); + for (Class<?> c : classes) { + P processor = processorsByModelType.get(c); + if (processor != null) { + return processor; + } + } + return processorsByModelType.get(modelType); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java new file mode 100644 index 0000000000..426d7beb29 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultPackageProcessorExtensionPoint.java @@ -0,0 +1,129 @@ +/* + * 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.contribution.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of a package processor extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultPackageProcessorExtensionPoint implements PackageProcessorExtensionPoint { + + private Map<String, PackageProcessor> processors = new HashMap<String, PackageProcessor>(); + private boolean loaded; + + public DefaultPackageProcessorExtensionPoint() { + } + + public void addPackageProcessor(PackageProcessor processor) { + processors.put(processor.getPackageType(), processor); + } + + public void removePackageProcessor(PackageProcessor processor) { + processors.remove(processor.getPackageType()); + } + + public PackageProcessor getPackageProcessor(String contentType) { + loadProcessors(); + return processors.get(contentType); + } + + private void loadProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(PackageProcessor.class); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (ServiceDeclaration processorDeclaration: processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + + // Load a URL artifact processor + String packageType = attributes.get("type"); + + // Create a processor wrapper and register it + PackageProcessor processor = new LazyPackageProcessor(packageType, processorDeclaration); + addPackageProcessor(processor); + } + + loaded = true; + } + + /** + * A facade for package processors. + */ + private static class LazyPackageProcessor implements PackageProcessor { + + private ServiceDeclaration processorDeclaration; + private String packageType; + private PackageProcessor processor; + + private LazyPackageProcessor(String packageType, ServiceDeclaration processorDeclaration) { + this.processorDeclaration = processorDeclaration; + this.packageType = packageType; + } + + public URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException { + return getProcessor().getArtifactURL(packageSourceURL, artifact); + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, IOException { + return getProcessor().getArtifacts(packageSourceURL, inputStream); + } + + public String getPackageType() { + return packageType; + } + + @SuppressWarnings("unchecked") + private PackageProcessor getProcessor() { + if (processor == null) { + try { + Class<PackageProcessor> processorClass = (Class<PackageProcessor>)processorDeclaration.loadClass(); + Constructor<PackageProcessor> constructor = processorClass.getConstructor(); + processor = constructor.newInstance(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return processor; + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..bfd0be4541 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java @@ -0,0 +1,368 @@ +/* + * 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.contribution.processor; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.Map; +import java.util.Set; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +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.builder.impl.ProblemImpl; +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.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * The default implementation of an extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public class DefaultStAXArtifactProcessorExtensionPoint extends + DefaultArtifactProcessorExtensionPoint<StAXArtifactProcessor> implements StAXArtifactProcessorExtensionPoint { + + private ExtensionPointRegistry extensionPoints; + private ModelFactoryExtensionPoint modelFactories; + private MonitorFactory monitorFactory; + private boolean loaded; + private StAXArtifactProcessor<Object> extensibleStAXProcessor; + private Monitor monitor = null; + + /** + * Constructs a new extension point. + */ + public DefaultStAXArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + this.modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + UtilityExtensionPoint utilities = this.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) + this.monitor = monitorFactory.createMonitor(); + this.extensibleStAXProcessor = new ExtensibleStAXArtifactProcessor(this, inputFactory, outputFactory, this.monitor); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public void addArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + } + + public void removeArtifactProcessor(StAXArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.remove(artifactProcessor.getModelType()); + } + } + + @Override + public StAXArtifactProcessor getProcessor(Class<?> modelType) { + loadArtifactProcessors(); + return super.getProcessor(modelType); + } + + @Override + public StAXArtifactProcessor getProcessor(Object artifactType) { + loadArtifactProcessors(); + return super.getProcessor(artifactType); + } + + /** + * Returns a QName object from a QName expressed as {ns}name + * or ns#name. + * + * @param qname + * @return + */ + private static QName getQName(String qname) { + if (qname == null) { + return null; + } + qname = qname.trim(); + if (qname.startsWith("{")) { + int h = qname.indexOf('}'); + if (h != -1) { + return new QName(qname.substring(1, h), qname.substring(h + 1)); + } + } else { + int h = qname.indexOf('#'); + if (h != -1) { + return new QName(qname.substring(0, h), qname.substring(h + 1)); + } + } + throw new IllegalArgumentException("Invalid qname: "+qname); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private void loadArtifactProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(StAXArtifactProcessor.class); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", extensibleStAXProcessor, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration : processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + + // Load a StAX artifact processor + + // Get the model QName + QName artifactType = getQName(attributes.get("qname")); + + // Get the model class name + String modelTypeName = attributes.get("model"); + + // Get the model factory class name + String factoryName = attributes.get("factory"); + + // Create a processor wrapper and register it + StAXArtifactProcessor processor = + new LazyStAXArtifactProcessor(artifactType, modelTypeName, factoryName, + processorDeclaration, extensionPoints, modelFactories, + extensibleStAXProcessor, monitor); + addArtifactProcessor(processor); + } + + loaded = true; + } + + /** + * A wrapper around an Artifact processor class allowing lazy loading and + * initialization of artifact processors. + */ + private static class LazyStAXArtifactProcessor implements StAXArtifactProcessor { + + private ExtensionPointRegistry extensionPoints; + private QName artifactType; + private String modelTypeName; + private String factoryName; + private ServiceDeclaration processorDeclaration; + private StAXArtifactProcessor processor; + private Class<?> modelType; + private StAXArtifactProcessor<Object> extensionProcessor; + private Monitor monitor; + + LazyStAXArtifactProcessor(QName artifactType, + String modelTypeName, + String factoryName, + ServiceDeclaration processorDeclaration, + ExtensionPointRegistry extensionPoints, + ModelFactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> extensionProcessor, + Monitor monitor) { + + this.extensionPoints = extensionPoints; + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.factoryName = factoryName; + this.processorDeclaration = processorDeclaration; + this.extensionProcessor = extensionProcessor; + this.monitor = monitor; + } + + public QName getArtifactType() { + return artifactType; + } + + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + private StAXArtifactProcessor getProcessor() { + if (processor == null) { + + if (processorDeclaration.getClassName() + .equals("org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor")) { + + // Specific initialization for the DefaultBeanModelProcessor + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + PolicyFactory policyFactory = modelFactories.getFactory(PolicyFactory.class); + try { + Class<StAXArtifactProcessor> processorClass = + (Class<StAXArtifactProcessor>)processorDeclaration.loadClass(); + Object modelFactory; + if (factoryName != null) { + Class<?> factoryClass = (Class<?>)processorDeclaration.loadClass(factoryName); + modelFactory = modelFactories.getFactory(factoryClass); + } else { + modelFactory = null; + } + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(AssemblyFactory.class, + PolicyFactory.class, + QName.class, + Class.class, + Object.class, + Monitor.class); + processor = + constructor.newInstance(assemblyFactory, + policyFactory, + artifactType, + getModelType(), + modelFactory, + monitor); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } else { + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + + // Load and instantiate the processor class + try { + Class<StAXArtifactProcessor> processorClass = + (Class<StAXArtifactProcessor>)processorDeclaration.loadClass(); + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ModelFactoryExtensionPoint.class, Monitor.class); + processor = constructor.newInstance(modelFactories, monitor); + } catch (NoSuchMethodException e) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, monitor); + } catch (NoSuchMethodException e1) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ModelFactoryExtensionPoint.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor, monitor); + } catch (NoSuchMethodException e2) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor, monitor); + } catch (NoSuchMethodException e3) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ModelFactoryExtensionPoint.class); + processor = constructor.newInstance(modelFactories); + } catch (NoSuchMethodException e4) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class); + processor = constructor.newInstance(extensionPoints); + } catch (NoSuchMethodException e4a) { + try { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ModelFactoryExtensionPoint.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(modelFactories, extensionProcessor); + } catch (NoSuchMethodException e5) { + Constructor<StAXArtifactProcessor> constructor = + processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class); + processor = constructor.newInstance(extensionPoints, extensionProcessor); + } + } + } + } + } + } + } + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } + } + return processor; + } + + public Object read(XMLStreamReader inputSource) throws ContributionReadException, XMLStreamException { + return getProcessor().read(inputSource); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, + XMLStreamException { + getProcessor().write(model, outputSource); + } + + public Class<?> getModelType() { + if (modelTypeName != null && modelType == null) { + try { + modelType = processorDeclaration.loadClass(modelTypeName); + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processorDeclaration, ie); + throw ie; + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..b27404271e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java @@ -0,0 +1,242 @@ +/* + * 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.contribution.processor; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URI; +import java.net.URL; +import java.util.Map; +import java.util.Set; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +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.ContributionResolveException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + + +/** + * The default implementation of a URL artifact processor extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultURLArtifactProcessorExtensionPoint + extends DefaultArtifactProcessorExtensionPoint<URLArtifactProcessor> + implements URLArtifactProcessorExtensionPoint { + + private ExtensionPointRegistry extensionPoints; + private StAXArtifactProcessor<?> staxProcessor; + private boolean loaded; + private Monitor monitor = null; + + /** + * Constructs a new extension point. + */ + public DefaultURLArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + ModelFactoryExtensionPoint modelFactories = this.extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + UtilityExtensionPoint utilities = this.extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) + this.monitor = monitorFactory.createMonitor(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, this.monitor); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + public void addArtifactProcessor(URLArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor); + } + } + + public void removeArtifactProcessor(URLArtifactProcessor artifactProcessor) { + if (artifactProcessor.getArtifactType() != null) { + processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType()); + } + if (artifactProcessor.getModelType() != null) { + processorsByModelType.remove(artifactProcessor.getModelType()); + } + } + + @Override + public URLArtifactProcessor getProcessor(Class<?> modelType) { + loadProcessors(); + return super.getProcessor(modelType); + } + + @Override + public URLArtifactProcessor getProcessor(Object artifactType) { + loadProcessors(); + return super.getProcessor(artifactType); + } + + /** + * Lazily load artifact processors registered in the extension point. + */ + private void loadProcessors() { + if (loaded) + return; + + // Get the processor service declarations + Set<ServiceDeclaration> processorDeclarations; + try { + processorDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(URLArtifactProcessor.class); + } catch (IOException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", staxProcessor, ie); + throw ie; + } + + for (ServiceDeclaration processorDeclaration: processorDeclarations) { + Map<String, String> attributes = processorDeclaration.getAttributes(); + // Load a URL artifact processor + String artifactType = attributes.get("type"); + String modelTypeName = attributes.get("model"); + + // Create a processor wrapper and register it + URLArtifactProcessor processor = new LazyURLArtifactProcessor(artifactType, modelTypeName, + processorDeclaration, extensionPoints, staxProcessor, monitor); + addArtifactProcessor(processor); + } + + loaded = true; + } + + /** + * A wrapper around an Artifact processor class allowing lazy loading and + * initialization of artifact processors. + */ + private static class LazyURLArtifactProcessor implements URLArtifactProcessor { + + private ExtensionPointRegistry extensionPoints; + private String artifactType; + private String modelTypeName; + private ServiceDeclaration processorDeclaration; + private URLArtifactProcessor processor; + private Class<?> modelType; + private StAXArtifactProcessor<?> staxProcessor; + private Monitor monitor; + + LazyURLArtifactProcessor(String artifactType, + String modelTypeName, + ServiceDeclaration processorDeclaration, + ExtensionPointRegistry extensionPoints, + StAXArtifactProcessor<?> staxProcessor, + Monitor monitor) { + this.artifactType = artifactType; + this.modelTypeName = modelTypeName; + this.processorDeclaration = processorDeclaration; + this.extensionPoints = extensionPoints; + this.staxProcessor = staxProcessor; + this.monitor = monitor; + } + + public String getArtifactType() { + return artifactType; + } + + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + private URLArtifactProcessor getProcessor() { + if (processor == null) { + try { + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + Class<URLArtifactProcessor> processorClass = (Class<URLArtifactProcessor>)processorDeclaration.loadClass(); + try { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(ModelFactoryExtensionPoint.class, Monitor.class); + processor = constructor.newInstance(modelFactories, monitor); + } catch (NoSuchMethodException e) { + try { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(ModelFactoryExtensionPoint.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(modelFactories, staxProcessor, monitor); + } catch (NoSuchMethodException e2) { + Constructor<URLArtifactProcessor> constructor = processorClass.getConstructor(ExtensionPointRegistry.class, StAXArtifactProcessor.class, Monitor.class); + processor = constructor.newInstance(extensionPoints, staxProcessor, monitor); + } + } + } catch (Exception e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processor, ie); + throw ie; + } + } + return processor; + } + + public Object read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException { + return getProcessor().read(contributionURL, artifactURI, artifactURL); + } + + public Class<?> getModelType() { + if (modelTypeName != null && modelType == null) { + try { + modelType = processorDeclaration.loadClass(modelTypeName); + } catch (ClassNotFoundException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", processorDeclaration, ie); + throw ie; + } + } + return modelType; + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + getProcessor().resolve(model, resolver); + } + + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java new file mode 100644 index 0000000000..f237ba69f2 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java @@ -0,0 +1,289 @@ +/* + * 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.contribution.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.List; + +import javax.xml.XMLConstants; +import javax.xml.stream.EventFilter; +import javax.xml.stream.StreamFilter; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLReporter; +import javax.xml.stream.XMLResolver; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.XMLEventAllocator; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Default implementation of an XMLInputFactory that creates validating + * XMLStreamReaders. + * + * @version $Rev$ $Date$ + */ +public class DefaultValidatingXMLInputFactory extends ValidatingXMLInputFactory { + + private XMLInputFactory inputFactory; + private ValidationSchemaExtensionPoint schemas; + private Monitor monitor; + private boolean initialized; + private boolean hasSchemas; + private Schema aggregatedSchema; + + /** + * Constructs a new XMLInputFactory. + * + * @param inputFactory + * @param schemas + */ + public DefaultValidatingXMLInputFactory(XMLInputFactory inputFactory, ValidationSchemaExtensionPoint schemas, Monitor monitor) { + this.inputFactory = inputFactory; + this.schemas = schemas; + this.monitor = monitor; + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + /** + * Initialize the registered schemas and create an aggregated schema for + * validation. + */ + private void initializeSchemas() { + if (initialized) { + return; + } + initialized = true; + + // Load the XSDs registered in the validation schema extension point + try { + List<String> uris = schemas.getSchemas(); + int n = uris.size(); + if (n ==0) { + return; + } else { + hasSchemas = true; + } + final Source[] sources = new Source[n]; + for (int i =0; i < n; i++) { + final String uri = uris.get(i); + // Allow privileged access to open URL stream. Requires FilePermission in security policy. + final URL url = new URL( uri ); + InputStream urlStream; + try { + urlStream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() { + public InputStream run() throws IOException { + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", url, (IOException)e.getException()); + throw (IOException)e.getException(); + } + sources[i] = new StreamSource(urlStream, uri); + } + + // Create an aggregated validation schemas from all the XSDs + final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + // Allow privileged access to check files. Requires FilePermission + // in security policy. + try { + aggregatedSchema = AccessController.doPrivileged(new PrivilegedExceptionAction<Schema>() { + public Schema run() throws SAXException { + return schemaFactory.newSchema(sources); + } + }); + } catch (PrivilegedActionException e) { + error("PrivilegedActionException", schemaFactory, (SAXException)e.getException()); + throw (SAXException)e.getException(); + } + + } catch (Error e) { + // FIXME Log this, some old JDKs don't support XMLSchema validation + //e.printStackTrace(); + } catch (SAXParseException e) { + IllegalStateException ie = new IllegalStateException(e); + error("IllegalStateException", schemas, ie); + throw ie; + } catch (Exception e) { + //FIXME Log this, some old JDKs don't support XMLSchema validation + e.printStackTrace(); + } + } + + public XMLEventReader createFilteredReader(XMLEventReader arg0, EventFilter arg1) throws XMLStreamException { + return inputFactory.createFilteredReader(arg0, arg1); + } + + public XMLStreamReader createFilteredReader(XMLStreamReader arg0, StreamFilter arg1) throws XMLStreamException { + return inputFactory.createFilteredReader(arg0, arg1); + } + + public XMLEventReader createXMLEventReader(InputStream arg0, String arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + public XMLEventReader createXMLEventReader(InputStream arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + public XMLEventReader createXMLEventReader(Reader arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + public XMLEventReader createXMLEventReader(Source arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + public XMLEventReader createXMLEventReader(String arg0, InputStream arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + public XMLEventReader createXMLEventReader(String arg0, Reader arg1) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0, arg1); + } + + public XMLEventReader createXMLEventReader(XMLStreamReader arg0) throws XMLStreamException { + return inputFactory.createXMLEventReader(arg0); + } + + public XMLStreamReader createXMLStreamReader(InputStream arg0, String arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + }else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + public XMLStreamReader createXMLStreamReader(InputStream arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + public XMLStreamReader createXMLStreamReader(Reader arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + public XMLStreamReader createXMLStreamReader(Source arg0) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0); + } + } + + public XMLStreamReader createXMLStreamReader(String arg0, InputStream arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + public XMLStreamReader createXMLStreamReader(String arg0, Reader arg1) throws XMLStreamException { + initializeSchemas(); + if (hasSchemas) { + return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema, monitor); + } else { + return inputFactory.createXMLStreamReader(arg0, arg1); + } + } + + public XMLEventAllocator getEventAllocator() { + return inputFactory.getEventAllocator(); + } + + public Object getProperty(String arg0) throws IllegalArgumentException { + return inputFactory.getProperty(arg0); + } + + public XMLReporter getXMLReporter() { + return inputFactory.getXMLReporter(); + } + + public XMLResolver getXMLResolver() { + return inputFactory.getXMLResolver(); + } + + public boolean isPropertySupported(String arg0) { + return inputFactory.isPropertySupported(arg0); + } + + public void setEventAllocator(XMLEventAllocator arg0) { + inputFactory.setEventAllocator(arg0); + } + + public void setProperty(String arg0, Object arg1) throws IllegalArgumentException { + inputFactory.setProperty(arg0, arg1); + } + + public void setXMLReporter(XMLReporter arg0) { + inputFactory.setXMLReporter(arg0); + } + + public void setXMLResolver(XMLResolver arg0) { + inputFactory.setXMLResolver(arg0); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java new file mode 100644 index 0000000000..1625984ed0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java @@ -0,0 +1,95 @@ +/* + * 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.contribution.processor; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of an extension point for XML schemas. + * + * @version $Rev$ $Date$ + */ +public class DefaultValidationSchemaExtensionPoint implements ValidationSchemaExtensionPoint { + + private List<String> schemas = new ArrayList<String>(); + private boolean loaded; + + public void addSchema(String uri) { + schemas.add(uri); + } + + public void removeSchema(String uri) { + schemas.remove(uri); + } + + /** + * Load schema declarations from META-INF/services/ + * org.apache.tuscany.sca.contribution.processor.ValidationSchema files + */ + private void loadSchemas() { + if (loaded) + return; + + // Get the schema declarations + Set<ServiceDeclaration> schemaDeclarations; + try { + schemaDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations("org.apache.tuscany.sca.contribution.processor.ValidationSchema"); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // TODO - temp fix to ensure that the schema tuscany-sca.xsd always comes first + String tuscanyScaXsd = null; + + // Find each schema + for (ServiceDeclaration schemaDeclaration: schemaDeclarations) { + URL url = schemaDeclaration.getResource(); + if (url == null) { + throw new IllegalArgumentException(new FileNotFoundException(schemaDeclaration.getClassName())); + } + + if (url.toString().contains("tuscany-sca.xsd")){ + tuscanyScaXsd = url.toString(); + } else { + schemas.add(url.toString()); + } + } + + if (tuscanyScaXsd != null){ + schemas.add(0, tuscanyScaXsd); + } + + loaded = true; + } + + public List<String> getSchemas() { + loadSchemas(); + return schemas; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.java new file mode 100644 index 0000000000..7ed2d45c2f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensiblePackageProcessor.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.contribution.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.service.ContributionException; +import org.apache.tuscany.sca.contribution.service.TypeDescriber; +import org.apache.tuscany.sca.contribution.service.UnsupportedPackageTypeException; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible package processor. + * + * Takes a package processor extension point and delegates to the proper package + * processor from the extension point based on the package's content type. + * + * @version $Rev$ $Date$ + */ +public class ExtensiblePackageProcessor implements PackageProcessor { + + private PackageProcessorExtensionPoint processors; + private TypeDescriber packageTypeDescriber; + private Monitor monitor; + + public ExtensiblePackageProcessor(PackageProcessorExtensionPoint processors, + TypeDescriber packageTypeDescriber, + Monitor monitor) { + this.processors = processors; + this.packageTypeDescriber = packageTypeDescriber; + this.monitor = monitor; + } + + /** + * Marshals errors into the monitor + * + * @param problems + * @param message + * @param model + */ + protected void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + public List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) + throws ContributionException, IOException { + String packageType = this.packageTypeDescriber.getType(packageSourceURL, null); + if (packageType == null) { + error("UnsupportedPackageTypeException", packageTypeDescriber, packageSourceURL.toString()); + throw new UnsupportedPackageTypeException("Unsupported contribution package type: " + packageSourceURL.toString()); + } + + PackageProcessor packageProcessor = this.processors.getPackageProcessor(packageType); + if (packageProcessor == null) { + error("UnsupportedPackageTypeException", packageTypeDescriber, packageType); + throw new UnsupportedPackageTypeException("Unsupported contribution package type: " + packageType); + } + + return packageProcessor.getArtifacts(packageSourceURL, inputStream); + } + + public URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException { + String contentType = this.packageTypeDescriber.getType(packageSourceURL, null); + PackageProcessor packageProcessor = this.processors.getPackageProcessor(contentType); + return packageProcessor.getArtifactURL(packageSourceURL, artifact); + } + + public String getPackageType() { + return null; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java new file mode 100644 index 0000000000..ce706fa69c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java @@ -0,0 +1,251 @@ +/* + * 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.contribution.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +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.contribution.service.UnrecognizedElementException; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible StAX artifact processor. + * + * Takes a StAXArtifactProcessorExtensionPoint and delegates to the proper + * StAXArtifactProcessor by element QName + * + * @version $Rev$ $Date$ + */ +public class ExtensibleStAXArtifactProcessor + implements StAXArtifactProcessor<Object> { + + private static final Logger logger = Logger.getLogger(ExtensibleStAXArtifactProcessor.class.getName()); + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private StAXArtifactProcessorExtensionPoint processors; + private Monitor monitor; + + /** + * Constructs a new ExtensibleStAXArtifactProcessor. + * @param processors + * @param inputFactory + * @param outputFactory + */ + public ExtensibleStAXArtifactProcessor(StAXArtifactProcessorExtensionPoint processors, + XMLInputFactory inputFactory, + XMLOutputFactory outputFactory, + Monitor monitor) { + super(); + this.processors = processors; + this.inputFactory = inputFactory; + this.outputFactory = outputFactory; + if (this.outputFactory != null) { + this.outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE); + } + this.monitor = monitor; + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void warning(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, ex); + monitor.problem(problem); + } + } + + + public Object read(XMLStreamReader source) throws ContributionReadException, XMLStreamException { + + // Delegate to the processor associated with the element QName + int event = source.getEventType(); + if (event == XMLStreamConstants.START_DOCUMENT) { + source.nextTag(); + } + QName name = source.getName(); + StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name); + if (processor == null) { + Location location = source.getLocation(); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Element " + name + " cannot be processed. (" + location + ")"); + } + warning("ElementCannotBeProcessed", processors, name, location); + return null; + } + return processor.read(source); + } + + @SuppressWarnings("unchecked") + public void write(Object model, XMLStreamWriter outputSource) throws ContributionWriteException, XMLStreamException { + + // Delegate to the processor associated with the model type + if (model != null) { + StAXArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.write(model, outputSource); + } else { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("No StAX processor is configured to handle " + model.getClass()); + } + warning("NoStaxProcessor", processors, model.getClass()); + } + } + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + + // Delegate to the processor associated with the model type + if (model != null) { + StAXArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.resolve(model, resolver); + } + } + } + + /** + * Read a model from an InputStream. + * @param is The artifact InputStream + * @param type Model type + * @return The model + * @throws ContributionReadException + */ + public <M> M read(InputStream is, Class<M> type) throws ContributionReadException { + try { + XMLStreamReader reader; + try { + reader = inputFactory.createXMLStreamReader(is); + try { + reader.nextTag(); + QName name = reader.getName(); + Object mo = read(reader); + if (type.isInstance(mo)) { + return type.cast(mo); + } else { + error("UnrecognizedElementException", reader, name); + UnrecognizedElementException e = new UnrecognizedElementException(name); + throw e; + } + } catch (ContributionReadException e) { + Location location = reader.getLocation(); + e.setLine(location.getLineNumber()); + e.setColumn(location.getColumnNumber()); + error("ContributionReadException", reader, e); + throw e; + } finally { + try { + reader.close(); + } catch (XMLStreamException e) { + // ignore + } + } + } finally { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException(e); + error("ContributionReadException", inputFactory, ce); + throw ce; + } + } + + /** + * Write a model to an OutputStream. + * @param model + * @param os + * @throws ContributionWriteException + */ + public void write(Object model, OutputStream os) throws ContributionWriteException { + try { + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os); + write(model, writer); + writer.flush(); + writer.close(); + } catch (XMLStreamException e) { + ContributionWriteException cw = new ContributionWriteException(e); + error("ContributionWriteException", outputFactory, cw); + throw cw; + } + } + + public QName getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java new file mode 100644 index 0000000000..2fa9469b93 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java @@ -0,0 +1,143 @@ +/* + * 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.contribution.processor; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +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.UnrecognizedElementException; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * Implementation of an extensible URL artifact processor. + * + * Takes a URLArtifactProcessorExtensionPoint and delegates to the proper URLArtifactProcessor + * by either fileName or fileExtention + * + * @version $Rev$ $Date$ + */ +public class ExtensibleURLArtifactProcessor + implements URLArtifactProcessor<Object> { + + private URLArtifactProcessorExtensionPoint processors; + private Monitor monitor; + + /** + * Constructs a new ExtensibleURLArtifactProcessor. + * + * @param processors + */ + public ExtensibleURLArtifactProcessor(URLArtifactProcessorExtensionPoint processors, Monitor monitor) { + this.processors = processors; + this.monitor = monitor; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + @SuppressWarnings("unchecked") + public Object read(URL contributionURL, URI sourceURI, URL sourceURL) throws ContributionReadException { + URLArtifactProcessor<Object> processor = null; + + // Delegate to the processor associated with file extension + String fileName = getFileName(sourceURL); + + //try to retrieve a processor for the specific filename + processor = (URLArtifactProcessor<Object>)processors.getProcessor(fileName); + + if (processor == null) { + //try to find my file type (extension) + String extension = sourceURL.getPath(); + + int extensionStart = extension.lastIndexOf('.'); + //handle files without extension (e.g NOTICE) + if (extensionStart > 0) { + extension = extension.substring(extensionStart); + processor = (URLArtifactProcessor<Object>)processors.getProcessor(extension); + } + } + + if (processor == null) { + return null; + } + return processor.read(contributionURL, sourceURI, sourceURL); + } + + @SuppressWarnings("unchecked") + public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException { + + // Delegate to the processor associated with the model type + if (model != null) { + URLArtifactProcessor processor = processors.getProcessor(model.getClass()); + if (processor != null) { + processor.resolve(model, resolver); + } + } + } + + public <M> M read(URL contributionURL, URI artifactURI, URL artifactUrl, Class<M> type) + throws ContributionReadException { + Object mo = read(contributionURL, artifactURI, artifactUrl); + if (type.isInstance(mo)) { + return type.cast(mo); + } else { + UnrecognizedElementException e = new UnrecognizedElementException(null); + e.setResourceURI(artifactURI.toString()); + error("UnrecognizedElementException", processors, artifactURI.toString()); + throw e; + } + } + + public String getArtifactType() { + return null; + } + + public Class<Object> getModelType() { + return null; + } + + /** + * Returns the file name from a URL. + * @param url + * @return + */ + private static String getFileName(URL url){ + String fileName = url.getPath(); + int pos = fileName.lastIndexOf("/"); + + return fileName.substring(pos +1); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.java new file mode 100644 index 0000000000..f17f31edb1 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessor.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.contribution.processor; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.service.ContributionException; + +/** + * Interface for contribution package processors + * + * Package processors understand the format of the contribution and how to get the + * artifacts in the contribution. + * + * @version $Rev$ $Date$ + */ +public interface PackageProcessor { + + /** + * Returns the type of package supported by this package processor. + * + * @return the package type + */ + String getPackageType(); + + /** + * Returns a list of artifacts in the contribution. + * + * @param packageSourceURL Contribution package location URL + * @param inputStream Optional content of the package + * @return List of artifact URIs + * @throws ContributionException + * @throws IOException + */ + List<URI> getArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, IOException; + + /** + * Return the URL for an artifact in the package. + * + * This is needed for archives such as jar files that have specific URL schemes + * for the artifacts they contain. + * + * @param packageSourceURL Contribution package location URL + * @param artifact The relative URI for the artifact + * @return The artifact URL + */ + URL getArtifactURL(URL packageSourceURL, URI artifact) throws MalformedURLException; + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java new file mode 100644 index 0000000000..ed99239b19 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/PackageProcessorExtensionPoint.java @@ -0,0 +1,50 @@ +/* + * 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.contribution.processor; + +/** + * An extension point for package processors + * + * @version $Rev$ $Date$ + */ +public interface PackageProcessorExtensionPoint { + + /** + * Register a PackageProcessor using the package type as the key. + * + * @param processor The package processor + */ + void addPackageProcessor(PackageProcessor processor); + + /** + * Unregister a PackageProcessor. + * + * @param processor The package processor + */ + void removePackageProcessor(PackageProcessor processor); + + /** + * Returns the PackageProcessor for the given package type. + * + * @param packageType The package type + * @return The package processor + */ + PackageProcessor getPackageProcessor(String packageType); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java new file mode 100644 index 0000000000..fcf9347564 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java @@ -0,0 +1,61 @@ +/* + * 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.contribution.processor; + +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.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; + +/** + * An artifact processor that can read models from a StAX XMLStreamReader. + * + * @version $Rev$ $Date$ + */ +public interface StAXArtifactProcessor<M> extends ArtifactProcessor<M> { + + /** + * Reads a model from an XMLStreamReader. + * + * @param reader The XMLStreamReader + * @return A model representation of the input. + */ + M read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException; + + /** + * Writes a model to an XMLStreamWriter. + * + * @param model A model representing the source + * @param writer The XML stream writer + * @throws ContributionWriteException + * @throws XMLStreamException + */ + void write(M model, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException; + + /** + * Returns the type of artifact handled by this artifact processor. + * + * @return The type of artifact handled by this artifact processor + */ + QName getArtifactType(); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..9700e2bc60 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java @@ -0,0 +1,29 @@ +/* + * 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.contribution.processor; + +/** + * An extension point for StAX artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface StAXArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<StAXArtifactProcessor> { + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java new file mode 100644 index 0000000000..2ecddf5465 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java @@ -0,0 +1,51 @@ +/* + * 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.contribution.processor; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.contribution.service.ContributionReadException; + +/** + * An artifact processor that can read models from a URL. + * + * @version $Rev$ $Date$ + */ +public interface URLArtifactProcessor<M> extends ArtifactProcessor<M> { + + /** + * Reads a model from a URL. + * + * @param contributionURL Contribution location URL + * @param artifactURI Artifact URI + * @param artifactURL Artifact location URL + * @return A model representation of the input. + */ + M read(URL contributionURL, URI artifactURI, URL artifactURL) throws ContributionReadException; + + /** + * Returns the type of artifact handled by this artifact processor. + * + * @return The type of artifact handled by this artifact processor + */ + String getArtifactType(); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java new file mode 100644 index 0000000000..7714586951 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java @@ -0,0 +1,29 @@ +/* + * 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.contribution.processor; + +/** + * An extension point for URL artifact processors. + * + * @version $Rev$ $Date$ + */ +public interface URLArtifactProcessorExtensionPoint extends + ArtifactProcessorExtensionPoint<URLArtifactProcessor> { + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java new file mode 100644 index 0000000000..da249a09e4 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.contribution.processor; + +import javax.xml.stream.XMLInputFactory; + +/** + * Base marker class for validating XML input factories. + * + * @version $Rev$ $Date$ + */ +public abstract class ValidatingXMLInputFactory extends XMLInputFactory { + + /** + * Create a new default validating XML input factory. + * @return + */ + public static ValidatingXMLInputFactory newInstance() { + return new DefaultValidatingXMLInputFactory( + XMLInputFactory.newInstance(), + new DefaultValidationSchemaExtensionPoint(), + null); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java new file mode 100644 index 0000000000..c136c62d33 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java @@ -0,0 +1,388 @@ +/* + * 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.contribution.processor; + +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.StreamReaderDelegate; +import javax.xml.validation.Schema; +import javax.xml.validation.ValidatorHandler; + +import org.xml.sax.Attributes; +import org.xml.sax.ErrorHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.AttributesImpl; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * + * A validating XMLStreamReader that reports XMLSchema validation errors. + * + * @version $Rev$ $Date$ + */ +class ValidatingXMLStreamReader extends StreamReaderDelegate implements XMLStreamReader { + private static final Logger logger = Logger.getLogger(ValidatingXMLStreamReader.class.getName()); + + private int level; + private ValidatorHandler handler; + private final Monitor monitor; + + /** + * Constructs a new ValidatingXMLStreamReader. + * + * @param reader + * @param schema + * @throws XMLStreamException + */ + ValidatingXMLStreamReader(XMLStreamReader reader, Schema schema, Monitor monitor) throws XMLStreamException { + super(reader); + this.monitor = monitor; + if (schema == null) { + return; + } + + handler = schema.newValidatorHandler(); + handler.setDocumentLocator(new LocatorAdapter()); + try { + handler.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + } catch (SAXException e) { + XMLStreamException xse = new XMLStreamException(e); + error("XMLStreamException", handler, xse); + throw xse; + } + + // These validation errors are just warnings for us as we want to support + // running from an XML document with XSD validation errors, as long as we can + // get the metadata we need from the document + handler.setErrorHandler(new ErrorHandler() { + private String getMessage(SAXParseException e) { + return "XMLSchema validation problem in: " + e.getSystemId() + ", line: " + e.getLineNumber() + ", column: " + e.getColumnNumber() + "\n" + e.getMessage(); + } + + public void error(SAXParseException exception) throws SAXException { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.error("SchemaError", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + + public void fatalError(SAXParseException exception) throws SAXException { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.error("SchemaFatalError", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + + public void warning(SAXParseException exception) throws SAXException { + if (ValidatingXMLStreamReader.this.monitor == null) + logger.warning(getMessage(exception)); + else + ValidatingXMLStreamReader.this.warning("SchemaWarning", ValidatingXMLStreamReader.this.getClass(), exception.getSystemId(), + exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage()); + } + }); + } + + /** + * Report a warning. + * + * @param problems + * @param message + * @param model + */ + private void warning(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = new ProblemImpl(this.getClass().getName(), "contribution-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); + monitor.problem(problem); + } + } + + @Override + public int next() throws XMLStreamException { + if (handler == null) { + return super.next(); + } + + int event = super.next(); + try { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(); + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(super.getPITarget(), super.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + case XMLStreamConstants.SPACE: + case XMLStreamConstants.ENTITY_REFERENCE: + handler.characters(super.getTextCharacters(), super.getTextStart(), super.getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(); + level--; + break; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + break; + } + } catch (SAXException e) { + XMLStreamException xse = new XMLStreamException(e.getMessage(), e); + error("XMLStreamException", handler, xse); + throw xse; + } + return event; + } + + @Override + public int nextTag() throws XMLStreamException { + if (handler == null) { + return super.nextTag(); + } + + for (;;) { + int event = super.getEventType(); + try { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(); + return event; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(super.getPITarget(), super.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + case XMLStreamConstants.SPACE: + case XMLStreamConstants.ENTITY_REFERENCE: + handler.characters(super.getTextCharacters(), super.getTextStart(), super.getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(); + level--; + return event; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + return event; + } + } catch (SAXException e) { + XMLStreamException xse = new XMLStreamException(e); + error("XMLStreamException", handler, xse); + throw xse; + } + super.next(); + } + } + + @Override + public String getElementText() throws XMLStreamException { + if (handler == null) { + return super.getElementText(); + } + + if (getEventType() != XMLStreamConstants.START_ELEMENT) { + return super.getElementText(); + } + StringBuffer text = new StringBuffer(); + + for (;;) { + int event = next(); + switch (event) { + case XMLStreamConstants.END_ELEMENT: + return text.toString(); + + case XMLStreamConstants.COMMENT: + case XMLStreamConstants.PROCESSING_INSTRUCTION: + continue; + + case CHARACTERS: + case CDATA: + case SPACE: + case ENTITY_REFERENCE: + text.append(getText()); + break; + + default: + break; + } + } + } + + /** + * Handle a start element event. + * + * @throws SAXException + */ + private void handleStartElement() throws SAXException { + + // send startPrefixMapping events immediately before startElement event + int nsCount = super.getNamespaceCount(); + for (int i = 0; i < nsCount; i++) { + String prefix = super.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.startPrefixMapping(prefix, super.getNamespaceURI(i)); + } + + // fire startElement + QName qname = super.getName(); + String prefix = qname.getPrefix(); + String rawname; + if (prefix == null || prefix.length() == 0) { + rawname = qname.getLocalPart(); + } else { + rawname = prefix + ':' + qname.getLocalPart(); + } + Attributes attrs = getAttributes(); + handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs); + } + + /** + * Handle an endElement event. + * + * @throws SAXException + */ + private void handleEndElement() throws SAXException { + + // fire endElement + QName qname = super.getName(); + handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString()); + + // send endPrefixMapping events immediately after endElement event + // we send them in the opposite order to that returned but this is not + // actually required by SAX + int nsCount = super.getNamespaceCount(); + for (int i = nsCount - 1; i >= 0; i--) { + String prefix = super.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.endPrefixMapping(prefix); + } + } + + /** + * Get the attributes associated with the current START_ELEMENT event. + * + * @return the StAX attributes converted to org.xml.sax.Attributes + */ + private Attributes getAttributes() { + AttributesImpl attrs = new AttributesImpl(); + + // add namespace declarations + for (int i = 0; i < super.getNamespaceCount(); i++) { + String prefix = super.getNamespacePrefix(i); + String uri = super.getNamespaceURI(i); + if (prefix == null) { + attrs.addAttribute("", "", "xmlns", "CDATA", uri); + } else { + attrs.addAttribute("", "", "xmlns:" + prefix, "CDATA", uri); + } + } + + // Regular attributes + for (int i = 0; i < super.getAttributeCount(); i++) { + String uri = super.getAttributeNamespace(i); + if (uri == null) { + uri = ""; + } + String localName = super.getAttributeLocalName(i); + String prefix = super.getAttributePrefix(i); + String qname; + if (prefix == null || prefix.length() == 0) { + qname = localName; + } else { + qname = prefix + ':' + localName; + } + String type = super.getAttributeType(i); + String value = super.getAttributeValue(i); + + attrs.addAttribute(uri, localName, qname, type, value); + } + + return attrs; + } + + /** + * Adapter for mapping Locator information. + */ + private final class LocatorAdapter implements Locator { + + private LocatorAdapter() { + } + + public int getColumnNumber() { + Location location = getLocation(); + return location == null ? 0 : location.getColumnNumber(); + } + + public int getLineNumber() { + Location location = getLocation(); + return location == null ? 0 : location.getLineNumber(); + } + + public String getPublicId() { + Location location = getLocation(); + return location == null ? "" : location.getPublicId(); + } + + public String getSystemId() { + Location location = getLocation(); + return location == null ? "" : location.getSystemId(); + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java new file mode 100644 index 0000000000..cc3bb59a5b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java @@ -0,0 +1,52 @@ +/* + * 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.contribution.processor; + +import java.util.List; + + +/** + * An extension point for XML schemas used for validation. + * + * @version $Rev$ $Date$ + */ +public interface ValidationSchemaExtensionPoint { + + /** + * Add a schema. + * + * @param uri the URI of the schema + */ + void addSchema(String uri); + + /** + * Remove a schema. + * + * @param uri the URI of the schema + */ + void removeSchema(String uri); + + /** + * Returns the list of schemas registered in the extension point. + * @return the list of schemas + */ + List<String> getSchemas(); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java new file mode 100644 index 0000000000..f3555ee71e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ClassReference.java @@ -0,0 +1,107 @@ +/* + * 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.contribution.resolver; + +import java.lang.ref.WeakReference; + +import org.apache.tuscany.sca.assembly.Base; + +/** + * A weak reference to a class, which should be used to register classes + * with an ArtifactResolver and resolve these classes later. + * + * FIXME The core contribution model should not have dependencies on classes + * and ClassLoaders. This should move to the Java import support module. + * + * @version $Rev$ $Date$ + */ +public class ClassReference implements Base { + + private WeakReference<Class<?>> clazz; + private String className; + + /** + * Constructs a new ClassReference. + * + * @param clazz The class reference + */ + public ClassReference(Class<?> clazz) { + this.clazz = new WeakReference<Class<?>>(clazz); + this.className = clazz.getName(); + } + + /** + * Constructs a new ClassReference. + * + * @param className The class name + */ + public ClassReference(String className) { + this.className = className; + } + + /** + * Get the referenced class. + * + * @return The referenced class + */ + public Class<?> getJavaClass() { + if (clazz != null) { + return clazz.get(); + } else { + return null; + } + } + + /** + * Get the referenced class name. + * + * @return The class name + */ + public String getClassName() { + return className; + } + + public boolean isUnresolved() { + return clazz == null; + } + + public void setUnresolved(boolean unresolved) { + throw new IllegalStateException(); + } + + @Override + public int hashCode() { + return className.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else { + if (obj instanceof ClassReference) { + return className.equals(((ClassReference)obj).className); + } else { + return false; + } + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java new file mode 100644 index 0000000000..13c622adf0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultDelegatingModelResolver.java @@ -0,0 +1,68 @@ +/* + * 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.contribution.resolver; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Base; + +/** + * A model resolver implementation that delegates to a list of model resolvers. + * + * @version $Rev$ $Date$ + */ +public class DefaultDelegatingModelResolver implements ModelResolver { + + private List<ModelResolver> resolvers; + + public DefaultDelegatingModelResolver(List<ModelResolver> resolvers) { + this.resolvers = resolvers; + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + //TODO optimize and cache results of the resolution later + + // Go over all resolvers + for (ModelResolver resolver: resolvers) { + + Object resolved = resolver.resolveModel(modelClass, unresolved); + + // Return the resolved model object + if (resolved instanceof Base) { + if (!((Base)resolved).isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + + // Model object was not resolved + return unresolved; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java new file mode 100644 index 0000000000..c6facd2b02 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportAllModelResolver.java @@ -0,0 +1,80 @@ +/*
+ * 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.contribution.resolver;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Base;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+
+/**
+ * A model resolver implementation that considers Exports in a list of contributions.
+ *
+ * @version $Rev: 560435 $ $Date: 2007-07-27 18:26:55 -0700 (Fri, 27 Jul 2007) $
+ */
+public class DefaultImportAllModelResolver implements ModelResolver {
+
+ private Import import_;
+ private List<Contribution> contributions;
+
+ public DefaultImportAllModelResolver(Import import_, List<Contribution> contributions) {
+ this.import_ = import_;
+ this.contributions = contributions;
+ }
+
+ public void addModel(Object resolved) {
+ throw new IllegalStateException();
+ }
+
+ public Object removeModel(Object resolved) {
+ throw new IllegalStateException();
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ //TODO optimize and cache results of the resolution later
+
+ // Go over all available contributions
+ for (Contribution contribution : contributions) {
+
+ // Go over all exports in the contribution
+ for (Export export : contribution.getExports()) {
+
+ // If the export matches the export, try to resolve the model object
+ if (import_.match(export)) {
+ Object resolved = export.getModelResolver().resolveModel(modelClass, unresolved);
+
+ // Return the resolved model object
+ if (resolved instanceof Base) {
+ if (!((Base)resolved).isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ }
+ }
+ }
+
+ // Model object was not resolved
+ return unresolved;
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.java new file mode 100644 index 0000000000..9ae57c41d0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultImportModelResolver.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.contribution.resolver; + +import java.util.List; + +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.contribution.Export; + +/** + * A model resolver implementation that delegates to a list of exports. + * + * @version $Rev$ $Date$ + */ +public class DefaultImportModelResolver implements ModelResolver { + + private List<Export> exports; + + public DefaultImportModelResolver(List<Export> exports) { + this.exports = exports; + } + + public void addModel(Object resolved) { + throw new IllegalStateException(); + } + + public Object removeModel(Object resolved) { + throw new IllegalStateException(); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + + //TODO optimize and cache results of the resolution later + + // Go over all exports + for (Export export: exports) { + + Object resolved = export.getModelResolver().resolveModel(modelClass, unresolved); + + // Return the resolved model object + if (resolved instanceof Base) { + if (!((Base)resolved).isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + + // Model object was not resolved + return unresolved; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.java new file mode 100644 index 0000000000..a001baa47f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolver.java @@ -0,0 +1,60 @@ +/* + * 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.contribution.resolver; + +import java.util.HashMap; +import java.util.Map; + + +/** + * A default implementation of a model resolver based on a map. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolver implements ModelResolver { + + private Map<Object, Object> map = new HashMap<Object, Object>(); + + public DefaultModelResolver() { + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + Object resolved = map.get(unresolved); + if (resolved != null) { + + // Return the resolved object + return modelClass.cast(resolved); + + } else { + + // Return the unresolved object + return unresolved; + } + } + + public void addModel(Object resolved) { + map.put(resolved, resolved); + } + + public Object removeModel(Object resolved) { + return map.remove(resolved); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java new file mode 100644 index 0000000000..77570aa13d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/DefaultModelResolverExtensionPoint.java @@ -0,0 +1,114 @@ +/* + * 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.contribution.resolver; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + + +/** + * The default implementation of a model resolver extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultModelResolverExtensionPoint implements ModelResolverExtensionPoint { + + private final Map<Class<?>, Class<? extends ModelResolver>> resolvers = new HashMap<Class<?>, Class<? extends ModelResolver>>(); + private Map<String, ServiceDeclaration> loadedResolvers; + + /** + * Constructs a new DefaultModelResolverExtensionPoint. + */ + public DefaultModelResolverExtensionPoint() { + } + + public void addResolver(Class<?> modelType, Class<? extends ModelResolver> resolver) { + resolvers.put(modelType, resolver); + } + + public void removeResolver(Class<?> modelType) { + resolvers.remove(modelType); + } + + @SuppressWarnings("unchecked") + public Class<? extends ModelResolver> getResolver(Class<?> modelType) { + loadModelResolvers(); + + Class<?>[] classes = modelType.getInterfaces(); + for (Class<?> c : classes) { + Class<? extends ModelResolver> resolver = resolvers.get(c); + if (resolver == null) { + ServiceDeclaration resolverClass = loadedResolvers.get(c.getName()); + if (resolverClass != null) { + try { + return (Class<? extends ModelResolver>)resolverClass.loadClass(); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + } else { + return resolver; + } + } + + Class<? extends ModelResolver > resolver = resolvers.get(modelType); + if (resolver == null) { + ServiceDeclaration resolverClass = loadedResolvers.get(modelType.getName()); + if (resolverClass != null) { + try { + return (Class<? extends ModelResolver>)resolverClass.loadClass(); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + } + return resolver; + } + + /** + * Dynamically load model resolvers declared under META-INF/services + */ + private void loadModelResolvers() { + if (loadedResolvers != null) + return; + loadedResolvers = new HashMap<String, ServiceDeclaration>(); + + // Get the model resolver service declarations + Set<ServiceDeclaration> modelResolverDeclarations; + try { + modelResolverDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ModelResolver.class); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Load model resolvers + for (ServiceDeclaration modelResolverDeclaration: modelResolverDeclarations) { + Map<String, String> attributes = modelResolverDeclaration.getAttributes(); + String model = attributes.get("model"); + + loadedResolvers.put(model, modelResolverDeclaration); + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java new file mode 100644 index 0000000000..0cfba8e1ed --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ExtensibleModelResolver.java @@ -0,0 +1,195 @@ +/* + * 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.contribution.resolver; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; + +/** + * An implementation of an extensible model resolver which delegates to the + * proper resolver extension based on the class of the model to resolve. + * + * @version $Rev$ $Date$ + */ +public class ExtensibleModelResolver implements ModelResolver { + private final ModelResolverExtensionPoint resolverExtensions; + private final ModelFactoryExtensionPoint modelFactories; + private final Contribution contribution; + private ModelResolver defaultResolver; + private final Map<Class<?>, ModelResolver> resolversByModelType = new HashMap<Class<?>, ModelResolver>(); + private final Map<Class<?>, ModelResolver> resolversByImplementationClass = new HashMap<Class<?>, ModelResolver>(); + private Map<Object, Object> map = new HashMap<Object, Object>(); + private Object lastUnresolved; + + /** + * Constructs an extensible model resolver + * + * @param contribution + * @param resolverExtensions + * @param modelFactories + * @param defaultResolver + */ + @Deprecated + public ExtensibleModelResolver(Contribution contribution, + ModelResolverExtensionPoint resolverExtensions, + ModelFactoryExtensionPoint modelFactories, + ModelResolver defaultResolver) { + this.contribution = contribution; + this.resolverExtensions = resolverExtensions; + this.modelFactories = modelFactories; + //FIXME Remove this default resolver, this is currently used to resolve policy declarations + // but they should be handled by the contribution import/export mechanism instead of this + // defaultResolver hack. + this.defaultResolver = defaultResolver; + } + + /** + * Constructs an extensible model resolver + * + * @param resolverExtensions + * @param contribution + * @param modelFactories + */ + public ExtensibleModelResolver(Contribution contribution, + ModelResolverExtensionPoint resolverExtensions, + ModelFactoryExtensionPoint modelFactories) { + this.contribution = contribution; + this.resolverExtensions = resolverExtensions; + this.modelFactories = modelFactories; + } + + /** + * Returns the proper resolver instance based on the interfaces of the model + * If one is not available on the registry, instantiate on demand + * + * @param modelType + * @return + */ + private ModelResolver getModelResolverInstance(Class<?> modelType) { + // Look up a model resolver instance for the model class or + // each implemented interface + Class<?>[] interfaces = modelType.getInterfaces(); + Class<?>[] classes = new Class<?>[interfaces.length + 1]; + classes[0] = modelType; + if (interfaces.length != 0) { + System.arraycopy(interfaces, 0, classes, 1, interfaces.length); + } + for (Class<?> c : classes) { + + // Look up an existing model resolver instance + ModelResolver resolverInstance = resolversByModelType.get(c); + if (resolverInstance != null) { + return resolverInstance; + } + + // We don't have an instance, lookup a model resolver class + // and instantiate it + Class<? extends ModelResolver> resolverClass = resolverExtensions.getResolver(c); + if (resolverClass != null) { + + // Construct the model resolver instance and cache it + resolverInstance = resolversByImplementationClass.get(resolverClass); + if (resolverInstance != null) { + resolversByModelType.put(c, resolverInstance); + return resolverInstance; + } + try { + Constructor<? extends ModelResolver> constructor = + resolverClass + .getConstructor(new Class[] {Contribution.class, ModelFactoryExtensionPoint.class}); + if (constructor != null) { + + resolverInstance = constructor.newInstance(contribution, modelFactories); + resolversByImplementationClass.put(resolverClass, resolverInstance); + resolversByModelType.put(c, resolverInstance); + return resolverInstance; + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + + return null; + } + + public void addModel(Object resolved) { + ModelResolver resolver = getModelResolverInstance(resolved.getClass()); + if (resolver != null) { + resolver.addModel(resolved); + } else { + map.put(resolved, resolved); + } + } + + public Object removeModel(Object resolved) { + ModelResolver resolver = getModelResolverInstance(resolved.getClass()); + if (resolver != null) { + return resolver.removeModel(resolved); + } else { + return map.remove(resolved); + } + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved) { + // Protect against dependency cycles causing infinite recursion + // Save the current unresolved object and check later if we are trying + // to resolve the same object again + if (unresolved == lastUnresolved) { + return unresolved; + } + lastUnresolved = unresolved; + + ModelResolver resolver = getModelResolverInstance(unresolved.getClass()); + if (resolver != null) { + Object resolved = resolver.resolveModel(modelClass, unresolved); + if (resolved != null && resolved != unresolved) { + lastUnresolved = null; + return modelClass.cast(resolved); + } + } else { + //FIXME Remove this default resolver, this is currently used to resolve policy declarations + // but they should be handled by the contribution import/export mechanism instead of this + // defaultResolver hack. + if (defaultResolver != null) { + Object resolved = defaultResolver.resolveModel(modelClass, unresolved); + if (resolved != null && resolved != unresolved) { + lastUnresolved = null; + return modelClass.cast(resolved); + } + } + + Object resolved = map.get(unresolved); + if (resolved != null) { + // Return the resolved object + lastUnresolved = null; + return modelClass.cast(resolved); + } + } + + return unresolved; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.java new file mode 100644 index 0000000000..2831bebbc4 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolver.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.contribution.resolver; + +/** + * A model resolver, responsible for resolving models in the scope of an + * SCA contribution. + * + * SCA Assemblies reference artifacts of a wide variety of types. These + * include: + * <ul> + * <li> Reference from one SCA composite to another SCA composite + * <li> Reference to PolicySet files + * <li> Reference to interface definition files, either WSDL or Java interfaces + * <li> Reference to XSD files + * <li> Reference to any of a wide variety of implementation artifact files, + * including Java classes, BPEL scripts, C++ DLLs and classes, PHP scripts + * </ul> + * + * In the SCA assemblies, these various artifacts are referenced using either + * QNames or logical URIs. Model resolvers are used to resolve these references + * and get the in-memory models representing the referenced artifacts. + * + * @version $Rev$ $Date$ + */ +public interface ModelResolver { + + /** + * Resolve the model representing an artifact. + * + * @param modelClass the type of artifact + * @param unresolved the unresolved model + * @return the resolved model + */ + <T> T resolveModel(Class<T> modelClass, T unresolved); + + /** + * Add a resolved model. + * + * @param resolved The model + */ + void addModel(Object resolved); + + /** + * Remove a resolved model. + * + * @param resolved + * @return The removed model, or null if the model was not removed + */ + Object removeModel(Object resolved); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java new file mode 100644 index 0000000000..4a25059792 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ModelResolverExtensionPoint.java @@ -0,0 +1,52 @@ +/* + * 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.contribution.resolver; + + +/** + * An extension point for model resolvers + * + * @version $Rev$ $Date$ + */ +public interface ModelResolverExtensionPoint { + + /** + * Register a model resolver class using the model type as the key + * + * @param modelType The model type + * @param resolver The model resolver Class + */ + void addResolver(Class<?> modelType, Class <? extends ModelResolver> resolver); + + /** + * Remove the model resolver class for a specific model type + * + * @param modelType The model type + */ + void removeResolver(Class<?> modelType); + + /** + * Retrieve a model resolver class for a specific model type + * + * @param modelType The model artifact type + * @return The model resolver Class + */ + Class <? extends ModelResolver> getResolver(Class<?> modelType); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java new file mode 100644 index 0000000000..74f0f2d71d --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResolverExtension.java @@ -0,0 +1,45 @@ +/* + * 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.contribution.resolver; + +/** + * Extension to assembly model implementations to provide a model resolver. + * + * @version $Rev$ $Date$ + */ +public interface ResolverExtension { + + /** + * Returns the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @return The model resolver + */ + ModelResolver getModelResolver(); + + /** + * Sets the model resolver for the models representing the artifacts + * visible in the scope of this contribution. + * + * @param modelResolver The model resolver + */ + void setModelResolver(ModelResolver modelResolver); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.java new file mode 100644 index 0000000000..2394f4510b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/resolver/ResourceReference.java @@ -0,0 +1,103 @@ +/*
+ * 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.contribution.resolver;
+
+import java.net.URL;
+
+/**
+ * A resource URL, which should be used to register resources
+ * with an ArtifactResolver and resolve these resources later.
+ *
+ * FIXME Don't use as its deprecated, use Artifact instead.
+ *
+ * @version $Rev$ $Date$
+ */
+@Deprecated
+public class ResourceReference {
+
+ private URL resourceURL;
+ private String resourceName;
+
+ /**
+ * Constructs a new ResourceReference.
+ *
+ * @param resourceName Name of resource
+ * @param resourceURL The resource URL
+ */
+ public ResourceReference(String resourceName, URL resourceURL) {
+ this.resourceURL = resourceURL;
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Constructs a new ResourceReference.
+ *
+ * @param resourceName Name of resource
+ */
+ public ResourceReference(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Get the resource URL.
+ *
+ * @return The resource URL
+ */
+ public URL getResource() {
+ return resourceURL;
+ }
+
+ /**
+ * Get the resource name.
+ *
+ * @return The resource name
+ */
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ /**
+ * Returns true if the resource reference is unresolved.
+ *
+ * @return Whether or not the resource has been resolved
+ */
+ public boolean isUnresolved() {
+ return resourceURL == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else {
+ if (obj instanceof ResourceReference) {
+ return resourceName.equals(((ResourceReference)obj).resourceName);
+ } else {
+ return false;
+ }
+ }
+ }
+
+}
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.java new file mode 100644 index 0000000000..2d03381c8a --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScanner.java @@ -0,0 +1,65 @@ +/* + * 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.contribution.scanner; + +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.service.ContributionReadException; + +/** + * Interface for contribution package scanners + * + * Contribution scanners understand the format of the contribution and how to get the + * artifacts in the contribution. + * + * @version $Rev$ $Date$ + */ +public interface ContributionScanner { + + /** + * Returns the type of package supported by this package scanner. + * + * @return the package type + */ + String getContributionType(); + + /** + * Returns a list of artifacts in the contribution. + * + * @param contributionURL Contribution URL + * @return List of artifact URIs + * @throws ContributionException + * @throws IOException + */ + List<String> getArtifacts(URL contributionURL) throws ContributionReadException; + + /** + * Return the URL for an artifact in the contribution. + * + * This is needed for archives such as jar files that have specific URL schemes + * for the artifacts they contain. + * + * @param contributionURL Contribution URL + * @param artifact The relative URI for the artifact + * @return The artifact URL + */ + URL getArtifactURL(URL contributionURL, String artifact) throws ContributionReadException; + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.java new file mode 100644 index 0000000000..1ca9def4ea --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/ContributionScannerExtensionPoint.java @@ -0,0 +1,50 @@ +/* + * 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.contribution.scanner; + +/** + * An extension point for contribution scanners + * + * @version $Rev$ $Date$ + */ +public interface ContributionScannerExtensionPoint { + + /** + * Add a ContributionScanner using the contribution type as the key. + * + * @param scanner The contribution scanner + */ + void addContributionScanner(ContributionScanner scanner); + + /** + * Remove a ContributionScanner. + * + * @param scanner The contribution scanner + */ + void removeContributionScanner(ContributionScanner scanner); + + /** + * Returns the ContributionScanner for the given contribution type. + * + * @param contributionType The contribution type + * @return The contribution scanner + */ + ContributionScanner getContributionScanner(String contributionType); + +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java new file mode 100644 index 0000000000..24aae45b59 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/scanner/DefaultContributionScannerExtensionPoint.java @@ -0,0 +1,125 @@ +/* + * 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.contribution.scanner; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of a contribution scanner extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionScannerExtensionPoint implements ContributionScannerExtensionPoint { + + private Map<String, ContributionScanner> scanners = new HashMap<String, ContributionScanner>(); + private boolean loaded; + + public DefaultContributionScannerExtensionPoint() { + } + + public void addContributionScanner(ContributionScanner scanner) { + scanners.put(scanner.getContributionType(), scanner); + } + + public void removeContributionScanner(ContributionScanner scanner) { + scanners.remove(scanner.getContributionType()); + } + + public ContributionScanner getContributionScanner(String contentType) { + loadScanners(); + return scanners.get(contentType); + } + + private void loadScanners() { + if (loaded) + return; + + // Get the scanner service declarations + Set<ServiceDeclaration> scannerDeclarations; + try { + scannerDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ContributionScanner.class); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + for (ServiceDeclaration scannerDeclaration: scannerDeclarations) { + Map<String, String> attributes = scannerDeclaration.getAttributes(); + + // Load a URL artifact scanner + String contributionType = attributes.get("type"); + + // Create a scanner wrapper and register it + ContributionScanner scanner = new LazyContributionScanner(contributionType, scannerDeclaration); + addContributionScanner(scanner); + } + + loaded = true; + } + + /** + * A facade for contribution scanners. + */ + private static class LazyContributionScanner implements ContributionScanner { + + private ServiceDeclaration scannerDeclaration; + private String contributionType; + private ContributionScanner scanner; + + private LazyContributionScanner(String contributionType, ServiceDeclaration scannerDeclaration) { + this.scannerDeclaration = scannerDeclaration; + this.contributionType = contributionType; + } + + public URL getArtifactURL(URL contributionSourceURL, String artifact) throws ContributionReadException { + return getScanner().getArtifactURL(contributionSourceURL, artifact); + } + + public List<String> getArtifacts(URL contributionSourceURL) throws ContributionReadException { + return getScanner().getArtifacts(contributionSourceURL); + } + + public String getContributionType() { + return contributionType; + } + + private ContributionScanner getScanner() { + if (scanner == null) { + try { + Class<ContributionScanner> scannerClass = (Class<ContributionScanner>)scannerDeclaration.loadClass(); + Constructor<ContributionScanner> constructor = scannerClass.getConstructor(); + scanner = constructor.newInstance(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + return scanner; + } + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java new file mode 100644 index 0000000000..e183206894 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionException.java @@ -0,0 +1,45 @@ +/* + * 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.contribution.service; + +/** + * Base class for exceptions raised by contribution services. + * + * @version $Rev$ $Date$ + */ +public class ContributionException extends Exception { + + private static final long serialVersionUID = 4432880414927652578L; + + protected ContributionException() { + super(); + } + + protected ContributionException(String message) { + super(message); + } + + protected ContributionException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionException(Throwable cause) { + super(cause); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.java new file mode 100644 index 0000000000..5158eaf85c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListener.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.contribution.service; + +import java.util.EventListener; + +import org.apache.tuscany.sca.contribution.Contribution; + +/** + * A listener interface used to listen to contribution repository events. + * + * @version $Rev$ $Date$ + */ +public interface ContributionListener extends EventListener { + + /** + * Notifies the listener that a contribution has been added. + * + * @param repository The contribution repository + * @param contribution The new contribution + */ + void contributionAdded(ContributionRepository repository, Contribution contribution); + + /** + * Notifies the listener that a contribution has been removed. + * + * @param repository The contribution repository + * @param contribution The removed contribution. + */ + void contributionRemoved(ContributionRepository repository, Contribution contribution); + + /** + * Notifies the listener that a contribution has been updated. + * + * @param repository The contribution repository + * @param oldContribution The old contribution + * @param contribution The new contribution + */ + void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java new file mode 100644 index 0000000000..ce2b4b13c3 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionListenerExtensionPoint.java @@ -0,0 +1,44 @@ +/* + * 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.contribution.service; + +import java.util.List; + +public interface ContributionListenerExtensionPoint { + + /** + * Adds a contribution repository listener extension. + * @param listener The listener to add + */ + void addContributionListener(ContributionListener listener); + + /** + * Removes a contribution repository listener extension. + * @param listener The listener to remove + */ + void removeContributionListener(ContributionListener listener); + + /** + * Returns the contribution repository listeners. + * @return + */ + List<ContributionListener> getContributionListeners(); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java new file mode 100644 index 0000000000..33399dcc2f --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionReadException.java @@ -0,0 +1,94 @@ +/* + * 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.contribution.service; + +/** + * Denotes an exception while reading artifacts inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionReadException extends ContributionException { + public static final int UNDEFINED = -1; + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + private int line = UNDEFINED; + private int column = UNDEFINED; + + public ContributionReadException(String message) { + super(message); + } + + public ContributionReadException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionReadException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being read. + * + * @return the location of the resource that was being read + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being read. + * + * @param resourceURI the location of the resource that was being read + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + + /** + * Returns the line inside the resource that was being read. + * @return the line inside the resource that was being read + */ + public int getLine() { + return line; + } + + /** + * Sets the line inside the resource that was being read. + * @param line the line inside the resource that was being read + */ + public void setLine(int line) { + this.line = line; + } + + /** + * Returns the column inside the resource that was being read. + * @return the column inside the resource that was being read + */ + public int getColumn() { + return column; + } + + /** + * Sets the column inside the resource that was being read. + * @param column the column inside the resource that was being read + */ + public void setColumn(int column) { + this.column = column; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java new file mode 100644 index 0000000000..d7d8216f66 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRepository.java @@ -0,0 +1,128 @@ +/* + * 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.contribution.service; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.contribution.Contribution; + +/** + * Contribution repository + * + * @version $Rev$ $Date$ + */ +public interface ContributionRepository { + + /** + * Get the URI of the SCA domain + * + * @return The domain URI + */ + URI getDomain(); + + /** + * Copies a contribution to the repository. + * + * @param contribution A URl pointing to the contribution being copied to + * the repository + * @param sourceURL URL of the source. this would be used to calculate the right + * filename to be stored on the repository when a inputStream is being + * provided + * @param contributionStream InputStream with the content of the + * distribution + * @return A URL pointing to the content of the contribution in the + * repository + * @throws IOException + */ + URL store(String contribution, URL sourceURL, InputStream contributionStream) throws IOException; + /** + * Copy a contribution from the source URL to the repository + * + * @param contribution A URl pointing to the contribution being copied to + * the repository + * @param sourceURL URL of the source. this would be used to calculate the right + * filename to be stored on the repository when a inputStream is being + * provided + * @return A URL pointing to the content of the contribution in the + * repository + * @throws IOException + */ + URL store(String contribution, URL sourceURL) throws IOException; + + /** + * Look up the contribution by URI + * + * @param contribution The URI of the contribution + * @return A URL pointing to the content of the contribution in the + * repository, it will be null if the contribution cannot be found + * in the repository + */ + URL find(String contribution); + + /** + * Remove a contribution from the repository + * + * @param contribution The URI of the contribution to be removed + */ + void remove(String contribution); + + /** + * Get list of URIs for all the contributions in the repository + * + * @return A list of contribution URIs + */ + List<String> list(); + + /** + * Returns the contributions available in the repository. + * @return The list of contributions. + */ + List<Contribution> getContributions(); + + /** + * Adds a contribution to the repository. + * @param contribution The new contribution. + */ + void addContribution(Contribution contribution); + + /** + * Removes a contribution from the repository. + * @param contribution The contribution to remove + */ + void removeContribution(Contribution contribution); + + /** + * Updates a contribution in the repository + * @param contribution The contribution to update + */ + void updateContribution(Contribution contribution); + + /** + * Returns the contribution with the given URI. + * @param uri the URI of the contribution + * @return The contribution + */ + Contribution getContribution(String uri); + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java new file mode 100644 index 0000000000..ecb774ac0c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionResolveException.java @@ -0,0 +1,41 @@ +/* + * 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.contribution.service; + +/** + * Denotes a problem while resolving models inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionResolveException extends ContributionException { + private static final long serialVersionUID = -7459051598906813461L; + + public ContributionResolveException(String message) { + super(message); + } + + public ContributionResolveException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionResolveException(Throwable cause) { + super(cause); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java new file mode 100644 index 0000000000..4bf29a3993 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionRuntimeException.java @@ -0,0 +1,44 @@ +/* + * 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.contribution.service; + +/** + * Base class for runtime exceptions raised by contribution services. + * + * @version $Rev$ $Date$ + */ +public class ContributionRuntimeException extends RuntimeException { + private static final long serialVersionUID = 7711215366287498896L; + + protected ContributionRuntimeException() { + super(); + } + + protected ContributionRuntimeException(String message) { + super(message); + } + + protected ContributionRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java new file mode 100644 index 0000000000..dcdb8733b8 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionService.java @@ -0,0 +1,137 @@ +/* + * 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.contribution.service; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * Service interface that manages artifacts contributed to a Tuscany runtime. + * + * @version $Rev$ $Date$ + */ +public interface ContributionService { + /** + * Contribute an artifact to the SCA Domain. The type of the contribution is + * determined by the Content-Type of the resource or, if that is undefined, + * by some implementation-specific means (such as mapping an extension in + * the URL's path). + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact + * @param storeInRepository Flag that identifies if you want to copy the + * contribution to the repository + * @return The contribution model representing the contribution + * @throws ContributionException if there was a problem with the contribution + * @throws IOException if there was a problem reading the resource + */ + Contribution contribute(String contributionURI, URL sourceURL, boolean storeInRepository) throws ContributionException, + IOException; + + /** + * Contribute an artifact to the SCA Domain. The type of the contribution is + * determined by the Content-Type of the resource or, if that is undefined, + * by some implementation-specific means (such as mapping an extension in + * the URL's path). + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param storeInRepository Flag that identifies if you want to copy the + * contribution to the repository + * @return The contribution model representing the contribution + * @throws ContributionException if there was a problem with the contribution + * @throws IOException if there was a problem reading the resource + */ + Contribution contribute(String contributionURI, URL sourceURL, ModelResolver modelResolver, boolean storeInRepository) throws ContributionException, + IOException; + + /** + * Contribute an artifact to the SCA Domain. + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact. + * This is used to identify what name should be used when storing + * the contribution on the repository + * @param contributionContent A stream containing the resource being + * contributed; the stream will not be closed but the read + * position after the call is undefined + * @return The contribution model representing the contribution + * @throws ContributionException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + Contribution contribute(String contributionURI, URL sourceURL, InputStream contributionContent) + throws ContributionException, IOException; + + /** + * Contribute an artifact to the SCA Domain. + * + * @param contributionURI The URI that is used as the contribution unique ID. + * @param sourceURL The location of the resource containing the artifact. + * This is used to identify what name should be used when storing + * the contribution on the repository + * @param modelResolver The model resolver to use to resolve models in the + * scope of this contribution + * @param contributionContent A stream containing the resource being + * contributed; the stream will not be closed but the read + * position after the call is undefined + * @return The contribution model representing the contribution + * @throws ContributionException if there was a problem with the contribution + * @throws IOException if there was a problem reading the stream + */ + Contribution contribute(String contributionURI, URL sourceURL, InputStream contributionContent, ModelResolver modelResolver) + throws ContributionException, IOException; + + /** + * Get the model for an installed contribution + * + * @param contribution The URI of an installed contribution + * @return The model for the contribution or null if there is no such + * contribution + */ + Contribution getContribution(String contribution); + + /** + * Adds or updates a deployment composite using a supplied composite + * ("composite by value" - a data structure, not an existing resource in the + * domain) to the contribution identified by a supplied contribution URI. + * The added or updated deployment composite is given a relative URI that + * matches the "name" attribute of the composite, with a ".composite" + * suffix. + * + * @param contribution The contribution to where + * @param composite + * @throws ContributionException + */ + void addDeploymentComposite(Contribution contribution, Composite composite) throws ContributionException; + + /** + * Remove a contribution from the SCA domain + * + * @param contribution The URI of the contribution + * @throws DeploymentException + */ + void remove(String contribution) throws ContributionException; +}
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java new file mode 100644 index 0000000000..8bfdedf180 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ContributionWriteException.java @@ -0,0 +1,61 @@ +/* + * 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.contribution.service; + + +/** + * Denotes an exception while writing artifacts inside an SCA contribution. + * + * @version $Rev$ $Date$ + */ +public class ContributionWriteException extends ContributionException { + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + + public ContributionWriteException(String message) { + super(message); + } + + public ContributionWriteException(String message, Throwable cause) { + super(message, cause); + } + + public ContributionWriteException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being written. + * + * @return the location of the resource that was being written + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being written. + * + * @param resourceURI the location of the resource that was being written + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java new file mode 100644 index 0000000000..1ab80e344b --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/DefaultContributionListenerExtensionPoint.java @@ -0,0 +1,118 @@ +/* + * 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.contribution.service; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; + +/** + * Default implementation of a contribution listener extension point. + * + * @version $Rev$ $Date$ + */ +public class DefaultContributionListenerExtensionPoint implements ContributionListenerExtensionPoint { + + private List<ContributionListener> listeners = new CopyOnWriteArrayList<ContributionListener>(); + private boolean loadedListeners; + private ModelFactoryExtensionPoint modelFactories; + + /** + * Constructs a new DefaultContributionListenerExtensionPoint. + * + */ + public DefaultContributionListenerExtensionPoint(ModelFactoryExtensionPoint modelFactories) { + this.modelFactories = modelFactories; + } + + /** + * Constructs a new DefaultContributionListenerExtensionPoint. + * + */ + public DefaultContributionListenerExtensionPoint(ExtensionPointRegistry extensionPoints) { + this.modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + } + + public void addContributionListener(ContributionListener listener) { + listeners.add(listener); + } + + public List<ContributionListener> getContributionListeners() { + loadListeners(); + return listeners; + } + + public void removeContributionListener(ContributionListener listener) { + listeners.remove(listener); + } + + /** + * Dynamically load listeners declared under META-INF/services + */ + @SuppressWarnings("unchecked") + private synchronized void loadListeners() { + if (loadedListeners) + return; + + // Get the listener service declarations + Set<ServiceDeclaration> listenerDeclarations; + try { + listenerDeclarations = ServiceDiscovery.getInstance().getServiceDeclarations(ContributionListener.class); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Load and instantiate the listeners + for (ServiceDeclaration listenerDeclaration: listenerDeclarations) { + ContributionListener listener; + try { + Class<ContributionListener> listenerClass = (Class<ContributionListener>)listenerDeclaration.loadClass(); + try { + Constructor<ContributionListener> constructor = listenerClass.getConstructor(ModelFactoryExtensionPoint.class); + try { + listener = constructor.newInstance(modelFactories); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } catch (NoSuchMethodException e) { + listener = listenerClass.newInstance(); + } + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + addContributionListener(listener); + } + + loadedListeners = true; + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java new file mode 100644 index 0000000000..fc0dc3aa99 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/ExtensibleContributionListener.java @@ -0,0 +1,77 @@ +/* + * 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.contribution.service; + +import org.apache.tuscany.sca.contribution.Contribution; + +public class ExtensibleContributionListener implements ContributionListener { + private final ContributionListenerExtensionPoint listeners; + + /** + * Default constructor receiving the listener extension point + * + * @param listeners + */ + public ExtensibleContributionListener(ContributionListenerExtensionPoint listeners) { + this.listeners = listeners; + } + + /** + * Process "contributionAdded" event to all registered listeners + */ + public void contributionAdded(ContributionRepository repository, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionAdded(repository, contribution); + } catch (Exception e) { + // ignore, continue to the next listener + } + } + } + + /** + * Process "contributionRemoved" event to all registered listeners + */ + public void contributionRemoved(ContributionRepository repository, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionRemoved(repository, contribution); + } catch (Exception e) { + // ignore, continue to the next listener + } + + } + } + + /** + * Process "contributionUpdated" event to all registered listeners + */ + public void contributionUpdated(ContributionRepository repository, Contribution oldContribution, Contribution contribution) { + for (ContributionListener listener : listeners.getContributionListeners()) { + try { + listener.contributionUpdated(repository, oldContribution, contribution); + } catch (Exception e) { + // ignore, continue to the next listener + } + + } + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java new file mode 100644 index 0000000000..74f303a5a5 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/TypeDescriber.java @@ -0,0 +1,38 @@ +/* + * 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.contribution.service; + +import java.net.URL; + +/** + * Provide content type for a given resource + * + * @version $Rev$ $Date$ + */ +public interface TypeDescriber { + /** + * Get the content type for the specified resource + * + * @param resourceURL The resource URL + * @param defaultType The default content type + * @return The content type + */ + String getType(URL resourceURL, String defaultType); +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java new file mode 100644 index 0000000000..ff21c894de --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnrecognizedElementException.java @@ -0,0 +1,48 @@ +/* + * 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.contribution.service; + +import javax.xml.namespace.QName; + +/** + * Exception that indicates an element was encountered that could not be handled. + * + * @version $Rev$ $Date$ + */ +public class UnrecognizedElementException extends ContributionReadException { + private static final long serialVersionUID = 2549543622209829032L; + private final QName element; + + /** + * Constructor that indicates which element could not be handled. + * @param element the element that could not be handled + */ + public UnrecognizedElementException(QName element) { + super("Unrecognized element: " + element); + this.element = element; + } + + /** + * Returns the element that could not be handled. + * @return the element that could not be handled. + */ + public QName getElement() { + return element; + } +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java new file mode 100644 index 0000000000..0660d69897 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedContentTypeException.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.contribution.service; + +/** + * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain. + * The Content-Type value supplied will be returned as the message text for this exception. + * + * FIXME Don't use as it's deprecated and replaced by UnsupportedPackageTypeException. + * + * @version $Rev$ $Date$ + */ +@Deprecated +public class UnsupportedContentTypeException extends ContributionException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructs a new UnsupportedContentTypeException. + * + * @param message + */ + public UnsupportedContentTypeException(String message) { + super(message); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedPackageTypeException.java b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedPackageTypeException.java new file mode 100644 index 0000000000..33c847a049 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/service/UnsupportedPackageTypeException.java @@ -0,0 +1,39 @@ +/* + * 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.contribution.service; + +/** + * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain. + * The Content-Type value supplied will be returned as the message text for this exception. + * + * @version $Rev$ $Date$ + */ +public class UnsupportedPackageTypeException extends ContributionException { + private static final long serialVersionUID = -1831797280021355672L; + + /** + * Constructs a new UnsupportedPackageTypeException. + * + * @param message + */ + public UnsupportedPackageTypeException(String message) { + super(message); + } + +} diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory new file mode 100644 index 0000000000..bcc346d9f8 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ContributionFactory @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.DefaultContributionFactory
\ No newline at end of file diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint new file mode 100644 index 0000000000..6b4d2ebdeb --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.DefaultModelFactoryExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint new file mode 100644 index 0000000000..9e6433ba6c --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultContributionPostProcessorExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessorExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessorExtensionPoint new file mode 100644 index 0000000000..7609eda0d1 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.PackageProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultPackageProcessorExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint new file mode 100644 index 0000000000..8ea5fc0a7e --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint new file mode 100644 index 0000000000..9d78ca93d0 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultURLArtifactProcessorExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint new file mode 100644 index 0000000000..ae6e876df6 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.processor.DefaultValidationSchemaExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint new file mode 100644 index 0000000000..4bb65e55e7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.resolver.DefaultModelResolverExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint new file mode 100644 index 0000000000..727f8f6ce7 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.scanner.DefaultContributionScannerExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListenerExtensionPoint b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListenerExtensionPoint new file mode 100644 index 0000000000..6e61bebf79 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.service.ContributionListenerExtensionPoint @@ -0,0 +1,18 @@ +# 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.
+
+org.apache.tuscany.sca.contribution.service.DefaultContributionListenerExtensionPoint
diff --git a/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/contribution-validation-messages.properties b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/contribution-validation-messages.properties new file mode 100644 index 0000000000..bd650fe457 --- /dev/null +++ b/tags/java/sca/1.3-RC1a/modules/contribution/src/main/resources/contribution-validation-messages.properties @@ -0,0 +1,31 @@ +# +# +# 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. +# +# +SchemaError = XMLSchema validation error occured in: {0} ,line = {1}, column = {2}, Message = {3} +SchemaFatalError = XMLSchema validation fatal error occured in: {0} ,line = {1}, column = {2}, Message = {3} +SchemaWarning = XMLSchema validation warning occured in: {0} ,line = {1}, column = {2}, Message = {3} +UnsupportedPackageTypeException = Unsupported contribution package type: {0} +ElementCannotBeProcessed = Element {0} cannot be processed. ({1}) +NoStaxProcessor = No StAX processor is configured to handle {0} +ContributionWriteException = ContributionWriteException occured due to : +ContributionReadException = ContributionReadException occured due to : +UnrecognizedElementException = Unrecognized Element : {0} +IllegalArgumentException = Invalid qname: {0} +PrivilegedActionException = PrivilegedActionException occured due to : |