summaryrefslogtreecommitdiffstats
path: root/tags/java/sca/2.0-M1/tools/maven
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-03-09 22:39:04 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-03-09 22:39:04 +0000
commita396aa07f68368d5a40dba071008bdec4e1a46ca (patch)
treedb0a63639024b04bcdbea36e32c8e31d75f8e62f /tags/java/sca/2.0-M1/tools/maven
parentfb958a75b99c50cfd90d3d6dd22c5e55447558b5 (diff)
2.0-M1 Final Release Tag
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@751885 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'tags/java/sca/2.0-M1/tools/maven')
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/pom.xml64
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/src/main/java/org/apache/tuscany/sca/tools/ant/generator/plugin/AntGeneratorMojo.java534
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/pom.xml81
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java1136
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java530
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java231
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java1556
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java351
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java68
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactAggregation.java73
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactMember.java61
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/BundleUtil.java387
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ModuleBundlesBuildMojo.java828
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ThirdPartyBundleBuildMojo.java152
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties78
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/LICENSE.txt205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/NOTICE.txt5
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/README46
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/pom.xml71
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/src/main/java/org/apache/tuscany/tools/sca/dependency/lister/plugin/DependencyListerMojo.java198
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/pom.xml304
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/ClassLoaderNameEnvironment.java195
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/CompilerRequestor.java114
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/FileCompilationUnit.java88
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/JavaCompiler.java212
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleResolver.java490
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleUtil.java618
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/resources/META-INF/plexus/components.xml28
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/pom.xml108
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/src/main/java/org/apache/tuscany/sca/tools/incremental/build/plugin/IncrementalBuildMojo.java415
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/pom.xml45
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/src/main/java/org/apache/tuscany/tools/java2wsdl/plugin/Java2WSDLGeneratorMojo.java153
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/pom.xml70
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/ForkConfiguration.java239
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefireBooter.java984
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefirePlugin.java1306
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-web-junit/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-web-junit/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-web-junit/pom.xml52
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitGeneratorMojo.java181
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitMojo.java205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/LICENSE205
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/NOTICE6
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/pom.xml45
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDL2JavaGeneratorMojo.java152
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDLFileOption.java92
-rw-r--r--tags/java/sca/2.0-M1/tools/maven/pom.xml62
61 files changed, 14712 insertions, 0 deletions
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/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/2.0-M1/tools/maven/maven-ant-generator/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/pom.xml
new file mode 100644
index 0000000000..b46c3125e1
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-ant-generator</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Ant Build Generator Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/src/main/java/org/apache/tuscany/sca/tools/ant/generator/plugin/AntGeneratorMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/src/main/java/org/apache/tuscany/sca/tools/ant/generator/plugin/AntGeneratorMojo.java
new file mode 100644
index 0000000000..d7b80bd67c
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-ant-generator/src/main/java/org/apache/tuscany/sca/tools/ant/generator/plugin/AntGeneratorMojo.java
@@ -0,0 +1,534 @@
+/*
+ * 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.tools.ant.generator.plugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.model.FileSet;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * A Maven plugin that generates an Ant build.xml file for Tuscany SCA samples.
+ *
+ * Build dependencies and additional build steps like WSDL2Java for example are
+ * automatically determined from the pom.xml file describing the module's Maven build.
+ *
+ * @version $Rev$ $Date$
+ * @goal generate
+ * @phase generate-sources
+ * @requiresDependencyResolution test
+ * @description Generate Ant build script for an SCA project
+ */
+public class AntGeneratorMojo extends AbstractMojo {
+
+ /**
+ * The project to generate an Ant build for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ */
+ private MavenProject project;
+
+ /**
+ * Used for resolving artifacts
+ *
+ * @component
+ */
+ private ArtifactResolver resolver;
+
+ /**
+ * Factory for creating artifact objects
+ *
+ * @component
+ */
+ private ArtifactFactory factory;
+
+ /**
+ * The local repository where the artifacts are located
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ */
+ private ArtifactRepository localRepository;
+
+ /**
+ * The remote repositories where artifacts are located
+ *
+ * @parameter expression="${project.remoteArtifactRepositories}"
+ */
+ private List remoteRepositories;
+
+ /**
+ * The current user system settings for use in Maven.
+ *
+ * @parameter expression="${settings}"
+ * @required
+ * @readonly
+ */
+ private Settings settings;
+
+ /**
+ * The main class name.
+ * @parameter
+ */
+ private String mainClass;
+
+ /**
+ * If set true then only the dependency file is created. The dependency
+ * file can then be included in a hand generated build.xml file
+ * @parameter
+ */
+ private Boolean buildDependencyFileOnly;
+
+ /**
+ * The build.xml file to generate.
+ * @parameter expression="${basedir}/build.xml"
+ */
+ private String buildFile;
+
+ /**
+ * The build-dependency.xml file to generate.
+ * @parameter expression="${basedir}/build-dependency.xml"
+ */
+ private String buildDependencyFile;
+
+ public void execute() throws MojoExecutionException {
+ if ((buildDependencyFileOnly != null) &&
+ (buildDependencyFileOnly == true)){
+ generateBuildDependencyFile();
+ } else {
+ generateBuildFile();
+ }
+ }
+
+ /**
+ * Generate Ant build dependency XML file
+ */
+ private void generateBuildDependencyFile() throws MojoExecutionException {
+
+ getLog().info("Generating " + buildDependencyFile);
+
+ // Open the target build-dependency.xml file
+ File targetFile = new File(buildDependencyFile);
+ PrintWriter pw;
+ try {
+ pw = new PrintWriter(new FileOutputStream(targetFile));
+ } catch (FileNotFoundException e) {
+ throw new MojoExecutionException(e.toString());
+ }
+
+ // Generate the Apache license header
+ generateLicenseHeader(pw);
+
+ // Generate Ant filesets representing the build dependencies
+ generateBuildDependencies(pw);
+
+ pw.close();
+ }
+
+ /**
+ * Generate Ant build XML file
+ */
+ private void generateBuildFile() throws MojoExecutionException {
+
+ getLog().info("Generating " + buildFile);
+
+ // Open the target build.xml file
+ File targetFile = new File(buildFile);
+ PrintWriter pw;
+ try {
+ pw = new PrintWriter(new FileOutputStream(targetFile));
+ } catch (FileNotFoundException e) {
+ throw new MojoExecutionException(e.toString());
+ }
+
+ // Determine the project packaging
+ String packaging = project.getPackaging().toLowerCase();
+
+ // Generate the Apache license header
+ generateLicenseHeader(pw);
+
+ pw.println("<project name=\"" + project.getArtifactId() + "\" default=\"compile\">");
+ pw.println();
+
+ // Generate the compile target
+ int base = project.getBasedir().toString().length() + 1;
+ pw.println(" <target name=\"compile\">");
+ pw.println(" <mkdir dir=\"target/classes\"/>");
+
+ // Generate any pre-compilation tasks
+ generatePreCompileTasks(pw);
+
+ // Generate the compile task
+ pw.println(" <javac destdir=\"target/classes\" debug=\"on\" source=\"1.5\" target=\"1.5\">");
+ for (String source: (List<String>)project.getCompileSourceRoots()) {
+ if (source.length() > base) {
+ source = source.substring(base);
+ } else {
+ source = ".";
+ }
+ pw.println(" <src path=\"" + source + "\"/>");
+ }
+ pw.println(" <classpath>");
+ pw.println(" <fileset refid=\"tuscany.jars\"/>");
+ pw.println(" <fileset refid=\"3rdparty.jars\"/>");
+ pw.println(" </classpath>");
+ pw.println(" </javac>");
+ pw.println(" <copy todir=\"target/classes\">");
+ for (FileSet resource: (List<FileSet>)project.getResources()) {
+ String source = resource.getDirectory();
+ if (source.length() > base) {
+ source = source.substring(base);
+
+ if (source.equals(".")){
+ pw.println(" <fileset dir=\".\" includes=\"*\" excludes=\"src, target, pom.xml, build.xml\"/>");
+ } else {
+ pw.println(" <fileset dir=\"" + source + "\"/>");
+ }
+ } else {
+ if (project.getResources().size() > 1) {
+ break;
+ }
+ pw.println(" <fileset dir=\".\" excludes=\"**/*.java, pom.xml, build.xml, target\"/>");
+ source = ".";
+ }
+ }
+ pw.println(" </copy>");
+
+ // Build a JAR
+ if (packaging.equals("jar")) {
+ pw.println(" <jar destfile=\"target/" + project.getArtifactId() + ".jar\" basedir=\"target/classes\">");
+ pw.println(" <manifest>");
+ if (mainClass != null) {
+ pw.println(" <attribute name=\"Main-Class\" value=\"" + mainClass + "\"/>");
+ }
+ pw.println(" </manifest>");
+ pw.println(" </jar>");
+
+ } else if (packaging.equals("war")) {
+
+ // Build a WAR
+ pw.println(" <war destfile=\"target/" + project.getArtifactId() + ".war\" webxml=\"src/main/webapp/WEB-INF/web.xml\">");
+ pw.println(" <fileset dir=\"src/main/webapp\"/>");
+ pw.println(" <lib refid=\"tuscany.jars\"/>");
+ pw.println(" <lib refid=\"3rdparty.jars\"/>");
+ pw.println(" <classes dir=\"target/classes\"/>");
+ pw.println(" </war>");
+ }
+ pw.println(" </target>");
+ pw.println();
+
+
+ // Generate a package target alongside the compile target
+ // Tuscany SCA samples use "package" as the target for webapps
+ pw.println(" <target name=\"package\" depends=\"compile\"/>");
+ pw.println();
+
+ // Generate the run target
+ if (mainClass != null) {
+ pw.println(" <target name=\"run\">");
+ pw.println(" <java classname=\"" + mainClass + "\" fork=\"true\">");
+ pw.println(" <classpath>");
+ pw.println(" <pathelement location=\"target/" + project.getArtifactId() + ".jar\"/>");
+ pw.println(" <fileset refid=\"tuscany.jars\"/>");
+ pw.println(" <fileset refid=\"3rdparty.jars\"/>");
+ pw.println(" </classpath>");
+ pw.println(" </java>");
+ pw.println(" </target>");
+ pw.println();
+ }
+
+ // Generate the clean target
+ pw.println(" <target name=\"clean\">");
+ pw.println(" <delete includeemptydirs=\"true\">");
+ pw.println(" <fileset dir=\"target\"/>");
+ pw.println(" </delete>");
+ pw.println(" </target>");
+ pw.println();
+
+ // Generate Ant filesets representing the build dependencies
+ generateBuildDependencies(pw);
+
+ pw.println("</project>");
+ pw.close();
+ }
+
+ /**
+ * Generate Ant filesets representing the build dependencies.
+ * @param pw PrintWriter to write to
+ */
+ private void generateBuildDependencies(PrintWriter pw) {
+
+ // Determine the module dependencies
+ List<String> tuscanyModules = new ArrayList<String>();
+ List<String> otherModules = new ArrayList<String>();
+ for (Artifact artifact: (List<Artifact>)project.getRuntimeArtifacts()) {
+ if (artifact.getGroupId().startsWith("org.apache.tuscany.sca")) {
+ tuscanyModules.add(artifact.getFile().getName());
+ } else {
+ otherModules.add(artifact.getFile().getName());
+ }
+ }
+
+ // Sort lists of modules, making output deterministic
+ Collections.sort(tuscanyModules);
+ Collections.sort(otherModules);
+
+ // Generate filesets for the tuscany and 3rd party dependencies
+ pw.println(" <fileset id=\"tuscany.jars\" dir=\"../../modules\">");
+ for (String name: tuscanyModules) {
+ pw.println(" <include name=\"" + name +"\"/>");
+ }
+ pw.println(" </fileset>");
+ pw.println(" <fileset id=\"3rdparty.jars\" dir=\"../../lib\">");
+ for (String name: otherModules) {
+ pw.println(" <include name=\"" + name +"\"/>");
+ }
+ pw.println(" </fileset>");
+ pw.println();
+ }
+
+ /**
+ * Extract plugin execution configurations out of the Maven model. This handles
+ * nested configurations with a base configuration and a collection of nested
+ * configuration elements, for example:
+ * <configuration>
+ * <schemaFiles>
+ * <configuration>
+ * <fileName>x.wsdl</fileName>
+ * </configuration>
+ * <configuration>
+ * <fileName>y.wsdl</fileName>
+ * </configuration>
+ * </schemaFiles>
+ * <noNotification>true</noNotification>
+ * </configuration>
+ *
+ * @param execution Maven plugin execution model
+ * @return a list of maps containing the plugin configuration key value pairs
+ */
+ private static List<Map<String, String>> pluginConfigurations(PluginExecution execution) {
+ List<Map<String, String>> configurations = new ArrayList<Map<String,String>>();
+ Map<String, String> topConfiguration = new HashMap<String, String>();
+
+ Xpp3Dom dom = (Xpp3Dom)execution.getConfiguration();
+ for (Xpp3Dom element: dom.getChildren()) {
+ if (element.getChildCount() != 0) {
+ // Handle nested configuration element, create a child configuration
+ // for each
+ for (Xpp3Dom childConfigurationElement: element.getChildren()) {
+ Map<String, String> childConfiguration = new HashMap<String, String>();
+ for (Xpp3Dom childElement: childConfigurationElement.getChildren()) {
+ childConfiguration.put(childElement.getName(), childElement.getValue());
+ }
+ configurations.add(childConfiguration);
+ }
+ } else {
+ // Handle top level key value pair element
+ topConfiguration.put(element.getName(), element.getValue());
+ }
+ }
+ // Return the top configuration or the child configurations merged
+ // with the top one
+ if (configurations.isEmpty()) {
+ configurations.add(topConfiguration);
+ } else {
+ for (Map<String, String> configuration: configurations) {
+ configuration.putAll(topConfiguration);
+ }
+ }
+ return configurations;
+ }
+
+ /**
+ * Generate Ant tasks for the pre-compilation generation plugins
+ * used in the Maven module.
+ * @param pw PrintWriter to write to
+ * @return list of directories containing generated source to compile
+ */
+ private void generatePreCompileTasks(PrintWriter pw) {
+ String baseDir = project.getBasedir().getAbsolutePath() + '/';
+
+ List<Plugin> plugins = (List<Plugin>)project.getBuildPlugins();
+ for (Plugin plugin: plugins) {
+
+ // Generate Ant task equivalent to the Tuscany SDO plugin
+ if ("org.apache.tuscany.sdo".equals(plugin.getGroupId()) && "tuscany-sdo-plugin".equals(plugin.getArtifactId())) {
+ for (PluginExecution execution: (List<PluginExecution>)plugin.getExecutions()) {
+ for (Map<String, String> configuration: pluginConfigurations(execution)) {
+
+ pw.println(" <java classname=\"org.apache.tuscany.sdo.generate.XSD2JavaGenerator\" fork=\"true\">");
+
+ // Generate the various code generation options
+ for (Map.Entry<String, String> element: configuration.entrySet()) {
+ String key = element.getKey();
+ String value = element.getValue();
+ if (key.equals("schemaNamespace")) {
+ pw.println(" <arg value=\"-schemaNamespace\"/>");
+ pw.println(" <arg value=\"" + value + "\"/>");
+ }
+ if (key.equals("javaPackage")) {
+ pw.println(" <arg value=\"-javaPackage\"/>");
+ pw.println(" <arg value=\"" + value + "\"/>");
+ }
+ if (key.equals("prefix")) {
+ pw.println(" <arg value=\"-prefix\"/>");
+ pw.println(" <arg value=\"" + value + "\"/>");
+ }
+ if (key.equals("noInterfaces") && "true".equals(value)) {
+ pw.println(" <arg value=\"-noInterfaces\"/>");
+ }
+ if (key.equals("noNotification") && "true".equals(value)) {
+ pw.println(" <arg value=\"-noNotification\"/>");
+ }
+ if (key.equals("noContainer") && "true".equals(value)) {
+ pw.println(" <arg value=\"-noContainment\"/>");
+ }
+ if (key.equals("noUnsettable") && "true".equals(value)) {
+ pw.println(" <arg value=\"-noUnsettable\"/>");
+ }
+ }
+
+ // Generate target directory parameter
+ String targetDirectory = configuration.get("targetDirectory");
+ if (targetDirectory == null) {
+ targetDirectory = "target/sdo-source";
+ } else if (targetDirectory.startsWith(baseDir)) {
+ targetDirectory = targetDirectory.substring(baseDir.length());
+ }
+ pw.println(" <arg value=\"-targetDirectory\"/>");
+ pw.println(" <arg value=\"" + targetDirectory + "\"/>");
+
+ // Generate schema file parameter
+ String schemaFile = configuration.get("schemaFile");
+ if (schemaFile == null) {
+ schemaFile = configuration.get("fileName");
+ }
+ if (schemaFile != null) {
+ if (schemaFile.startsWith(baseDir)) {
+ schemaFile = schemaFile.substring(baseDir.length());
+ }
+ pw.println(" <arg value=\"" + schemaFile + "\"/>");
+ }
+
+ pw.println(" <classpath>");
+ pw.println(" <fileset refid=\"tuscany.jars\"/>");
+ pw.println(" <fileset refid=\"3rdparty.jars\"/>");
+ pw.println(" </classpath>");
+ pw.println(" </java>");
+ }
+ }
+ }
+
+ // Generate Ant task equivalent to the Tuscany WSDL2Java plugin
+ else if ("org.apache.tuscany.sca".equals(plugin.getGroupId()) && "tuscany-maven-wsdl2java".equals(plugin.getArtifactId())) {
+ for (PluginExecution execution: (List<PluginExecution>)plugin.getExecutions()) {
+ for (Map<String, String> configuration: pluginConfigurations(execution)) {
+
+ pw.println(" <java classname=\"org.apache.tuscany.tools.wsdl2java.generate.WSDL2JavaGenerator\" fork=\"true\">");
+
+ // Generate the various code generation options
+ for (Map.Entry<String, String> element: configuration.entrySet()) {
+ String key = element.getKey();
+ String value = element.getValue();
+ if (key.equals("javaPackage")) {
+ pw.println(" <arg value=\"-javaPackage\"/>");
+ pw.println(" <arg value=\"" + value + "\"/>");
+ }
+ }
+
+ // Generate target directory parameter
+ String targetDirectory = configuration.get("targetDirectory");
+ if (targetDirectory == null) {
+ targetDirectory = "target/wsdl2java-source";
+ } else if (targetDirectory.startsWith(baseDir)) {
+ targetDirectory = targetDirectory.substring(baseDir.length());
+ }
+ pw.println(" <arg value=\"-targetDirectory\"/>");
+ pw.println(" <arg value=\"" + targetDirectory + "\"/>");
+
+ // Generate WSDL file parameter
+ String wsdlFile = configuration.get("wsdlFile");
+ if (wsdlFile == null) {
+ wsdlFile = configuration.get("fileName");
+ }
+ if (wsdlFile != null) {
+ if (wsdlFile.startsWith(baseDir)) {
+ wsdlFile = wsdlFile.substring(baseDir.length());
+ }
+ pw.println(" <arg value=\"" + wsdlFile + "\"/>");
+ }
+
+ pw.println(" <classpath>");
+ pw.println(" <fileset refid=\"tuscany.jars\"/>");
+ pw.println(" <fileset refid=\"3rdparty.jars\"/>");
+ pw.println(" </classpath>");
+ pw.println(" </java>");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Generate license header.
+ *
+ * @param pw PrintWriter to write to
+ */
+ private void generateLicenseHeader(PrintWriter pw) {
+ pw.println("<!--");
+ pw.println(" * Licensed to the Apache Software Foundation (ASF) under one");
+ pw.println(" * or more contributor license agreements. See the NOTICE file");
+ pw.println(" * distributed with this work for additional information");
+ pw.println(" * regarding copyright ownership. The ASF licenses this file");
+ pw.println(" * to you under the Apache License, Version 2.0 (the");
+ pw.println(" * \"License\"); you may not use this file except in compliance");
+ pw.println(" * with the License. You may obtain a copy of the License at");
+ pw.println(" * ");
+ pw.println(" * http://www.apache.org/licenses/LICENSE-2.0");
+ pw.println(" * ");
+ pw.println(" * Unless required by applicable law or agreed to in writing,");
+ pw.println(" * software distributed under the License is distributed on an");
+ pw.println(" * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY");
+ pw.println(" * KIND, either express or implied. See the License for the");
+ pw.println(" * specific language governing permissions and limitations");
+ pw.println(" * under the License.");
+ pw.println("-->");
+ pw.println();
+ }
+
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/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/2.0-M1/tools/maven/maven-bundle-plugin/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/pom.xml
new file mode 100644
index 0000000000..8c3a9576c9
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/pom.xml
@@ -0,0 +1,81 @@
+<?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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-bundle-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Maven OSGi Bundle Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-dependency-tree</artifactId>
+ <version>1.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.3</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.5.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
new file mode 100644
index 0000000000..8d2663a8b9
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/AbstractIdeSupportMojo.java
@@ -0,0 +1,1136 @@
+/*
+ * 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.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipFile;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.DebugResolutionListener;
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.resolver.WarningResolutionListener;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * Abstract base plugin which takes care of the common stuff usually needed by maven IDE plugins. A plugin extending
+ * AbstractIdeSupportMojo should implement the <code>setup()</code> and <code>writeConfiguration()</code> methods,
+ * plus the getters needed to get the various configuration flags and required components. The lifecycle:
+ *
+ * <pre>
+ * *** calls setup() where you can configure your specific stuff and stop the mojo from execute if appropriate ***
+ * - manually resolve project dependencies, NOT failing if a dependency is missing
+ * - compute project references (reactor projects) if the getUseProjectReferences() flag is set
+ * - download sources/javadocs if the getDownloadSources() flag is set
+ * *** calls writeConfiguration(), passing the list of resolved referenced dependencies ***
+ * - report the list of missing sources or just tell how to turn this feature on if the flag was disabled
+ * </pre>
+ *
+ * @author Fabrizio Giustina
+ * @version $Id: AbstractIdeSupportMojo.java 628794 2008-02-18 16:09:11Z aheritier $
+ */
+public abstract class AbstractIdeSupportMojo
+ extends AbstractMojo
+ implements LogEnabled
+{
+ /**
+ * Is it an PDE project? If yes, the plugin adds the necessary natures and build commands to the .project file.
+ * Additionally it copies all libraries to a project local directory and references them instead of referencing the
+ * files in the local Maven repository. It also ensured that the "Bundle-Classpath" in META-INF/MANIFEST.MF is
+ * synchronized.
+ *
+ * @parameter expression="${eclipse.pde}" default-value="true"
+ */
+ protected boolean pde;
+
+ /**
+ * The project whose project files to create.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ protected MavenProject project;
+
+ // [rfeng] Change it to use the current project
+ /**
+ * The currently executed project (can be a reactor project).
+ *
+ * @parameter expression="${executedProject}"
+ * @readonly
+ */
+ protected MavenProject executedProject;
+
+ /**
+ * The project packaging.
+ *
+ * @parameter expression="${project.packaging}"
+ */
+ protected String packaging;
+
+ /**
+ * Artifact factory, needed to download source jars for inclusion in classpath.
+ *
+ * @component role="org.apache.maven.artifact.factory.ArtifactFactory"
+ * @required
+ * @readonly
+ */
+ protected ArtifactFactory artifactFactory;
+
+ /**
+ * Artifact resolver, needed to download source jars for inclusion in classpath.
+ *
+ * @component role="org.apache.maven.artifact.resolver.ArtifactResolver"
+ * @required
+ * @readonly
+ */
+ protected ArtifactResolver artifactResolver;
+
+ /**
+ * Artifact collector, needed to resolve dependencies.
+ *
+ * @component role="org.apache.maven.artifact.resolver.ArtifactCollector"
+ * @required
+ * @readonly
+ */
+ protected ArtifactCollector artifactCollector;
+
+ /**
+ * @component role="org.apache.maven.artifact.metadata.ArtifactMetadataSource" hint="maven"
+ */
+ protected ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * Remote repositories which will be searched for source attachments.
+ *
+ * @parameter expression="${project.remoteArtifactRepositories}"
+ * @required
+ * @readonly
+ */
+ protected List remoteArtifactRepositories;
+
+ /**
+ * Local maven repository.
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ * @readonly
+ */
+ protected ArtifactRepository localRepository;
+
+ /**
+ * If the executed project is a reactor project, this will contains the full list of projects in the reactor.
+ *
+ * @parameter expression="${reactorProjects}"
+ * @required
+ * @readonly
+ */
+ protected List reactorProjects;
+
+ /**
+ * Skip the operation when true.
+ *
+ * @parameter expression="${eclipse.skip}" default-value="false"
+ */
+ private boolean skip;
+
+ /**
+ * Enables/disables the downloading of source attachments. Defaults to false. When this flag is <code>true</code>
+ * remote repositories are checked for sources: in order to avoid repeated check for unavailable source archives, a
+ * status cache is mantained into the target dir of the root project. Run <code>mvn:clean</code> or delete the
+ * file <code>mvn-eclipse-cache.properties</code> in order to reset this cache.
+ *
+ * @parameter expression="${downloadSources}"
+ */
+ protected boolean downloadSources;
+
+ /**
+ * Enables/disables the downloading of javadoc attachments. Defaults to false. When this flag is <code>true</code>
+ * remote repositories are checked for javadocs: in order to avoid repeated check for unavailable javadoc archives,
+ * a status cache is mantained into the target dir of the root project. Run <code>mvn:clean</code> or delete the
+ * file <code>mvn-eclipse-cache.properties</code> in order to reset this cache.
+ *
+ * @parameter expression="${downloadJavadocs}"
+ */
+ protected boolean downloadJavadocs;
+
+ /**
+ * Plexus logger needed for debugging manual artifact resolution.
+ */
+ protected Logger logger;
+
+ /**
+ * Getter for <code>artifactMetadataSource</code>.
+ *
+ * @return Returns the artifactMetadataSource.
+ */
+ public ArtifactMetadataSource getArtifactMetadataSource()
+ {
+ return artifactMetadataSource;
+ }
+
+ /**
+ * Setter for <code>artifactMetadataSource</code>.
+ *
+ * @param artifactMetadataSource The artifactMetadataSource to set.
+ */
+ public void setArtifactMetadataSource( ArtifactMetadataSource artifactMetadataSource )
+ {
+ this.artifactMetadataSource = artifactMetadataSource;
+ }
+
+ /**
+ * Getter for <code>project</code>.
+ *
+ * @return Returns the project.
+ */
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ /**
+ * Setter for <code>project</code>.
+ *
+ * @param project The project to set.
+ */
+ public void setProject( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ /**
+ * Getter for <code>reactorProjects</code>.
+ *
+ * @return Returns the reactorProjects.
+ */
+ public List getReactorProjects()
+ {
+ return reactorProjects;
+ }
+
+ /**
+ * Setter for <code>reactorProjects</code>.
+ *
+ * @param reactorProjects The reactorProjects to set.
+ */
+ public void setReactorProjects( List reactorProjects )
+ {
+ this.reactorProjects = reactorProjects;
+ }
+
+ /**
+ * Getter for <code>remoteArtifactRepositories</code>.
+ *
+ * @return Returns the remoteArtifactRepositories.
+ */
+ public List getRemoteArtifactRepositories()
+ {
+ return remoteArtifactRepositories;
+ }
+
+ /**
+ * Setter for <code>remoteArtifactRepositories</code>.
+ *
+ * @param remoteArtifactRepositories The remoteArtifactRepositories to set.
+ */
+ public void setRemoteArtifactRepositories( List remoteArtifactRepositories )
+ {
+ this.remoteArtifactRepositories = remoteArtifactRepositories;
+ }
+
+ /**
+ * Getter for <code>artifactFactory</code>.
+ *
+ * @return Returns the artifactFactory.
+ */
+ public ArtifactFactory getArtifactFactory()
+ {
+ return artifactFactory;
+ }
+
+ /**
+ * Setter for <code>artifactFactory</code>.
+ *
+ * @param artifactFactory The artifactFactory to set.
+ */
+ public void setArtifactFactory( ArtifactFactory artifactFactory )
+ {
+ this.artifactFactory = artifactFactory;
+ }
+
+ /**
+ * Getter for <code>artifactResolver</code>.
+ *
+ * @return Returns the artifactResolver.
+ */
+ public ArtifactResolver getArtifactResolver()
+ {
+ return artifactResolver;
+ }
+
+ /**
+ * Setter for <code>artifactResolver</code>.
+ *
+ * @param artifactResolver The artifactResolver to set.
+ */
+ public void setArtifactResolver( ArtifactResolver artifactResolver )
+ {
+ this.artifactResolver = artifactResolver;
+ }
+
+ /**
+ * Getter for <code>executedProject</code>.
+ *
+ * @return Returns the executedProject.
+ */
+ public MavenProject getExecutedProject()
+ {
+ return executedProject;
+ }
+
+ /**
+ * Setter for <code>executedProject</code>.
+ *
+ * @param executedProject The executedProject to set.
+ */
+ public void setExecutedProject( MavenProject executedProject )
+ {
+ this.executedProject = executedProject;
+ }
+
+ /**
+ * Getter for <code>localRepository</code>.
+ *
+ * @return Returns the localRepository.
+ */
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ /**
+ * Setter for <code>localRepository</code>.
+ *
+ * @param localRepository The localRepository to set.
+ */
+ public void setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ }
+
+ /**
+ * Getter for <code>downloadJavadocs</code>.
+ *
+ * @return Returns the downloadJavadocs.
+ */
+ public boolean getDownloadJavadocs()
+ {
+ return downloadJavadocs;
+ }
+
+ /**
+ * Setter for <code>downloadJavadocs</code>.
+ *
+ * @param downloadJavadocs The downloadJavadocs to set.
+ */
+ public void setDownloadJavadocs( boolean downloadJavadoc )
+ {
+ downloadJavadocs = downloadJavadoc;
+ }
+
+ /**
+ * Getter for <code>downloadSources</code>.
+ *
+ * @return Returns the downloadSources.
+ */
+ public boolean getDownloadSources()
+ {
+ return downloadSources;
+ }
+
+ /**
+ * Setter for <code>downloadSources</code>.
+ *
+ * @param downloadSources The downloadSources to set.
+ */
+ public void setDownloadSources( boolean downloadSources )
+ {
+ this.downloadSources = downloadSources;
+ }
+
+ protected void setResolveDependencies( boolean resolveDependencies )
+ {
+ this.resolveDependencies = resolveDependencies;
+ }
+
+ protected boolean isResolveDependencies()
+ {
+ return resolveDependencies;
+ }
+
+ /**
+ * return <code>false</code> if projects available in a reactor build should be considered normal dependencies,
+ * <code>true</code> if referenced project will be linked and not need artifact resolution.
+ *
+ * @return <code>true</code> if referenced project will be linked and not need artifact resolution
+ */
+ protected abstract boolean getUseProjectReferences();
+
+ /**
+ * Hook for preparation steps before the actual plugin execution.
+ *
+ * @return <code>true</code> if execution should continue or <code>false</code> if not.
+ * @throws MojoExecutionException generic mojo exception
+ */
+ protected abstract boolean setup()
+ throws MojoExecutionException;
+
+ /**
+ * Main plugin method where dependencies should be processed in order to generate IDE configuration files.
+ *
+ * @param deps list of <code>IdeDependency</code> objects, with artifacts, sources and javadocs already resolved
+ * @throws MojoExecutionException generic mojo exception
+ */
+ protected abstract void writeConfiguration( IdeDependency[] deps )
+ throws MojoExecutionException;
+
+ /**
+ * Not a plugin parameter. Collect the list of dependencies with a missing source artifact for the final report.
+ */
+ private List missingSourceDependencies = new ArrayList();
+
+ /**
+ * Not a plugin parameter. Collect the list of dependencies with a missing javadoc artifact for the final report.
+ */
+ // TODO merge this with the missingSourceDependencies in a classifier based map?
+ private List missingJavadocDependencies = new ArrayList();
+
+ /**
+ * Cached array of resolved dependencies.
+ */
+ private IdeDependency[] ideDeps;
+
+ /**
+ * Flag for mojo implementations to control whether normal maven dependencies should be resolved. Default value is
+ * true.
+ */
+ private boolean resolveDependencies = true;
+
+ /**
+ * @see org.codehaus.plexus.logging.LogEnabled#enableLogging(org.codehaus.plexus.logging.Logger)
+ */
+ public void enableLogging( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.Mojo#execute()
+ */
+ public final void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ if ( skip )
+ {
+ return;
+ }
+
+ boolean processProject = setup();
+ if ( !processProject )
+ {
+ return;
+ }
+
+ // resolve artifacts
+ IdeDependency[] deps = doDependencyResolution();
+
+ resolveSourceAndJavadocArtifacts( deps );
+
+ writeConfiguration( deps );
+
+ reportMissingArtifacts();
+
+ }
+
+ /**
+ * Resolve project dependencies. Manual resolution is needed in order to avoid resolution of multiproject artifacts
+ * (if projects will be linked each other an installed jar is not needed) and to avoid a failure when a jar is
+ * missing.
+ *
+ * @throws MojoExecutionException if dependencies can't be resolved
+ * @return resolved IDE dependencies, with attached jars for non-reactor dependencies
+ */
+ protected IdeDependency[] doDependencyResolution()
+ throws MojoExecutionException
+ {
+ if ( ideDeps == null )
+ {
+ if ( resolveDependencies )
+ {
+ MavenProject project = getProject();
+ ArtifactRepository localRepo = getLocalRepository();
+
+ List deps = getProject().getDependencies();
+
+ // Collect the list of resolved IdeDependencies.
+ List dependencies = new ArrayList();
+
+ if ( deps != null )
+ {
+ Map managedVersions =
+ createManagedVersionMap( getArtifactFactory(), project.getId(),
+ project.getDependencyManagement() );
+
+ ArtifactResolutionResult artifactResolutionResult = null;
+
+ try
+ {
+
+ List listeners = new ArrayList();
+
+ if ( logger.isDebugEnabled() )
+ {
+ listeners.add( new DebugResolutionListener( logger ) );
+ }
+
+ listeners.add( new WarningResolutionListener( logger ) );
+
+ artifactResolutionResult =
+ artifactCollector.collect( getProjectArtifacts(), project.getArtifact(), managedVersions,
+ localRepo, project.getRemoteArtifactRepositories(),
+ getArtifactMetadataSource(), null, listeners );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().error(
+ Messages.getString( "artifactresolution", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+
+ // if we are here artifactResolutionResult is null, create a project without dependencies but
+ // don't fail
+ // (this could be a reactor projects, we don't want to fail everything)
+ // Causes MECLIPSE-185. Not sure if it should be handled this way??
+ return new IdeDependency[0];
+ }
+
+ // keep track of added reactor projects in order to avoid duplicates
+ Set emittedReactorProjectId = new HashSet();
+
+ for ( Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator(); i.hasNext(); )
+ {
+
+ ResolutionNode node = (ResolutionNode) i.next();
+ int dependencyDepth = node.getDepth();
+ Artifact art = node.getArtifact();
+ // don't resolve jars for reactor projects
+ if ( hasToResolveJar( art ) )
+ {
+ try
+ {
+ artifactResolver.resolve( art, node.getRemoteRepositories(), localRepository );
+ }
+ catch ( ArtifactNotFoundException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().warn(
+ Messages.getString( "artifactdownload", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ getLog().debug( e.getMessage(), e );
+ getLog().warn(
+ Messages.getString( "artifactresolution", new Object[] { //$NON-NLS-1$
+ e.getGroupId(), e.getArtifactId(), e.getVersion(),
+ e.getMessage() } ) );
+ }
+ }
+
+ boolean includeArtifact = true;
+ if ( getExcludes() != null )
+ {
+ String artifactFullId = art.getGroupId() + ":" + art.getArtifactId();
+ if ( getExcludes().contains( artifactFullId ) )
+ {
+ getLog().info( "excluded: " + artifactFullId );
+ includeArtifact = false;
+ }
+ }
+
+ if ( includeArtifact &&
+ ( !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) ) || emittedReactorProjectId.add( art.getGroupId() +
+ '-' + art.getArtifactId() ) ) )
+ {
+
+ // the following doesn't work: art.getArtifactHandler().getPackaging() always returns "jar"
+ // also
+ // if the packaging specified in pom.xml is different.
+
+ // osgi-bundle packaging is provided by the felix osgi plugin
+ // eclipse-plugin packaging is provided by this eclipse plugin
+ // String packaging = art.getArtifactHandler().getPackaging();
+ // boolean isOsgiBundle = "osgi-bundle".equals( packaging ) || "eclipse-plugin".equals(
+ // packaging );
+
+ // we need to check the manifest, if "Bundle-SymbolicName" is there the artifact can be
+ // considered
+ // an osgi bundle
+ boolean isOsgiBundle = false;
+ String osgiSymbolicName = null;
+ if ( art.getFile() != null )
+ {
+ JarFile jarFile = null;
+ try
+ {
+ jarFile = new JarFile( art.getFile(), false, ZipFile.OPEN_READ );
+
+ Manifest manifest = jarFile.getManifest();
+ if ( manifest != null )
+ {
+ osgiSymbolicName =
+ manifest.getMainAttributes().getValue(
+ new Attributes.Name(
+ "Bundle-SymbolicName" ) );
+ }
+ }
+ catch ( IOException e )
+ {
+ getLog().info( "Unable to read jar manifest from " + art.getFile() );
+ }
+ finally
+ {
+ if ( jarFile != null )
+ {
+ try
+ {
+ jarFile.close();
+ }
+ catch ( IOException e )
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+ isOsgiBundle = osgiSymbolicName != null;
+
+ IdeDependency dep =
+ new IdeDependency( art.getGroupId(), art.getArtifactId(), art.getVersion(),
+ art.getClassifier(), useProjectReference( art ),
+ Artifact.SCOPE_TEST.equals( art.getScope() ),
+ Artifact.SCOPE_SYSTEM.equals( art.getScope() ),
+ Artifact.SCOPE_PROVIDED.equals( art.getScope() ),
+ art.getArtifactHandler().isAddedToClasspath(), art.getFile(),
+ art.getType(), isOsgiBundle, osgiSymbolicName, dependencyDepth,
+ getProjectNameForArifact( art ) );
+ // no duplicate entries allowed. System paths can cause this problem.
+ if ( !dependencies.contains( dep ) )
+ {
+ // [rfeng] Do not add compile/provided dependencies
+ if (!(pde && (Artifact.SCOPE_COMPILE.equals(art.getScope()) || Artifact.SCOPE_PROVIDED
+ .equals(art.getScope())))) {
+ dependencies.add( dep );
+ }
+ }
+ }
+
+ }
+
+ // @todo a final report with the list of
+ // missingArtifacts?
+
+ }
+
+ ideDeps = (IdeDependency[]) dependencies.toArray( new IdeDependency[dependencies.size()] );
+ }
+ else
+ {
+ ideDeps = new IdeDependency[0];
+ }
+ }
+
+ return ideDeps;
+ }
+
+ /**
+ * Find the name of the project as used in eclipse.
+ *
+ * @param artifact The artifact to find the eclipse name for.
+ * @return The name os the eclipse project.
+ */
+ abstract public String getProjectNameForArifact( Artifact artifact );
+
+ /**
+ * Returns the list of project artifacts. Also artifacts generated from referenced projects will be added, but with
+ * the <code>resolved</code> property set to true.
+ *
+ * @return list of projects artifacts
+ * @throws MojoExecutionException if unable to parse dependency versions
+ */
+ private Set getProjectArtifacts()
+ throws MojoExecutionException
+ {
+ // keep it sorted, this should avoid random classpath order in tests
+ Set artifacts = new TreeSet();
+
+ for ( Iterator dependencies = getProject().getDependencies().iterator(); dependencies.hasNext(); )
+ {
+ Dependency dependency = (Dependency) dependencies.next();
+
+ String groupId = dependency.getGroupId();
+ String artifactId = dependency.getArtifactId();
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( dependency.getVersion() );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new MojoExecutionException(
+ Messages.getString(
+ "unabletoparseversion", new Object[] { //$NON-NLS-1$
+ dependency.getArtifactId(),
+ dependency.getVersion(),
+ dependency.getManagementKey(), e.getMessage() } ),
+ e );
+ }
+
+ String type = dependency.getType();
+ if ( type == null )
+ {
+ type = Constants.PROJECT_PACKAGING_JAR;
+ }
+ String classifier = dependency.getClassifier();
+ boolean optional = dependency.isOptional();
+ String scope = dependency.getScope();
+ if ( scope == null )
+ {
+ scope = Artifact.SCOPE_COMPILE;
+ }
+
+ Artifact art =
+ getArtifactFactory().createDependencyArtifact( groupId, artifactId, versionRange, type, classifier,
+ scope, optional );
+
+ if ( scope.equalsIgnoreCase( Artifact.SCOPE_SYSTEM ) )
+ {
+ art.setFile( new File( dependency.getSystemPath() ) );
+ }
+
+ List exclusions = new ArrayList();
+ for ( Iterator j = dependency.getExclusions().iterator(); j.hasNext(); )
+ {
+ Exclusion e = (Exclusion) j.next();
+ exclusions.add( e.getGroupId() + ":" + e.getArtifactId() ); //$NON-NLS-1$
+ }
+
+ ArtifactFilter newFilter = new ExcludesArtifactFilter( exclusions );
+
+ art.setDependencyFilter( newFilter );
+
+ artifacts.add( art );
+ }
+
+ return artifacts;
+ }
+
+ /**
+ * Utility method that locates a project producing the given artifact.
+ *
+ * @param artifact the artifact a project should produce.
+ * @return <code>true</code> if the artifact is produced by a reactor projectart.
+ */
+ protected boolean isAvailableAsAReactorProject( Artifact artifact )
+ {
+ if ( reactorProjects != null )
+ {
+ for ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); )
+ {
+ MavenProject reactorProject = (MavenProject) iter.next();
+
+ if ( reactorProject.getGroupId().equals( artifact.getGroupId() ) &&
+ reactorProject.getArtifactId().equals( artifact.getArtifactId() ) )
+ {
+ if ( reactorProject.getVersion().equals( artifact.getVersion() ) )
+ {
+ return true;
+ }
+ else
+ {
+ getLog().info(
+ "Artifact " +
+ artifact.getId() +
+ " already available as a reactor project, but with different version. Expected: " +
+ artifact.getVersion() + ", found: " + reactorProject.getVersion() );
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return an array with all dependencies avalaible in the workspace, to be implemented by the subclasses.
+ */
+ protected IdeDependency[] getWorkspaceArtefacts()
+ {
+ return new IdeDependency[0];
+ }
+
+ private Map createManagedVersionMap( ArtifactFactory artifactFactory, String projectId,
+ DependencyManagement dependencyManagement )
+ throws MojoExecutionException
+ {
+ Map map;
+ if ( dependencyManagement != null && dependencyManagement.getDependencies() != null )
+ {
+ map = new HashMap();
+ for ( Iterator i = dependencyManagement.getDependencies().iterator(); i.hasNext(); )
+ {
+ Dependency d = (Dependency) i.next();
+
+ try
+ {
+ VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
+ Artifact artifact =
+ artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange,
+ d.getType(), d.getClassifier(), d.getScope(),
+ d.isOptional() );
+ map.put( d.getManagementKey(), artifact );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "unabletoparseversion", new Object[] { //$NON-NLS-1$
+ projectId, d.getVersion(),
+ d.getManagementKey(), e.getMessage() } ),
+ e );
+ }
+ }
+ }
+ else
+ {
+ map = Collections.EMPTY_MAP;
+ }
+ return map;
+ }
+
+ /**
+ * Find the reactor target dir. executedProject doesn't have the multiproject root dir set, and the only way to
+ * extract it is iterating on parent projects.
+ *
+ * @param prj current project
+ * @return the parent target dir.
+ */
+ private File getReactorTargetDir( MavenProject prj )
+ {
+ if ( prj.getParent() != null )
+ {
+ if ( prj.getParent().getBasedir() != null && prj.getParent().getBasedir().exists() )
+ {
+ return getReactorTargetDir( prj.getParent() );
+ }
+ }
+ return new File( prj.getBuild().getDirectory() );
+ }
+
+ /**
+ * Resolve source artifacts and download them if <code>downloadSources</code> is <code>true</code>. Source and
+ * javadocs artifacts will be attached to the <code>IdeDependency</code> Resolve source and javadoc artifacts. The
+ * resolved artifacts will be downloaded based on the <code>downloadSources</code> and
+ * <code>downloadJavadocs</code> attributes. Source and
+ *
+ * @param deps resolved dependencies
+ */
+ private void resolveSourceAndJavadocArtifacts( IdeDependency[] deps )
+ {
+
+ File reactorTargetDir = getReactorTargetDir( project );
+ File unavailableArtifactsTmpFile = new File( reactorTargetDir, "mvn-eclipse-cache.properties" );
+
+ getLog().info( "Using source status cache: " + unavailableArtifactsTmpFile.getAbsolutePath() );
+
+ // create target dir if missing
+ if ( !unavailableArtifactsTmpFile.getParentFile().exists() )
+ {
+ unavailableArtifactsTmpFile.getParentFile().mkdirs();
+ }
+
+ Properties unavailableArtifactsCache = new Properties();
+ if ( unavailableArtifactsTmpFile.exists() )
+ {
+ InputStream is = null;
+ try
+ {
+ is = new FileInputStream( unavailableArtifactsTmpFile );
+ unavailableArtifactsCache.load( is );
+ }
+ catch ( IOException e )
+ {
+ getLog().warn( "Unable to read source status for reactor projects" );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+
+ }
+
+ final List missingSources =
+ resolveDependenciesWithClassifier( deps, "sources", getDownloadSources(), unavailableArtifactsCache );
+ missingSourceDependencies.addAll( missingSources );
+
+ final List missingJavadocs =
+ resolveDependenciesWithClassifier( deps, "javadoc", getDownloadJavadocs(), unavailableArtifactsCache );
+ missingJavadocDependencies.addAll( missingJavadocs );
+
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream( unavailableArtifactsTmpFile );
+ unavailableArtifactsCache.store( fos, "Temporary index for unavailable sources and javadocs" );
+ }
+ catch ( IOException e )
+ {
+ getLog().warn( "Unable to cache source status for reactor projects" );
+ }
+ finally
+ {
+ IOUtil.close( fos );
+ }
+
+ }
+
+ /**
+ * Resolve the required artifacts for each of the dependency. <code>sources</code> or <code>javadoc</code>
+ * artifacts (depending on the <code>classifier</code>) are attached to the dependency.
+ *
+ * @param deps resolved dependencies
+ * @param inClassifier the classifier we are looking for (either <code>sources</code> or <code>javadoc</code>)
+ * @param includeRemoteRepositories flag whether we should search remote repositories for the artifacts or not
+ * @param unavailableArtifactsCache cache of unavailable artifacts
+ * @return the list of dependencies for which the required artifact was not found
+ */
+ private List resolveDependenciesWithClassifier( IdeDependency[] deps, String inClassifier,
+ boolean includeRemoteRepositories,
+ Properties unavailableArtifactsCache )
+ {
+ List missingClassifierDependencies = new ArrayList();
+
+ // if downloadSources is off, just check
+ // local repository for reporting missing source jars
+ List remoteRepos = includeRemoteRepositories ? getRemoteArtifactRepositories() : Collections.EMPTY_LIST;
+
+ for ( int j = 0; j < deps.length; j++ )
+ {
+ IdeDependency dependency = deps[j];
+
+ if ( dependency.isReferencedProject() || dependency.isSystemScoped() )
+ {
+ // artifact not needed
+ continue;
+ }
+
+ if ( getLog().isDebugEnabled() )
+ {
+ getLog().debug(
+ "Searching for sources for " + dependency.getId() + ":" + dependency.getClassifier() +
+ " at " + dependency.getId() + ":" + inClassifier );
+ }
+
+ String key =
+ dependency.getClassifier() == null ? dependency.getId() + ":" + inClassifier : dependency.getId() +
+ ":" + inClassifier + ":" + dependency.getClassifier();
+
+ if ( !unavailableArtifactsCache.containsKey( key ) )
+ {
+ Artifact artifact =
+ IdeUtils.resolveArtifactWithClassifier( dependency.getGroupId(), dependency.getArtifactId(),
+ dependency.getVersion(), dependency.getClassifier(),
+ inClassifier, localRepository, artifactResolver,
+ artifactFactory, remoteRepos, getLog() );
+ if ( artifact.isResolved() )
+ {
+ if ( "sources".equals( inClassifier ) )
+ {
+ dependency.setSourceAttachment( artifact.getFile() );
+ }
+ else if ( "javadoc".equals( inClassifier ) )
+ {
+ dependency.setJavadocAttachment( artifact.getFile() );
+ }
+ }
+ else
+ {
+ unavailableArtifactsCache.put( key, Boolean.TRUE.toString() );
+ // add the dependencies to the list
+ // of those lacking the required
+ // artifact
+ missingClassifierDependencies.add( dependency );
+ }
+ }
+ }
+
+ // return the list of dependencies missing the
+ // required artifact
+ return missingClassifierDependencies;
+
+ }
+
+ /**
+ * Output a message with the list of missing dependencies and info on how turn download on if it was disabled.
+ */
+ private void reportMissingArtifacts()
+ {
+ StringBuffer msg = new StringBuffer();
+
+ if ( !missingSourceDependencies.isEmpty() )
+ {
+ if ( getDownloadSources() )
+ {
+ msg.append( Messages.getString( "sourcesnotavailable" ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ msg.append( Messages.getString( "sourcesnotdownloaded" ) ); //$NON-NLS-1$
+ }
+
+ for ( Iterator it = missingSourceDependencies.iterator(); it.hasNext(); )
+ {
+ IdeDependency art = (IdeDependency) it.next();
+ msg.append( Messages.getString( "sourcesmissingitem", art.getId() ) ); //$NON-NLS-1$
+ }
+ msg.append( "\n" ); //$NON-NLS-1$
+ }
+
+ if ( !missingJavadocDependencies.isEmpty() )
+ {
+ if ( getDownloadJavadocs() )
+ {
+ msg.append( Messages.getString( "javadocnotavailable" ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ msg.append( Messages.getString( "javadocnotdownloaded" ) ); //$NON-NLS-1$
+ }
+
+ for ( Iterator it = missingJavadocDependencies.iterator(); it.hasNext(); )
+ {
+ IdeDependency art = (IdeDependency) it.next();
+ msg.append( Messages.getString( "javadocmissingitem", art.getId() ) ); //$NON-NLS-1$
+ }
+ msg.append( "\n" ); //$NON-NLS-1$
+ }
+ getLog().info( msg );
+ }
+
+ /**
+ * @return List of dependencies to exclude from eclipse classpath.
+ * @since 2.5
+ */
+ public abstract List getExcludes();
+
+ /**
+ * Checks if jar has to be resolved for the given artifact
+ *
+ * @param art the artifact to check
+ * @return true if resolution should happen
+ */
+ protected boolean hasToResolveJar( Artifact art )
+ {
+ return !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) );
+ }
+
+ /**
+ * Checks if a projects reference has to be used for the given artifact
+ *
+ * @param art the artifact to check
+ * @return true if a project reference has to be used.
+ */
+ protected boolean useProjectReference( Artifact art )
+ {
+ return getUseProjectReferences() && isAvailableAsAReactorProject( art );
+ }
+
+ protected boolean isOSGiBundle() {
+ File base = project.getBasedir();
+ File mf = new File(base, "META-INF/MANIFEST.MF");
+ if (mf.isFile()) {
+ Manifest manifest = null;
+ try {
+ InputStream is = new FileInputStream(mf);
+ manifest = new Manifest(is);
+ is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ if (manifest != null) {
+ String bundleName = manifest.getMainAttributes().getValue("Bundle-SymbolicName");
+ if (bundleName != null) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
new file mode 100644
index 0000000000..88afd024db
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseClasspathWriter.java
@@ -0,0 +1,530 @@
+/*
+ * 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.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.eclipse.EclipseSourceDir;
+import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * Writes eclipse .classpath file.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipseClasspathWriter.java 636955 2008-03-14 02:10:42Z aheritier $
+ */
+public class EclipseClasspathWriter
+ extends AbstractEclipseWriter
+{
+
+ /**
+ * Eclipse build path variable M2_REPO
+ */
+ private static final String M2_REPO = "M2_REPO"; //$NON-NLS-1$
+
+ /**
+ * Attribute for sourcepath.
+ */
+ private static final String ATTR_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
+
+ /**
+ * Attribute for output.
+ */
+ private static final String ATTR_OUTPUT = "output"; //$NON-NLS-1$
+
+ /**
+ * Attribute for path.
+ */
+ private static final String ATTR_PATH = "path"; //$NON-NLS-1$
+
+ /**
+ * Attribute for kind - Container (con), Variable (var)..etc.
+ */
+ private static final String ATTR_KIND = "kind"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: var
+ */
+ private static final String ATTR_VAR = "var"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: lib
+ */
+ private static final String ATTR_LIB = "lib"; //$NON-NLS-1$
+
+ /**
+ * Attribute value for kind: src
+ */
+ private static final String ATTR_SRC = "src"; //$NON-NLS-1$
+
+ /**
+ * Attribute name for source file includes in a path.
+ */
+ private static final String ATTR_INCLUDING = "including";
+
+ /**
+ * Attribute name for source file excludes in a path.
+ */
+ private static final String ATTR_EXCLUDING = "excluding";
+
+ /**
+ * Element for classpathentry.
+ */
+ private static final String ELT_CLASSPATHENTRY = "classpathentry"; //$NON-NLS-1$
+
+ /**
+ * Element for classpath.
+ */
+ private static final String ELT_CLASSPATH = "classpath"; //$NON-NLS-1$
+
+ /**
+ * File name that stores project classpath settings.
+ */
+ private static final String FILE_DOT_CLASSPATH = ".classpath"; //$NON-NLS-1$
+
+ /**
+ * @see org.apache.tuscany.sca.maven.plugin.eclipse.writers.EclipseWriter#write()
+ */
+ public void write()
+ throws MojoExecutionException
+ {
+
+ Writer w;
+
+ try
+ {
+ w =
+ new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
+ FILE_DOT_CLASSPATH ) ), "UTF-8" );
+ }
+ catch ( IOException ex )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex ); //$NON-NLS-1$
+ }
+
+ XMLWriter writer = new PrettyPrintXMLWriter( w );
+
+ writer.startElement( ELT_CLASSPATH );
+
+ String defaultOutput =
+ IdeUtils.toRelativeAndFixSeparator( config.getProjectBaseDir(), config.getBuildOutputDirectory(), false );
+
+ // ----------------------------------------------------------------------
+ // Source roots and resources
+ // ----------------------------------------------------------------------
+
+ // List<EclipseSourceDir>
+ List specialSources = new ArrayList();
+
+ // Map<String,List<EclipseSourceDir>>
+ Map byOutputDir = new HashMap();
+
+ for ( int j = 0; j < config.getSourceDirs().length; j++ )
+ {
+ EclipseSourceDir dir = config.getSourceDirs()[j];
+
+ // List<EclipseSourceDir>
+ List byOutputDirs = (List) byOutputDir.get( dir.getOutput() );
+ if ( byOutputDirs == null )
+ {
+ // ArrayList<EclipseSourceDir>
+ byOutputDir.put( dir.getOutput() == null ? defaultOutput : dir.getOutput(), byOutputDirs =
+ new ArrayList() );
+ }
+ byOutputDirs.add( dir );
+ }
+
+ for ( int j = 0; j < config.getSourceDirs().length; j++ )
+ {
+ EclipseSourceDir dir = config.getSourceDirs()[j];
+
+ log.debug( "Processing " + ( dir.isResource() ? "re" : "" ) + "source " + dir.getPath() + ": output=" +
+ dir.getOutput() + "; default output=" + defaultOutput );
+
+ boolean isSpecial = false;
+
+ // handle resource with nested output folders
+ if ( dir.isResource() )
+ {
+ // Check if the output is a subdirectory of the default output,
+ // and if the default output has any sources that copy there.
+
+ if ( dir.getOutput() != null // resource output dir is set
+ &&
+ !dir.getOutput().equals( defaultOutput ) // output dir is not default target/classes
+ && dir.getOutput().startsWith( defaultOutput ) // ... but is nested
+ && byOutputDir.get( defaultOutput ) != null // ???
+ && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty() // ???
+ )
+ {
+ // do not specify as source since the output will be nested. Instead, mark
+ // it as a todo, and handle it with a custom build.xml file later.
+
+ log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output=" +
+ dir.getOutput() + ")" );
+
+ isSpecial = true;
+ specialSources.add( dir );
+ }
+ }
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+
+ writer.addAttribute( ATTR_KIND, "src" ); //$NON-NLS-1$
+ writer.addAttribute( ATTR_PATH, dir.getPath() );
+
+ if ( !isSpecial && dir.getOutput() != null && !defaultOutput.equals( dir.getOutput() ) )
+ {
+ writer.addAttribute( ATTR_OUTPUT, dir.getOutput() );
+ }
+
+ if ( StringUtils.isNotEmpty( dir.getInclude() ) )
+ {
+ writer.addAttribute( ATTR_INCLUDING, dir.getInclude() );
+ }
+
+ String excludes = dir.getExclude();
+
+ if ( dir.isResource() )
+ {
+ // automatically exclude java files: eclipse doesn't have the concept of resource directory so it will
+ // try to compile any java file found in maven resource dirs
+ excludes = StringUtils.isEmpty( excludes ) ? "**/*.java" : excludes + "|**/*.java";
+ }
+
+ if ( StringUtils.isNotEmpty( excludes ) )
+ {
+ writer.addAttribute( ATTR_EXCLUDING, excludes );
+ }
+
+ writer.endElement();
+
+ }
+
+ /* --------------- Commented out by rfeng
+ // handle the special sources.
+ if ( !specialSources.isEmpty() )
+ {
+ log.info( "Creating maven-eclipse.xml Ant file to handle resources" );
+
+ try
+ {
+ Writer buildXmlWriter =
+ new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
+ "maven-eclipse.xml" ) ), "UTF-8" );
+ PrettyPrintXMLWriter buildXmlPrinter = new PrettyPrintXMLWriter( buildXmlWriter );
+
+ buildXmlPrinter.startElement( "project" );
+ buildXmlPrinter.addAttribute( "default", "copy-resources" );
+
+ buildXmlPrinter.startElement( "target" );
+ buildXmlPrinter.addAttribute( "name", "init" );
+ // initialize filtering tokens here
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.startElement( "target" );
+ buildXmlPrinter.addAttribute( "name", "copy-resources" );
+ buildXmlPrinter.addAttribute( "depends", "init" );
+
+ for ( Iterator it = specialSources.iterator(); it.hasNext(); )
+ {
+ // TODO: merge source dirs on output path+filtering to reduce
+ // <copy> tags for speed.
+ EclipseSourceDir dir = (EclipseSourceDir) it.next();
+ buildXmlPrinter.startElement( "copy" );
+ buildXmlPrinter.addAttribute( "todir", dir.getOutput() );
+ buildXmlPrinter.addAttribute( "filtering", "" + dir.isFiltering() );
+
+ buildXmlPrinter.startElement( "fileset" );
+ buildXmlPrinter.addAttribute( "dir", dir.getPath() );
+ if ( dir.getInclude() != null )
+ {
+ buildXmlPrinter.addAttribute( "includes", dir.getInclude() );
+ }
+ if ( dir.getExclude() != null )
+ {
+ buildXmlPrinter.addAttribute( "excludes", dir.getExclude() );
+ }
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.endElement();
+ }
+
+ buildXmlPrinter.endElement();
+
+ buildXmlPrinter.endElement();
+
+ IOUtil.close( buildXmlWriter );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( "Cannot create " + config.getEclipseProjectDirectory() +
+ "/maven-eclipse.xml", e );
+ }
+
+ log.info( "Creating external launcher file" );
+ // now create the launcher
+ new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch",
+ "maven-eclipse.xml" ).write();
+
+ // finally add it to the project writer.
+
+ config.getBuildCommands().add(
+ new BuildCommand(
+ "org.eclipse.ui.externaltools.ExternalToolBuilder",
+ "LaunchConfigHandle",
+ "<project>/" +
+ EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS +
+ "Maven_Ant_Builder.launch" ) );
+ }
+ */
+
+ // ----------------------------------------------------------------------
+ // The default output
+ // ----------------------------------------------------------------------
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, ATTR_OUTPUT );
+ writer.addAttribute( ATTR_PATH, defaultOutput );
+ writer.endElement();
+
+ // ----------------------------------------------------------------------
+ // Container classpath entries
+ // ----------------------------------------------------------------------
+
+ for ( Iterator it = config.getClasspathContainers().iterator(); it.hasNext(); )
+ {
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, "con" ); //$NON-NLS-1$
+ writer.addAttribute( ATTR_PATH, (String) it.next() );
+ writer.endElement(); // name
+ }
+
+ // ----------------------------------------------------------------------
+ // The dependencies
+ // ----------------------------------------------------------------------
+ Set addedDependencies = new HashSet();
+ // TODO if (..magic property equals orderDependencies..)
+ IdeDependency[] depsToWrite = config.getDepsOrdered();
+ for ( int j = 0; j < depsToWrite.length; j++ )
+ {
+ IdeDependency dep = depsToWrite[j];
+
+ if ( dep.isAddedToClasspath() )
+ {
+ String depId =
+ dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getClassifier() + ":" + dep.getVersion();
+ /* avoid duplicates in the classpath for artifacts with different types (like ejbs) */
+ if ( !addedDependencies.contains( depId ) )
+ {
+ addDependency( writer, dep );
+ addedDependencies.add( depId );
+ }
+ }
+ }
+
+ writer.endElement();
+
+ IOUtil.close( w );
+
+ }
+
+ protected void addDependency( XMLWriter writer, IdeDependency dep )
+ throws MojoExecutionException
+ {
+
+ String path;
+ String kind;
+ String sourcepath = null;
+ String javadocpath = null;
+ // [rfeng] Force to non-PDE mode
+ boolean pdeMode = false;
+
+ if ( dep.isReferencedProject() && !pdeMode )
+ {
+ path = "/" + dep.getEclipseProjectName(); //$NON-NLS-1$
+ kind = ATTR_SRC;
+ }
+ else if ( dep.isReferencedProject() && pdeMode )
+ {
+ // don't do anything, referenced projects are automatically handled by eclipse in PDE builds
+ return;
+ }
+ else
+ {
+ File artifactPath = dep.getFile();
+
+ if ( artifactPath == null )
+ {
+ log.error( Messages.getString( "EclipsePlugin.artifactpathisnull", dep.getId() ) ); //$NON-NLS-1$
+ return;
+ }
+
+ if ( dep.isSystemScoped() )
+ {
+ path = IdeUtils.toRelativeAndFixSeparator( config.getEclipseProjectDirectory(), artifactPath, false );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( Messages.getString( "EclipsePlugin.artifactissystemscoped", //$NON-NLS-1$
+ new Object[] { dep.getArtifactId(), path } ) );
+ }
+
+ kind = ATTR_LIB;
+ }
+ else
+ {
+ File localRepositoryFile = new File( config.getLocalRepository().getBasedir() );
+
+ // if the dependency is not provided and the plugin runs in "pde mode", the dependency is
+ // added to the Bundle-Classpath:
+ if ( pdeMode && ( dep.isProvided() || dep.isOsgiBundle() ) )
+ {
+ return;
+ }
+ else if ( pdeMode && !dep.isProvided() && !dep.isTestDependency() )
+ {
+ // path for link created in .project, not to the actual file
+ path = dep.getFile().getName();
+
+ kind = ATTR_LIB;
+ }
+ // running in PDE mode and the dependency is provided means, that it is provided by
+ // the target platform. This case is covered by adding the plugin container
+ else
+ {
+ String fullPath = artifactPath.getPath();
+ String relativePath =
+ IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, new File( fullPath ), false );
+
+ if ( !new File( relativePath ).isAbsolute() )
+ {
+ path = M2_REPO + "/" //$NON-NLS-1$
+ + relativePath;
+ kind = ATTR_VAR; //$NON-NLS-1$
+ }
+ else
+ {
+ path = relativePath;
+ kind = ATTR_LIB;
+ }
+ }
+
+ if ( dep.getSourceAttachment() != null )
+ {
+ if ( ATTR_VAR.equals( kind ) )
+ {
+ sourcepath =
+ M2_REPO +
+ "/" //$NON-NLS-1$
+ +
+ IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, dep.getSourceAttachment(),
+ false );
+ }
+ else
+ {
+ // source archive must be referenced with the full path, we can't mix a lib with a variable
+ sourcepath = IdeUtils.getCanonicalPath( dep.getSourceAttachment() );
+ }
+ }
+
+ if ( dep.getJavadocAttachment() != null )
+ {
+ // NB eclipse (3.1) doesn't support variables in javadoc paths, so we need to add the
+ // full path for the maven repo
+ javadocpath =
+ StringUtils.replace( IdeUtils.getCanonicalPath( dep.getJavadocAttachment() ), "\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ }
+
+ }
+
+ writer.startElement( ELT_CLASSPATHENTRY );
+ writer.addAttribute( ATTR_KIND, kind );
+ writer.addAttribute( ATTR_PATH, path );
+
+ if ( sourcepath != null )
+ {
+ writer.addAttribute( ATTR_SOURCEPATH, sourcepath );
+ }
+
+ boolean attributeElemOpen = false;
+
+ if ( javadocpath != null )
+ {
+ if ( !attributeElemOpen )
+ {
+ writer.startElement( "attributes" ); //$NON-NLS-1$
+ attributeElemOpen = true;
+ }
+
+ writer.startElement( "attribute" ); //$NON-NLS-1$
+ writer.addAttribute( "value", "jar:" + new File( javadocpath ).toURI() + "!/" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ writer.addAttribute( "name", "javadoc_location" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.endElement();
+
+ }
+
+ if ( Constants.PROJECT_PACKAGING_WAR.equals( this.config.getPackaging() ) && config.getWtpapplicationxml() &&
+ kind.equals( ATTR_VAR ) && !dep.isTestDependency() && !dep.isProvided() &&
+ !dep.isSystemScopedOutsideProject( this.config.getProject() ) )
+ {
+ if ( !attributeElemOpen )
+ {
+ writer.startElement( "attributes" ); //$NON-NLS-1$
+ attributeElemOpen = true;
+ }
+
+ writer.startElement( "attribute" ); //$NON-NLS-1$
+ writer.addAttribute( "value", "/WEB-INF/lib" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.addAttribute( "name", "org.eclipse.jst.component.dependency" ); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.endElement();
+
+ }
+
+ if ( attributeElemOpen )
+ {
+ writer.endElement();
+ }
+ writer.endElement();
+
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
new file mode 100644
index 0000000000..ac770c743c
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseCleanMojo.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.eclipse.EclipseConfigFile;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Deletes the .project, .classpath, .wtpmodules files and .settings folder used by Eclipse.
+ *
+ * @goal clean
+ */
+public class EclipseCleanMojo
+ extends AbstractMojo
+{
+
+ /**
+ * Definition file for Eclipse Web Tools project.
+ */
+ private static final String FILE_DOT_WTPMODULES = ".wtpmodules"; //$NON-NLS-1$
+
+ /**
+ * Classpath definition file for an Eclipse Java project.
+ */
+ private static final String FILE_DOT_CLASSPATH = ".classpath"; //$NON-NLS-1$
+
+ /**
+ * Project definition file for an Eclipse Project.
+ */
+ private static final String FILE_DOT_PROJECT = ".project"; //$NON-NLS-1$
+
+ /**
+ * Web Project definition file for Eclipse Web Tools Project (Release 1.0x).
+ */
+ private static final String DIR_DOT_SETTINGS = ".settings"; //$NON-NLS-1$
+
+ /**
+ * File name where the WTP component settings will be stored - WTP 1.0 name.
+ */
+ private static final String FILE_DOT_COMPONENT = ".settings/.component"; //$NON-NLS-1$
+
+ /**
+ * File name where the WTP component settings will be stored - WTP 1.5 name.
+ */
+ private static final String FILE_DOT_COMPONENT_15 = ".settings/org.eclipse.wst.common.component"; //$NON-NLS-1$
+
+ /**
+ * File name where Eclipse Project's Facet configuration will be stored.
+ */
+ private static final String FILE_FACET_CORE_XML = ".settings/org.eclipse.wst.common.project.facet.core.xml"; //$NON-NLS-1$
+
+ /**
+ * General project preferences.
+ */
+ private static final String FILE_ECLIPSE_JDT_CORE_PREFS = ".settings/org.eclipse.jdt.core.prefs"; //$NON-NLS-1$
+
+ /**
+ * Packaging for the current project.
+ *
+ * @parameter expression="${project.packaging}"
+ */
+ private String packaging;
+
+ /**
+ * The root directory of the project
+ *
+ * @parameter expression="${basedir}"
+ */
+ private File basedir;
+
+ /**
+ * Skip the operation when true.
+ *
+ * @parameter expression="${eclipse.skip}" default-value="false"
+ */
+ private boolean skip;
+
+ /**
+ * additional generic configuration files for eclipse
+ *
+ * @parameter
+ */
+ private EclipseConfigFile[] additionalConfig;
+
+ /**
+ * @see org.apache.maven.plugin.AbstractMojo#execute()
+ */
+ public void execute()
+ throws MojoExecutionException
+ {
+ if ( skip )
+ {
+ return;
+ }
+
+ if ( Constants.PROJECT_PACKAGING_POM.equals( this.packaging ) )
+ {
+ return;
+ }
+
+ delete( new File( basedir, FILE_DOT_PROJECT ) );
+ delete( new File( basedir, FILE_DOT_CLASSPATH ) );
+ delete( new File( basedir, FILE_DOT_WTPMODULES ) );
+
+ delete( new File( basedir, FILE_DOT_COMPONENT ) );
+ delete( new File( basedir, FILE_DOT_COMPONENT_15 ) );
+ delete( new File( basedir, FILE_FACET_CORE_XML ) );
+ delete( new File( basedir, FILE_ECLIPSE_JDT_CORE_PREFS ) );
+
+ File settingsDir = new File( basedir, DIR_DOT_SETTINGS );
+ if ( settingsDir.exists() && settingsDir.isDirectory() && settingsDir.list().length == 0 )
+ {
+ delete( settingsDir );
+ }
+
+ if ( additionalConfig != null )
+ {
+ for ( int i = 0; i < additionalConfig.length; i++ )
+ {
+ delete( new File( basedir, additionalConfig[i].getName() ) );
+ }
+ }
+
+ cleanExtras();
+ }
+
+ protected void cleanExtras()
+ throws MojoExecutionException
+ {
+ // extension point.
+ }
+
+ /**
+ * Delete a file, handling log messages and exceptions
+ *
+ * @param f File to be deleted
+ * @throws MojoExecutionException only if a file exists and can't be deleted
+ */
+ protected void delete( File f )
+ throws MojoExecutionException
+ {
+ if ( f.isDirectory() )
+ {
+ getLog().info( Messages.getString( "EclipseCleanMojo.deletingDirectory", f.getName() ) ); //$NON-NLS-1$
+ }
+ else
+ {
+ getLog().info( Messages.getString( "EclipseCleanMojo.deletingFile", f.getName() ) ); //$NON-NLS-1$
+ }
+
+ if ( f.exists() )
+ {
+ if ( !f.delete() )
+ {
+ try
+ {
+ FileUtils.forceDelete( f );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.failedtodelete", //$NON-NLS-1$
+ new Object[] { f.getName(),
+ f.getAbsolutePath() } ) );
+ }
+ }
+ }
+ else
+ {
+ getLog().debug( Messages.getString( "EclipseCleanMojo.nofilefound", f.getName() ) ); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Getter for <code>basedir</code>.
+ *
+ * @return Returns the basedir.
+ */
+ public File getBasedir()
+ {
+ return this.basedir;
+ }
+
+ /**
+ * Setter for <code>basedir</code>.
+ *
+ * @param basedir The basedir to set.
+ */
+ public void setBasedir( File basedir )
+ {
+ this.basedir = basedir;
+ }
+
+ /**
+ * @return the packaging
+ */
+ public String getPackaging()
+ {
+ return this.packaging;
+ }
+
+ /**
+ * @param packaging the packaging to set
+ */
+ public void setPackaging( String packaging )
+ {
+ this.packaging = packaging;
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java
new file mode 100644
index 0000000000..fccd64540b
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipsePlugin.java
@@ -0,0 +1,1556 @@
+/*
+ * 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.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.BuildCommand;
+import org.apache.maven.plugin.eclipse.Constants;
+import org.apache.maven.plugin.eclipse.EclipseConfigFile;
+import org.apache.maven.plugin.eclipse.EclipseSourceDir;
+import org.apache.maven.plugin.eclipse.WorkspaceConfiguration;
+import org.apache.maven.plugin.eclipse.reader.ReadWorkspaceLocations;
+import org.apache.maven.plugin.eclipse.writers.EclipseManifestWriter;
+import org.apache.maven.plugin.eclipse.writers.EclipseSettingsWriter;
+import org.apache.maven.plugin.eclipse.writers.EclipseWriterConfig;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpApplicationXMLWriter;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponent15Writer;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpComponentWriter;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpFacetsWriter;
+import org.apache.maven.plugin.eclipse.writers.wtp.EclipseWtpmodulesWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.apache.maven.plugin.ide.JeeUtils;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.resource.ResourceManager;
+import org.codehaus.plexus.resource.loader.FileResourceLoader;
+import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * Generates the following eclipse configuration files:
+ * <ul>
+ * <li><code>.project</code> and <code>.classpath</code> files</li>
+ * <li><code>.setting/org.eclipse.jdt.core.prefs</code> with project specific compiler settings</li>
+ * <li>various configuration files for WTP (Web Tools Project), if the parameter <code>wtpversion</code> is set to a
+ * valid version (WTP configuration is not generated by default)</li>
+ * </ul>
+ * If this goal is run on a multiproject root, dependencies between modules will be configured as direct project
+ * dependencies in Eclipse (unless <code>useProjectReferences</code> is set to <code>false</code>).
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipsePlugin.java 641616 2008-03-26 22:42:42Z aheritier $
+ * @goal eclipse
+ * @execute phase="generate-resources"
+ */
+public class EclipsePlugin
+ extends AbstractIdeSupportMojo
+{
+
+ private static final String NATURE_WST_FACET_CORE_NATURE = "org.eclipse.wst.common.project.facet.core.nature"; //$NON-NLS-1$
+
+ private static final String BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER =
+ "org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver"; //$NON-NLS-1$
+
+ protected static final String BUILDER_WST_VALIDATION = "org.eclipse.wst.validation.validationbuilder"; //$NON-NLS-1$
+
+ private static final String BUILDER_JDT_CORE_JAVA = "org.eclipse.jdt.core.javabuilder"; //$NON-NLS-1$
+
+ private static final String BUILDER_WST_COMPONENT_STRUCTURAL =
+ "org.eclipse.wst.common.modulecore.ComponentStructuralBuilder"; //$NON-NLS-1$
+
+ private static final String BUILDER_WST_FACET = "org.eclipse.wst.common.project.facet.core.builder"; //$NON-NLS-1$
+
+ private static final String BUILDER_PDE_MANIFEST = "org.eclipse.pde.ManifestBuilder"; //$NON-NLS-1$
+
+ private static final String BUILDER_PDE_SCHEMA = "org.eclipse.pde.SchemaBuilder"; //$NON-NLS-1$
+
+ private static final String NATURE_WST_MODULE_CORE_NATURE = "org.eclipse.wst.common.modulecore.ModuleCoreNature"; //$NON-NLS-1$
+
+ private static final String NATURE_JDT_CORE_JAVA = "org.eclipse.jdt.core.javanature"; //$NON-NLS-1$
+
+ private static final String NATURE_JEM_WORKBENCH_JAVA_EMF = "org.eclipse.jem.workbench.JavaEMFNature"; //$NON-NLS-1$
+
+ private static final String NATURE_PDE_PLUGIN = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$
+
+ protected static final String COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER"; //$NON-NLS-1$
+
+ protected static final String REQUIRED_PLUGINS_CONTAINER = "org.eclipse.pde.core.requiredPlugins"; //$NON-NLS-1$
+
+ // warning, order is important for binary search
+ public static final String[] WTP_SUPPORTED_VERSIONS = new String[] { "1.0", "1.5", "2.0", "R7", "none" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ /**
+ * Constant for 'artifactId' element in POM.xml.
+ */
+ private static final String POM_ELT_ARTIFACT_ID = "artifactId"; //$NON-NLS-1$
+
+ /**
+ * Constant for 'groupId' element in POM.xml.
+ */
+ private static final String POM_ELT_GROUP_ID = "groupId"; //$NON-NLS-1$
+
+ /**
+ * List of eclipse project natures. By default the <code>org.eclipse.jdt.core.javanature</code> nature plus the
+ * needed WTP natures are added. Natures added using this property <strong>replace</strong> the default list.
+ *
+ * <pre>
+ * &lt;projectnatures&gt;
+ * &lt;projectnature&gt;org.eclipse.jdt.core.javanature&lt;/projectnature&gt;
+ * &lt;projectnature&gt;org.eclipse.wst.common.modulecore.ModuleCoreNature&lt;/projectnature&gt;
+ * &lt;/projectnatures&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private List projectnatures;
+
+ /**
+ * List of artifact to exclude from eclipse classpath, beeing provided by some eclipse classPathContainer
+ * [MECLIPSE-79]
+ *
+ * @since 2.5
+ * @parameter
+ */
+ private List excludes;
+
+ /**
+ * List of eclipse project natures to be added to the default ones.
+ *
+ * <pre>
+ * &lt;additionalProjectnatures&gt;
+ * &lt;projectnature&gt;org.springframework.ide.eclipse.core.springnature&lt;/projectnature&gt;
+ * &lt;/additionalProjectnatures&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private List additionalProjectnatures;
+
+ /**
+ * List of eclipse project facets to be added to the default ones.
+ *
+ * <pre>
+ * &lt;additionalProjectFacets&gt;
+ * &lt;jst.jsf&gt;1.1&lt;jst.jsf/&gt;
+ * &lt;/additionalProjectFacets&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private Map additionalProjectFacets;
+
+ /**
+ * List of eclipse build commands. By default the <code>org.eclipse.jdt.core.javabuilder</code> builder plus the
+ * needed WTP builders are added. If you specify any configuration for this parameter, only those buildcommands
+ * specified will be used; the defaults won't be added. Use the <code>additionalBuildCommands</code> parameter for
+ * that. Configuration example: Old style:
+ *
+ * <pre>
+ * &lt;buildcommands&gt;
+ * &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilder&lt;/buildcommand&gt;
+ * &lt;buildcommand&gt;org.eclipse.jdt.core.javabuilder&lt;/buildcommand&gt;
+ * &lt;buildcommand&gt;org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver&lt;/buildcommand&gt;
+ * &lt;/buildcommands&gt;
+ * </pre>
+ *
+ * For new style, see <code>additionalBuildCommands</code>.
+ *
+ * @parameter
+ */
+ private List buildcommands;
+
+ /**
+ * List of eclipse build commands to be added to the default ones. Old style:
+ *
+ * <pre>
+ * &lt;additionalBuildcommands&gt;
+ * &lt;buildcommand&gt;org.springframework.ide.eclipse.core.springbuilder&lt;/buildcommand&gt;
+ * &lt;/additionalBuildcommands&gt;
+ * </pre>
+ *
+ * New style:
+ *
+ * <pre>
+ * &lt;additionalBuildcommands&gt;
+ * &lt;buildCommand&gt;
+ * &lt;name&gt;org.ui.externaltools.ExternalToolBuilder&lt;/name&gt;
+ * &lt;triggers&gt;auto,full,incremental,&lt;/triggers&gt;
+ * &lt;arguments&gt;
+ * &lt;LaunchConfigHandle&gt;&amp;lt;project&amp;gt;./externalToolBuilders/MavenBuilder.launch&lt;/LaunchConfighandle&gt;
+ * &lt;/arguments&gt;
+ * &lt;/buildCommand&gt;
+ * &lt;/additionalBuildcommands&gt;
+ * </pre>
+ *
+ * Note the difference between <code>build<strong>c</strong>ommand</code> and
+ * <code>build<strong>C</strong>ommand</code>. You can mix and match old and new-style configuration entries.
+ *
+ * @parameter
+ */
+ private List additionalBuildcommands;
+
+ /**
+ * List of container classpath entries. By default the <code>org.eclipse.jdt.launching.JRE_CONTAINER</code>
+ * classpath container is added. Configuration example:
+ *
+ * <pre>
+ * &lt;classpathContainers&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jdt.launching.JRE_CONTAINER&lt;/classpathContainer&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v5.5&lt;/classpathContainer&gt;
+ * &lt;classpathContainer&gt;org.eclipse.jst.j2ee.internal.web.container/artifact&lt;/classpathContainer&gt;
+ * &lt;/classpathContainers&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private List classpathContainers;
+
+ /**
+ * Enables/disables the downloading of source attachments. Defaults to false. DEPRECATED - use downloadSources
+ *
+ * @parameter expression="${eclipse.downloadSources}"
+ * @deprecated use downloadSources
+ */
+ private boolean eclipseDownloadSources;
+
+ /**
+ * Eclipse workspace directory.
+ *
+ * @parameter expression="${eclipse.projectDir}" alias="outputDir"
+ */
+ private File eclipseProjectDir;
+
+ /**
+ * When set to false, the plugin will not create sub-projects and instead reference those sub-projects using the
+ * installed package in the local repository
+ *
+ * @parameter expression="${eclipse.useProjectReferences}" default-value="true"
+ * @required
+ */
+ private boolean useProjectReferences;
+
+ /**
+ * The default output directory
+ *
+ * @parameter expression="${outputDirectory}" alias="outputDirectory"
+ * default-value="${project.build.outputDirectory}"
+ * @required
+ */
+ private File buildOutputDirectory;
+
+ /**
+ * The version of WTP for which configuration files will be generated. The default value is "none" (don't generate
+ * WTP configuration), supported versions are "R7", "1.0", and "1.5"
+ *
+ * @parameter expression="${wtpversion}" default-value="none"
+ */
+ private String wtpversion;
+
+ /**
+ * JEE context name of the WTP module. ( ex. WEB context name ).
+ *
+ * @parameter expression="${wtpContextName}"
+ */
+ private String wtpContextName;
+
+ /**
+ * The relative path of the manifest file
+ *
+ * @parameter expression="${eclipse.manifest}" default-value="${basedir}/META-INF/MANIFEST.MF"
+ */
+ private File manifest;
+
+ /**
+ * Allow to configure additional generic configuration files for eclipse that will be written out to disk when
+ * running eclipse:eclipse. FOr each file you can specify the name and the text content.
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;content&gt;
+ * &lt;![CDATA[&lt;fileset-config file-format-version=&quot;1.2.0&quot; simple-config=&quot;true&quot;&gt;
+ * &lt;fileset name=&quot;all&quot; enabled=&quot;true&quot; check-config-name=&quot;acme corporate style&quot; local=&quot;false&quot;&gt;
+ * &lt;file-match-pattern match-pattern=&quot;.&quot; include-pattern=&quot;true&quot;/&gt;
+ * &lt;/fileset&gt;
+ * &lt;filter name=&quot;NonSrcDirs&quot; enabled=&quot;true&quot;/&gt;
+ * &lt;/fileset-config&gt;]]&gt;
+ * &lt;/content&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * &lt;/plugin&gt;
+ * </pre>
+ *
+ * Instead of the content you can also define (from version 2.5) an url to download the file :
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;url&gt;http://some.place.org/path/to/file&lt;/url&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * </pre>
+ *
+ * or a location :
+ *
+ * <pre>
+ * &lt;plugin&gt;
+ * &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+ * &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
+ * &lt;configuration&gt;
+ * &lt;additionalConfig&gt;
+ * &lt;file&gt;
+ * &lt;name&gt;.checkstyle&lt;/name&gt;
+ * &lt;location&gt;/checkstyle-config.xml&lt;/location&gt;
+ * &lt;/file&gt;
+ * &lt;/additionalConfig&gt;
+ * &lt;/configuration&gt;
+ * &lt;dependencies&gt;
+ * &lt;!-- The file defined in the location is stored in this dependency --&gt;
+ * &lt;dependency&gt;
+ * &lt;groupId&gt;eclipsetest&lt;/groupId&gt;
+ * &lt;artifactId&gt;checkstyle-config&lt;/artifactId&gt;
+ * &lt;version&gt;1.0&lt;/version&gt;
+ * &lt;/dependency&gt;
+ * &lt;/dependencies&gt;
+ * &lt;/plugin&gt;
+ * </pre>
+ *
+ * @parameter
+ */
+ private EclipseConfigFile[] additionalConfig;
+
+ /**
+ * If set to <code>true</code>, the version number of the artifact is appended to the name of the generated
+ * Eclipse project. See projectNameTemplate for other options.
+ *
+ * @parameter expression="${eclipse.addVersionToProjectName}" default-value="false"
+ */
+ private boolean addVersionToProjectName;
+
+ /**
+ * If set to <code>true</code>, the groupId of the artifact is appended to the name of the generated Eclipse
+ * project. See projectNameTemplate for other options.
+ *
+ * @parameter expression="${eclipse.addGroupIdToProjectName}" default-value="false"
+ */
+ private boolean addGroupIdToProjectName;
+
+ /**
+ * Allows configuring the name of the eclipse projects. This property if set wins over addVersionToProjectName and
+ * addGroupIdToProjectName You can use <code>[groupId]</code>, <code>[artifactId]</code> and
+ * <code>[version]</code> variables. eg. <code>[groupId].[artifactId]-[version]</code>
+ *
+ * @parameter expression="${eclipse.projectNameTemplate}"
+ */
+ private String projectNameTemplate;
+
+ /**
+ * Parsed wtp version.
+ */
+ private float wtpVersionFloat;
+
+ /**
+ * Not a plugin parameter. Is this a java project?
+ */
+ private boolean isJavaProject;
+
+ /**
+ * Must the manifest files be written for java projects so that that the jee classpath for wtp is correct.
+ *
+ * @parameter expression="${eclipse.wtpmanifest}" default-value="false"
+ */
+ private boolean wtpmanifest;
+
+ /**
+ * Must the application files be written for ear projects in a separate directory.
+ *
+ * @parameter expression="${eclipse.wtpapplicationxml}" default-value="false"
+ */
+ private boolean wtpapplicationxml;
+
+ /**
+ * What WTP defined server to use for deployment informations.
+ *
+ * @parameter expression="${eclipse.wtpdefaultserver}"
+ */
+ private String wtpdefaultserver;
+
+ private WorkspaceConfiguration workspaceConfiguration;
+
+ /**
+ * ResourceManager for getting additonalConfig files from resources
+ *
+ * @component
+ * @required
+ * @readonly
+ */
+ private ResourceManager locator;
+
+ /**
+ * This eclipse workspace is read and all artifacts detected there will be connected as eclipse projects and will
+ * not be linked to the jars in the local repository. Requirement is that it was created with the similar wtp
+ * settings as the reactor projects, but the project name template my differ. The pom's in the workspace projects
+ * may not contain variables in the artefactId, groupId and version tags.
+ *
+ * @since 2.5
+ * @parameter expression="${eclipse.workspace}"
+ */
+ protected String workspace;
+
+ /**
+ * Limit the use of project references to the current workspace. No project references will be created to projects
+ * in the reactor when they are not available in the workspace.
+ *
+ * @parameter expression="${eclipse.limitProjectReferencesToWorkspace}" default-value="false"
+ */
+ protected boolean limitProjectReferencesToWorkspace;
+
+ protected boolean isJavaProject()
+ {
+ return isJavaProject;
+ }
+
+ protected boolean isPdeProject()
+ {
+ return pde;
+ }
+
+ /**
+ * Getter for <code>buildcommands</code>.
+ *
+ * @return Returns the buildcommands.
+ */
+ public List getBuildcommands()
+ {
+ return buildcommands;
+ }
+
+ /**
+ * Setter for <code>buildcommands</code>.
+ *
+ * @param buildcommands The buildcommands to set.
+ */
+ public void setBuildcommands( List buildcommands )
+ {
+ this.buildcommands = buildcommands;
+ }
+
+ /**
+ * Getter for <code>buildOutputDirectory</code>.
+ *
+ * @return Returns the buildOutputDirectory.
+ */
+ public File getBuildOutputDirectory()
+ {
+ return buildOutputDirectory;
+ }
+
+ /**
+ * Setter for <code>buildOutputDirectory</code>.
+ *
+ * @param buildOutputDirectory The buildOutputDirectory to set.
+ */
+ public void setBuildOutputDirectory( File buildOutputDirectory )
+ {
+ this.buildOutputDirectory = buildOutputDirectory;
+ }
+
+ /**
+ * Getter for <code>classpathContainers</code>.
+ *
+ * @return Returns the classpathContainers.
+ */
+ public List getClasspathContainers()
+ {
+ return classpathContainers;
+ }
+
+ /**
+ * Setter for <code>classpathContainers</code>.
+ *
+ * @param classpathContainers The classpathContainers to set.
+ */
+ public void setClasspathContainers( List classpathContainers )
+ {
+ this.classpathContainers = classpathContainers;
+ }
+
+ /**
+ * Getter for <code>eclipseProjectDir</code>.
+ *
+ * @return Returns the eclipseProjectDir.
+ */
+ public File getEclipseProjectDir()
+ {
+ return eclipseProjectDir;
+ }
+
+ /**
+ * Setter for <code>eclipseProjectDir</code>.
+ *
+ * @param eclipseProjectDir The eclipseProjectDir to set.
+ */
+ public void setEclipseProjectDir( File eclipseProjectDir )
+ {
+ this.eclipseProjectDir = eclipseProjectDir;
+ }
+
+ /**
+ * Getter for <code>projectnatures</code>.
+ *
+ * @return Returns the projectnatures.
+ */
+ public List getProjectnatures()
+ {
+ return projectnatures;
+ }
+
+ /**
+ * Setter for <code>projectnatures</code>.
+ *
+ * @param projectnatures The projectnatures to set.
+ */
+ public void setProjectnatures( List projectnatures )
+ {
+ this.projectnatures = projectnatures;
+ }
+
+ /**
+ * Getter for <code>useProjectReferences</code>.
+ *
+ * @return Returns the useProjectReferences.
+ */
+ public boolean getUseProjectReferences()
+ {
+ return useProjectReferences;
+ }
+
+ /**
+ * Setter for <code>useProjectReferences</code>.
+ *
+ * @param useProjectReferences The useProjectReferences to set.
+ */
+ public void setUseProjectReferences( boolean useProjectReferences )
+ {
+ this.useProjectReferences = useProjectReferences;
+ }
+
+ /**
+ * Getter for <code>wtpversion</code>.
+ *
+ * @return Returns the wtpversion.
+ */
+ public String getWtpversion()
+ {
+ return wtpversion;
+ }
+
+ /**
+ * Setter for <code>wtpversion</code>.
+ *
+ * @param wtpversion The wtpversion to set.
+ */
+ public void setWtpversion( String wtpversion )
+ {
+ this.wtpversion = wtpversion;
+ }
+
+ /**
+ * Getter for <code>additionalBuildcommands</code>.
+ *
+ * @return Returns the additionalBuildcommands.
+ */
+ public List getAdditionalBuildcommands()
+ {
+ return additionalBuildcommands;
+ }
+
+ /**
+ * Setter for <code>additionalBuildcommands</code>.
+ *
+ * @param additionalBuildcommands The additionalBuildcommands to set.
+ */
+ public void setAdditionalBuildcommands( List additionalBuildcommands )
+ {
+ this.additionalBuildcommands = additionalBuildcommands;
+ }
+
+ /**
+ * Getter for <code>additionalProjectnatures</code>.
+ *
+ * @return Returns the additionalProjectnatures.
+ */
+ public List getAdditionalProjectnatures()
+ {
+ return additionalProjectnatures;
+ }
+
+ /**
+ * Setter for <code>additionalProjectnatures</code>.
+ *
+ * @param additionalProjectnatures The additionalProjectnatures to set.
+ */
+ public void setAdditionalProjectnatures( List additionalProjectnatures )
+ {
+ this.additionalProjectnatures = additionalProjectnatures;
+ }
+
+ /**
+ * Getter for <code>addVersionToProjectName</code>.
+ */
+ public boolean isAddVersionToProjectName()
+ {
+ return addVersionToProjectName;
+ }
+
+ /**
+ * Setter for <code>addVersionToProjectName</code>.
+ */
+ public void setAddVersionToProjectName( boolean addVersionToProjectName )
+ {
+ this.addVersionToProjectName = addVersionToProjectName;
+ }
+
+ /**
+ * Getter for <code>addGroupIdToProjectName</code>.
+ */
+ public boolean isAddGroupIdToProjectName()
+ {
+ return addGroupIdToProjectName;
+ }
+
+ /**
+ * Setter for <code>addGroupIdToProjectName</code>.
+ */
+ public void setAddGroupIdToProjectName( boolean addGroupIdToProjectName )
+ {
+ this.addGroupIdToProjectName = addGroupIdToProjectName;
+ }
+
+ public String getProjectNameTemplate()
+ {
+ return projectNameTemplate;
+ }
+
+ public void setProjectNameTemplate( String projectNameTemplate )
+ {
+ this.projectNameTemplate = projectNameTemplate;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.Mojo#execute()
+ */
+ public boolean setup()
+ throws MojoExecutionException
+ {
+ boolean ready = true;
+
+ checkDeprecations();
+
+ ready = validate();
+
+ // TODO: Why are we using project in some places, and executedProject in others??
+ ArtifactHandler artifactHandler = project.getArtifact().getArtifactHandler();
+
+ // ear projects don't contain java sources
+ // pde projects are always java projects
+ isJavaProject =
+ pde ||
+ ( Constants.LANGUAGE_JAVA.equals( artifactHandler.getLanguage() ) && !Constants.PROJECT_PACKAGING_EAR.equals( packaging ) );
+
+ setupExtras();
+
+ parseConfigurationOptions();
+
+ // defaults
+ if ( projectnatures == null )
+ {
+ fillDefaultNatures( packaging );
+ }
+
+ if ( additionalProjectnatures != null )
+ {
+ projectnatures.addAll( additionalProjectnatures );
+ }
+
+ if ( buildcommands == null )
+ {
+ fillDefaultBuilders( packaging );
+ }
+ else
+ {
+ convertBuildCommandList( buildcommands );
+ }
+
+ if ( additionalBuildcommands != null )
+ {
+ convertBuildCommandList( additionalBuildcommands );
+ buildcommands.addAll( additionalBuildcommands );
+ }
+
+ if ( classpathContainers == null )
+ {
+ fillDefaultClasspathContainers( packaging );
+ }
+ else
+ {
+ verifyClasspathContainerListIsComplete();
+ }
+ locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
+ locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
+
+ // ready to start
+ return ready;
+ }
+
+ protected void convertBuildCommandList( List commands )
+ {
+ if ( commands != null )
+ {
+ for ( ListIterator i = commands.listIterator(); i.hasNext(); )
+ {
+ Object command = i.next();
+
+ if ( command instanceof String )
+ {
+ command = new BuildCommand( (String) command );
+ i.set( command );
+ }
+ }
+ }
+ }
+
+ private void parseConfigurationOptions()
+ {
+ if ( "R7".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
+ {
+ wtpVersionFloat = 0.7f;
+ }
+ else if ( "1.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
+ {
+ wtpVersionFloat = 1.0f;
+ }
+ else if ( "1.5".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
+ {
+ wtpVersionFloat = 1.5f;
+ }
+ else if ( "2.0".equalsIgnoreCase( wtpversion ) ) //$NON-NLS-1$
+ {
+ wtpVersionFloat = 2.0f;
+ }
+ if ( !"none".equalsIgnoreCase( wtpversion ) )
+ {
+ getLog().info( Messages.getString( "EclipsePlugin.wtpversion", wtpversion ) );
+ }
+ }
+
+ protected void setupExtras()
+ throws MojoExecutionException
+ {
+ // extension point.
+ }
+
+ protected void verifyClasspathContainerListIsComplete()
+ {
+ boolean containsJREContainer = false;
+ // Check if classpathContainer contains a JRE (default, alternate or
+ // Execution Environment)
+ for ( Iterator iter = classpathContainers.iterator(); iter.hasNext(); )
+ {
+ Object classPathContainer = iter.next();
+ if ( classPathContainer != null &&
+ classPathContainer.toString().startsWith( COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER ) )
+ {
+ containsJREContainer = true;
+ break;
+ }
+ }
+ if ( !containsJREContainer )
+ {
+ getLog().warn( Messages.getString( "EclipsePlugin.missingjrecontainer" ) ); //$NON-NLS-1$
+ classpathContainers.add( 0, COMMON_PATH_JDT_LAUNCHING_JRE_CONTAINER );
+ }
+ }
+
+ private boolean validate()
+ throws MojoExecutionException
+ {
+ // validate sanity of the current m2 project
+ if ( Arrays.binarySearch( WTP_SUPPORTED_VERSIONS, wtpversion ) < 0 )
+ {
+ throw new MojoExecutionException(
+ Messages.getString( "EclipsePlugin.unsupportedwtp", new Object[] { //$NON-NLS-1$
+ wtpversion,
+ StringUtils.join( WTP_SUPPORTED_VERSIONS, " " ) } ) ); //$NON-NLS-1$
+ }
+
+ assertNotEmpty( executedProject.getGroupId(), POM_ELT_GROUP_ID );
+ assertNotEmpty( executedProject.getArtifactId(), POM_ELT_ARTIFACT_ID );
+
+ if ( executedProject.getFile() == null || !executedProject.getFile().exists() )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingpom" ) ); //$NON-NLS-1$
+ }
+
+ if ( "pom".equals( packaging ) && eclipseProjectDir == null ) //$NON-NLS-1$
+ {
+ getLog().info( Messages.getString( "EclipsePlugin.pompackaging" ) ); //$NON-NLS-1$
+ return false;
+ }
+
+ if ( "eclipse-plugin".equals( packaging ) )
+ {
+ pde = true;
+ }
+
+ // [rfeng] Set PDE to false if the project is not a bundle
+ if(!isOSGiBundle()) {
+ pde = false;
+ }
+
+ if ( eclipseProjectDir == null )
+ {
+ eclipseProjectDir = executedProject.getFile().getParentFile();
+ }
+
+ if ( !eclipseProjectDir.exists() && !eclipseProjectDir.mkdirs() )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$
+ }
+
+ if ( !eclipseProjectDir.equals( executedProject.getFile().getParentFile() ) )
+ {
+ if ( !eclipseProjectDir.isDirectory() )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.notadir", eclipseProjectDir ) ); //$NON-NLS-1$
+ }
+ eclipseProjectDir = new File( eclipseProjectDir, executedProject.getArtifactId() );
+ if ( !eclipseProjectDir.isDirectory() && !eclipseProjectDir.mkdirs() )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcreatedir", eclipseProjectDir ) ); //$NON-NLS-1$
+ }
+ }
+
+ validateExtras();
+
+ return true;
+ }
+
+ protected void validateExtras()
+ {
+ // provided for extension.
+ }
+
+ private void checkDeprecations()
+ {
+ if ( eclipseDownloadSources )
+ {
+ // deprecated warning
+ getLog().warn( Messages.getString( "EclipsePlugin.deprecatedpar", new Object[] { //$NON-NLS-1$
+ "eclipse.downloadSources", //$NON-NLS-1$
+ "downloadSources" } ) ); //$NON-NLS-1$
+ downloadSources = true;
+ }
+
+ checkExtraDeprecations();
+ }
+
+ protected void checkExtraDeprecations()
+ {
+ // provided for extension.
+ }
+
+ public void writeConfiguration( IdeDependency[] deps )
+ throws MojoExecutionException
+ {
+ EclipseWriterConfig config = createEclipseWriterConfig( deps );
+
+ if ( wtpmanifest && isJavaProject() )
+ {
+ EclipseManifestWriter.addManifestResource( getLog(), config );
+ }
+ // NOTE: This could change the config!
+ writeExtraConfiguration( config );
+
+ if ( wtpVersionFloat == 0.7f )
+ {
+ new EclipseWtpmodulesWriter().init( getLog(), config ).write();
+ }
+
+ if ( wtpVersionFloat >= 1.0f )
+ {
+ new EclipseWtpFacetsWriter().init( getLog(), config ).write();
+ }
+ if ( wtpVersionFloat == 1.0f )
+ {
+ new EclipseWtpComponentWriter().init( getLog(), config ).write();
+ }
+ if ( wtpVersionFloat >= 1.5 )
+ {
+ new EclipseWtpComponent15Writer().init( getLog(), config ).write();
+ }
+
+ new EclipseSettingsWriter().init( getLog(), config ).write();
+
+ if ( isJavaProject )
+ {
+ new EclipseClasspathWriter().init( getLog(), config ).write();
+ }
+
+ if ( wtpapplicationxml )
+ {
+ new EclipseWtpApplicationXMLWriter().init( getLog(), config ).write();
+ }
+
+ // [rfeng]
+ /*
+ if ( pde )
+ {
+ this.getLog().info( "The Maven Eclipse plugin runs in 'pde'-mode." );
+ new EclipseOSGiManifestWriter().init( getLog(), config ).write();
+ }
+ */
+ // [rfeng]
+
+ // NOTE: This one MUST be after EclipseClasspathwriter, and possibly others,
+ // since currently EclipseClasspathWriter does some magic to detect nested
+ // output folders and modifies the configuration by adding new (Ant) builders.
+ // So the .project file must be written AFTER those have run!
+ new EclipseProjectWriter().init( getLog(), config ).write();
+
+ writeAdditionalConfig();
+
+ getLog().info( Messages.getString( "EclipsePlugin.wrote", new Object[] { //$NON-NLS-1$
+ config.getEclipseProjectName(), eclipseProjectDir.getAbsolutePath() } ) );
+ }
+
+ protected void writeAdditionalConfig()
+ throws MojoExecutionException
+ {
+ if ( additionalConfig != null )
+ {
+ for ( int j = 0; j < additionalConfig.length; j++ )
+ {
+ EclipseConfigFile file = additionalConfig[j];
+ File projectRelativeFile = new File( eclipseProjectDir, file.getName() );
+ if ( projectRelativeFile.isDirectory() )
+ {
+ // just ignore?
+ getLog().warn( Messages.getString( "EclipsePlugin.foundadir", //$NON-NLS-1$
+ projectRelativeFile.getAbsolutePath() ) );
+ }
+
+ try
+ {
+ projectRelativeFile.getParentFile().mkdirs();
+ if ( file.getContent() == null )
+ {
+ InputStream inStream;
+ if ( file.getLocation() != null )
+ {
+ inStream = locator.getResourceAsInputStream( file.getLocation() );
+ }
+ else
+ {
+ inStream = file.getURL().openConnection().getInputStream();
+ }
+ OutputStream outStream = new FileOutputStream( projectRelativeFile );
+ try
+ {
+ IOUtil.copy( inStream, outStream );
+ }
+ finally
+ {
+ inStream.close();
+ outStream.close();
+ }
+ }
+ else
+ {
+ FileUtils.fileWrite( projectRelativeFile.getAbsolutePath(), file.getContent() );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantwritetofile", //$NON-NLS-1$
+ projectRelativeFile.getAbsolutePath() ) );
+ }
+ catch ( ResourceNotFoundException e )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantfindresource", //$NON-NLS-1$
+ file.getLocation() ) );
+ }
+
+ }
+ }
+ }
+
+ protected EclipseWriterConfig createEclipseWriterConfig( IdeDependency[] deps )
+ throws MojoExecutionException
+ {
+ File projectBaseDir = executedProject.getFile().getParentFile();
+
+ // build a list of UNIQUE source dirs (both src and resources) to be
+ // used in classpath and wtpmodules
+ EclipseSourceDir[] sourceDirs = buildDirectoryList( executedProject, eclipseProjectDir, buildOutputDirectory );
+
+ EclipseWriterConfig config = new EclipseWriterConfig();
+
+ config.setWorkspaceConfiguration( getWorkspaceConfiguration() );
+
+ config.setProjectNameTemplate( calculateProjectNameTemplate() );
+
+ String projectName = IdeUtils.getProjectName( config.getProjectNameTemplate(), project );
+
+ config.setEclipseProjectName( projectName );
+
+ config.setWtpapplicationxml( wtpapplicationxml );
+
+ config.setWtpVersion( wtpVersionFloat );
+
+ Set convertedBuildCommands = new LinkedHashSet();
+
+ if ( buildcommands != null )
+ {
+ for ( Iterator it = buildcommands.iterator(); it.hasNext(); )
+ {
+ Object cmd = it.next();
+
+ if ( cmd instanceof BuildCommand )
+ {
+ convertedBuildCommands.add( cmd );
+ }
+ else
+ {
+ convertedBuildCommands.add( new BuildCommand( (String) cmd ) );
+ }
+ }
+ }
+
+ config.setBuildCommands( new LinkedList( convertedBuildCommands ) );
+
+ config.setBuildOutputDirectory( buildOutputDirectory );
+ config.setClasspathContainers( classpathContainers );
+ config.setDeps( deps );
+ config.setEclipseProjectDirectory( eclipseProjectDir );
+ config.setLocalRepository( localRepository );
+ config.setOSGIManifestFile( manifest );
+ config.setPde( pde );
+ config.setProject( project );
+ config.setProjectBaseDir( projectBaseDir );
+ config.setProjectnatures( projectnatures );
+ config.setProjectFacets( additionalProjectFacets );
+ config.setSourceDirs( sourceDirs );
+ config.setAddVersionToProjectName( isAddVersionToProjectName() );
+ config.setPackaging( packaging );
+
+ collectWarContextRootsFromReactorEarConfiguration( config );
+
+ return config;
+ }
+
+ /**
+ * If this is a war module peek into the reactor an search for an ear module that defines the context root of this
+ * module.
+ *
+ * @param config config to save the context root.
+ */
+ private void collectWarContextRootsFromReactorEarConfiguration( EclipseWriterConfig config )
+ {
+ if ( reactorProjects != null && wtpContextName == null &&
+ Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
+ {
+ for ( Iterator iter = reactorProjects.iterator(); iter.hasNext(); )
+ {
+ MavenProject reactorProject = (MavenProject) iter.next();
+
+ if ( Constants.PROJECT_PACKAGING_EAR.equals( reactorProject.getPackaging() ) )
+ {
+ Xpp3Dom[] warDefinitions =
+ IdeUtils.getPluginConfigurationDom( reactorProject, JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN,
+ new String[] { "modules", "webModule" } );
+ for ( int index = 0; index < warDefinitions.length; index++ )
+ {
+ Xpp3Dom groupId = warDefinitions[index].getChild( "groupId" );
+ Xpp3Dom artifactId = warDefinitions[index].getChild( "artifactId" );
+ Xpp3Dom contextRoot = warDefinitions[index].getChild( "contextRoot" );
+ if ( groupId != null && artifactId != null && contextRoot != null &&
+ groupId.getValue() != null && artifactId.getValue() != null &&
+ contextRoot.getValue() != null )
+ {
+ getLog().info(
+ "Found context root definition for " + groupId.getValue() + ":" +
+ artifactId.getValue() + " " + contextRoot.getValue() );
+ if ( project.getArtifactId().equals( artifactId.getValue() ) &&
+ project.getGroupId().equals( groupId.getValue() ) )
+ {
+ config.setContextName( contextRoot.getValue() );
+ }
+ }
+ else
+ {
+ getLog().info(
+ "Found incomplete ear configuration in " + reactorProject.getGroupId() +
+ ":" + reactorProject.getGroupId() + " found " +
+ warDefinitions[index].toString() );
+ }
+ }
+ }
+ }
+ }
+ if ( config.getContextName() == null && Constants.PROJECT_PACKAGING_WAR.equals( project.getPackaging() ) )
+ {
+ if ( wtpContextName == null )
+ {
+ config.setContextName( project.getArtifactId() );
+ }
+ else
+ {
+ config.setContextName( wtpContextName );
+ }
+ }
+ }
+
+ /**
+ * Write any extra configuration information for the Eclipse project. This is an extension point, called before the
+ * main configurations are written. <br/> <b> NOTE: This could change the config! </b>
+ *
+ * @param config
+ * @throws MojoExecutionException
+ */
+ protected void writeExtraConfiguration( EclipseWriterConfig config )
+ throws MojoExecutionException
+ {
+ // extension point.
+ }
+
+ private void assertNotEmpty( String string, String elementName )
+ throws MojoExecutionException
+ {
+ if ( string == null )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.missingelement", elementName ) ); //$NON-NLS-1$
+ }
+ }
+
+ protected void fillDefaultNatures( String packaging )
+ {
+ projectnatures = new ArrayList();
+
+ if ( wtpVersionFloat >= 1.0f )
+ {
+ projectnatures.add( NATURE_WST_FACET_CORE_NATURE ); // WTP 1.0 nature
+ }
+
+ if ( isJavaProject )
+ {
+ projectnatures.add( NATURE_JDT_CORE_JAVA );
+ }
+
+ if ( wtpVersionFloat >= 0.7f )
+ {
+ projectnatures.add( NATURE_WST_MODULE_CORE_NATURE ); // WTP 0.7/1.0 nature
+
+ if ( isJavaProject )
+ {
+ projectnatures.add( NATURE_JEM_WORKBENCH_JAVA_EMF ); // WTP 0.7/1.0 nature
+ }
+ }
+
+ if ( pde )
+ {
+ projectnatures.add( NATURE_PDE_PLUGIN );
+ }
+
+ }
+
+ protected void fillDefaultClasspathContainers( String packaging )
+ {
+ classpathContainers = new ArrayList();
+
+ if ( getWorkspaceConfiguration().getDefaultClasspathContainer() != null )
+ {
+ getLog().info(
+ "Adding default classpath contaigner: " +
+ getWorkspaceConfiguration().getDefaultClasspathContainer() );
+ classpathContainers.add( getWorkspaceConfiguration().getDefaultClasspathContainer() );
+ }
+ if ( pde )
+ {
+ classpathContainers.add( REQUIRED_PLUGINS_CONTAINER );
+ }
+ }
+
+ protected void fillDefaultBuilders( String packaging )
+ {
+ buildcommands = new ArrayList();
+
+ if ( wtpVersionFloat == 0.7f )
+ {
+ buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL ) ); // WTP 0.7 builder
+ }
+
+ if ( isJavaProject )
+ {
+ buildcommands.add( new BuildCommand( BUILDER_JDT_CORE_JAVA ) );
+ }
+
+ if ( wtpVersionFloat >= 1.5f )
+ {
+ buildcommands.add( new BuildCommand( BUILDER_WST_FACET ) ); // WTP 1.5 builder
+ }
+
+ if ( wtpVersionFloat >= 0.7f )
+ {
+ buildcommands.add( new BuildCommand( BUILDER_WST_VALIDATION ) ); // WTP 0.7/1.0 builder
+ }
+
+ if ( wtpVersionFloat == 0.7f )
+ {
+ // WTP 0.7 builder
+ buildcommands.add( new BuildCommand( BUILDER_WST_COMPONENT_STRUCTURAL_DEPENDENCY_RESOLVER ) );
+ }
+
+ if ( pde )
+ {
+ buildcommands.add( new BuildCommand( BUILDER_PDE_MANIFEST ) );
+ buildcommands.add( new BuildCommand( BUILDER_PDE_SCHEMA ) );
+ }
+ }
+
+ public EclipseSourceDir[] buildDirectoryList( MavenProject project, File basedir, File buildOutputDirectory )
+ throws MojoExecutionException
+ {
+ File projectBaseDir = project.getFile().getParentFile();
+
+ // avoid duplicated entries
+ Set directories = new TreeSet();
+
+ extractSourceDirs( directories, project.getCompileSourceRoots(), basedir, projectBaseDir, false, null );
+
+ String relativeOutput = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, buildOutputDirectory, false );
+
+ extractResourceDirs( directories, project.getBuild().getResources(), project, basedir, projectBaseDir, false,
+ relativeOutput );
+
+ // If using the standard output location, don't mix the test output into it.
+ String testOutput = null;
+ boolean useStandardOutputDir =
+ buildOutputDirectory.equals( new File( project.getBuild().getOutputDirectory() ) );
+ if ( useStandardOutputDir )
+ {
+ getLog().debug(
+ "testOutput toRelativeAndFixSeparator " + projectBaseDir + " , " +
+ project.getBuild().getTestOutputDirectory() );
+ testOutput =
+ IdeUtils.toRelativeAndFixSeparator( projectBaseDir,
+ new File( project.getBuild().getTestOutputDirectory() ), false );
+ getLog().debug( "testOutput after toRelative : " + testOutput );
+ }
+
+ extractSourceDirs( directories, project.getTestCompileSourceRoots(), basedir, projectBaseDir, true, testOutput );
+
+ extractResourceDirs( directories, project.getBuild().getTestResources(), project, basedir, projectBaseDir,
+ true, testOutput );
+
+ return (EclipseSourceDir[]) directories.toArray( new EclipseSourceDir[directories.size()] );
+ }
+
+ private void extractSourceDirs( Set directories, List sourceRoots, File basedir, File projectBaseDir, boolean test,
+ String output )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
+ {
+
+ File sourceRootFile = new File( (String) it.next() );
+ getLog().debug( "Processing source dir: " + sourceRootFile );
+
+ if ( sourceRootFile.isDirectory() )
+ {
+ String sourceRoot =
+ IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRootFile,
+ !projectBaseDir.equals( basedir ) );
+
+ directories.add( new EclipseSourceDir( sourceRoot, output, false, test, null, null, false ) );
+ }
+ }
+ }
+
+ void extractResourceDirs( Set directories, List resources, MavenProject project, File basedir,
+ File workspaceProjectBaseDir, boolean test, final String output )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = resources.iterator(); it.hasNext(); )
+ {
+ Resource resource = (Resource) it.next();
+
+ getLog().debug( "Processing resource dir: " + resource.getDirectory() );
+
+ String includePattern = null;
+ String excludePattern = null;
+
+ if ( resource.getIncludes().size() != 0 )
+ {
+ includePattern = StringUtils.join( resource.getIncludes().iterator(), "|" );
+ }
+
+ if ( resource.getExcludes().size() != 0 )
+ {
+ excludePattern = StringUtils.join( resource.getExcludes().iterator(), "|" );
+ }
+
+ // TODO: figure out how to merge if the same dir is specified twice
+ // with different in/exclude patterns.
+
+ File resourceDirectory = new File( /* basedir, */resource.getDirectory() );
+
+ if ( !resourceDirectory.exists() || !resourceDirectory.isDirectory() )
+ {
+ getLog().debug( "Resource dir: " + resourceDirectory + " either missing or not a directory." );
+ continue;
+ }
+
+ String resourceDir =
+ IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, resourceDirectory,
+ !workspaceProjectBaseDir.equals( basedir ) );
+ String thisOutput = output;
+ if ( thisOutput != null )
+ {
+ // sometimes thisOutput is already an absolute path
+ File outputFile = new File( thisOutput );
+ if ( !outputFile.isAbsolute() )
+ {
+ outputFile = new File( workspaceProjectBaseDir, thisOutput );
+ }
+ // create output dir if it doesn't exist
+ outputFile.mkdirs();
+
+ if ( !StringUtils.isEmpty( resource.getTargetPath() ) )
+ {
+ outputFile = new File( outputFile, resource.getTargetPath() );
+ // create output dir if it doesn't exist
+ outputFile.mkdirs();
+ }
+
+ getLog().debug(
+ "Making relative and fixing separator: { " + workspaceProjectBaseDir + ", " +
+ outputFile + ", false }." );
+ thisOutput = IdeUtils.toRelativeAndFixSeparator( workspaceProjectBaseDir, outputFile, false );
+ }
+
+ getLog().debug(
+ "Adding eclipse source dir: { " + resourceDir + ", " + thisOutput + ", true, " + test +
+ ", " + includePattern + ", " + excludePattern + " }." );
+
+ directories.add( new EclipseSourceDir( resourceDir, thisOutput, true, test, includePattern, excludePattern,
+ resource.isFiltering() ) );
+ }
+ }
+
+ /**
+ * Calculate the project name template from the fields {@link #projectNameTemplate},
+ * {@link #addVersionToProjectName} and {@link #addGroupIdToProjectName}
+ *
+ * @return the project name template that should be used after considering the plugin configuration
+ */
+ private String calculateProjectNameTemplate()
+ {
+ if ( getProjectNameTemplate() != null )
+ {
+ if ( isAddVersionToProjectName() || isAddGroupIdToProjectName() )
+ {
+ getLog().warn(
+ "projectNameTemplate definition overrides "
+ + "addVersionToProjectName or addGroupIdToProjectName" );
+ }
+ return getProjectNameTemplate();
+ }
+ else if ( isAddVersionToProjectName() && isAddGroupIdToProjectName() )
+ {
+ return IdeUtils.PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE;
+ }
+ else if ( isAddVersionToProjectName() )
+ {
+ return IdeUtils.PROJECT_NAME_WITH_VERSION_TEMPLATE;
+ }
+ else if ( isAddGroupIdToProjectName() )
+ {
+ return IdeUtils.PROJECT_NAME_WITH_GROUP_TEMPLATE;
+ }
+ return IdeUtils.PROJECT_NAME_DEFAULT_TEMPLATE;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getProjectNameForArifact( Artifact artifact )
+ {
+ IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
+ for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
+ {
+ IdeDependency workspaceArtefact = workspaceArtefacts[index];
+ if ( workspaceArtefact.isAddedToClasspath() &&
+ workspaceArtefact.getGroupId().equals( artifact.getGroupId() ) &&
+ workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
+ {
+ if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) )
+ {
+ return workspaceArtefact.getEclipseProjectName();
+ }
+ }
+ }
+ return IdeUtils.getProjectName( calculateProjectNameTemplate(), artifact );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected IdeDependency[] getWorkspaceArtefacts()
+ {
+ return getWorkspaceConfiguration().getWorkspaceArtefacts();
+ }
+
+ public WorkspaceConfiguration getWorkspaceConfiguration()
+ {
+ if ( workspaceConfiguration == null )
+ {
+ workspaceConfiguration = new WorkspaceConfiguration();
+ if ( workspace != null )
+ {
+ workspaceConfiguration.setWorkspaceDirectory( new File( workspace ) );
+ }
+ new ReadWorkspaceLocations().init( getLog(), workspaceConfiguration, project, wtpdefaultserver );
+ }
+ return workspaceConfiguration;
+ }
+
+ public List getExcludes()
+ {
+ return excludes;
+ }
+
+ /**
+ * Utility method that locates a project in the workspace for the given artifact.
+ *
+ * @param artifact the artifact a project should produce.
+ * @return <code>true</code> if the artifact is produced by a reactor projectart.
+ */
+ private boolean isAvailableAsAWorkspaceProject( Artifact artifact )
+ {
+ IdeDependency[] workspaceArtefacts = getWorkspaceArtefacts();
+ for ( int index = 0; workspaceArtefacts != null && index < workspaceArtefacts.length; index++ )
+ {
+ IdeDependency workspaceArtefact = workspaceArtefacts[index];
+ if ( workspaceArtefact.getGroupId().equals( artifact.getGroupId() ) &&
+ workspaceArtefact.getArtifactId().equals( artifact.getArtifactId() ) )
+ {
+ if ( workspaceArtefact.getVersion().equals( artifact.getVersion() ) )
+ {
+ workspaceArtefact.setAddedToClasspath( true );
+ getLog().debug( "Using workspace project: " + workspaceArtefact.getEclipseProjectName() );
+ return true;
+ }
+ else
+ {
+ getLog().info(
+ "Artifact " +
+ artifact.getId() +
+ " already available as a workspace project, but with different version. Expected: " +
+ artifact.getVersion() + ", found: " + workspaceArtefact.getVersion() );
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.maven.plugin.ide.AbstractIdeSupportMojo#doDependencyResolution()
+ */
+ protected IdeDependency[] doDependencyResolution()
+ throws MojoExecutionException
+ {
+
+ return super.doDependencyResolution();
+ }
+
+ /**
+ * Checks if jar has to be resolved for the given artifact
+ *
+ * @param art the artifact to check
+ * @return true if resolution should happen
+ */
+ protected boolean hasToResolveJar( Artifact art )
+ {
+ return !( getUseProjectReferences() && isAvailableAsAReactorProject( art ) ) ||
+ ( limitProjectReferencesToWorkspace && !( getUseProjectReferences() && isAvailableAsAWorkspaceProject( art ) ) );
+ }
+
+ /**
+ * Checks if a projects reference has to be used for the given artifact
+ *
+ * @param art the artifact to check
+ * @return true if a project reference has to be used.
+ */
+ protected boolean useProjectReference( Artifact art )
+ {
+ boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject( art );
+ boolean isWorkspaceProject = getUseProjectReferences() && isAvailableAsAWorkspaceProject( art );
+ return ( isReactorProject && !limitProjectReferencesToWorkspace ) || // default
+ ( limitProjectReferencesToWorkspace && isWorkspaceProject ) || // limitProjectReferencesToWorkspace
+ ( !isReactorProject && isWorkspaceProject ); // default + workspace projects
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java
new file mode 100644
index 0000000000..070b9b3e8b
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/EclipseProjectWriter.java
@@ -0,0 +1,351 @@
+/*
+ * 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.maven.plugin.eclipse;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.BuildCommand;
+import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.plugin.ide.IdeUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Writes eclipse .project file.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
+ * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
+ * @version $Id: EclipseProjectWriter.java 616816 2008-01-30 17:23:08Z aheritier $
+ */
+public class EclipseProjectWriter
+ extends AbstractEclipseWriter
+{
+ private static final String ELT_NAME = "name"; //$NON-NLS-1$
+
+ private static final String ELT_BUILD_COMMAND = "buildCommand"; //$NON-NLS-1$
+
+ private static final String ELT_BUILD_SPEC = "buildSpec"; //$NON-NLS-1$
+
+ private static final String ELT_NATURE = "nature"; //$NON-NLS-1$
+
+ private static final String ELT_NATURES = "natures"; //$NON-NLS-1$
+
+ private static final String FILE_DOT_PROJECT = ".project"; //$NON-NLS-1$
+
+ /**
+ * Constant for links to files.
+ */
+ private static final int LINK_TYPE_FILE = 1;
+
+ /**
+ * Constant for links to directories.
+ */
+ private static final int LINK_TYPE_DIRECTORY = 2;
+
+ /**
+ * @see org.apache.tuscany.sca.maven.plugin.eclipse.writers.EclipseWriter#write()
+ */
+ public void write()
+ throws MojoExecutionException
+ {
+
+ Set projectnatures = new LinkedHashSet();
+ Set buildCommands = new LinkedHashSet();
+
+ File dotProject = new File( config.getEclipseProjectDirectory(), FILE_DOT_PROJECT );
+
+ if ( dotProject.exists() )
+ {
+
+ log.info( Messages.getString( "EclipsePlugin.keepexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+
+ // parse existing file in order to keep manually-added entries
+ Reader reader = null;
+ try
+ {
+ reader = new InputStreamReader( new FileInputStream( dotProject ), "UTF-8" );
+ Xpp3Dom dom = Xpp3DomBuilder.build( reader );
+
+ Xpp3Dom naturesElement = dom.getChild( ELT_NATURES );
+ if ( naturesElement != null )
+ {
+ Xpp3Dom[] existingNatures = naturesElement.getChildren( ELT_NATURE );
+ for ( int j = 0; j < existingNatures.length; j++ )
+ {
+ // adds all the existing natures
+ projectnatures.add( existingNatures[j].getValue() );
+ }
+ }
+
+ Xpp3Dom buildSpec = dom.getChild( ELT_BUILD_SPEC );
+ if ( buildSpec != null )
+ {
+ Xpp3Dom[] existingBuildCommands = buildSpec.getChildren( ELT_BUILD_COMMAND );
+ for ( int j = 0; j < existingBuildCommands.length; j++ )
+ {
+ Xpp3Dom buildCommandName = existingBuildCommands[j].getChild( ELT_NAME );
+ if ( buildCommandName != null )
+ {
+ buildCommands.add( new BuildCommand( existingBuildCommands[j] ) );
+ }
+ }
+ }
+ }
+ catch ( XmlPullParserException e )
+ {
+ log.warn( Messages.getString( "EclipsePlugin.cantparseexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+ }
+ catch ( IOException e )
+ {
+ log.warn( Messages.getString( "EclipsePlugin.cantparseexisting", dotProject.getAbsolutePath() ) ); //$NON-NLS-1$
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+ }
+
+ // adds new entries after the existing ones
+ for ( Iterator iter = config.getProjectnatures().iterator(); iter.hasNext(); )
+ {
+ projectnatures.add( iter.next() );
+ }
+
+ for ( Iterator iter = config.getBuildCommands().iterator(); iter.hasNext(); )
+ {
+ buildCommands.add( (BuildCommand) iter.next() );
+ }
+
+ Writer w;
+
+ try
+ {
+ w = new OutputStreamWriter( new FileOutputStream( dotProject ), "UTF-8" );
+ }
+ catch ( IOException ex )
+ {
+ throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex ); //$NON-NLS-1$
+ }
+
+ XMLWriter writer = new PrettyPrintXMLWriter( w );
+
+ writer.startElement( "projectDescription" ); //$NON-NLS-1$
+
+ writer.startElement( ELT_NAME );
+ writer.writeText( config.getEclipseProjectName() );
+ writer.endElement();
+
+ // TODO: this entire element might be dropped if the comment is null.
+ // but as the maven1 eclipse plugin does it, it's better to be safe than sorry
+ // A eclipse developer might want to look at this.
+ writer.startElement( "comment" ); //$NON-NLS-1$
+
+ if ( config.getProject().getDescription() != null )
+ {
+ writer.writeText( config.getProject().getDescription() );
+ }
+
+ writer.endElement();
+
+ writer.startElement( "projects" ); //$NON-NLS-1$
+
+ // referenced projects should not be added for plugins
+ if ( !config.isPde() )
+ {
+ for ( int j = 0; j < config.getDepsOrdered().length; j++ )
+ {
+ IdeDependency dep = config.getDepsOrdered()[j];
+ if ( dep.isReferencedProject() )
+ {
+ writer.startElement( "project" ); //$NON-NLS-1$
+ writer.writeText( dep.getEclipseProjectName() );
+ writer.endElement();
+ }
+ }
+ }
+
+ writer.endElement(); // projects
+
+ writer.startElement( ELT_BUILD_SPEC );
+
+ for ( Iterator it = buildCommands.iterator(); it.hasNext(); )
+ {
+ ( (BuildCommand) it.next() ).print( writer );
+ }
+
+ writer.endElement(); // buildSpec
+
+ writer.startElement( ELT_NATURES );
+
+ for ( Iterator it = projectnatures.iterator(); it.hasNext(); )
+ {
+ writer.startElement( ELT_NATURE );
+ writer.writeText( (String) it.next() );
+ writer.endElement(); // name
+ }
+
+ writer.endElement(); // natures
+
+ /*
+ boolean addLinks = !config.getProjectBaseDir().equals( config.getEclipseProjectDirectory() );
+
+ if ( addLinks || ( config.isPde() && config.getDepsOrdered().length > 0 ) )
+ {
+ writer.startElement( "linkedResources" ); //$NON-NLS-1$
+
+ if ( addLinks )
+ {
+
+ addFileLink( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getFile() );
+
+ addSourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getCompileSourceRoots() );
+ addResourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getBuild().getResources() );
+
+ addSourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getTestCompileSourceRoots() );
+ addResourceLinks( writer, config.getProjectBaseDir(), config.getEclipseProjectDirectory(),
+ config.getProject().getBuild().getTestResources() );
+
+ }
+
+ if ( config.isPde() )
+ {
+ for ( int j = 0; j < config.getDepsOrdered().length; j++ )
+ {
+ IdeDependency dep = config.getDepsOrdered()[j];
+
+ if ( dep.isAddedToClasspath() && !dep.isProvided() && !dep.isReferencedProject() &&
+ !dep.isTestDependency() && !dep.isOsgiBundle() )
+ {
+ String name = dep.getFile().getName();
+ addLink( writer, name, StringUtils.replace( IdeUtils.getCanonicalPath( dep.getFile() ), "\\",
+ "/" ), LINK_TYPE_FILE );
+ }
+ }
+ }
+
+ writer.endElement(); // linkedResources
+ }
+ */
+
+ writer.endElement(); // projectDescription
+
+ IOUtil.close( w );
+ }
+
+ private void addFileLink( XMLWriter writer, File projectBaseDir, File basedir, File file )
+ throws MojoExecutionException
+ {
+ if ( file.isFile() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, file, true );
+ String location = IdeUtils.getCanonicalPath( file ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_FILE );
+ }
+ else
+ {
+ log.warn( Messages.getString( "EclipseProjectWriter.notafile", file ) ); //$NON-NLS-1$
+ }
+ }
+
+ private void addSourceLinks( XMLWriter writer, File projectBaseDir, File basedir, List sourceRoots )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
+ {
+ String sourceRootString = (String) it.next();
+ File sourceRoot = new File( sourceRootString );
+
+ if ( sourceRoot.isDirectory() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, sourceRoot, true );
+ String location = IdeUtils.getCanonicalPath( sourceRoot ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_DIRECTORY );
+ }
+ }
+ }
+
+ private void addResourceLinks( XMLWriter writer, File projectBaseDir, File basedir, List sourceRoots )
+ throws MojoExecutionException
+ {
+ for ( Iterator it = sourceRoots.iterator(); it.hasNext(); )
+ {
+ String resourceDirString = ( (Resource) it.next() ).getDirectory();
+ File resourceDir = new File( resourceDirString );
+
+ if ( resourceDir.isDirectory() )
+ {
+ String name = IdeUtils.toRelativeAndFixSeparator( projectBaseDir, resourceDir, true );
+ String location = IdeUtils.getCanonicalPath( resourceDir ).replaceAll( "\\\\", "/" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ addLink( writer, name, location, LINK_TYPE_DIRECTORY );
+ }
+ }
+ }
+
+ /**
+ * @param writer
+ * @param name
+ * @param location
+ */
+ private void addLink( XMLWriter writer, String name, String location, int type )
+ {
+ writer.startElement( "link" ); //$NON-NLS-1$
+
+ writer.startElement( ELT_NAME );
+ writer.writeText( name );
+ writer.endElement(); // name
+
+ writer.startElement( "type" ); //$NON-NLS-1$
+ writer.writeText( Integer.toString( type ) );
+ writer.endElement(); // type
+
+ writer.startElement( "location" ); //$NON-NLS-1$
+
+ writer.writeText( location );
+
+ writer.endElement(); // location
+
+ writer.endElement(); // link
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.java
new file mode 100644
index 0000000000..553cae6256
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/maven/plugin/eclipse/Messages.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.maven.plugin.eclipse;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author <a href="mailto:fgiust@users.sourceforge.net">Fabrizio Giustina</a>
+ * @version $Id: Messages.java 485864 2006-12-11 20:41:36Z fgiust $
+ */
+public class Messages
+{
+
+ private static final String BUNDLE_NAME = "org.apache.tuscany.sca.maven.plugin.eclipse.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME );
+
+ private Messages()
+ {
+ }
+
+ public static String getString( String key )
+ {
+ try
+ {
+ return RESOURCE_BUNDLE.getString( key );
+ }
+ catch ( MissingResourceException e )
+ {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String getString( String key, Object[] params )
+ {
+ try
+ {
+ return MessageFormat.format( RESOURCE_BUNDLE.getString( key ), params );
+ }
+ catch ( MissingResourceException e )
+ {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String getString( String key, Object param )
+ {
+ return getString( key, new Object[] { param } );
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactAggregation.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactAggregation.java
new file mode 100644
index 0000000000..062c935ad9
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactAggregation.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.tools.bundle.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+
+
+public class ArtifactAggregation {
+ private String symbolicName;
+ private String version;
+ private List<ArtifactMember> artifactMemebers = new ArrayList<ArtifactMember>();
+ private transient List<Artifact> artifacts = new ArrayList<Artifact>();
+
+ public List<Artifact> getArtifacts() {
+ return artifacts;
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ public void setSymbolicName(String symbolicName) {
+ this.symbolicName = symbolicName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public List<ArtifactMember> getArtifactMembers() {
+ return artifactMemebers;
+ }
+
+ public void setArtifactMembers(List<ArtifactMember> artifacts) {
+ this.artifactMemebers = artifacts;
+ }
+
+ public String toString() {
+ return symbolicName + ";version=\"" + version + "\"\n" + artifactMemebers;
+ }
+
+ public boolean matches(Artifact artifact) {
+ for(ArtifactMember m: artifactMemebers) {
+ if(m.matches(artifact)) {
+ return true;
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactMember.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactMember.java
new file mode 100644
index 0000000000..19315aa19f
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ArtifactMember.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.tools.bundle.plugin;
+
+import org.apache.maven.artifact.Artifact;
+
+public class ArtifactMember {
+ private String groupId;
+ private String artifactId;
+ private String version;
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String toString() {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ public boolean matches(Artifact artifact) {
+ return groupId.equals(artifact.getGroupId()) && (artifactId == null || artifactId.equals("")
+ || artifactId.equals("*") || artifactId.equals(artifact.getArtifactId()))
+ && (version == null || version.equals("") || version.equals("*") || version.equals(artifact.getVersion()));
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/BundleUtil.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/BundleUtil.java
new file mode 100644
index 0000000000..6c97a34676
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/BundleUtil.java
@@ -0,0 +1,387 @@
+/*
+ * 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.tools.bundle.plugin;
+
+import static org.osgi.framework.Constants.BUNDLE_CLASSPATH;
+import static org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION;
+import static org.osgi.framework.Constants.BUNDLE_NAME;
+import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
+import static org.osgi.framework.Constants.BUNDLE_VERSION;
+import static org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE;
+import static org.osgi.framework.Constants.EXPORT_PACKAGE;
+import static org.osgi.framework.Constants.IMPORT_PACKAGE;
+
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.osgi.framework.Version;
+
+/**
+ * Common functions used by the plugin.
+ *
+ * @version $Rev$ $Date$
+ */
+final class BundleUtil {
+ private final static Logger logger = Logger.getLogger(BundleUtil.class.getName());
+ /**
+ * Returns the name of a bundle, or null if the given file is not a bundle.
+ *
+ * @param file
+ * @return
+ * @throws IOException
+ */
+ static String getBundleSymbolicName(File file) throws IOException {
+ if (!file.exists()) {
+ return null;
+ }
+ String bundleName = null;
+ if (file.isDirectory()) {
+ File mf = new File(file, "META-INF/MANIFEST.MF");
+ if (mf.isFile()) {
+ Manifest manifest = new Manifest(new FileInputStream(mf));
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ }
+ } else {
+ JarFile jar = new JarFile(file, false);
+ Manifest manifest = jar.getManifest();
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ jar.close();
+ }
+ if (bundleName == null) {
+ return bundleName;
+ }
+ int sc = bundleName.indexOf(';');
+ if (sc != -1) {
+ bundleName = bundleName.substring(0, sc);
+ }
+ return bundleName;
+ }
+
+ /**
+ * Generate a Bundle manifest for a set of JAR files.
+ *
+ * @param jarFiles
+ * @param name
+ * @param symbolicName
+ * @param version
+ * @param dir
+ * @return
+ * @throws IllegalStateException
+ */
+ static Manifest libraryManifest(Set<File> jarFiles, String name, String symbolicName, String version, String dir)
+ throws IllegalStateException {
+ try {
+
+ // List exported packages and bundle classpath entries
+ StringBuffer classpath = new StringBuffer();
+ Set<String> exportedPackages = new HashSet<String>();
+ for (File jarFile : jarFiles) {
+ addPackages(jarFile, exportedPackages, version);
+ if (dir != null) {
+ classpath.append(dir).append("/");
+ }
+ classpath.append(jarFile.getName());
+ classpath.append(",");
+ }
+
+ // Generate export-package and import-package declarations
+ StringBuffer exports = new StringBuffer();
+ StringBuffer imports = new StringBuffer();
+ Set<String> pkgs = new HashSet<String>();
+ for (String export : exportedPackages) {
+ String packageName = packageName(export);
+ if (!pkgs.contains(packageName)) {
+ // Add corresponding import declaration
+// imports.append(export);
+// imports.append(',');
+ pkgs.add(packageName);
+ exports.append(export);
+ exports.append(',');
+ } else {
+ logger.warning("Duplicate package skipped: " + export);
+ }
+ }
+
+ // Create a manifest
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.putValue("Manifest-Version", "1.0");
+ attributes.putValue(BUNDLE_MANIFESTVERSION, "2");
+ attributes.putValue(BUNDLE_SYMBOLICNAME, symbolicName);
+ attributes.putValue(BUNDLE_NAME, name);
+ attributes.putValue(BUNDLE_VERSION, version);
+ attributes.putValue(DYNAMICIMPORT_PACKAGE, "*");
+ if (exports.length() > 1) {
+ attributes.putValue(EXPORT_PACKAGE, exports.substring(0, exports.length() - 1));
+ }
+ if (imports.length() > 1) {
+ attributes.putValue(IMPORT_PACKAGE, imports.substring(0, imports.length() - 1));
+ }
+ if (classpath.length() > 1) {
+ attributes.putValue(BUNDLE_CLASSPATH, classpath.substring(0, classpath.length() - 1));
+ }
+
+ return manifest;
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Write a bundle manifest.
+ *
+ * @param manifest
+ * @param out
+ * @throws IOException
+ */
+ static void write(Manifest manifest, OutputStream out) throws IOException {
+ DataOutputStream dos = new DataOutputStream(out);
+ Attributes attributes = manifest.getMainAttributes();
+ write(attributes, "Manifest-Version", dos);
+ write(attributes, BUNDLE_MANIFESTVERSION, dos);
+ write(attributes, BUNDLE_SYMBOLICNAME, dos);
+ write(attributes, BUNDLE_NAME, dos);
+ write(attributes, BUNDLE_VERSION, dos);
+ write(attributes, DYNAMICIMPORT_PACKAGE, dos);
+ write(attributes, BUNDLE_CLASSPATH, dos);
+ write(attributes, IMPORT_PACKAGE, dos);
+ write(attributes, EXPORT_PACKAGE, dos);
+ dos.flush();
+ }
+
+ /**
+ * Add packages to be exported out of a JAR file.
+ *
+ * @param jarFile
+ * @param packages
+ * @throws IOException
+ */
+ private static void addPackages(File jarFile, Set<String> packages, String version) throws IOException {
+ if (getBundleSymbolicName(jarFile) == null) {
+ String ver = ";version=" + version;
+ addAllPackages(jarFile, packages, ver);
+ } else {
+ addExportedPackages(jarFile, packages);
+ }
+ }
+
+ /**
+ * Write manifest attributes.
+ *
+ * @param attributes
+ * @param key
+ * @param dos
+ * @throws IOException
+ */
+ private static void write(Attributes attributes, String key, DataOutputStream dos) throws IOException {
+ String value = attributes.getValue(key);
+ if (value == null) {
+ return;
+ }
+ StringBuffer line = new StringBuffer();
+ line.append(key);
+ line.append(": ");
+ line.append(new String(value.getBytes("UTF8")));
+ line.append("\r\n");
+ int l = line.length();
+ if (l > 72) {
+ for (int i = 70; i < l - 2;) {
+ line.insert(i, "\r\n ");
+ i += 72;
+ l += 3;
+ }
+ }
+ dos.writeBytes(line.toString());
+ }
+
+ /**
+ * Strip an OSGi export, only retain the package name and version.
+ *
+ * @param export
+ * @return
+ */
+ private static String stripExport(String export) {
+ int sc = export.indexOf(';');
+ if (sc == -1) {
+ return export;
+ }
+ String base = export.substring(0, sc);
+ int v = export.indexOf("version=");
+ if (v != -1) {
+ sc = export.indexOf(';', v + 1);
+ if (sc != -1) {
+ return base + ";" + export.substring(v, sc);
+ } else {
+ return base + ";" + export.substring(v);
+ }
+ } else {
+ return base;
+ }
+ }
+
+ /**
+ * Add all the packages out of a JAR.
+ *
+ * @param jarFile
+ * @param packages
+ * @param version
+ * @throws IOException
+ */
+ private static void addAllPackages(File jarFile, Set<String> packages, String version) throws IOException {
+ ZipInputStream is = new ZipInputStream(new FileInputStream(jarFile));
+ ZipEntry entry;
+ while ((entry = is.getNextEntry()) != null) {
+ String entryName = entry.getName();
+ if (!entry.isDirectory() && entryName != null
+ && entryName.length() > 0
+ && !entryName.startsWith(".")
+ && entryName.endsWith(".class") // Exclude resources from Export-Package
+ && entryName.lastIndexOf("/") > 0
+ && Character.isJavaIdentifierStart(entryName.charAt(0))) {
+ String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.');
+ if (!pkg.endsWith(".enum")) {
+ packages.add(pkg + version);
+ }
+ }
+ }
+ is.close();
+ }
+
+ /**
+ * Returns the name of the exported package in the given export.
+ * @param export
+ * @return
+ */
+ private static String packageName(String export) {
+ int sc = export.indexOf(';');
+ if (sc != -1) {
+ export = export.substring(0, sc);
+ }
+ return export;
+ }
+
+ /**
+ * Add the packages exported by a bundle.
+ *
+ * @param file
+ * @param packages
+ * @return
+ * @throws IOException
+ */
+ private static void addExportedPackages(File file, Set<String> packages) throws IOException {
+ if (!file.exists()) {
+ return;
+ }
+
+ // Read the export-package declaration and get a list of the packages available in a JAR
+ Set<String> existingPackages = null;
+ String exports = null;
+ if (file.isDirectory()) {
+ File mf = new File(file, "META-INF/MANIFEST.MF");
+ if (mf.isFile()) {
+ Manifest manifest = new Manifest(new FileInputStream(mf));
+ exports = manifest.getMainAttributes().getValue(EXPORT_PACKAGE);
+ }
+ } else {
+ JarFile jar = new JarFile(file, false);
+ Manifest manifest = jar.getManifest();
+ exports = manifest.getMainAttributes().getValue(EXPORT_PACKAGE);
+ jar.close();
+ existingPackages = new HashSet<String>();
+ addAllPackages(file, existingPackages, "");
+ }
+ if (exports == null) {
+ return;
+ }
+
+ // Parse the export-package declaration, and extract the individual packages
+ StringBuffer buffer = new StringBuffer();
+ boolean q = false;
+ for (int i = 0, n = exports.length(); i < n; i++) {
+ char c = exports.charAt(i);
+ if (c == '\"') {
+ q = !q;
+ }
+ if (!q) {
+ if (c == ',') {
+
+ // Add the exported package to the set, after making sure it really exists in
+ // the JAR
+ String export = buffer.toString();
+ if (existingPackages == null || existingPackages.contains(packageName(export))) {
+ packages.add(stripExport(export));
+ }
+ buffer = new StringBuffer();
+ continue;
+ }
+ }
+ buffer.append(c);
+ }
+ if (buffer.length() != 0) {
+
+ // Add the exported package to the set, after making sure it really exists in
+ // the JAR
+ String export = buffer.toString();
+ if (existingPackages == null || existingPackages.contains(packageName(export))) {
+ packages.add(stripExport(export));
+ }
+ }
+ }
+
+ /**
+ * Convert the maven version into OSGi version
+ * @param mavenVersion
+ * @return
+ */
+ static String osgiVersion(String mavenVersion) {
+ ArtifactVersion ver = new DefaultArtifactVersion(mavenVersion);
+ String qualifer = ver.getQualifier();
+ if (qualifer != null) {
+ StringBuffer buf = new StringBuffer(qualifer);
+ for (int i = 0; i < buf.length(); i++) {
+ char c = buf.charAt(i);
+ if (Character.isLetterOrDigit(c) || c == '-' || c == '_') {
+ // Keep as-is
+ } else {
+ buf.setCharAt(i, '_');
+ }
+ }
+ qualifer = buf.toString();
+ }
+ Version osgiVersion =
+ new Version(ver.getMajorVersion(), ver.getMinorVersion(), ver.getIncrementalVersion(), qualifer);
+ String version = osgiVersion.toString();
+ return version;
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ModuleBundlesBuildMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ModuleBundlesBuildMojo.java
new file mode 100644
index 0000000000..bd6368aaa0
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ModuleBundlesBuildMojo.java
@@ -0,0 +1,828 @@
+/*
+ * 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.tools.bundle.plugin;
+
+import static org.apache.tuscany.sca.tools.bundle.plugin.BundleUtil.write;
+
+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.PrintStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+
+/**
+ * A maven plugin that generates a modules directory containing OSGi bundles for all the project's module dependencies.
+ *
+ * @version $Rev$ $Date$
+ * @goal generate-modules
+ * @phase generate-resources
+ * @requiresDependencyResolution test
+ * @description Generate a modules directory containing OSGi bundles for all the project's module dependencies.
+ */
+public class ModuleBundlesBuildMojo extends AbstractMojo {
+
+ /**
+ * The project to create a distribution for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ /**
+ * Project builder -- builds a model from a pom.xml
+ *
+ * @component role="org.apache.maven.project.MavenProjectBuilder"
+ * @required
+ * @readonly
+ */
+ private MavenProjectBuilder mavenProjectBuilder;
+ /**
+ * Used to look up Artifacts in the remote repository.
+ *
+ * @component
+ */
+ private org.apache.maven.artifact.factory.ArtifactFactory factory;
+
+ /**
+ * Used to look up Artifacts in the remote repository.
+ *
+ * @component
+ */
+ private org.apache.maven.artifact.resolver.ArtifactResolver resolver;
+
+ /**
+ * @component role="org.apache.maven.artifact.metadata.ArtifactMetadataSource"
+ * hint="maven"
+ * @required
+ * @readonly
+ */
+ private ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * Location of the local repository.
+ *
+ * @parameter expression="${localRepository}"
+ * @readonly
+ * @required
+ */
+ private org.apache.maven.artifact.repository.ArtifactRepository local;
+
+ /**
+ * List of Remote Repositories used by the resolver
+ *
+ * @parameter expression="${project.remoteArtifactRepositories}"
+ * @readonly
+ * @required
+ */
+ private java.util.List remoteRepos;
+
+ /**
+ * Target directory.
+ *
+ * @parameter expression="${project.build.directory}/modules"
+ */
+ private File targetDirectory;
+
+ /**
+ * @parameter default-value="features"
+ */
+ private String featuresName = "features";
+
+ /**
+ * Directories containing artifacts to exclude.
+ *
+ * @parameter
+ */
+ private File[] excludeDirectories;
+
+ /**
+ * Directories containing groupids to exclude.
+ *
+ * @parameter
+ */
+ private String[] excludeGroupIds;
+
+ /**
+ * Directories containing groupids to include.
+ *
+ * @parameter
+ */
+ private String[] includeGroupIds;
+
+ /**
+ * Set to true to generate configurations under a folder named as the distro
+ *
+ * @parameter default-value="true"
+ */
+ private boolean useDistributionName = true;
+
+ /**
+ * Set to true to generate a PDE target platform configuration.
+ *
+ * @parameter default-value="true"
+ */
+ private boolean generateTargetPlatform = true;
+
+ /**
+ * OSGi execution environment
+ */
+ private String executionEnvironment;
+
+ /**
+ * A list of Eclipse features to be added to the target definition
+ * @parameter
+ */
+ private String[] eclipseFeatures;
+
+ /**
+ * If we use the running eclipse as the default location for the target
+ * @parameter default-value="true"
+ */
+ private boolean useDefaultLocation = true;
+
+ /**
+ * Set to true to generate a plugin.xml.
+ *
+ * @parameter default-value="false"
+ */
+ private boolean generatePlugin;
+
+ /**
+ * Generate a configuration/config.ini for equinox
+ * @parameter default-value="true"
+ */
+ private boolean generateConfig = true;
+
+ /**
+ * @parameter default-value="true"
+ */
+ private boolean generateBundleStart = true;
+
+ /**
+ * Generete manifest.jar
+ * @parameter default-value="true"
+ */
+ private boolean generateManifestJar = true;
+
+ /**
+ * @parameter default-value="tuscany-sca-manifest.jar"
+ */
+ private String manifestJarName = "tuscany-sca-manifest.jar";
+
+ /**
+ * @parameter default-value="tuscany-sca-equinox-manifest.jar"
+ */
+ private String equinoxManifestJarName = "tuscany-sca-equinox-manifest.jar";
+
+
+ /**
+ * @parameter default-value="true"
+ */
+ private boolean generateAntScript = true;
+
+ /**
+ * @parameter
+ */
+ private ArtifactAggregation[] artifactAggregations;
+
+ private static final String XML_PI = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ private static final String ASL_HEADER =
+ "<!--"
+ + "\n * Licensed to the Apache Software Foundation (ASF) under one"
+ + "\n * or more contributor license agreements. See the NOTICE file"
+ + "\n * distributed with this work for additional information"
+ + "\n * regarding copyright ownership. The ASF licenses this file"
+ + "\n * to you under the Apache License, Version 2.0 (the"
+ + "\n * \"License\"); you may not use this file except in compliance"
+ + "\n * with the License. You may obtain a copy of the License at"
+ + "\n * "
+ + "\n * http://www.apache.org/licenses/LICENSE-2.0"
+ + "\n * "
+ + "\n * Unless required by applicable law or agreed to in writing,"
+ + "\n * software distributed under the License is distributed on an"
+ + "\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY"
+ + "\n * KIND, either express or implied. See the License for the"
+ + "\n * specific language governing permissions and limitations"
+ + "\n * under the License."
+ + "\n-->";
+
+ /**
+ * Group the artifacts by distribution poms
+ */
+ private class ProjectSet {
+ // Distribution projects
+ private Map<String, MavenProject> projects;
+ // Key: the pom artifact id
+ // Value: the names for the artifacts
+ private Map<String, Set<String>> nameMap = new HashMap<String, Set<String>>();
+
+ private Map<String, String> artifactToNameMap = new HashMap<String, String>();
+
+ public ProjectSet(List<MavenProject> projects) {
+ super();
+ this.projects = new HashMap<String, MavenProject>();
+ for (MavenProject p : projects) {
+ this.projects.put(p.getArtifactId(), p);
+ }
+ }
+
+ private MavenProject getProject(String artifactId) {
+ return projects.get(artifactId);
+ }
+
+ private void add(Artifact artifact, String name) {
+ String key = ArtifactUtils.versionlessKey(artifact);
+ for (MavenProject p : projects.values()) {
+ Artifact a = (Artifact)p.getArtifactMap().get(key);
+ if (a != null) {
+ Set<String> names = nameMap.get(p.getArtifactId());
+ if (names == null) {
+ names = new HashSet<String>();
+ nameMap.put(p.getArtifactId(), names);
+ }
+ names.add(name);
+ }
+ }
+ artifactToNameMap.put(key, name);
+ }
+ }
+
+ public void execute() throws MojoExecutionException {
+ Log log = getLog();
+
+ try {
+
+ // Create the target directory
+ File root;
+ if (targetDirectory == null) {
+ root = new File(project.getBuild().getDirectory(), "plugins/");
+ } else {
+ root = targetDirectory;
+ }
+ root.mkdirs();
+
+ // Build sets of exclude directories and included/excluded/groupids
+ Set<String> excludedFileNames = new HashSet<String>();
+ if (excludeDirectories != null) {
+ for (File f : excludeDirectories) {
+ if (f.isDirectory()) {
+ for (String n : f.list()) {
+ excludedFileNames.add(n);
+ }
+ }
+ }
+ }
+ Set<String> includedGroupIds = new HashSet<String>();
+ if (includeGroupIds != null) {
+ for (String g : includeGroupIds) {
+ includedGroupIds.add(g);
+ }
+ }
+ Set<String> excludedGroupIds = new HashSet<String>();
+ if (excludeGroupIds != null) {
+ for (String g : excludeGroupIds) {
+ excludedGroupIds.add(g);
+ }
+ }
+
+ // Find all the distribution poms
+ List<MavenProject> poms = new ArrayList<MavenProject>();
+ poms.add(project);
+ if (useDistributionName) {
+ for (Object o : project.getArtifacts()) {
+ Artifact artifact = (Artifact)o;
+ if ("pom".equals(artifact.getType()) && artifact.getGroupId().equals(project.getGroupId())
+ && artifact.getArtifactId().startsWith("tuscany-feature-")) {
+ log.info("Dependent distribution: " + artifact);
+ MavenProject pomProject = buildProject(artifact);
+ poms.add(pomProject);
+ // log.info(pomProject.getArtifactMap().toString());
+ }
+ }
+ }
+
+ // Process all the dependency artifacts
+ ProjectSet bundleSymbolicNames = new ProjectSet(poms);
+ ProjectSet bundleLocations = new ProjectSet(poms);
+ ProjectSet jarNames = new ProjectSet(poms);
+ for (Object o : project.getArtifacts()) {
+ Artifact artifact = (Artifact)o;
+
+ // Only consider Compile and Runtime dependencies
+ if (!(Artifact.SCOPE_COMPILE.equals(artifact.getScope()) || Artifact.SCOPE_RUNTIME.equals(artifact
+ .getScope())
+ || Artifact.SCOPE_PROVIDED.equals(artifact.getScope()) || (generateTargetPlatform && Artifact.SCOPE_TEST
+ .equals(artifact.getScope())))) {
+ log.info("Skipping artifact: " + artifact);
+ continue;
+ }
+
+ // Only consider JAR and WAR files
+ if (!"jar".equals(artifact.getType()) && !"war".equals(artifact.getType())) {
+ continue;
+ }
+
+ // Exclude artifact if its groupId is excluded or if it's not included
+ if (excludedGroupIds.contains(artifact.getGroupId())) {
+ log.debug("Artifact groupId is excluded: " + artifact);
+ continue;
+ }
+ if (!includedGroupIds.isEmpty()) {
+ if (!includedGroupIds.contains(artifact.getGroupId())) {
+ log.debug("Artifact groupId is not included: " + artifact);
+ continue;
+ }
+ }
+
+ File artifactFile = artifact.getFile();
+ if (!artifactFile.exists()) {
+ log.warn("Artifact doesn't exist: " + artifact);
+ continue;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Processing artifact: " + artifact);
+ }
+
+ // Get the bundle name if the artifact is an OSGi bundle
+ String bundleName = null;
+ try {
+ bundleName = BundleUtil.getBundleSymbolicName(artifact.getFile());
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ if (bundleName != null) {
+
+ // Exclude artifact if its file name is excluded
+ if (excludedFileNames.contains(artifactFile.getName())) {
+ log.debug("Artifact file is excluded: " + artifact);
+ continue;
+ }
+
+ // Copy an OSGi bundle as is
+ log.info("Adding OSGi bundle artifact: " + artifact);
+ copyFile(artifactFile, root);
+ bundleSymbolicNames.add(artifact, bundleName);
+ bundleLocations.add(artifact, artifactFile.getName());
+ jarNames.add(artifact, artifactFile.getName());
+
+ } else if ("war".equals(artifact.getType())) {
+
+ // Exclude artifact if its file name is excluded
+ if (excludedFileNames.contains(artifactFile.getName())) {
+ log.debug("Artifact file is excluded: " + artifact);
+ continue;
+ }
+
+ // Copy a WAR as is
+ log.info("Adding WAR artifact: " + artifact);
+ copyFile(artifactFile, root);
+
+ } else {
+
+ // String version = BundleUtil.osgiVersion(artifact.getVersion());
+ // String symbolicName = (artifact.getGroupId() + "." + artifact.getArtifactId());
+ // String dirName = symbolicName + "_" + version;
+
+ String dirName = artifactFile.getName().substring(0, artifactFile.getName().length() - 4);
+ File dir = new File(root, dirName);
+
+ // Exclude artifact if its file name is excluded
+ if (excludedFileNames.contains(dir.getName())) {
+ log.debug("Artifact file is excluded: " + artifact);
+ continue;
+ }
+
+ if (artifactAggregations != null) {
+ boolean aggregated = false;
+ for (ArtifactAggregation group : artifactAggregations) {
+ if (group.matches(artifact)) {
+ group.getArtifacts().add(artifact);
+ aggregated = true;
+ break;
+ }
+ }
+ if (aggregated) {
+ continue;
+ }
+ }
+
+ // Create a bundle directory for a non-OSGi JAR
+ log.info("Adding JAR artifact: " + artifact);
+ String version = BundleUtil.osgiVersion(artifact.getVersion());
+
+ Set<File> jarFiles = new HashSet<File>();
+ jarFiles.add(artifactFile);
+ String symbolicName = (artifact.getGroupId() + "." + artifact.getArtifactId());
+ Manifest mf = BundleUtil.libraryManifest(jarFiles, symbolicName, symbolicName, version, null);
+ File file = new File(dir, "META-INF");
+ file.mkdirs();
+ file = new File(file, "MANIFEST.MF");
+
+ FileOutputStream fos = new FileOutputStream(file);
+ write(mf, fos);
+ fos.close();
+ copyFile(artifactFile, dir);
+ bundleSymbolicNames.add(artifact, symbolicName);
+ bundleLocations.add(artifact, dir.getName());
+ jarNames.add(artifact, dirName + "/" + artifactFile.getName());
+ }
+ }
+
+ if (artifactAggregations != null) {
+ for (ArtifactAggregation group : artifactAggregations) {
+ if (group.getArtifacts().isEmpty()) {
+ continue;
+ }
+ String symbolicName = group.getSymbolicName();
+ String version = group.getVersion();
+ File dir = new File(root, symbolicName + "-" + version);
+ dir.mkdir();
+ Set<File> jarFiles = new HashSet<File>();
+ Artifact artifact = null;
+ for (Artifact a : group.getArtifacts()) {
+ log.info("Aggragating JAR artifact: " + a);
+ artifact = a;
+ jarFiles.add(a.getFile());
+ copyFile(a.getFile(), dir);
+ jarNames.add(a, symbolicName + "-" + version + "/" + a.getFile().getName());
+ }
+ Manifest mf = BundleUtil.libraryManifest(jarFiles, symbolicName, symbolicName, version, null);
+ File file = new File(dir, "META-INF");
+ file.mkdirs();
+ file = new File(file, "MANIFEST.MF");
+
+ FileOutputStream fos = new FileOutputStream(file);
+ write(mf, fos);
+ fos.close();
+ bundleSymbolicNames.add(artifact, symbolicName);
+ bundleLocations.add(artifact, dir.getName());
+ }
+ }
+
+ // Generate a PDE target
+ if (generateTargetPlatform) {
+ generatePDETarget(bundleSymbolicNames, root, log);
+ }
+
+ // Generate a plugin.xml referencing the PDE target
+ if (generatePlugin) {
+ File pluginxml = new File(project.getBasedir(), "plugin.xml");
+ FileOutputStream pluginXMLFile = new FileOutputStream(pluginxml);
+ writePluginXML(new PrintStream(pluginXMLFile));
+ pluginXMLFile.close();
+ }
+
+ if (generateConfig) {
+ generateEquinoxConfig(bundleLocations, root, log);
+ }
+
+ if (generateManifestJar) {
+ generateManifestJar(jarNames, root, log);
+ generateEquinoxLauncherManifestJar(jarNames, root, log);
+ }
+
+ if (generateAntScript) {
+ generateANTPath(jarNames, root, log);
+ }
+
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ }
+
+ private void generateANTPath(ProjectSet jarNames, File root, Log log) throws FileNotFoundException, IOException {
+ for (Map.Entry<String, Set<String>> e : jarNames.nameMap.entrySet()) {
+ Set<String> jars = e.getValue();
+ File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? trim(e.getKey()) : ""));
+ feature.mkdirs();
+ File antPath = new File(feature, "build-path.xml");
+ log.info("Generating ANT build path: " + antPath.getCanonicalPath());
+ FileOutputStream fos = new FileOutputStream(antPath);
+ PrintStream ps = new PrintStream(fos);
+ // ps.println(XML_PI);
+ ps.println(ASL_HEADER);
+ String name = trim(e.getKey());
+ ps.println("<project name=\"tuscany."+name+"\">");
+ ps.println(" <property name=\"tuscany.distro\" value=\"" + name + "\"/>");
+ ps.println(" <property name=\"tuscany.manifest\" value=\"" + new File(feature, manifestJarName).getCanonicalPath()
+ + "\"/>");
+ ps.println(" <path id=\"" + "tuscany.path" + "\">");
+ ps.println(" <fileset dir=\"" + root.getCanonicalPath() + "\">");
+ for (String jar : jars) {
+ ps.println(" <include name=\"" + jar + "\"/>");
+ }
+ ps.println(" </fileset>");
+ ps.println(" </path>");
+ ps.println("</project>");
+ }
+ }
+
+ private void generateManifestJar(ProjectSet jarNames, File root, Log log) throws FileNotFoundException, IOException {
+ for (Map.Entry<String, Set<String>> e : jarNames.nameMap.entrySet()) {
+ MavenProject pom = jarNames.getProject(e.getKey());
+ Set<String> jars = e.getValue();
+ File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? trim(e.getKey()) : ""));
+ feature.mkdirs();
+ File mfJar = new File(feature, manifestJarName);
+ log.info("Generating manifest jar: " + mfJar.getCanonicalPath());
+ FileOutputStream fos = new FileOutputStream(mfJar);
+ Manifest mf = new Manifest();
+ StringBuffer cp = new StringBuffer();
+ String path = (useDistributionName ? "../../" : "../") + root.getName();
+ for (String jar : jars) {
+ cp.append(path).append('/').append(jar).append(' ');
+ }
+ if (cp.length() > 0) {
+ cp.deleteCharAt(cp.length() - 1);
+ }
+ Attributes attrs = mf.getMainAttributes();
+ attrs.putValue("Manifest-Version", "1.0");
+ attrs.putValue("Implementation-Title", pom.getName());
+ attrs.putValue("Implementation-Vendor", "The Apache Software Foundation");
+ attrs.putValue("Implementation-Vendor-Id", "org.apache");
+ attrs.putValue("Implementation-Version", pom.getVersion());
+ attrs.putValue("Class-Path", cp.toString());
+ attrs.putValue("Main-Class", "org.apache.tuscany.sca.node.launcher.NodeMain");
+ JarOutputStream jos = new JarOutputStream(fos, mf);
+ addFileToJar(jos, "META-INF/LICENSE", getClass().getResource("LICENSE.txt"));
+ addFileToJar(jos, "META-INF/NOTICE", getClass().getResource("NOTICE.txt"));
+ jos.close();
+ }
+ }
+
+ private void generateEquinoxLauncherManifestJar(ProjectSet jarNames, File root, Log log) throws Exception {
+ String equinoxLauncher = "org.apache.tuscany.sca:tuscany-node-launcher-equinox";
+ Artifact artifact = (Artifact)project.getArtifactMap().get(equinoxLauncher);
+ if (artifact == null) {
+ return;
+ }
+ Set artifacts = resolveTransitively(artifact).getArtifacts();
+ File feature = new File(root, "../" + featuresName + "/");
+ feature.mkdirs();
+ File mfJar = new File(feature, equinoxManifestJarName);
+ log.info("Generating equinox manifest jar: " + mfJar.getCanonicalPath());
+ FileOutputStream fos = new FileOutputStream(mfJar);
+ Manifest mf = new Manifest();
+ StringBuffer cp = new StringBuffer();
+ String path = "../" + root.getName();
+
+ for (Object o : artifacts) {
+ Artifact a = (Artifact)o;
+ if (!Artifact.SCOPE_TEST.equals(a.getScope())) {
+ String id = ArtifactUtils.versionlessKey(a);
+ String jar = jarNames.artifactToNameMap.get(id);
+ if (jar != null) {
+ cp.append(path).append('/').append(jar).append(' ');
+ }
+ }
+ }
+ if (cp.length() > 0) {
+ cp.deleteCharAt(cp.length() - 1);
+ }
+ Attributes attrs = mf.getMainAttributes();
+ attrs.putValue("Manifest-Version", "1.0");
+ attrs.putValue("Implementation-Title", artifact.getId());
+ attrs.putValue("Implementation-Vendor", "The Apache Software Foundation");
+ attrs.putValue("Implementation-Vendor-Id", "org.apache");
+ attrs.putValue("Implementation-Version", artifact.getVersion());
+ attrs.putValue("Class-Path", cp.toString());
+ attrs.putValue("Main-Class", "org.apache.tuscany.sca.node.equinox.launcher.NodeMain");
+ JarOutputStream jos = new JarOutputStream(fos, mf);
+ addFileToJar(jos, "META-INF/LICENSE", getClass().getResource("LICENSE.txt"));
+ addFileToJar(jos, "META-INF/NOTICE", getClass().getResource("NOTICE.txt"));
+ jos.close();
+ }
+
+ private void generateEquinoxConfig(ProjectSet bundleLocations, File root, Log log) throws IOException {
+ for (Map.Entry<String, Set<String>> e : bundleLocations.nameMap.entrySet()) {
+ Set<String> locations = e.getValue();
+ File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? trim(e.getKey()) : ""));
+ File config = new File(feature, "configuration");
+ config.mkdirs();
+ File ini = new File(config, "config.ini");
+ log.info("Generating configuation: " + ini.getCanonicalPath());
+ FileOutputStream fos = new FileOutputStream(ini);
+ PrintStream ps = new PrintStream(fos);
+ ps.print("osgi.bundles=");
+ for (String f : locations) {
+ ps.print(f);
+ if (generateBundleStart) {
+ ps.print("@:start,");
+ } else {
+ ps.println(",");
+ }
+ }
+ ps.println();
+ ps.println("eclipse.ignoreApp=true");
+ // Do not shutdown
+ ps.println("osgi.noShutdown=true");
+ // Start a default console
+ ps.println("osgi.console=");
+ ps.close();
+ }
+ }
+
+ private void generatePDETarget(ProjectSet bundleSymbolicNames, File root, Log log) throws FileNotFoundException,
+ IOException {
+ for (Map.Entry<String, Set<String>> e : bundleSymbolicNames.nameMap.entrySet()) {
+ Set<String> bundles = e.getValue();
+ String name = trim(e.getKey());
+ File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? name : ""));
+ feature.mkdirs();
+ File target = new File(feature, "tuscany.target");
+ log.info("Generating target definition: " + target.getCanonicalPath());
+ FileOutputStream targetFile = new FileOutputStream(target);
+ if (!bundles.contains("org.eclipse.osgi")) {
+ bundles.add("org.eclipse.osgi");
+ }
+ writeTarget(new PrintStream(targetFile), name, bundles, eclipseFeatures);
+ targetFile.close();
+ }
+ }
+
+ private MavenProject buildProject(Artifact artifact) throws ProjectBuildingException,
+ InvalidDependencyVersionException, ArtifactResolutionException, ArtifactNotFoundException {
+ MavenProject pomProject =
+ mavenProjectBuilder.buildFromRepository(artifact, this.remoteRepos, this.local);
+ if (pomProject.getDependencyArtifacts() == null) {
+ pomProject.setDependencyArtifacts(pomProject
+ .createArtifacts(factory,
+ null, // Artifact.SCOPE_TEST,
+ new ScopeArtifactFilter(Artifact.SCOPE_TEST)));
+ }
+ ArtifactResolutionResult result =
+ resolver.resolveTransitively(pomProject.getDependencyArtifacts(),
+ pomProject.getArtifact(),
+ remoteRepos,
+ local,
+ artifactMetadataSource);
+ pomProject.setArtifacts(result.getArtifacts());
+ return pomProject;
+ }
+
+ private ArtifactResolutionResult resolveTransitively(Artifact artifact) throws ArtifactResolutionException, ArtifactNotFoundException {
+ Artifact originatingArtifact = factory.createBuildArtifact("dummy", "dummy", "1.0", "jar");
+
+ return resolver.resolveTransitively(Collections.singleton(artifact),
+ originatingArtifact,
+ local,
+ remoteRepos,
+ artifactMetadataSource,
+ null);
+ }
+
+ /**
+ * Convert tuscany-feature-xyz to feature-xyz
+ * @param artifactId
+ * @return
+ */
+ private String trim(String artifactId) {
+ if (artifactId.startsWith("tuscany-feature-")) {
+ return artifactId.substring("tuscany-feature-".length());
+ } else {
+ return artifactId;
+ }
+ }
+
+ private static void copyFile(File jar, File dir) throws FileNotFoundException, IOException {
+ byte[] buf = new byte[4096];
+ File jarFile = new File(dir, jar.getName());
+ FileInputStream in = new FileInputStream(jar);
+ FileOutputStream out = new FileOutputStream(jarFile);
+ for (;;) {
+ int len = in.read(buf);
+ if (len > 0) {
+ out.write(buf, 0, len);
+ } else {
+ break;
+ }
+ }
+ in.close();
+ out.close();
+ }
+
+ private static void addFileToJar(JarOutputStream out, String entryName, URL file) throws FileNotFoundException, IOException {
+ byte[] buf = new byte[4096];
+ InputStream in = file.openStream();
+ out.putNextEntry(new ZipEntry(entryName));
+ for (;;) {
+ int len = in.read(buf);
+ if (len > 0) {
+ out.write(buf, 0, len);
+ } else {
+ break;
+ }
+ }
+ in.close();
+ out.closeEntry();
+ }
+
+ private void writeTarget(PrintStream ps, String pom, Set<String> ids, String[] features) {
+ ps.println(XML_PI);
+ ps.println("<?pde version=\"3.2\"?>");
+ ps.println(ASL_HEADER);
+
+ ps.println("<target name=\"Eclipse Target - " + pom + "\">");
+
+ if (executionEnvironment != null) {
+ ps.println(" <targetJRE>");
+ ps.println(" <execEnv>" + executionEnvironment + "</execEnv>");
+ ps.println(" </targetJRE>");
+ }
+
+ if (useDefaultLocation) {
+ ps.println(" <location useDefault=\"true\"/>");
+ } else {
+ ps.println(" <location path=\"" + targetDirectory + "\"/>");
+ }
+
+ // ps.println("<content useAllPlugins=\"true\">");
+ ps.println(" <content>");
+ ps.println(" <plugins>");
+ for (String id : ids) {
+ ps.println(" <plugin id=\"" + id + "\"/>");
+ }
+ ps.println(" </plugins>");
+ ps.println(" <features>");
+ if (features != null) {
+ for (String f : features) {
+ ps.println(" <feature id=\"" + f + "\"/>");
+ }
+ }
+ ps.println(" </features>");
+ if (useDefaultLocation) {
+ ps.println(" <extraLocations>");
+ // Not sure why the extra path needs to the plugins folder
+ ps.println(" <location path=\"" + targetDirectory + "\"/>");
+ ps.println(" </extraLocations>");
+ }
+ ps.println(" </content>");
+
+ ps.println("</target>");
+
+ }
+
+ private static void writePluginXML(PrintStream ps) {
+ ps.println(XML_PI);
+ ps.println("<?pde version=\"3.2\"?>");
+ ps.println(ASL_HEADER);
+ ps.println("<plugin>");
+ ps.println("<extension point = \"org.eclipse.pde.core.targets\">");
+ ps.println("<target");
+ ps.println("id=\"org.apache.tuscany.sca.target\"");
+ ps.println("name=\"Apache Tuscany Eclipse Target\"");
+ ps.println("path=\"tuscany.target\"/>");
+ ps.println("</extension>");
+ ps.println("</plugin>");
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ThirdPartyBundleBuildMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ThirdPartyBundleBuildMojo.java
new file mode 100644
index 0000000000..e183e7e197
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/java/org/apache/tuscany/sca/tools/bundle/plugin/ThirdPartyBundleBuildMojo.java
@@ -0,0 +1,152 @@
+/*
+ * 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.tools.bundle.plugin;
+
+import static org.apache.tuscany.sca.tools.bundle.plugin.BundleUtil.write;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.Manifest;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * A Maven plugin that builds an OSGi bundle for the project's third-party dependencies.
+ *
+ * @version $Rev$ $Date$
+ * @goal assemble-thirdparty-bundle
+ * @phase generate-resources
+ * @requiresDependencyResolution test
+ * @description Build an OSGi bundle for the project's third party dependencies
+ */
+public class ThirdPartyBundleBuildMojo extends AbstractMojo {
+
+ /**
+ * The project to build the bundle for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ /**
+ * The bundle symbolic name
+ *
+ * @parameter
+ */
+ private String symbolicName;
+
+ public void execute() throws MojoExecutionException {
+ Log log = getLog();
+
+ String projectGroupId = project.getGroupId();
+ Set<File> jarFiles = new HashSet<File>();
+ for (Object o : project.getArtifacts()) {
+ Artifact artifact = (Artifact)o;
+
+ if (!(Artifact.SCOPE_COMPILE.equals(artifact.getScope()) || Artifact.SCOPE_RUNTIME.equals(artifact
+ .getScope()))) {
+ if (log.isDebugEnabled()) {
+ log.debug("Skipping artifact: " + artifact);
+ }
+ continue;
+ }
+ if (!"jar".equals(artifact.getType())) {
+ continue;
+ }
+ if (projectGroupId.equals(artifact.getGroupId())) {
+ continue;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Artifact: " + artifact);
+ }
+ String bundleName = null;
+ try {
+ bundleName = BundleUtil.getBundleSymbolicName(artifact.getFile());
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ if (bundleName == null || true) {
+ if (artifact.getFile().exists()) {
+ log.info("Adding third party jar: " + artifact);
+ jarFiles.add(artifact.getFile());
+ } else {
+ log.warn("Third party jar not found: " + artifact);
+ }
+ }
+ }
+
+ try {
+ String version = BundleUtil.osgiVersion(project.getVersion());
+
+ Manifest mf = BundleUtil.libraryManifest(jarFiles, project.getName(), symbolicName, version, "lib");
+ File file = new File(project.getBasedir(), "META-INF");
+ file.mkdir();
+ file = new File(file, "MANIFEST.MF");
+ if (log.isDebugEnabled()) {
+ log.debug("Generating " + file);
+ }
+
+ FileOutputStream fos = new FileOutputStream(file);
+ write(mf, fos);
+ fos.close();
+
+ File lib = new File(project.getBasedir(), "lib");
+ if (lib.isDirectory()) {
+ for (File c : lib.listFiles()) {
+ c.delete();
+ }
+ }
+ lib.mkdir();
+ byte[] buf = new byte[4096];
+ for (File jar : jarFiles) {
+ File jarFile = new File(lib, jar.getName());
+ if (log.isDebugEnabled()) {
+ log.debug("Copying " + jar + " to " + jarFile);
+ }
+ FileInputStream in = new FileInputStream(jar);
+ FileOutputStream out = new FileOutputStream(jarFile);
+ for (;;) {
+ int len = in.read(buf);
+ if (len > 0) {
+ out.write(buf, 0, len);
+ } else {
+ break;
+ }
+ }
+ in.close();
+ out.close();
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties
new file mode 100644
index 0000000000..b016c69065
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/maven/plugin/eclipse/messages.properties
@@ -0,0 +1,78 @@
+#
+#
+# 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.
+#
+#
+EclipsePlugin.missingpom=There must be a POM in the current working directory for the Eclipse plugin to work.
+EclipsePlugin.pompackaging=Not running eclipse plugin goal for pom project
+EclipsePlugin.notadir=Not a directory: "{0}"
+EclipsePlugin.cantcreatedir=Can''t create directory "{0}"
+EclipsePlugin.erroropeningfile=Exception while opening file.
+EclipsePlugin.cantwritetofile=Unable to write to file: {0}
+EclipsePlugin.cantfindresource=Unable to resolve resource location: {0}
+EclipsePlugin.cantreadfile=Unable to read file: {0}
+EclipsePlugin.keepexisting=File {0} already exists.\n Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
+EclipsePlugin.cantparseexisting=Unable to parse existing file: {0}. Settings will not be preserved.
+EclipsePlugin.cantresolvesources=Cannot resolve source artifact. Artifact id: {0} (Message: {1})
+EclipsePlugin.wrote=Wrote Eclipse project for "{0}" to {1}.
+EclipsePlugin.missingelement=Missing element from the project descriptor: "{0}"
+EclipsePlugin.includenotsupported=This plugin currently doesn't support include patterns for resources. Adding the entire directory.
+EclipsePlugin.excludenotsupported=This plugin currently doesn't support exclude patterns for resources. Adding the entire directory.
+EclipsePlugin.artifactpathisnull=The artifact path was null. Artifact id: {0}
+EclipsePlugin.artifactissystemscoped=The artifact has scope ''system''. Artifact id: {0}. System path: {1}
+EclipsePlugin.unsupportedwtp=Unsupported WTP version: {0}. This plugin currently supports only the following versions: {1}.
+EclipsePlugin.wtpversion=Adding support for WTP version {0}.
+EclipsePlugin.missingjrecontainer=You did specify a list of classpath containers without the base org.eclipse.jdt.launching.JRE_CONTAINER.\n If you specify custom classpath containers you should also add org.eclipse.jdt.launching.JRE_CONTAINER to the list
+EclipsePlugin.deprecatedpar=Plugin parameter "{0}" is deprecated, please use "{1}"
+EclipsePlugin.cantcopyartifact=Can''t copy artifact "{0}".
+EclipsePlugin.foundadir={0} is a directory, ignoring.
+
+EclipseSettingsWriter.wrotesettings=Wrote settings to {0}
+EclipseSettingsWriter.cannotcreatesettings=Cannot create settings file
+EclipseSettingsWriter.errorwritingsettings=Error writing settings file
+EclipseSettingsWriter.usingdefaults=Not writing settings - defaults suffice
+
+EclipseClasspathWriter.lookingforsources=Looking for source archive for artifact {0}
+EclipseClasspathWriter.sourcesavailable=Sources attachment for artifact {0} set to {1}
+
+EclipseProjectWriter.notafile=Not adding a file link to {0}; it is not a file
+
+EclipseCleanMojo.failedtodelete=Failed to delete {0} file: {0}
+EclipseCleanMojo.nofilefound=No {0} file found
+EclipseCleanMojo.deletingFile=Deleting file: {0}
+EclipseCleanMojo.deletingDirectory=Deleting directory: {0}
+
+EclipseOSGiManifestWriter.nomanifestfile=The references manifest file doesn''t exist, plugin dependencies will not be updated: {0}
+
+IdeDependency.cantreadfile=Unable to read file: {0}
+
+Rad6LibCopier.cantdeletefile=Failed to delete file: {0}
+
+MyEclipseSpringBeansWriter.springVersionNotFound=Spring must be declared in the project's dependencies to generate .springBeans file.
+
+sourcesnotavailable=\n Sources for some artifacts are not available.\n List of artifacts without a source archive:
+sourcesnotdownloaded=\n Sources for some artifacts are not available.\n Please run the same goal with the -DdownloadSources=true parameter in order to check remote repositories for sources.\n List of artifacts without a source archive:
+sourcesmissingitem=\n o {0}
+javadocnotavailable=\n Javadoc for some artifacts is not available.\n List of artifacts without a javadoc archive:
+javadocnotdownloaded=\n Javadoc for some artifacts is not available.\n Please run the same goal with the -DdownloadJavadocs=true parameter in order to check remote repositories for javadoc.\n List of artifacts without a javadoc archive:
+javadocmissingitem=\n o {0}
+errorresolving=Error resolving {0} artifact. Artifact id: {1} (Message: {2})
+artifactresolution=An error occurred during dependency resolution of the following artifact:\n {0}:{1}:{2}\nCaused by: {3}
+artifactdownload=An error occurred during dependency resolution.\n Failed to retrieve {0}:{1}-{2}\nCaused by: {3}
+cantcanonicalize=Can''t canonicalize system path: {0}
+unabletoparseversion={0}: unable to parse version ''{1}'' for dependency ''{2}'': {3}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/LICENSE.txt b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/LICENSE.txt
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/LICENSE.txt
@@ -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/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/NOTICE.txt b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/NOTICE.txt
new file mode 100644
index 0000000000..644a49d98b
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-bundle-plugin/src/main/resources/org/apache/tuscany/sca/tools/bundle/plugin/NOTICE.txt
@@ -0,0 +1,5 @@
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/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/2.0-M1/tools/maven/maven-dependency-lister/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/NOTICE
new file mode 100644
index 0000000000..51042eab05
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/README b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/README
new file mode 100644
index 0000000000..d53760029f
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/README
@@ -0,0 +1,46 @@
+Tuscany SCA Dependency Lister
+=============================
+
+Makes use of the extension Maven dependency support to list out all of the
+dependencis in the module where the plugin is used. The module is
+analysed and a report (dependency.txt) is written into the modules directory including
+each dependency and the path through the maven transitive dependencies that caused
+the original dependency to be included. For example, Here is a line which lists
+a a jar dependency, the phase in which it was found, the module being processed
+and he path that causes the dependency
+
+DEPENDENCY PHASE MODULE PATH TO DEPENDENCY
+jaxb-api-2.1.jar compile Apache Tuscany SCA Atom+RSS Feed Aggregator Sample Webapp tuscany-host-webapp-1.1-incubating-SNAPSHOT tuscany-host-embedded-1.1-incubating-SNAPSHOT tuscany-core-databinding-1.1-incubating-SNAPSHOT tuscany-databinding-jaxb-1.1-incubating-SNAPSHOT jaxb-api-2.1
+
+It is often convenient to further analyse these entries using the spreadsheet of your
+choice so the columns are tab separated to allow for easy conversion.
+
+The plugin can be included in a module using the following,
+
+<plugin>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-maven-dependency-lister</artifactId>
+ <version>1.1-incubating-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ </execution>
+ </executions>
+</plugin>
+
+If you include this at the top level of you project and have it run for each model you
+will get a report for each model independently. For example, in the Tuscany SCA project
+the plugin is included in the pom.xml files at the sca level under the profile
+"dependecies" so to generate a dependencies report for the Tuscany SCA project:
+
+cd sca
+mvn -o -Pdependencies -Dmaven.test.skip=true
+
+Once you have dependency.txt files in your modules
+the you favourite command line tools can be used to concatenate and sort them
+to get a full picture of the dependencies in you project, for example, with linux you
+could do,
+
+find . -name dependency.txt -exec cat '{}' >> deptotal.txt \;
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/pom.xml
new file mode 100644
index 0000000000..d5651a59fa
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-dependency-lister</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Dependency Lister Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-dependency-tree</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/src/main/java/org/apache/tuscany/tools/sca/dependency/lister/plugin/DependencyListerMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/src/main/java/org/apache/tuscany/tools/sca/dependency/lister/plugin/DependencyListerMojo.java
new file mode 100644
index 0000000000..b904ac4804
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-dependency-lister/src/main/java/org/apache/tuscany/tools/sca/dependency/lister/plugin/DependencyListerMojo.java
@@ -0,0 +1,198 @@
+/*
+ * 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.tools.sca.dependency.lister.plugin;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.shared.dependency.tree.DependencyNode;
+import org.apache.maven.shared.dependency.tree.DependencyTree;
+import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
+import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
+
+/**
+ * @version $Rev: 588816 $ $Date: 2007-10-27 01:22:38 +0100 (Sat, 27 Oct 2007) $
+ * @goal execute
+ * @phase generate-sources
+ * @requiresDependencyResolution test
+ * @description List dependencies for an SCA project
+ */
+public class DependencyListerMojo extends AbstractMojo {
+ /**
+ * The project to create a build for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ */
+ private MavenProject project;
+
+ /**
+ * Used for resolving artifacts
+ *
+ * @component
+ */
+ private ArtifactResolver artifactResolver;
+
+ /**
+ * Factory for creating artifact objects
+ *
+ * @component
+ */
+ private ArtifactFactory artifactFactory;
+
+ /**
+ * @component
+ */
+ private ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * @component
+ */
+ private DependencyTreeBuilder dependencyTreeBuilder;
+
+ /**
+ * @component
+ */
+ private ArtifactCollector collector;
+
+ /**
+ * @component
+ */
+ private MavenProjectBuilder mavenProjectBuilder;
+
+ /**
+ * The local repository where the artifacts are located
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ */
+ private ArtifactRepository localRepository;
+
+ /**
+ * The remote repositories where artifacts are located
+ *
+ * @parameter expression="${project.remoteArtifactRepositories}"
+ */
+ private List remoteRepositories;
+
+ /**
+ * The current user system settings for use in Maven.
+ *
+ * @parameter expression="${settings}"
+ * @required
+ * @readonly
+ */
+ private Settings settings;
+
+
+ /**
+ * The build.xml file to generate.
+ * @parameter expression="${basedir}/target/dependency.txt"
+ */
+ private String buildFile;
+
+ public void execute() throws MojoExecutionException {
+
+ System.out.println("Analysing " + buildFile);
+
+ // Open the target build.xml file
+ File targetFile = new File(buildFile);
+ PrintWriter pw;
+ try {
+ pw = new PrintWriter(new FileOutputStream(targetFile));
+ } catch (FileNotFoundException e) {
+ System.out.println(e.toString());
+ return;
+ }
+
+ DependencyTree dependencyTree;
+
+ try
+ {
+ dependencyTree = dependencyTreeBuilder.buildDependencyTree( project, localRepository, artifactFactory,
+ artifactMetadataSource, collector );
+ }
+ catch ( DependencyTreeBuilderException e )
+ {
+ throw new MojoExecutionException( "Can't build dependency tree", e );
+ }
+
+ // processNode(dependencyTree.getRootNode(), "--", pw);
+
+ for (Artifact artifact: (List<Artifact>)project.getTestArtifacts()) {
+ pw.println( artifact.getFile().getName() + "\t" +
+ artifact.getScope() + "\t" +
+ project.getName() + "\t" +
+ findArtifactPath(dependencyTree.getRootNode(), artifact));
+ }
+
+ pw.close();
+ }
+
+ private void processNode(DependencyNode node, String indent, PrintWriter pw){
+
+ pw.println(indent + node.getArtifact().getScope() + " " + node.getArtifact().toString());
+
+ Iterator it = node.getChildren().iterator();
+ while ( it.hasNext() )
+ {
+ DependencyNode child = (DependencyNode) it.next();
+
+ processNode(child, indent + "--", pw);
+ }
+ }
+
+ private String findArtifactPath(DependencyNode node, Artifact artifact){
+ String path = null;
+
+ Iterator it = node.getChildren().iterator();
+ while ( it.hasNext() && (path == null) )
+ {
+ DependencyNode child = (DependencyNode) it.next();
+
+ if (child.getArtifact().getArtifactId().equals(artifact.getArtifactId())) {
+ path = child.getArtifact().getArtifactId() + "-" + child.getArtifact().getVersion();
+ } else {
+ path = findArtifactPath(child, artifact);
+
+ if (path != null){
+ path = child.getArtifact().getArtifactId() + "-" + child.getArtifact().getVersion() + "\t" + path;
+ }
+ }
+ }
+
+ return path;
+ }
+
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/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/2.0-M1/tools/maven/maven-eclipse-compiler/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/pom.xml
new file mode 100644
index 0000000000..e2fae8c108
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/pom.xml
@@ -0,0 +1,304 @@
+<?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</groupId>
+ <artifactId>apache</artifactId>
+ <version>4</version>
+ </parent>
+
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-maven-eclipse-compiler</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Tuscany SCA Eclipse Compiler Plugin</name>
+ <version>2.0-M1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.8</version>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-compiler-api</artifactId>
+ <version>1.5.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jdt</groupId>
+ <artifactId>core</artifactId>
+ <version>3.3.0-v_771</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>resources</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>runtime</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>filesystem</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse</groupId>
+ <artifactId>text</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse</groupId>
+ <artifactId>osgi</artifactId>
+ <version>3.3.0-v20070530</version>
+ <scope>compile</scope>
+ </dependency>
+
+<!--
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>resources</artifactId>
+ <version>3.3.0-v20070604</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>expressions</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>filesystem</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>runtime</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>runtime</artifactId>
+ <version>3.3.100-v20070530</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>expressions</artifactId>
+ <version>3.3.0-v20070606-0010</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>runtime</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>filesystem</artifactId>
+ <version>1.1.0-v20070606</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse</groupId>
+ <artifactId>text</artifactId>
+ <version>3.3.0-v20070606-0010</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>commands</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>commands</artifactId>
+ <version>3.3.0-I20070605-0010</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ <version>1.0.0-v20070606</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ <version>3.3.0-v20070426</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>app</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+-->
+ </dependencies>
+
+ <build>
+ <defaultGoal>install</defaultGoal>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>${notice.dir}</directory>
+ <targetPath>META-INF</targetPath>
+ <filtering>true</filtering>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+
+ <pluginManagement>
+ <plugins>
+
+ <!-- compiler plugin configuration -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+ <!-- jar plugin configuration -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Extension-Name>${project.artifactId}</Extension-Name>
+ <Specification-Title>${name}</Specification-Title>
+ <Specification-Vendor>The Apache Software Foundation</Specification-Vendor>
+ <Specification-Version>${version}</Specification-Version>
+ <Implementation-Title>${name}</Implementation-Title>
+ <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+ <Implementation-Vendor>The Apache Software Foundation</Implementation-Vendor>
+ <Implementation-Version>${version}</Implementation-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/ClassLoaderNameEnvironment.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/ClassLoaderNameEnvironment.java
new file mode 100644
index 0000000000..4b3f84edf4
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/ClassLoaderNameEnvironment.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.tools.maven.compiler;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+
+/**
+ * An implementation of INameEnvironment based on a ClassLoader.
+ *
+ * @version $Rev: $ $Date: $
+ */
+class ClassLoaderNameEnvironment implements INameEnvironment {
+ private final static char fileSeparator = System.getProperty("file.separator").charAt(0);
+
+ private ClassLoader classLoader;
+ private List<String> sourceLocations;
+ private Map<String, File> sourceFiles;
+
+ ClassLoaderNameEnvironment(ClassLoader classLoader, List<String> sourceLocations) {
+ this.classLoader = classLoader;
+ this.sourceLocations = sourceLocations;
+ sourceFiles = new HashMap<String, File>();
+ }
+
+ public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
+ StringBuffer className = new StringBuffer();
+ for (char[] name: compoundTypeName) {
+ if (className.length() != 0) {
+ className.append('.');
+ }
+ className.append(name);
+ }
+ return nameAnswer(className.toString());
+ }
+
+ public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+ StringBuffer className = new StringBuffer();
+ for (char[] name: packageName) {
+ if (className.length() != 0) {
+ className.append('.');
+ }
+ className.append(name);
+ }
+ if (className.length() != 0) {
+ className.append('.');
+ }
+ className.append(typeName);
+ return nameAnswer(className.toString());
+ }
+
+ public boolean isPackage(char[][] parentPackageName, char[] packageName) {
+ StringBuffer fullPackageName = new StringBuffer();
+ if (parentPackageName != null) {
+ for (char[] name: parentPackageName) {
+ if (fullPackageName.length() != 0) {
+ fullPackageName.append('.');
+ }
+ fullPackageName.append(name);
+ }
+ }
+ if (fullPackageName.length() != 0) {
+ fullPackageName.append('.');
+ }
+ fullPackageName.append(packageName);
+ return isPackage(fullPackageName.toString());
+ }
+
+ public void cleanup() {
+ }
+
+ /**
+ * Returns the source file for the given class name.
+ *
+ * @param className
+ * @return
+ */
+ private File sourceFile(String className) {
+ File sourceFile = (File)sourceFiles.get(className);
+ if (sourceFile != null) {
+ return sourceFile;
+ }
+ String sourceName = className.replace('.', fileSeparator) + ".java";
+ sourceFile = sourceFileInSourceLocations(sourceName);
+ sourceFiles.put(className, sourceFile);
+ return sourceFile;
+ }
+
+ /**
+ * Returns the source file for the given source path relative to the source locations.
+ *
+ * @param className
+ * @return
+ */
+ private File sourceFileInSourceLocations(String relativePath) {
+ for (String sourceLocation : sourceLocations) {
+ File sourceFile = new File(sourceLocation, relativePath);
+ if (sourceFile.exists()) {
+ return sourceFile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the given name is a package name.
+ *
+ * @param name
+ * @return
+ */
+ private boolean isPackage(String name) {
+ if (sourceFile(name) != null) {
+ return false;
+ }
+ String resourceName = '/' + name.replace('.', '/') + ".class";
+ InputStream is = classLoader.getResourceAsStream(resourceName);
+ if (is == null) {
+ return true;
+ } else {
+ try {
+ is.close();
+ } catch (IOException e) {}
+ return false;
+ }
+ }
+
+ /**
+ * Find the NameAnswer for by the given class name.
+ *
+ * @param className
+ * @return
+ */
+ private NameEnvironmentAnswer nameAnswer(String className) {
+ try {
+ File sourceFile = sourceFile(className);
+ if (sourceFile != null) {
+ ICompilationUnit compilationUnit = new FileCompilationUnit(sourceFile.getAbsolutePath(), className);
+ return new NameEnvironmentAnswer(compilationUnit, null);
+ }
+
+ String resourceName = className.replace('.', '/') + ".class";
+ InputStream is = classLoader.getResourceAsStream(resourceName);
+ if (is == null) {
+ return null;
+ }
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[2048];
+ for (;;) {
+ int n = is.read(b);
+ if (n <= 0) {
+ break;
+ }
+ bos.write(b, 0, n);
+ }
+ byte[] classBytes = bos.toByteArray();
+
+ ClassFileReader classFileReader = new ClassFileReader(classBytes, className.toCharArray(), true);
+ return new NameEnvironmentAnswer(classFileReader, null);
+
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ } catch (ClassFormatException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/CompilerRequestor.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/CompilerRequestor.java
new file mode 100644
index 0000000000..3df4b4d602
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/CompilerRequestor.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.tools.maven.compiler;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.codehaus.plexus.compiler.CompilerError;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+
+class CompilerRequestor implements ICompilerRequestor {
+ private String outputDirectory;
+ private boolean showWarnings;
+ private List<CompilerError> compilerErrors;
+
+ public CompilerRequestor(String outputDirectory, boolean showWarnings, List<CompilerError> compilerErrors) {
+ this.outputDirectory = outputDirectory;
+ this.showWarnings = showWarnings;
+ this.compilerErrors = compilerErrors;
+ }
+
+ public void acceptResult(CompilationResult result) {
+ boolean hasErrors = false;
+ if (result.hasProblems()) {
+
+ // Convert JDT IProblems into plexus CompilerErrors
+ for (IProblem problem: result.getProblems()) {
+ if (problem.isWarning()) {
+ if (showWarnings) {
+ compilerErrors.add(new CompilerError(new String(problem.getOriginatingFileName()),
+ false,
+ problem.getSourceLineNumber(),
+ problem.getSourceStart(),
+ problem.getSourceLineNumber(),
+ problem.getSourceEnd(),
+ problem.getMessage()));
+ }
+
+ } else if (problem.isError()) {
+ hasErrors = true;
+ compilerErrors.add(new CompilerError(new String(problem.getOriginatingFileName()),
+ true,
+ problem.getSourceLineNumber(),
+ problem.getSourceStart(),
+ problem.getSourceLineNumber(),
+ problem.getSourceEnd(),
+ problem.getMessage()));
+
+ }
+ }
+ }
+
+ // Write the class files
+ if (!hasErrors) {
+ ClassFile[] classFiles = result.getClassFiles();
+ for (ClassFile classFile: classFiles) {
+
+ // Create file and parent directories
+ StringBuffer className = new StringBuffer();
+ for (char[] name: classFile.getCompoundName()) {
+ if (className.length() != 0) {
+ className.append('.');
+ }
+ className.append(name);
+ }
+ File file = new File(outputDirectory, className.toString().replace('.', '/') + ".class");
+ if (!file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+
+ // Write class file contents
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(file);
+ fos.write(classFile.getBytes());
+ } catch (FileNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (IOException e) {}
+ }
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/FileCompilationUnit.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/FileCompilationUnit.java
new file mode 100644
index 0000000000..08ed7f034e
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/FileCompilationUnit.java
@@ -0,0 +1,88 @@
+/*
+ * 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.tools.maven.compiler;
+
+import java.io.CharArrayWriter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.StringTokenizer;
+
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+
+/**
+ * An implementation of ICompilationUnit that wraps a File.
+ *
+ * @version $Rev: $ $Date: $
+ */
+class FileCompilationUnit implements ICompilationUnit {
+ private final static char fileSeparator = System.getProperty("file.separator").charAt(0);
+ private String className;
+ private String sourceFile;
+
+ FileCompilationUnit(String sourceFile, String className) {
+ this.className = className;
+ this.sourceFile = sourceFile;
+ }
+
+ public char[] getContents() {
+ try {
+ InputStreamReader reader = new InputStreamReader(new FileInputStream(sourceFile));
+ CharArrayWriter writer = new CharArrayWriter();
+ char[] b = new char[2048];
+ for (;;) {
+ int n = reader.read(b);
+ if (n <= 0) {
+ break;
+ }
+ writer.write(b, 0, n);
+ }
+ return writer.toCharArray();
+
+ } catch (FileNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public char[] getFileName() {
+ return (className.replace('.', fileSeparator) + ".java").toCharArray();
+ }
+
+ public char[] getMainTypeName() {
+ int dot = className.lastIndexOf('.');
+ if (dot > 0) {
+ return className.substring(dot + 1).toCharArray();
+ }
+ return className.toCharArray();
+ }
+
+ public char[][] getPackageName() {
+ StringTokenizer tokens = new StringTokenizer(className, ".");
+ char[][] packageName = new char[tokens.countTokens() - 1][];
+ for (int i = 0; i < packageName.length; i++) {
+ String token = tokens.nextToken();
+ packageName[i] = token.toCharArray();
+ }
+ return packageName;
+ }
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/JavaCompiler.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/JavaCompiler.java
new file mode 100644
index 0000000000..f628a38e95
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/JavaCompiler.java
@@ -0,0 +1,212 @@
+/*
+ * 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.tools.maven.compiler;
+
+import static org.codehaus.plexus.compiler.CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE;
+import static org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies.proceedWithAllProblems;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.GENERATE;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.IGNORE;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_Encoding;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_LineNumberAttribute;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_LocalVariableAttribute;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_ReportDeprecation;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_Source;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_SourceFileAttribute;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.OPTION_TargetPlatform;
+import static org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WARNING;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.sca.tools.maven.compiler.osgi.BundleResolver;
+import org.apache.tuscany.sca.tools.maven.compiler.osgi.BundleUtil;
+import org.codehaus.plexus.compiler.AbstractCompiler;
+import org.codehaus.plexus.compiler.CompilerConfiguration;
+import org.codehaus.plexus.compiler.CompilerError;
+import org.codehaus.plexus.compiler.CompilerException;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.osgi.framework.BundleException;
+
+/**
+ * A custom Plexus Java compiler plugin that uses the Eclipse compiler.
+ *
+ * @version $Rev: $ $Date: $
+ */
+public class JavaCompiler extends AbstractCompiler {
+
+ public JavaCompiler() {
+ super(ONE_OUTPUT_FILE_PER_INPUT_FILE, ".java", ".class", null);
+ }
+
+ public List<CompilerError> compile(CompilerConfiguration configuration) throws CompilerException {
+ BundleResolver stateController = new BundleResolver(getLogger());
+
+ getLogger().info("Invoking Tuscany Eclipse JDT compiler");
+
+ List<URL> urls = new ArrayList<URL>();
+ try {
+ for (String entry : (List<String>)configuration.getClasspathEntries()) {
+ urls.add(new File(entry).toURI().toURL());
+ }
+ } catch (MalformedURLException e) {
+ throw new CompilerException(e.getMessage(), e);
+ }
+
+ ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
+
+ // Determine compiler configuration
+ Map<String, String> settings = new HashMap<String, String>();
+ String sourceVersion = configuration.getSourceVersion();
+ if (sourceVersion != null && sourceVersion.length() != 0) {
+ settings.put(OPTION_Source, sourceVersion);
+ }
+ String targetVersion = configuration.getTargetVersion();
+ if (targetVersion != null && targetVersion.length() != 0) {
+ settings.put(OPTION_TargetPlatform, targetVersion);
+ }
+ settings.put(OPTION_LineNumberAttribute, GENERATE);
+ settings.put(OPTION_SourceFileAttribute, GENERATE);
+ if (configuration.isDebug()) {
+ settings.put(OPTION_LocalVariableAttribute, GENERATE);
+ }
+ if (configuration.getSourceEncoding() != null && !(configuration.getSourceEncoding().length() == 0)) {
+ settings.put(OPTION_Encoding, configuration.getSourceEncoding());
+ }
+ if (configuration.isShowDeprecation()) {
+ settings.put(OPTION_ReportDeprecation, WARNING);
+ } else {
+ settings.put(OPTION_ReportDeprecation, IGNORE);
+ }
+
+ // Create a compiler
+ List<CompilerError> compilerErrors = new ArrayList<CompilerError>();
+ INameEnvironment nameEnvironment =
+ new ClassLoaderNameEnvironment(classLoader, configuration.getSourceLocations());
+ ICompilerRequestor requestor =
+ new CompilerRequestor(configuration.getOutputLocation(), configuration.isShowWarnings(), compilerErrors);
+ Compiler compiler =
+ new Compiler(nameEnvironment, proceedWithAllProblems(), new CompilerOptions(settings), requestor,
+ new DefaultProblemFactory(Locale.getDefault()));
+
+ // Create compilation units for the source files
+ List<FileCompilationUnit> compilationUnits = new ArrayList<FileCompilationUnit>();
+
+ // Go over the input source locations
+ List<String> sourceLocations = (List<String>)configuration.getSourceLocations();
+ for (String sourceLocation : sourceLocations) {
+
+ // Exclude nested source locations
+ List<String> excludeLocations = new ArrayList<String>();
+ for (String nestedLocation : sourceLocations) {
+ if (nestedLocation != sourceLocation && nestedLocation.startsWith(sourceLocation)) {
+ excludeLocations.add(nestedLocation);
+ }
+ }
+
+ // List source files in each source location
+ for (String sourceFile : (Set<String>)getSourceFilesForSourceRoot(configuration, sourceLocation)) {
+
+ // Exclude files from excluded nested locations
+ boolean excluded = false;
+ for (String excludeLocation : excludeLocations) {
+ if (sourceFile.startsWith(excludeLocation)) {
+ excluded = true;
+ }
+ }
+ if (!excluded) {
+
+ // Create a compilation unit for the source file
+ FileCompilationUnit compilationUnit =
+ new FileCompilationUnit(sourceFile, makeClassName(sourceFile, sourceLocation));
+ compilationUnits.add(compilationUnit);
+ }
+ }
+ }
+
+ // Compile all the compilation units
+ getLogger().info("Compiling " + compilationUnits.size() + " to " + configuration.getOutputLocation());
+ compiler.compile((ICompilationUnit[])compilationUnits.toArray(new ICompilationUnit[compilationUnits.size()]));
+
+ // getLogger().info(configuration.getCustomCompilerArguments().toString());
+ boolean osgi = "true".equals(configuration.getCustomCompilerArguments().get("-osgi"));
+ File proj = new File(configuration.getOutputLocation());
+
+ String symbol = null;
+ try {
+ // Don't trigger the resolution for test-compile
+ if (!"test-classes".equals(proj.getName())) {
+ symbol = BundleUtil.getBundleSymbolicName(proj);
+ }
+ } catch (IOException e1) {
+ symbol = null;
+ }
+
+ if (osgi && symbol != null) {
+ getLogger().info("Resolving OSGi bundle: "+symbol);
+ for (String entry : (List<String>)configuration.getClasspathEntries()) {
+ try {
+ File cp = new File(entry);
+ if (cp.exists()) {
+ stateController.addBundle(cp);
+ }
+ } catch (BundleException e) {
+ getLogger().error(e.getMessage(), e);
+ }
+ }
+
+ stateController.resolveState();
+ BundleDescription b = stateController.getBundleDescription(proj);
+ if (b != null) {
+ try {
+ stateController.assertResolved(b);
+ getLogger().info("OSGi bundle is resolved: " + b.getSymbolicName());
+ } catch (BundleException e) {
+ stateController.analyzeErrors(b);
+ if(getLogger().isDebugEnabled()) {
+ getLogger().debug(stateController.reportErrors(b));
+ }
+ // FIXME: For now, only a warning is reported
+ // throw new CompilerException(e.getMessage(), e);
+ }
+ }
+ }
+
+ return compilerErrors;
+ }
+
+ public String[] createCommandLine(CompilerConfiguration config) throws CompilerException {
+ return null;
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleResolver.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleResolver.java
new file mode 100644
index 0000000000..06f26f7e65
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleResolver.java
@@ -0,0 +1,490 @@
+/*
+ * 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.tools.maven.compiler.osgi;
+
+import static org.eclipse.osgi.service.resolver.ResolverError.IMPORT_PACKAGE_USES_CONFLICT;
+import static org.eclipse.osgi.service.resolver.ResolverError.MISSING_FRAGMENT_HOST;
+import static org.eclipse.osgi.service.resolver.ResolverError.MISSING_IMPORT_PACKAGE;
+import static org.eclipse.osgi.service.resolver.ResolverError.MISSING_REQUIRE_BUNDLE;
+import static org.eclipse.osgi.service.resolver.ResolverError.REQUIRE_BUNDLE_USES_CONFLICT;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.HostSpecification;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.ResolverError;
+import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.osgi.service.resolver.StateObjectFactory;
+import org.eclipse.osgi.service.resolver.VersionConstraint;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+
+public class BundleResolver {
+ private static final String PROP_MAVEN_PROJECT = "MavenProject";
+ private static final String PROP_MANIFEST = "BundleManifest";
+
+ private StateObjectFactory factory = StateObjectFactory.defaultFactory;
+ private State state;
+ private long id = 0;
+ private Logger logger;
+
+ public static BundleDescription[] getDependentBundles(BundleDescription root) {
+ if (root == null)
+ return new BundleDescription[0];
+ BundleDescription[] imported = getImportedBundles(root);
+ BundleDescription[] required = getRequiredBundles(root);
+ BundleDescription[] dependents = new BundleDescription[imported.length + required.length];
+ System.arraycopy(imported, 0, dependents, 0, imported.length);
+ System.arraycopy(required, 0, dependents, imported.length, required.length);
+ return dependents;
+ }
+
+ public static BundleDescription[] getImportedBundles(BundleDescription root) {
+ if (root == null)
+ return new BundleDescription[0];
+ ExportPackageDescription[] packages = root.getResolvedImports();
+ List<BundleDescription> resolvedImports = new ArrayList<BundleDescription>(packages.length);
+ for (int i = 0; i < packages.length; i++)
+ if (!root.getLocation().equals(packages[i].getExporter().getLocation()) && !resolvedImports
+ .contains(packages[i].getExporter()))
+ resolvedImports.add(packages[i].getExporter());
+ return (BundleDescription[])resolvedImports.toArray(new BundleDescription[resolvedImports.size()]);
+ }
+
+ public static BundleDescription[] getRequiredBundles(BundleDescription root) {
+ if (root == null)
+ return new BundleDescription[0];
+ return root.getResolvedRequires();
+ }
+
+ public BundleResolver(Logger logger) {
+ this.logger = logger;
+ this.state = factory.createState(true);
+ Properties props = new Properties();
+ props.putAll(System.getProperties());
+ BundleUtil.loadVMProfile(props);
+ state.setPlatformProperties(props);
+ URL url = Bundle.class.getProtectionDomain().getCodeSource().getLocation();
+
+ File osgi = toFile(url);
+ try {
+ addBundle(osgi);
+ } catch (BundleException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private long getNextId() {
+ return ++id;
+ }
+
+ public BundleDescription addBundle(File bundleLocation) throws BundleException {
+ return addBundle(bundleLocation, false);
+ }
+
+ public BundleDescription addBundle(File bundleLocation, boolean override) throws BundleException {
+ if (bundleLocation == null || !bundleLocation.exists())
+ throw new IllegalArgumentException("bundleLocation not found: " + bundleLocation);
+ Dictionary manifest = loadManifestAttributes(bundleLocation);
+ if (manifest == null) {
+ // throw new BundleException("manifest not found in " + bundleLocation);
+ return null;
+ }
+ return addBundle(manifest, bundleLocation, override);
+ }
+
+ public BundleDescription addBundle(File manifestLocation, File bundleLocation, boolean override)
+ throws BundleException {
+ if (bundleLocation == null || !bundleLocation.exists())
+ throw new IllegalArgumentException("bundleLocation not found: " + bundleLocation);
+ Dictionary manifest = loadManifestAttributes(manifestLocation);
+ if (manifest == null)
+ throw new IllegalArgumentException("manifest not found in " + manifestLocation);
+ return addBundle(manifest, bundleLocation, override);
+ }
+
+ private Dictionary loadManifestAttributes(File bundleLocation) {
+ Manifest m = loadManifest(bundleLocation);
+ if (m == null) {
+ return null;
+ }
+
+ return manifestToProperties(m.getMainAttributes());
+ }
+
+ public Manifest loadManifest(File bundleLocation) {
+ try {
+ return BundleUtil.getManifest(bundleLocation);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private Properties manifestToProperties(Attributes d) {
+ Iterator iter = d.keySet().iterator();
+ Properties result = new Properties();
+ while (iter.hasNext()) {
+ Attributes.Name key = (Attributes.Name)iter.next();
+ result.put(key.toString(), d.get(key));
+ }
+ return result;
+ }
+
+ private BundleDescription addBundle(Dictionary enhancedManifest, File bundleLocation, boolean override)
+ throws BundleException {
+
+ BundleDescription descriptor =
+ factory.createBundleDescription(state, enhancedManifest, bundleLocation.getAbsolutePath(), getNextId());
+
+ setUserProperty(descriptor, PROP_MANIFEST, enhancedManifest);
+ if (override) {
+ BundleDescription[] conflicts = state.getBundles(descriptor.getSymbolicName());
+ if (conflicts != null) {
+ for (BundleDescription conflict : conflicts) {
+ state.removeBundle(conflict);
+ logger
+ .warn(conflict.toString() + " has been replaced by another bundle with the same symbolic name "
+ + descriptor.toString());
+ }
+ }
+ }
+
+ state.addBundle(descriptor);
+ return descriptor;
+ }
+
+ public BundleDescription getResolvedBundle(String bundleId) {
+ BundleDescription[] description = state.getBundles(bundleId);
+ if (description == null)
+ return null;
+ for (int i = 0; i < description.length; i++) {
+ if (description[i].isResolved())
+ return description[i];
+ }
+ return null;
+ }
+
+ public void resolveState() {
+ state.resolve(false);
+
+ if (logger.isDebugEnabled()) {
+ StringBuilder sb = new StringBuilder("Resolved OSGi state\n");
+ for (BundleDescription bundle : state.getBundles()) {
+ if (!bundle.isResolved()) {
+ sb.append("[X] ");
+ } else {
+ sb.append("[V] ");
+ }
+ sb.append(bundle).append(": (").append(bundle.getLocation());
+ sb.append(")\n");
+ for (ResolverError error : state.getResolverErrors(bundle)) {
+ sb.append(" ").append(error.toString()).append('\n');
+ }
+ }
+ logger.debug(sb.toString());
+ }
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public BundleDescription[] getBundles() {
+ return state.getBundles();
+ }
+
+ public ResolverError[] getResolverErrors(BundleDescription bundle) {
+ Set<ResolverError> errors = new LinkedHashSet<ResolverError>();
+ getRelevantErrors(errors, bundle);
+ return (ResolverError[])errors.toArray(new ResolverError[errors.size()]);
+ }
+
+ private void getRelevantErrors(Set<ResolverError> errors, BundleDescription bundle) {
+ ResolverError[] bundleErrors = state.getResolverErrors(bundle);
+ for (int j = 0; j < bundleErrors.length; j++) {
+ ResolverError error = bundleErrors[j];
+ errors.add(error);
+
+ VersionConstraint constraint = error.getUnsatisfiedConstraint();
+ if (constraint instanceof BundleSpecification || constraint instanceof HostSpecification) {
+ BundleDescription[] requiredBundles = state.getBundles(constraint.getName());
+ for (int i = 0; i < requiredBundles.length; i++) {
+ getRelevantErrors(errors, requiredBundles[i]);
+ }
+ }
+ }
+ }
+
+ private void logError(BundleDescription bundle, int level, Object object) {
+ StringBuffer msg = new StringBuffer();
+ for (int i = 0; i < level; i++) {
+ msg.append("--");
+ }
+ msg.append("> [").append(bundle.getSymbolicName()).append("] ");
+ msg.append(object);
+ logger.error(msg.toString());
+ }
+
+ public void analyzeErrors(BundleDescription bundle) {
+ analyzeErrors(bundle, new HashSet<BundleDescription>(), 1);
+ }
+
+ private void analyzeErrors(BundleDescription bundle, Set<BundleDescription> bundles, int level) {
+ if (bundles.contains(bundle)) {
+ return;
+ }
+ bundles.add(bundle);
+ ResolverError[] errors = state.getResolverErrors(bundle);
+ for (ResolverError error : errors) {
+ logError(bundle, level, error);
+ VersionConstraint constraint = error.getUnsatisfiedConstraint();
+ switch (error.getType()) {
+ case MISSING_IMPORT_PACKAGE:
+ ImportPackageSpecification pkgSpec = (ImportPackageSpecification)constraint;
+ for (BundleDescription b : getBundles()) {
+ for (ExportPackageDescription pkg : b.getExportPackages()) {
+ if (pkg.getName().equals(pkgSpec.getName())) {
+ if (pkgSpec.getVersionRange().isIncluded(pkg.getVersion())) {
+ if (!pkg.getExporter().isResolved()) {
+ logError(b, level, "Bundle unresolved: " + pkg);
+ analyzeErrors(pkg.getExporter(), bundles, level + 1);
+ }
+ } else {
+ logError(b, level, "Version mismatch: " + pkgSpec + " " + pkg);
+ }
+ }
+ }
+ }
+ break;
+ case MISSING_REQUIRE_BUNDLE:
+ case MISSING_FRAGMENT_HOST:
+ // BundleSpecification bundleSpec = (BundleSpecification)constraint;
+ for (BundleDescription b : getBundles()) {
+ if (b == bundle) {
+ continue;
+ }
+ if (b.getSymbolicName().equals(constraint.getName())) {
+ if (constraint.getVersionRange().isIncluded(b.getVersion())) {
+ // There must be something wrong in the bundle
+ analyzeErrors(b, bundles, level);
+ } else {
+ logError(bundle, level, "Version mismatch: " + constraint + " " + b);
+ }
+ }
+ }
+ break;
+ case IMPORT_PACKAGE_USES_CONFLICT:
+ case REQUIRE_BUNDLE_USES_CONFLICT:
+ default:
+ logger.error(reportErrors(bundle));
+ break;
+ }
+ }
+
+ }
+
+ public Set<ResolverError> getAllErrors() {
+ BundleDescription[] bundles = state.getBundles();
+ Set<ResolverError> errors = new LinkedHashSet<ResolverError>();
+ for (int i = 0; i < bundles.length; i++) {
+ BundleDescription bundle = bundles[i];
+ ResolverError[] bundleErrors = state.getResolverErrors(bundle);
+ if (bundleErrors != null) {
+ errors.addAll(Arrays.asList(bundleErrors));
+ }
+ }
+ return errors;
+ }
+
+ public List<BundleDescription> getDependencies(BundleDescription desc) {
+ Set<Long> bundleIds = new LinkedHashSet<Long>();
+ addBundleAndDependencies(desc, bundleIds, true);
+ List<BundleDescription> dependencies = new ArrayList<BundleDescription>();
+ for (long bundleId : bundleIds) {
+ if (desc.getBundleId() != bundleId) {
+ BundleDescription dependency = state.getBundle(bundleId);
+ BundleDescription supplier = dependency.getSupplier().getSupplier();
+ HostSpecification host = supplier.getHost();
+ if (host == null || !desc.equals(host.getSupplier())) {
+ dependencies.add(dependency);
+ }
+ }
+ }
+ return dependencies;
+ }
+
+ /**
+ * Code below is copy&paste from org.eclipse.pde.internal.core.DependencyManager
+ * which seems to calculate runtime dependencies. In particular, it adds
+ * fragments' dependencies to the host bundle (see TychoTest#testFragment unit test).
+ * This may or may not cause problems...
+ *
+ * RequiredPluginsClasspathContainer#computePluginEntries has the logic to
+ * calculate compile-time dependencies in IDE.
+ *
+ * TODO find the code used by PDE/Build
+ */
+ private static void addBundleAndDependencies(BundleDescription desc, Set<Long> bundleIds, boolean includeOptional) {
+ if (desc != null && bundleIds.add(new Long(desc.getBundleId()))) {
+ BundleSpecification[] required = desc.getRequiredBundles();
+ for (int i = 0; i < required.length; i++) {
+ if (includeOptional || !required[i].isOptional())
+ addBundleAndDependencies((BundleDescription)required[i].getSupplier(), bundleIds, includeOptional);
+ }
+ ImportPackageSpecification[] importedPkgs = desc.getImportPackages();
+ for (int i = 0; i < importedPkgs.length; i++) {
+ ExportPackageDescription exporter = (ExportPackageDescription)importedPkgs[i].getSupplier();
+ // Continue if the Imported Package is unresolved of the package is optional and don't want optional packages
+ if (exporter == null || (!includeOptional && Constants.RESOLUTION_OPTIONAL.equals(importedPkgs[i]
+ .getDirective(Constants.RESOLUTION_DIRECTIVE))))
+ continue;
+ addBundleAndDependencies(exporter.getExporter(), bundleIds, includeOptional);
+ }
+ BundleDescription[] fragments = desc.getFragments();
+ for (int i = 0; i < fragments.length; i++) {
+ if (!fragments[i].isResolved())
+ continue;
+ String id = fragments[i].getSymbolicName();
+ if (!"org.eclipse.ui.workbench.compatibility".equals(id)) //$NON-NLS-1$
+ addBundleAndDependencies(fragments[i], bundleIds, includeOptional);
+ }
+ HostSpecification host = desc.getHost();
+ if (host != null)
+ addBundleAndDependencies((BundleDescription)host.getSupplier(), bundleIds, includeOptional);
+ }
+ }
+
+ public BundleDescription getBundleDescription(MavenProject project) {
+ String location = project.getFile().getParentFile().getAbsolutePath();
+ return state.getBundleByLocation(location);
+ }
+
+ public BundleDescription getBundleDescription(File location) {
+ String absolutePath = location.getAbsolutePath();
+ return state.getBundleByLocation(absolutePath);
+ }
+
+ private static void setUserProperty(BundleDescription desc, String name, Object value) {
+ Object userObject = desc.getUserObject();
+
+ if (userObject != null && !(userObject instanceof Map)) {
+ throw new IllegalStateException("Unexpected user object " + desc.toString());
+ }
+
+ Map props = (Map)userObject;
+ if (props == null) {
+ props = new HashMap();
+ desc.setUserObject(props);
+ }
+
+ props.put(name, value);
+ }
+
+ private static Object getUserProperty(BundleDescription desc, String name) {
+ Object userObject = desc.getUserObject();
+ if (userObject instanceof Map) {
+ return ((Map)userObject).get(name);
+ }
+ return null;
+ }
+
+ public MavenProject getMavenProject(BundleDescription desc) {
+ return (MavenProject)getUserProperty(desc, PROP_MAVEN_PROJECT);
+ }
+
+ public void assertResolved(BundleDescription desc) throws BundleException {
+ if (!desc.isResolved()) {
+ throw new BundleException("Bundle cannot be resolved: " + desc);
+ }
+ }
+
+ public String reportErrors(BundleDescription desc) {
+ StringBuffer msg = new StringBuffer();
+ msg.append("Bundle ").append(desc.getSymbolicName()).append(" cannot be resolved: \n");
+ BundleDescription[] bundles = state.getBundles();
+ int index = 0;
+ for (BundleDescription b : bundles) {
+ if (b.isResolved()) {
+ continue;
+ }
+ ResolverError[] errors = state.getResolverErrors(b);
+ if (errors.length > 0) {
+ msg.append(" ").append("[").append(index++).append("] ").append(b.getSymbolicName()).append("\n");
+ }
+ for (int i = 0; i < errors.length; i++) {
+ ResolverError error = errors[i];
+ msg.append(" -->").append(error).append("\n");
+ }
+ }
+ return msg.toString();
+ }
+
+ public String getManifestAttribute(BundleDescription desc, String attr) {
+ Dictionary mf = (Dictionary)getUserProperty(desc, PROP_MANIFEST);
+ if (mf != null) {
+ return (String)mf.get(attr);
+ }
+ return null;
+ }
+
+ private static File toFile(URL url) {
+ if (url.getProtocol().equals("file") == false) {
+ return null;
+ } else {
+ String filename = url.getFile().replace('/', File.separatorChar).replace("%20", " ");
+ return new File(filename);
+ }
+ }
+
+ /*
+ public static void main(String[] args) throws Exception {
+ BundleResolver resolver = new BundleResolver(new ConsoleLogger(Logger.LEVEL_INFO, "tuscany"));
+
+ String home = System.getProperty("user.home");
+ File jar =
+ new File(new File(home),
+ ".m2/repository/org/apache/tuscany/sca/tuscany-sca-api/1.4-EQUINOX-SNAPSHOT/tuscany-sca-api-1.4-EQUINOX-SNAPSHOT.jar");
+ BundleDescription bundle = resolver.addBundle(jar);
+ resolver.resolveState();
+ resolver.assertResolved(bundle);
+ }
+ */
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleUtil.java b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleUtil.java
new file mode 100644
index 0000000000..be8ee92fb6
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/java/org/apache/tuscany/sca/tools/maven/compiler/osgi/BundleUtil.java
@@ -0,0 +1,618 @@
+/*
+ * 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.tools.maven.compiler.osgi;
+
+import static org.osgi.framework.Constants.BUNDLE_CLASSPATH;
+import static org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION;
+import static org.osgi.framework.Constants.BUNDLE_NAME;
+import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
+import static org.osgi.framework.Constants.BUNDLE_VERSION;
+import static org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE;
+import static org.osgi.framework.Constants.EXPORT_PACKAGE;
+import static org.osgi.framework.Constants.IMPORT_PACKAGE;
+
+import java.io.BufferedInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.Version;
+
+/**
+ * Common functions used by the plugin.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class BundleUtil {
+
+ /**
+ * Returns the name of a bundle, or null if the given file is not a bundle.
+ *
+ * @param file
+ * @return
+ * @throws IOException
+ */
+ public static String getBundleSymbolicName(File file) throws IOException {
+ if (!file.exists()) {
+ return null;
+ }
+ String bundleName = null;
+ if (file.isDirectory()) {
+ File mf = new File(file, JarFile.MANIFEST_NAME);
+ if (!mf.isFile()) {
+ mf = new File(file, "../../" + JarFile.MANIFEST_NAME);
+ }
+ if (mf.isFile()) {
+ Manifest manifest = new Manifest(new FileInputStream(mf));
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ }
+ } else {
+ JarFile jar = new JarFile(file, false);
+ Manifest manifest = jar.getManifest();
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ jar.close();
+ }
+ if (bundleName == null) {
+ return bundleName;
+ }
+ int sc = bundleName.indexOf(';');
+ if (sc != -1) {
+ bundleName = bundleName.substring(0, sc);
+ }
+ return bundleName;
+ }
+
+ static Manifest getManifest(File file) throws IOException {
+ if (!file.exists()) {
+ return null;
+ }
+ Manifest manifest = null;
+ String bundleName = null;
+ if (file.isDirectory()) {
+ File mf = new File(file, JarFile.MANIFEST_NAME);
+ if (!mf.isFile()) {
+ mf = new File(file, "../../" + JarFile.MANIFEST_NAME);
+ }
+ if (mf.isFile()) {
+ manifest = new Manifest(new FileInputStream(mf));
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ }
+ } else {
+ JarFile jar = new JarFile(file, false);
+ manifest = jar.getManifest();
+ bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ jar.close();
+ }
+ if (bundleName != null) {
+ return manifest;
+ }
+
+ if (file.isFile()) {
+ Set<File> jars = new HashSet<File>();
+ jars.add(file);
+ String name = file.getName();
+ manifest = libraryManifest(jars, name, name, jarVersion(name), null);
+ }
+ return manifest;
+ }
+
+ /**
+ * Generate a Bundle manifest for a set of JAR files.
+ *
+ * @param jarFiles
+ * @param name
+ * @param symbolicName
+ * @param version
+ * @param dir
+ * @return
+ * @throws IllegalStateException
+ */
+ static Manifest libraryManifest(Set<File> jarFiles, String name, String symbolicName, String version, String dir)
+ throws IllegalStateException {
+ try {
+
+ // List exported packages and bundle classpath entries
+ StringBuffer classpath = new StringBuffer();
+ Set<String> exportedPackages = new HashSet<String>();
+ for (File jarFile : jarFiles) {
+ addPackages(jarFile, exportedPackages, version);
+ if (dir != null) {
+ classpath.append(dir).append("/");
+ classpath.append(jarFile.getName());
+ } else {
+ classpath.append("\"external:");
+ classpath.append(jarFile.getPath().replace(File.separatorChar, '/'));
+ classpath.append("\"");
+ }
+ classpath.append(",");
+ }
+
+ // Generate export-package and import-package declarations
+ StringBuffer exports = new StringBuffer();
+ StringBuffer imports = new StringBuffer();
+ Set<String> importedPackages = new HashSet<String>();
+ for (String export : exportedPackages) {
+
+ // Add export declaration
+ exports.append(export);
+ exports.append(',');
+
+ // Add corresponding import declaration
+ String packageName = packageName(export);
+ if (!importedPackages.contains(packageName)) {
+ importedPackages.add(packageName);
+ imports.append(packageName);
+ imports.append(',');
+ }
+ }
+
+ // Create a manifest
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.putValue("Manifest-Version", "1.0");
+ attributes.putValue(BUNDLE_MANIFESTVERSION, "2");
+ attributes.putValue(BUNDLE_SYMBOLICNAME, symbolicName);
+ attributes.putValue(BUNDLE_NAME, name);
+ attributes.putValue(BUNDLE_VERSION, version);
+ attributes.putValue(DYNAMICIMPORT_PACKAGE, "*");
+ if (exports.length() > 1) {
+ attributes.putValue(EXPORT_PACKAGE, exports.substring(0, exports.length() - 1));
+ }
+ if (imports.length() > 1) {
+ attributes.putValue(IMPORT_PACKAGE, imports.substring(0, imports.length() - 1));
+ }
+ if (classpath.length() > 1) {
+ attributes.putValue(BUNDLE_CLASSPATH, classpath.substring(0, classpath.length() - 1));
+ }
+
+ return manifest;
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Write a bundle manifest.
+ *
+ * @param manifest
+ * @param out
+ * @throws IOException
+ */
+ static void write(Manifest manifest, OutputStream out) throws IOException {
+ DataOutputStream dos = new DataOutputStream(out);
+ Attributes attributes = manifest.getMainAttributes();
+ write(attributes, "Manifest-Version", dos);
+ write(attributes, BUNDLE_MANIFESTVERSION, dos);
+ write(attributes, BUNDLE_SYMBOLICNAME, dos);
+ write(attributes, BUNDLE_NAME, dos);
+ write(attributes, BUNDLE_VERSION, dos);
+ write(attributes, DYNAMICIMPORT_PACKAGE, dos);
+ write(attributes, BUNDLE_CLASSPATH, dos);
+ write(attributes, IMPORT_PACKAGE, dos);
+ write(attributes, EXPORT_PACKAGE, dos);
+ dos.flush();
+ }
+
+ /**
+ * Add packages to be exported out of a JAR file.
+ *
+ * @param jarFile
+ * @param packages
+ * @throws IOException
+ */
+ private static void addPackages(File jarFile, Set<String> packages, String version) throws IOException {
+ if (getBundleSymbolicName(jarFile) == null) {
+ String ver = ";version=" + version;
+ addAllPackages(jarFile, packages, ver);
+ } else {
+ addExportedPackages(jarFile, packages);
+ }
+ }
+
+ /**
+ * Write manifest attributes.
+ *
+ * @param attributes
+ * @param key
+ * @param dos
+ * @throws IOException
+ */
+ private static void write(Attributes attributes, String key, DataOutputStream dos) throws IOException {
+ String value = attributes.getValue(key);
+ if (value == null) {
+ return;
+ }
+ StringBuffer line = new StringBuffer();
+ line.append(key);
+ line.append(": ");
+ line.append(new String(value.getBytes("UTF8")));
+ line.append("\r\n");
+ int l = line.length();
+ if (l > 72) {
+ for (int i = 70; i < l - 2;) {
+ line.insert(i, "\r\n ");
+ i += 72;
+ l += 3;
+ }
+ }
+ dos.writeBytes(line.toString());
+ }
+
+ /**
+ * Strip an OSGi export, only retain the package name and version.
+ *
+ * @param export
+ * @return
+ */
+ private static String stripExport(String export) {
+ int sc = export.indexOf(';');
+ if (sc == -1) {
+ return export;
+ }
+ String base = export.substring(0, sc);
+ int v = export.indexOf("version=");
+ if (v != -1) {
+ sc = export.indexOf(';', v + 1);
+ if (sc != -1) {
+ return base + ";" + export.substring(v, sc);
+ } else {
+ return base + ";" + export.substring(v);
+ }
+ } else {
+ return base;
+ }
+ }
+
+ /**
+ * Add all the packages out of a JAR.
+ *
+ * @param jarFile
+ * @param packages
+ * @param version
+ * @throws IOException
+ */
+ private static void addAllPackages(File jarFile, Set<String> packages, String version) throws IOException {
+ ZipInputStream is = new ZipInputStream(new FileInputStream(jarFile));
+ ZipEntry entry;
+ while ((entry = is.getNextEntry()) != null) {
+ String entryName = entry.getName();
+ if (!entry.isDirectory() && entryName != null
+ && entryName.length() > 0
+ && !entryName.startsWith(".")
+ && entryName.endsWith(".class") // Exclude resources from Export-Package
+ && entryName.lastIndexOf("/") > 0
+ && Character.isJavaIdentifierStart(entryName.charAt(0))) {
+ String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.');
+ if (!pkg.endsWith(".enum")) {
+ packages.add(pkg + version);
+ }
+ }
+ }
+ is.close();
+ }
+
+ /**
+ * Returns the name of the exported package in the given export.
+ * @param export
+ * @return
+ */
+ private static String packageName(String export) {
+ int sc = export.indexOf(';');
+ if (sc != -1) {
+ export = export.substring(0, sc);
+ }
+ return export;
+ }
+
+ /**
+ * Add the packages exported by a bundle.
+ *
+ * @param file
+ * @param packages
+ * @return
+ * @throws IOException
+ */
+ private static void addExportedPackages(File file, Set<String> packages) throws IOException {
+ if (!file.exists()) {
+ return;
+ }
+
+ // Read the export-package declaration and get a list of the packages available in a JAR
+ Set<String> existingPackages = null;
+ String exports = null;
+ if (file.isDirectory()) {
+ File mf = new File(file, "META-INF/MANIFEST.MF");
+ if (mf.isFile()) {
+ Manifest manifest = new Manifest(new FileInputStream(mf));
+ exports = manifest.getMainAttributes().getValue(EXPORT_PACKAGE);
+ }
+ } else {
+ JarFile jar = new JarFile(file, false);
+ Manifest manifest = jar.getManifest();
+ exports = manifest.getMainAttributes().getValue(EXPORT_PACKAGE);
+ jar.close();
+ existingPackages = new HashSet<String>();
+ addAllPackages(file, existingPackages, "");
+ }
+ if (exports == null) {
+ return;
+ }
+
+ // Parse the export-package declaration, and extract the individual packages
+ StringBuffer buffer = new StringBuffer();
+ boolean q = false;
+ for (int i = 0, n = exports.length(); i < n; i++) {
+ char c = exports.charAt(i);
+ if (c == '\"') {
+ q = !q;
+ }
+ if (!q) {
+ if (c == ',') {
+
+ // Add the exported package to the set, after making sure it really exists in
+ // the JAR
+ String export = buffer.toString();
+ if (existingPackages == null || existingPackages.contains(packageName(export))) {
+ packages.add(stripExport(export));
+ }
+ buffer = new StringBuffer();
+ continue;
+ }
+ }
+ buffer.append(c);
+ }
+ if (buffer.length() != 0) {
+
+ // Add the exported package to the set, after making sure it really exists in
+ // the JAR
+ String export = buffer.toString();
+ if (existingPackages == null || existingPackages.contains(packageName(export))) {
+ packages.add(stripExport(export));
+ }
+ }
+ }
+
+ /**
+ * starting with -, then some digits, then . or - or _, then some digits again
+ *
+ */
+ private static Pattern pattern = Pattern.compile("-(\\d)+((\\.|-|_)(\\d)+)*");
+
+ /**
+ * Returns the version number to use for the given JAR file.
+ *
+ * @param fileName
+ * @return
+ */
+ static String jarVersion(String fileName) {
+ String name = fileName;
+ int index = name.lastIndexOf('.');
+ if (index != -1) {
+ // Trim the extension
+ name = name.substring(0, index);
+ }
+
+ Matcher matcher = pattern.matcher(name);
+ String version = "0.0.0";
+ if (matcher.find()) {
+ version = matcher.group();
+ version = version.substring(1);
+ }
+ return version;
+ }
+
+ /**
+ * Convert the maven version into OSGi version
+ * @param mavenVersion
+ * @return
+ */
+ static String osgiVersion(String mavenVersion) {
+ ArtifactVersion ver = new DefaultArtifactVersion(mavenVersion);
+ String qualifer = ver.getQualifier();
+ if (qualifer != null) {
+ StringBuffer buf = new StringBuffer(qualifer);
+ for (int i = 0; i < buf.length(); i++) {
+ char c = buf.charAt(i);
+ if (Character.isLetterOrDigit(c) || c == '-' || c == '_') {
+ // Keep as-is
+ } else {
+ buf.setCharAt(i, '_');
+ }
+ }
+ qualifer = buf.toString();
+ }
+ Version osgiVersion =
+ new Version(ver.getMajorVersion(), ver.getMinorVersion(), ver.getIncrementalVersion(), qualifer);
+ String version = osgiVersion.toString();
+ return version;
+ }
+
+ private static String J2SE = "J2SE-";
+ private static String JAVASE = "JavaSE-";
+ private static String PROFILE_EXT = ".profile";
+
+ public static void loadVMProfile(Properties properties) {
+ Properties profileProps = findVMProfile(properties);
+ String systemExports = properties.getProperty(Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES);
+ // set the system exports property using the vm profile; only if the property is not already set
+ if (systemExports == null) {
+ systemExports = profileProps.getProperty(Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES);
+ if (systemExports != null)
+ properties.put(Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES, systemExports);
+ }
+ // set the org.osgi.framework.bootdelegation property according to the java profile
+ String type = properties.getProperty(Constants.OSGI_JAVA_PROFILE_BOOTDELEGATION); // a null value means ignore
+ String profileBootDelegation = profileProps.getProperty(Constants.OSGI_BOOTDELEGATION);
+ if (Constants.OSGI_BOOTDELEGATION_OVERRIDE.equals(type)) {
+ if (profileBootDelegation == null)
+ properties.remove(Constants.OSGI_BOOTDELEGATION); // override with a null value
+ else
+ properties.put(Constants.OSGI_BOOTDELEGATION, profileBootDelegation); // override with the profile value
+ } else if (Constants.OSGI_BOOTDELEGATION_NONE.equals(type))
+ properties.remove(Constants.OSGI_BOOTDELEGATION); // remove the bootdelegation property in case it was set
+ // set the org.osgi.framework.executionenvironment property according to the java profile
+ if (properties.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT) == null) {
+ // get the ee from the java profile; if no ee is defined then try the java profile name
+ String ee =
+ profileProps.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, profileProps
+ .getProperty(Constants.OSGI_JAVA_PROFILE_NAME));
+ if (ee != null)
+ properties.put(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, ee);
+ }
+ }
+
+ private static Properties findVMProfile(Properties properties) {
+ Properties result = new Properties();
+ // Find the VM profile name using J2ME properties
+ String j2meConfig = properties.getProperty(Constants.J2ME_MICROEDITION_CONFIGURATION);
+ String j2meProfiles = properties.getProperty(Constants.J2ME_MICROEDITION_PROFILES);
+ String vmProfile = null;
+ String javaEdition = null;
+ Version javaVersion = null;
+ if (j2meConfig != null && j2meConfig.length() > 0 && j2meProfiles != null && j2meProfiles.length() > 0) {
+ // save the vmProfile based off of the config and profile
+ // use the last profile; assuming that is the highest one
+ String[] j2meProfileList = ManifestElement.getArrayFromList(j2meProfiles, " ");
+ if (j2meProfileList != null && j2meProfileList.length > 0)
+ vmProfile = j2meConfig + '_' + j2meProfileList[j2meProfileList.length - 1];
+ } else {
+ // No J2ME properties; use J2SE properties
+ // Note that the CDC spec appears not to require VM implementations to set the
+ // javax.microedition properties!! So we will try to fall back to the
+ // java.specification.name property, but this is pretty ridiculous!!
+ String javaSpecVersion = properties.getProperty("java.specification.version");
+ // set the profile and EE based off of the java.specification.version
+ // TODO We assume J2ME Foundation and J2SE here. need to support other profiles J2EE ...
+ if (javaSpecVersion != null) {
+ StringTokenizer st = new StringTokenizer(javaSpecVersion, " _-");
+ javaSpecVersion = st.nextToken();
+ String javaSpecName = properties.getProperty("java.specification.name");
+ if ("J2ME Foundation Specification".equals(javaSpecName))
+ vmProfile = "CDC-" + javaSpecVersion + "_Foundation-" + javaSpecVersion; //$NON-NLS-2$
+ else {
+ // look for JavaSE if 1.6 or greater; otherwise look for J2SE
+ Version v16 = new Version("1.6");
+ javaEdition = J2SE;
+ try {
+ javaVersion = new Version(javaSpecVersion);
+ if (v16.compareTo(javaVersion) <= 0)
+ javaEdition = JAVASE;
+ } catch (IllegalArgumentException e) {
+ // do nothing
+ }
+ vmProfile = javaEdition + javaSpecVersion;
+ }
+ }
+ }
+ URL url = null;
+ // check for the java profile property for a url
+ String propJavaProfile = FrameworkProperties.getProperty(Constants.OSGI_JAVA_PROFILE);
+ if (propJavaProfile != null)
+ try {
+ // we assume a URL
+ url = new URL(propJavaProfile);
+ } catch (MalformedURLException e1) {
+ // try using a relative path in the system bundle
+ url = findInSystemBundle(propJavaProfile);
+ }
+ if (url == null && vmProfile != null) {
+ // look for a profile in the system bundle based on the vm profile
+ String javaProfile = vmProfile + PROFILE_EXT;
+ url = findInSystemBundle(javaProfile);
+ if (url == null)
+ url = getNextBestProfile(javaEdition, javaVersion);
+ }
+ if (url == null)
+ // the profile url is still null then use the osgi min profile in OSGi by default
+ url = findInSystemBundle("OSGi_Minimum-1.1.profile");
+ if (url != null) {
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ result.load(new BufferedInputStream(in));
+ } catch (IOException e) {
+ // TODO consider logging ...
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // do nothing
+ }
+ }
+ }
+ // set the profile name if it does not provide one
+ if (result.getProperty(Constants.OSGI_JAVA_PROFILE_NAME) == null)
+ if (vmProfile != null)
+ result.put(Constants.OSGI_JAVA_PROFILE_NAME, vmProfile.replace('_', '/'));
+ else
+ // last resort; default to the absolute minimum profile name for the framework
+ result.put(Constants.OSGI_JAVA_PROFILE_NAME, "OSGi/Minimum-1.1");
+ return result;
+ }
+
+ private static URL getNextBestProfile(String javaEdition, Version javaVersion) {
+ if (javaVersion == null || (javaEdition != J2SE && javaEdition != JAVASE))
+ return null; // we cannot automatically choose the next best profile unless this is a J2SE or JavaSE vm
+ URL bestProfile = findNextBestProfile(javaEdition, javaVersion);
+ if (bestProfile == null && javaEdition == JAVASE)
+ // if this is a JavaSE VM then search for a lower J2SE profile
+ bestProfile = findNextBestProfile(J2SE, javaVersion);
+ return bestProfile;
+ }
+
+ private static URL findNextBestProfile(String javaEdition, Version javaVersion) {
+ URL result = null;
+ int minor = javaVersion.getMinor();
+ do {
+ result = findInSystemBundle(javaEdition + javaVersion.getMajor() + "." + minor + PROFILE_EXT);
+ minor = minor - 1;
+ } while (result == null && minor > 0);
+ return result;
+ }
+
+ private static URL findInSystemBundle(String entry) {
+ ClassLoader loader = BundleUtil.class.getClassLoader();
+ return loader == null ? ClassLoader.getSystemResource(entry) : loader.getResource(entry);
+ }
+
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/resources/META-INF/plexus/components.xml b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000000..4332d3f205
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-eclipse-compiler/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<component-set>
+ <components>
+ <component>
+ <role>org.codehaus.plexus.compiler.Compiler</role>
+ <role-hint>tuscany-eclipse</role-hint>
+ <implementation>org.apache.tuscany.sca.tools.maven.compiler.JavaCompiler</implementation>
+ </component>
+ </components>
+</component-set>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/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/2.0-M1/tools/maven/maven-incremental-build/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/pom.xml
new file mode 100644
index 0000000000..1d50138a8d
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/pom.xml
@@ -0,0 +1,108 @@
+<?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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-incremental-build</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Incremental Build Generator Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-invoker</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-compiler-api</artifactId>
+ <version>1.5.3</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-compiler-manager</artifactId>
+ <version>1.5.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-compiler-javac</artifactId>
+ <version>1.5.3</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>LATEST</version>
+ <configuration>
+ <goalPrefix>incremental</goalPrefix>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/src/main/java/org/apache/tuscany/sca/tools/incremental/build/plugin/IncrementalBuildMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/src/main/java/org/apache/tuscany/sca/tools/incremental/build/plugin/IncrementalBuildMojo.java
new file mode 100644
index 0000000000..3a6870732b
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-incremental-build/src/main/java/org/apache/tuscany/sca/tools/incremental/build/plugin/IncrementalBuildMojo.java
@@ -0,0 +1,415 @@
+/*
+ * 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.tools.incremental.build.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.shared.invoker.DefaultInvocationRequest;
+import org.apache.maven.shared.invoker.InvocationResult;
+import org.apache.maven.shared.invoker.Invoker;
+import org.apache.maven.shared.invoker.MavenInvocationException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.cli.CommandLineException;
+
+/**
+ * @version $Rev$ $Date$
+ * @goal build
+ * @phase validate
+ * @requiresDependencyResolution test
+ * @description Incrementally build project modules that depend on modified modules.
+ */
+public class IncrementalBuildMojo extends AbstractMojo {
+
+ /**
+ * Keep track of modified projects.
+ */
+ private static Set<String> modifiedProjectIDs = new HashSet<String>();
+
+ /**
+ * The current user system settings for use in Maven.
+ *
+ * @parameter expression="${settings}"
+ * @required
+ * @readonly
+ */
+ private Settings settings;
+
+ /**
+ * Used to invoke Maven builds.
+ *
+ * @component
+ */
+ private Invoker invoker;
+
+ /**
+ * The target directory of the compiler if fork is true.
+ *
+ * @parameter expression="${project.build.directory}"
+ * @required
+ * @readonly
+ */
+ private File buildDirectory;
+
+ /**
+ * The project to create a build for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ private File outputFile;
+
+ public void execute() throws MojoExecutionException {
+ String projectID = id(project);
+ outputFile = getOutputFile();
+
+ File testMarkerFile = new File(project.getBasedir().getPath() + "/.test");
+
+ List<String> goals = new ArrayList<String>();
+ String type = project.getArtifact().getType();
+ if ("pom".equals(type)) {
+
+ // Always install pom modules
+ goals.add("install");
+
+ } else {
+
+ // Check if anything has changed in the project
+ boolean changed = false;
+ boolean testChanged = false;
+ boolean testFailed = false;
+ if (new File(project.getBasedir().getPath() + "/.modified").exists()) {
+ getLog().info("Found .modified marker file.");
+ changed = true;
+ } else {
+ changed = areSourcesStale() || areResourcesStale() || isPOMStale();
+ }
+ if (changed) {
+ modifiedProjectIDs.add(projectID);
+ } else {
+ testChanged = areTestSourcesStale() || areTestResourcesStale();
+ }
+
+ // Check if a project has compile dependencies on the modified projects
+ // and will need to be recompiled, or has runtime or test dependencies
+ // on the modified projects and needs to be retested
+ if (changed) {
+ goals.add("clean");
+ goals.add("install");
+ getLog().info("Project " + projectID + " has changed and will be recompiled.");
+
+ } else {
+ for (Artifact artifact : (List<Artifact>)project.getCompileArtifacts()) {
+ String artifactID = id(artifact);
+ if (modifiedProjectIDs.contains(artifactID)) {
+ getLog().info("Project " + projectID + " depends on modified project " + artifactID + " and will be recompiled.");
+ goals.add("clean");
+ goals.add("install");
+ break;
+ }
+ }
+
+ if (goals.isEmpty()) {
+ List<Artifact> artifacts = new ArrayList<Artifact>();
+ artifacts.addAll(project.getRuntimeArtifacts());
+ artifacts.addAll(project.getTestArtifacts());
+ for (Artifact artifact : artifacts) {
+ String artifactID = id(artifact);
+ if (modifiedProjectIDs.contains(artifactID)) {
+ getLog().info("Project " + projectID + " depends on modified project " + artifactID + " and will be retested.");
+ goals.add("test");
+ break;
+ }
+ }
+ }
+ }
+
+ if (testChanged && goals.isEmpty()) {
+ getLog().info("Project " + projectID + " has changed and will be retested.");
+ goals.add("test");
+ }
+
+ if (goals.isEmpty()) {
+ if (testMarkerFile.exists()) {
+ testFailed = true;
+ getLog().info("Project " + projectID + " contains failed tests and will be retested.");
+ goals.add("test");
+ }
+ }
+ }
+
+ // Invoke Maven with the necessary goals
+ if (!goals.isEmpty()) {
+ DefaultInvocationRequest request = new DefaultInvocationRequest();
+ request.setGoals(goals);
+ // FIXME: The maven invoker doesn't handle the directory names with spaces
+ // request.setLocalRepositoryDirectory(new File(localRepository.getBasedir()));
+ request.setInteractive(false);
+ request.setShowErrors(false);
+ request.setRecursive(false);
+ // request.setDebug(true);
+ request.setOffline(settings.isOffline());
+ request.setBaseDirectory(project.getBasedir());
+ request.setPomFile(project.getFile());
+
+ boolean success = false;
+ try {
+ try {
+ InvocationResult result = invoker.execute(request);
+
+ CommandLineException cle = result.getExecutionException();
+ if (cle != null) {
+ throw new MojoExecutionException(cle.getMessage(), cle);
+ }
+
+ int ec = result.getExitCode();
+ if (ec != 0) {
+ throw new MojoExecutionException("Maven invocation exit code: " + ec);
+ }
+
+ success = true;
+
+
+
+ } catch (MavenInvocationException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ } finally {
+
+ // Create or delete a .test marker file to keep track of the latest
+ // test result status and trigger testing again next time the build
+ // is run
+ if (!success) {
+ try {
+ if (!testMarkerFile.exists()) {
+ testMarkerFile.createNewFile();
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ } else {
+ if (testMarkerFile.exists()) {
+ testMarkerFile.delete();
+ }
+ }
+ }
+ } else {
+ getLog().info("The project is up-to-date. No build is required.");
+ }
+ }
+
+ private File getOutputFile() {
+ File basedir = buildDirectory;
+ String finalName = project.getBuild().getFinalName();
+ String classifier = project.getArtifact().getClassifier();
+ if (classifier == null) {
+ classifier = "";
+ } else if (classifier.trim().length() > 0 && !classifier.startsWith("-")) {
+ classifier = "-" + classifier;
+ }
+
+ String pkg = project.getPackaging();
+ if ("maven-plugin".equals(pkg)) {
+ pkg = "jar";
+ }
+ return new File(basedir, finalName + classifier + "." + pkg);
+ }
+
+ /**
+ * Test if any of the resources are stale
+ * @param resources
+ * @param outputDirectory
+ * @return
+ * @throws MojoExecutionException
+ */
+ private boolean areStale(List<Resource> resources, String outputDirectory) throws MojoExecutionException {
+
+ for (Resource resource: resources) {
+
+ File resourceDirectory = new File(resource.getDirectory());
+ if (!resourceDirectory.exists()) {
+ continue;
+ }
+
+ DirectoryScanner scanner = new DirectoryScanner();
+
+ scanner.setBasedir(resource.getDirectory());
+ if (resource.getIncludes() != null && !resource.getIncludes().isEmpty()) {
+ scanner.setIncludes((String[])resource.getIncludes().toArray(new String[]{}));
+ } else {
+ scanner.setIncludes(new String[]{"**/**"});
+ }
+ if (resource.getExcludes() != null && !resource.getExcludes().isEmpty()) {
+ scanner.setExcludes((String[])resource.getExcludes().toArray(new String[]{}));
+ }
+
+ scanner.addDefaultExcludes();
+ scanner.scan();
+
+ List<String> includedFiles = Arrays.asList(scanner.getIncludedFiles());
+ String targetPath = resource.getTargetPath();
+ for (String source: includedFiles) {
+ String target;
+ if (source.endsWith(".java")) {
+ target = source.substring(0, source.length() - 5) + ".class";
+ } else {
+ target = source;
+ }
+
+ String destination;
+ if (targetPath != null) {
+ destination = targetPath + "/" + target;
+ } else {
+ destination = target;
+ }
+
+ File sourceFile = new File(resource.getDirectory(), source);
+ File destinationFile = new File(outputDirectory, destination);
+
+ if (!destinationFile.exists()) {
+ getLog().info("Source file " + sourceFile + ".");
+ getLog().info("Target file " + destinationFile + " could not be found.");
+ return true;
+ } else {
+ if (sourceFile.lastModified() > destinationFile.lastModified()) {
+ getLog().info("Source file " + sourceFile + " has changed.");
+ getLog().info("Target file " + destinationFile + " is stale.");
+ return true;
+ } else if (sourceFile.lastModified() > outputFile.lastModified()) {
+ getLog().info("Source file " + sourceFile + " has changed.");
+ getLog().info("Target build output file " + outputFile + " is stale.");
+ return true;
+ } else if (outputFile.lastModified() == 0) {
+ getLog().info("Target build output file " + outputFile + " could not be found.");
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test if the POM resource is stale.
+ *
+ * @return
+ */
+ private boolean isPOMStale() {
+ File pom = project.getFile();
+ if (pom.lastModified() > outputFile.lastModified()) {
+ getLog().info("File " + pom + " has changed.");
+ getLog().info("Target build output file " + pom + " is stale.");
+ return true;
+ } else if (outputFile.lastModified() == 0) {
+ getLog().info("Target build output file " + outputFile + " could not be found.");
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Test if the project resources are stale.
+ *
+ * @return
+ * @throws MojoExecutionException
+ */
+ private boolean areResourcesStale() throws MojoExecutionException {
+ return areStale(project.getResources(), project.getBuild().getOutputDirectory());
+ }
+
+ /**
+ * Test if the project sources are stale.
+ *
+ * @return
+ * @throws MojoExecutionException
+ */
+ private boolean areSourcesStale() throws MojoExecutionException {
+ List<Resource> resources = new ArrayList<Resource>();
+ for (String root: (List<String>)project.getCompileSourceRoots()) {
+ if (new File(root).exists()) {
+ Resource resource = new Resource();
+ resource.setDirectory(root);
+ resource.addInclude("*.java");
+ resources.add(resource);
+ }
+ }
+ return areStale(resources, project.getBuild().getOutputDirectory());
+ }
+
+ /**
+ * Tests if the project test resources are stale.
+ *
+ * @return
+ * @throws MojoExecutionException
+ */
+ private boolean areTestResourcesStale() throws MojoExecutionException {
+ return areStale(project.getTestResources(), project.getBuild().getTestOutputDirectory());
+ }
+
+ /**
+ * Tests if the project test sources are stale.
+ *
+ * @return
+ * @throws MojoExecutionException
+ */
+ private boolean areTestSourcesStale() throws MojoExecutionException {
+ List<Resource> resources = new ArrayList<Resource>();
+ for (String root: (List<String>)project.getTestCompileSourceRoots()) {
+ if (new File(root).exists()) {
+ Resource resource = new Resource();
+ resource.setDirectory(root);
+ resources.add(resource);
+ }
+ }
+ return areStale(resources, project.getBuild().getTestOutputDirectory());
+ }
+
+ /**
+ * Returns the qualified id of a Maven artifact .
+ * @param p a Maven artifact
+ * @return a qualified id
+ */
+ private static String id(Artifact a) {
+ return a.getGroupId() + ':' + a.getArtifactId();
+ }
+
+ /**
+ * Returns the qualified id of a Maven project.
+ * @param p a Maven project
+ * @return a qualified id
+ */
+ private static String id(MavenProject p) {
+ return p.getGroupId() + ':' + p.getArtifactId();
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/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/2.0-M1/tools/maven/maven-java2wsdl/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/pom.xml
new file mode 100644
index 0000000000..a6ff3f411c
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/pom.xml
@@ -0,0 +1,45 @@
+<?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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-java2wsdl</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Java2WSDL Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-java2wsdl</artifactId>
+ <version>2.0-M1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/src/main/java/org/apache/tuscany/tools/java2wsdl/plugin/Java2WSDLGeneratorMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/src/main/java/org/apache/tuscany/tools/java2wsdl/plugin/Java2WSDLGeneratorMojo.java
new file mode 100644
index 0000000000..620e32a6fd
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-java2wsdl/src/main/java/org/apache/tuscany/tools/java2wsdl/plugin/Java2WSDLGeneratorMojo.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.tools.java2wsdl.plugin;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.axis2.description.java2wsdl.Java2WSDLConstants;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.tuscany.tools.java2wsdl.generate.Java2WSDLGeneratorFactory;
+import org.apache.ws.java2wsdl.utils.Java2WSDLCommandLineOption;
+
+/**
+ * @version $Rev$ $Date$
+ * @goal generate
+ * @phase generate-sources
+ * @description Generate WSDL from a given Java class / interface
+ */
+public class Java2WSDLGeneratorMojo extends AbstractMojo
+{
+
+ /**
+ * The name of the class for which the WSDL must be generated
+ * @parameter
+ *
+ */
+ private String sourceClassName;
+
+ /**
+ * The location where the WSDLs should be generated into
+ * @parameter expression="${project.build.directory}\\java2wsdl-wsdl"
+ */
+ private String targetLocation;
+
+ /**
+ * The name of the WSDL file
+ * @parameter
+ */
+ private String wsdlFilename;
+
+
+ /**
+ * Classpaths to be included
+ * @parameter
+ *
+ */
+ String[] classpaths;
+
+ /**
+ * The name of the service
+ * @parameter
+ */
+ private String serviceName;
+
+ /**
+ * The binding style for the service
+ * @parameter
+ */
+ private String bindingStyle;
+
+ /**
+ * The binding use option
+ * @parameter
+ */
+ private String bindingUse;
+
+ /**
+ * The soap address
+ * @parameter
+ */
+ private String soapAddress;
+
+ public void execute() throws MojoExecutionException
+ {
+ try
+ {
+ Java2WSDLGeneratorFactory.getInstance().createGenerator().generateWSDL(createOptionsMap ());
+ }
+ catch ( Exception e )
+ {
+ throw new MojoExecutionException("Exception in Java2WSDL Maven Plugin ", e);
+ }
+ }
+
+ protected Map createOptionsMap()
+ {
+ Map optionsMap = new Hashtable();
+
+ optionsMap.put(Java2WSDLConstants.CLASSNAME_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.CLASSNAME_OPTION, new String[]{sourceClassName}));
+
+ if ( targetLocation != null )
+ {
+ optionsMap.put(Java2WSDLConstants.OUTPUT_LOCATION_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.OUTPUT_LOCATION_OPTION, new String[]{targetLocation}));
+ }
+
+ if ( wsdlFilename != null )
+ {
+ optionsMap.put(Java2WSDLConstants.OUTPUT_FILENAME_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.OUTPUT_FILENAME_OPTION, new String[]{wsdlFilename}));
+ }
+
+ if ( classpaths != null && classpaths.length > 0 )
+ {
+ optionsMap.put(Java2WSDLConstants.CLASSPATH_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.CLASSPATH_OPTION, classpaths));
+ }
+
+ if ( serviceName != null )
+ {
+ optionsMap.put(Java2WSDLConstants.SERVICE_NAME_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.SERVICE_NAME_OPTION, new String[]{serviceName}));
+ }
+
+ if ( bindingStyle != null )
+ {
+ optionsMap.put(Java2WSDLConstants.STYLE_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.STYLE_OPTION, new String[]{bindingStyle}));
+ }
+
+ if ( bindingUse != null )
+ {
+ optionsMap.put(Java2WSDLConstants.USE_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.USE_OPTION, new String[]{bindingUse}));
+ }
+
+ if ( soapAddress != null )
+ {
+ optionsMap.put(Java2WSDLConstants.LOCATION_OPTION,
+ new Java2WSDLCommandLineOption(Java2WSDLConstants.LOCATION_OPTION, new String[]{soapAddress}));
+ }
+
+ return optionsMap;
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/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/2.0-M1/tools/maven/maven-osgi-junit/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/NOTICE
new file mode 100644
index 0000000000..51042eab05
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/pom.xml
new file mode 100644
index 0000000000..17b1ed337f
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-osgi-junit</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA OSGi JUnit Maven Plugin</name>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-booter</artifactId>
+ <version>2.4.3</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-toolchain</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-node-launcher-equinox</artifactId>
+ <version>2.0-M1</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/ForkConfiguration.java b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/ForkConfiguration.java
new file mode 100644
index 0000000000..30282c908b
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/ForkConfiguration.java
@@ -0,0 +1,239 @@
+package org.apache.tuscany.sca.maven.plugin.surefire;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.Commandline;
+import org.apache.maven.surefire.util.UrlUtils;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Derived from surefire-booter 2.4.3
+ * Configuration for forking tests.
+ *
+ */
+@SuppressWarnings("unchecked")
+public class ForkConfiguration {
+ public static final String FORK_ONCE = "once";
+
+ public static final String FORK_ALWAYS = "always";
+
+ public static final String FORK_NEVER = "never";
+
+ private String forkMode;
+
+ private boolean useSystemClassLoader;
+ private boolean useManifestOnlyJar;
+
+ private Properties systemProperties;
+
+ private String jvmExecutable;
+
+ private String argLine;
+
+ private Map environmentVariables;
+
+ private File workingDirectory;
+
+ private boolean debug;
+
+ private String debugLine;
+
+ public void setForkMode(String forkMode) {
+ if ("pertest".equalsIgnoreCase(forkMode)) {
+ this.forkMode = FORK_ALWAYS;
+ } else if ("none".equalsIgnoreCase(forkMode)) {
+ this.forkMode = FORK_NEVER;
+ } else if (forkMode.equals(FORK_NEVER) || forkMode.equals(FORK_ONCE) || forkMode.equals(FORK_ALWAYS)) {
+ this.forkMode = forkMode;
+ } else {
+ throw new IllegalArgumentException("Fork mode " + forkMode + " is not a legal value");
+ }
+ }
+
+ public boolean isForking() {
+ return !FORK_NEVER.equals(forkMode);
+ }
+
+ public void setUseSystemClassLoader(boolean useSystemClassLoader) {
+ this.useSystemClassLoader = useSystemClassLoader;
+ }
+
+ public boolean isUseSystemClassLoader() {
+ return useSystemClassLoader;
+ }
+
+ public void setSystemProperties(Properties systemProperties) {
+ this.systemProperties = (Properties)systemProperties.clone();
+ }
+
+ public void setJvmExecutable(String jvmExecutable) {
+ this.jvmExecutable = jvmExecutable;
+ }
+
+ public void setArgLine(String argLine) {
+ this.argLine = argLine;
+ }
+
+ public void setDebugLine(String debugLine) {
+ this.debugLine = debugLine;
+ }
+
+ public void setEnvironmentVariables(Map environmentVariables) {
+ this.environmentVariables = new HashMap(environmentVariables);
+ }
+
+ public void setWorkingDirectory(File workingDirectory) {
+ this.workingDirectory = workingDirectory;
+ }
+
+ public String getForkMode() {
+ return forkMode;
+ }
+
+ public Properties getSystemProperties() {
+ return systemProperties;
+ }
+
+ /**
+ * @throws SurefireBooterForkException
+ * @deprecated use the 2-arg alternative.
+ */
+ public Commandline createCommandLine(List classPath) throws SurefireBooterForkException {
+ return createCommandLine(classPath, false);
+ }
+
+ public Commandline createCommandLine(List classPath, boolean useJar) throws SurefireBooterForkException {
+ Commandline cli = new Commandline();
+
+ cli.setExecutable(jvmExecutable);
+
+ if (argLine != null) {
+ cli.createArg().setLine(argLine);
+ }
+
+ if (environmentVariables != null) {
+ Iterator iter = environmentVariables.keySet().iterator();
+
+ while (iter.hasNext()) {
+ String key = (String)iter.next();
+
+ String value = (String)environmentVariables.get(key);
+
+ cli.addEnvironment(key, value);
+ }
+ }
+
+ if (debugLine != null && !"".equals(debugLine)) {
+ cli.createArg().setLine(debugLine);
+ }
+
+ if (useJar) {
+ File jarFile;
+ try {
+ jarFile = createJar(classPath);
+ } catch (IOException e) {
+ throw new SurefireBooterForkException("Error creating archive file", e);
+ }
+
+ cli.createArg().setValue("-jar");
+
+ cli.createArg().setValue(jarFile.getAbsolutePath());
+ } else {
+ cli.createArg().setValue("-classpath");
+
+ cli.createArg().setValue(StringUtils.join(classPath.iterator(), File.pathSeparator));
+
+ cli.createArg().setValue(OSGiSurefireBooter.class.getName());
+ }
+
+ cli.setWorkingDirectory(workingDirectory.getAbsolutePath());
+
+ return cli;
+ }
+
+ /**
+ * Create a jar with just a manifest containing a Main-Class entry for SurefireBooter and a Class-Path entry
+ * for all classpath elements.
+ *
+ * @param classPath List&lt;String> of all classpath elements.
+ * @return
+ * @throws IOException
+ */
+ private File createJar(List classPath) throws IOException {
+ File file = File.createTempFile("surefirebooter", ".jar");
+ if (!debug) {
+ file.deleteOnExit();
+ }
+ FileOutputStream fos = new FileOutputStream(file);
+ JarOutputStream jos = new JarOutputStream(fos);
+ jos.setLevel(JarOutputStream.STORED);
+ JarEntry je = new JarEntry("META-INF/MANIFEST.MF");
+ jos.putNextEntry(je);
+
+ Manifest man = new Manifest();
+
+ // we can't use StringUtils.join here since we need to add a '/' to
+ // the end of directory entries - otherwise the jvm will ignore them.
+ String cp = "";
+ for (Iterator it = classPath.iterator(); it.hasNext();) {
+ String el = (String)it.next();
+ // NOTE: if File points to a directory, this entry MUST end in '/'.
+ cp += UrlUtils.getURL(new File(el)).toExternalForm() + " ";
+ }
+
+ man.getMainAttributes().putValue("Manifest-Version", "1.0");
+ man.getMainAttributes().putValue("Class-Path", cp.trim());
+ man.getMainAttributes().putValue("Main-Class", OSGiSurefireBooter.class.getName());
+
+ man.write(jos);
+ jos.close();
+
+ return file;
+ }
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ public boolean isDebug() {
+ return debug;
+ }
+
+ public void setUseManifestOnlyJar(boolean useManifestOnlyJar) {
+ this.useManifestOnlyJar = useManifestOnlyJar;
+ }
+
+ public boolean isUseManifestOnlyJar() {
+ return useManifestOnlyJar;
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefireBooter.java b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefireBooter.java
new file mode 100644
index 0000000000..2bc14d4241
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefireBooter.java
@@ -0,0 +1,984 @@
+package org.apache.tuscany.sca.maven.plugin.surefire;
+
+/*
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.maven.surefire.Surefire;
+import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.booter.SurefireExecutionException;
+import org.apache.maven.surefire.booter.output.FileOutputConsumerProxy;
+import org.apache.maven.surefire.booter.output.ForkingStreamConsumer;
+import org.apache.maven.surefire.booter.output.OutputConsumer;
+import org.apache.maven.surefire.booter.output.StandardOutputConsumer;
+import org.apache.maven.surefire.booter.output.SupressFooterOutputConsumerProxy;
+import org.apache.maven.surefire.booter.output.SupressHeaderOutputConsumerProxy;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.IOUtil;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.StringUtils;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.Commandline;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.StreamConsumer;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.apache.maven.surefire.util.NestedRuntimeException;
+import org.apache.tuscany.sca.node.equinox.launcher.EquinoxHost;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Derived from surefire-booter 2.4.3
+ */
+public class OSGiSurefireBooter {
+ private static final String TEST_SUITE_PROPERTY_PREFIX = "testSuite.";
+ private static final String REPORT_PROPERTY_PREFIX = "report.";
+ private static final String PARAMS_SUFIX = ".params";
+ private static final String TYPES_SUFIX = ".types";
+
+ /**
+ * A classloader that delegates an OSGi bundle
+ */
+ static class BundleClassLoader extends ClassLoader {
+ private Bundle bundle;
+
+ public BundleClassLoader(Bundle bundle, ClassLoader parent) {
+ super(parent);
+ this.bundle = bundle;
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ return bundle.loadClass(name);
+ }
+
+ @Override
+ protected URL findResource(String name) {
+ return bundle.getResource(name);
+ }
+
+ @Override
+ protected Enumeration<URL> findResources(String name) throws IOException {
+ return bundle.getResources(name);
+ }
+
+ }
+
+ private List reports = new ArrayList();
+
+ /**
+ * Test classpath
+ */
+ private List classPathUrls = new ArrayList();
+
+ /**
+ * surefire provider classpath
+ */
+ private List surefireClassPathUrls = new ArrayList();
+
+ /**
+ * surefire boot classpath
+ */
+ private List surefireBootClassPathUrls = new ArrayList();
+
+ private List testSuites = new ArrayList();
+
+ private boolean failIfNoTests = false;
+
+ private int forkedProcessTimeoutInSeconds = 0;
+
+ private boolean redirectTestOutputToFile = false;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ private ForkConfiguration forkConfiguration;
+
+ public static final int TESTS_SUCCEEDED_EXIT_CODE = 0;
+
+ public static final int TESTS_FAILED_EXIT_CODE = 255;
+
+ public static final int NO_TESTS_EXIT_CODE = 254;
+
+ private static Method assertionStatusMethod;
+
+ /**
+ * @deprecated because the OSGi classloader is really isolated - no parent.
+ */
+ private boolean childDelegation = true;
+
+ private File reportsDirectory;
+
+ /**
+ * This field is set to true if it's running from main. It's used to help decide what classloader to use.
+ */
+ private final boolean isForked;
+
+ /**
+ * Whether to enable assertions or not (can be affected by the fork arguments, and the ability to do so based on the
+ * JVM).
+ */
+ private boolean enableAssertions;
+
+ static {
+ try {
+ assertionStatusMethod =
+ ClassLoader.class.getMethod("setDefaultAssertionStatus", new Class[] {boolean.class});
+ } catch (NoSuchMethodException e) {
+ assertionStatusMethod = null;
+ }
+ }
+
+ public OSGiSurefireBooter() {
+ isForked = false;
+ }
+
+ private OSGiSurefireBooter(boolean isForked) {
+ this.isForked = isForked;
+ }
+
+ // ----------------------------------------------------------------------
+ // Accessors
+ // ----------------------------------------------------------------------
+
+ public void addReport(String report) {
+ addReport(report, null);
+ }
+
+ public void addReport(String report, Object[] constructorParams) {
+ reports.add(new Object[] {report, constructorParams});
+ }
+
+ public void addTestSuite(String suiteClassName, Object[] constructorParams) {
+ testSuites.add(new Object[] {suiteClassName, constructorParams});
+ }
+
+ public void addClassPathUrl(String path) {
+ if (!classPathUrls.contains(path)) {
+ classPathUrls.add(path);
+ }
+ }
+
+ public void addSurefireClassPathUrl(String path) {
+ if (!surefireClassPathUrls.contains(path)) {
+ surefireClassPathUrls.add(path);
+ }
+ }
+
+ public void addSurefireBootClassPathUrl(String path) {
+ if (!surefireBootClassPathUrls.contains(path)) {
+ surefireBootClassPathUrls.add(path);
+ }
+ }
+
+ /**
+ * Setting this to true will cause a failure if there are no tests to run
+ *
+ * @param redirectTestOutputToFile
+ */
+ public void setFailIfNoTests(boolean failIfNoTests) {
+ this.failIfNoTests = failIfNoTests;
+ }
+
+ /**
+ * When forking, setting this to true will make the test output to be saved in a file instead of showing it on the
+ * standard output
+ *
+ * @param redirectTestOutputToFile
+ */
+ public void setRedirectTestOutputToFile(boolean redirectTestOutputToFile) {
+ this.redirectTestOutputToFile = redirectTestOutputToFile;
+ }
+
+ /**
+ * Set the directory where reports will be saved
+ *
+ * @param reportsDirectory the directory
+ */
+ public void setReportsDirectory(File reportsDirectory) {
+ this.reportsDirectory = reportsDirectory;
+ }
+
+ /**
+ * Get the directory where reports will be saved
+ */
+ public File getReportsDirectory() {
+ return reportsDirectory;
+ }
+
+ public void setForkConfiguration(ForkConfiguration forkConfiguration) {
+ this.forkConfiguration = forkConfiguration;
+ }
+
+ public boolean isForking() {
+ return forkConfiguration.isForking();
+ }
+
+ public int run() throws SurefireBooterForkException, SurefireExecutionException {
+ int result;
+
+ if (ForkConfiguration.FORK_NEVER.equals(forkConfiguration.getForkMode())) {
+ result = runSuitesInProcess();
+ } else if (ForkConfiguration.FORK_ONCE.equals(forkConfiguration.getForkMode())) {
+ result = runSuitesForkOnce();
+ } else if (ForkConfiguration.FORK_ALWAYS.equals(forkConfiguration.getForkMode())) {
+ result = runSuitesForkPerTestSet();
+ } else {
+ throw new SurefireExecutionException("Unknown forkmode: " + forkConfiguration.getForkMode(), null);
+ }
+ return result;
+ }
+
+ private int runSuitesInProcess(String testSet, Properties results) throws SurefireExecutionException {
+ if (testSuites.size() != 1) {
+ throw new IllegalArgumentException("Cannot only specify testSet for single test suites");
+ }
+
+ // TODO: replace with plexus
+
+ // noinspection CatchGenericClass,OverlyBroadCatchBlock
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+ start();
+ try {
+ ClassLoader testsClassLoader =
+ useSystemClassLoader() ? ClassLoader.getSystemClassLoader() : createClassLoader(classPathUrls,
+ null,
+ childDelegation);
+
+ // TODO: assertions = true shouldn't be required for this CL if we had proper separation (see TestNG)
+ ClassLoader surefireClassLoader = createClassLoader(surefireClassPathUrls, testsClassLoader);
+
+ Class surefireClass = surefireClassLoader.loadClass(Surefire.class.getName());
+
+ Object surefire = surefireClass.newInstance();
+
+ Method run =
+ surefireClass.getMethod("run", new Class[] {List.class, Object[].class, String.class,
+ ClassLoader.class, ClassLoader.class, Properties.class,
+ Boolean.class});
+
+ Thread.currentThread().setContextClassLoader(testsClassLoader);
+
+ Integer result =
+ (Integer)run.invoke(surefire, new Object[] {reports, testSuites.get(0), testSet, surefireClassLoader,
+ testsClassLoader, results, new Boolean(failIfNoTests)});
+
+ return result.intValue();
+ } catch (InvocationTargetException e) {
+ throw new SurefireExecutionException(e.getTargetException().getMessage(), e.getTargetException());
+ } catch (Exception e) {
+ throw new SurefireExecutionException("Unable to instantiate and execute Surefire", e);
+ } finally {
+ stop();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ }
+ }
+
+ private int runSuitesInProcess() throws SurefireExecutionException {
+ // TODO: replace with plexus
+
+ // noinspection CatchGenericClass,OverlyBroadCatchBlock
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+ start();
+
+ try {
+ // The test classloader must be constructed first to avoid issues with commons-logging until we properly
+ // separate the TestNG classloader
+ ClassLoader testsClassLoader;
+ String testClassPath = getTestClassPathAsString();
+ System.setProperty("surefire.test.class.path", testClassPath);
+ if (useManifestOnlyJar()) {
+ // testsClassLoader = getClass().getClassLoader(); // ClassLoader.getSystemClassLoader()
+ testsClassLoader = createClassLoader(classPathUrls, null, childDelegation);
+ // SUREFIRE-459, trick the app under test into thinking its classpath was conventional (instead of a single manifest-only jar)
+ System.setProperty("surefire.real.class.path", System.getProperty("java.class.path"));
+ System.setProperty("java.class.path", testClassPath);
+ } else {
+ testsClassLoader = createClassLoader(classPathUrls, null, childDelegation);
+ }
+
+ ClassLoader surefireClassLoader = createClassLoader(surefireClassPathUrls, testsClassLoader);
+
+ Class surefireClass = surefireClassLoader.loadClass(Surefire.class.getName());
+
+ Object surefire = surefireClass.newInstance();
+
+ Method run =
+ surefireClass.getMethod("run", new Class[] {List.class, List.class, ClassLoader.class,
+ ClassLoader.class, Boolean.class});
+
+ Thread.currentThread().setContextClassLoader(testsClassLoader);
+
+ Integer result =
+ (Integer)run.invoke(surefire, new Object[] {reports, testSuites, surefireClassLoader, testsClassLoader,
+ new Boolean(failIfNoTests)});
+
+ return result.intValue();
+ } catch (InvocationTargetException e) {
+ throw new SurefireExecutionException(e.getTargetException().getMessage(), e.getTargetException());
+ } catch (Exception e) {
+ throw new SurefireExecutionException("Unable to instantiate and execute Surefire", e);
+ } finally {
+ stop();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ }
+ }
+
+ private String getTestClassPathAsString() {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < classPathUrls.size(); i++) {
+ sb.append(classPathUrls.get(i)).append(File.pathSeparatorChar);
+ }
+ return sb.toString();
+ }
+
+ private int runSuitesForkOnce() throws SurefireBooterForkException {
+ return forkSuites(testSuites, true, true);
+ }
+
+ private int runSuitesForkPerTestSet() throws SurefireBooterForkException {
+ ClassLoader testsClassLoader;
+ ClassLoader surefireClassLoader;
+ try {
+ testsClassLoader = createClassLoader(classPathUrls, null, false);
+ // TODO: assertions = true shouldn't be required if we had proper separation (see TestNG)
+ surefireClassLoader = createClassLoader(surefireClassPathUrls, testsClassLoader, false);
+ } catch (MalformedURLException e) {
+ throw new SurefireBooterForkException("Unable to create classloader to find test suites", e);
+ }
+
+ int globalResult = 0;
+
+ boolean showHeading = true;
+ Properties properties = new Properties();
+ for (Iterator i = testSuites.iterator(); i.hasNext();) {
+ Object[] testSuite = (Object[])i.next();
+
+ Map testSets = getTestSets(testSuite, testsClassLoader, surefireClassLoader);
+
+ for (Iterator j = testSets.keySet().iterator(); j.hasNext();) {
+ Object testSet = j.next();
+ boolean showFooter = !j.hasNext() && !i.hasNext();
+ int result = forkSuite(testSuite, testSet, showHeading, showFooter, properties);
+ if (result > globalResult) {
+ globalResult = result;
+ }
+ showHeading = false;
+ }
+ }
+
+ return globalResult;
+ }
+
+ private Map getTestSets(Object[] testSuite, ClassLoader testsClassLoader, ClassLoader surefireClassLoader)
+ throws SurefireBooterForkException {
+ String className = (String)testSuite[0];
+
+ Object[] params = (Object[])testSuite[1];
+
+ Object suite;
+ try {
+ suite = Surefire.instantiateObject(className, params, surefireClassLoader);
+ } catch (TestSetFailedException e) {
+ throw new SurefireBooterForkException(e.getMessage(), e.getCause());
+ } catch (ClassNotFoundException e) {
+ throw new SurefireBooterForkException("Unable to find class for test suite '" + className + "'", e);
+ } catch (NoSuchMethodException e) {
+ throw new SurefireBooterForkException("Unable to find appropriate constructor for test suite '" + className
+ + "': "
+ + e.getMessage(), e);
+ }
+
+ Map testSets;
+ try {
+ Method m = suite.getClass().getMethod("locateTestSets", new Class[] {ClassLoader.class});
+
+ testSets = (Map)m.invoke(suite, new Object[] {testsClassLoader});
+ } catch (IllegalAccessException e) {
+ throw new SurefireBooterForkException("Error obtaining test sets", e);
+ } catch (NoSuchMethodException e) {
+ throw new SurefireBooterForkException("Error obtaining test sets", e);
+ } catch (InvocationTargetException e) {
+ throw new SurefireBooterForkException(e.getTargetException().getMessage(), e.getTargetException());
+ }
+ return testSets;
+ }
+
+ private int forkSuites(List testSuites, boolean showHeading, boolean showFooter) throws SurefireBooterForkException {
+ Properties properties = new Properties();
+
+ setForkProperties(testSuites, properties);
+
+ return fork(properties, showHeading, showFooter);
+ }
+
+ private int forkSuite(Object[] testSuite,
+ Object testSet,
+ boolean showHeading,
+ boolean showFooter,
+ Properties properties) throws SurefireBooterForkException {
+ setForkProperties(Collections.singletonList(testSuite), properties);
+
+ if (testSet instanceof String) {
+ properties.setProperty("testSet", (String)testSet);
+ }
+
+ return fork(properties, showHeading, showFooter);
+ }
+
+ private void setForkProperties(List testSuites, Properties properties) {
+ addPropertiesForTypeHolder(reports, properties, REPORT_PROPERTY_PREFIX);
+ addPropertiesForTypeHolder(testSuites, properties, TEST_SUITE_PROPERTY_PREFIX);
+
+ for (int i = 0; i < classPathUrls.size(); i++) {
+ String url = (String)classPathUrls.get(i);
+ properties.setProperty("classPathUrl." + i, url);
+ }
+
+ for (int i = 0; i < surefireClassPathUrls.size(); i++) {
+ String url = (String)surefireClassPathUrls.get(i);
+ properties.setProperty("surefireClassPathUrl." + i, url);
+ }
+
+ properties.setProperty("childDelegation", String.valueOf(childDelegation));
+ properties.setProperty("enableAssertions", String.valueOf(enableAssertions));
+ properties.setProperty("useSystemClassLoader", String.valueOf(useSystemClassLoader()));
+ properties.setProperty("useManifestOnlyJar", String.valueOf(useManifestOnlyJar()));
+ properties.setProperty("failIfNoTests", String.valueOf(failIfNoTests));
+ properties.setProperty("mainBundleName", mainBundleName);
+ }
+
+ private File writePropertiesFile(String name, Properties properties) throws IOException {
+ File file = File.createTempFile(name, "tmp");
+ if (!forkConfiguration.isDebug()) {
+ file.deleteOnExit();
+ }
+
+ writePropertiesFile(file, name, properties);
+
+ return file;
+ }
+
+ private void writePropertiesFile(File file, String name, Properties properties) throws IOException {
+ FileOutputStream out = new FileOutputStream(file);
+
+ try {
+ properties.store(out, name);
+ } finally {
+ IOUtil.close(out);
+ }
+ }
+
+ private void addPropertiesForTypeHolder(List typeHolderList, Properties properties, String propertyPrefix) {
+ for (int i = 0; i < typeHolderList.size(); i++) {
+ Object[] report = (Object[])typeHolderList.get(i);
+
+ String className = (String)report[0];
+ Object[] params = (Object[])report[1];
+
+ properties.setProperty(propertyPrefix + i, className);
+
+ if (params != null) {
+ String paramProperty = convert(params[0]);
+ String typeProperty = params[0].getClass().getName();
+ for (int j = 1; j < params.length; j++) {
+ paramProperty += "|";
+ typeProperty += "|";
+ if (params[j] != null) {
+ paramProperty += convert(params[j]);
+ typeProperty += params[j].getClass().getName();
+ }
+ }
+ properties.setProperty(propertyPrefix + i + PARAMS_SUFIX, paramProperty);
+ properties.setProperty(propertyPrefix + i + TYPES_SUFIX, typeProperty);
+ }
+ }
+ }
+
+ private static String convert(Object param) {
+ if (param instanceof File[]) {
+ File[] files = (File[])param;
+ return "[" + StringUtils.join(files, ",") + "]";
+ } else if (param instanceof Properties) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ ((Properties)param).store(baos, "");
+ return new String(baos.toByteArray(), "8859_1");
+ } catch (Exception e) {
+ throw new RuntimeException("bug in property conversion", e);
+ }
+ } else {
+ return param.toString();
+ }
+ }
+
+ private final boolean useSystemClassLoader() {
+ return forkConfiguration.isUseSystemClassLoader() && (isForked || forkConfiguration.isForking());
+ }
+
+ private final boolean useManifestOnlyJar() {
+ return forkConfiguration.isUseSystemClassLoader() && forkConfiguration.isUseManifestOnlyJar();
+ }
+
+ private int fork(Properties properties, boolean showHeading, boolean showFooter) throws SurefireBooterForkException {
+ File surefireProperties;
+ File systemProperties = null;
+ try {
+ surefireProperties = writePropertiesFile("surefire", properties);
+ if (forkConfiguration.getSystemProperties() != null) {
+ systemProperties = writePropertiesFile("surefire", forkConfiguration.getSystemProperties());
+ }
+ } catch (IOException e) {
+ throw new SurefireBooterForkException("Error creating properties files for forking", e);
+ }
+
+ /*
+ System.out.println("cp: " + classPathUrls);
+ System.out.println("scp: " + surefireClassPathUrls);
+ System.out.println("sbcp: " + surefireBootClassPathUrls);
+ */
+
+ List bootClasspath = new ArrayList(surefireBootClassPathUrls.size() + classPathUrls.size());
+
+ bootClasspath.addAll(surefireBootClassPathUrls);
+
+ if (useSystemClassLoader()) {
+ bootClasspath.addAll(classPathUrls);
+ }
+
+ Commandline cli =
+ forkConfiguration.createCommandLine(bootClasspath, useManifestOnlyJar());
+
+ cli.createArg().setFile(surefireProperties);
+
+ if (systemProperties != null) {
+ cli.createArg().setFile(systemProperties);
+ }
+
+ ForkingStreamConsumer out = getForkingStreamConsumer(showHeading, showFooter, redirectTestOutputToFile);
+
+ StreamConsumer err;
+
+ if (redirectTestOutputToFile) {
+ err = out;
+ } else {
+ err = getForkingStreamConsumer(showHeading, showFooter, redirectTestOutputToFile);
+ }
+
+ if (forkConfiguration.isDebug()) {
+ System.out.println("Forking command line: " + cli);
+ }
+
+ int returnCode;
+
+ try {
+ returnCode =
+ org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.CommandLineUtils
+ .executeCommandLine(cli, out, err, forkedProcessTimeoutInSeconds);
+ } catch (org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.cli.CommandLineException e) {
+ throw new SurefireBooterForkException("Error while executing forked tests.", e);
+ }
+
+ if (redirectTestOutputToFile) {
+ // ensure the FileOutputConsumerProxy flushes/closes the output file
+ try {
+ out.getOutputConsumer().testSetCompleted();
+ } catch (Exception e) {
+ // the FileOutputConsumerProxy might throw an IllegalStateException but that's not of interest now
+ }
+ }
+
+ if (surefireProperties != null && surefireProperties.exists()) {
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(surefireProperties);
+
+ properties.load(inStream);
+ } catch (FileNotFoundException e) {
+ throw new SurefireBooterForkException("Unable to reload properties file from forked process", e);
+ } catch (IOException e) {
+ throw new SurefireBooterForkException("Unable to reload properties file from forked process", e);
+ } finally {
+ IOUtil.close(inStream);
+ }
+ }
+
+ return returnCode;
+ }
+
+ private ClassLoader createClassLoader(List classPathUrls, ClassLoader parent) throws MalformedURLException {
+ return createClassLoader(classPathUrls, parent, false);
+ }
+
+ private ClassLoader createClassLoader(List classPathUrls, ClassLoader parent, boolean childDelegation)
+ throws MalformedURLException {
+ Set<URL> urls = new HashSet<URL>();
+
+ for (Iterator i = classPathUrls.iterator(); i.hasNext();) {
+ String url = (String)i.next();
+
+ if (url != null) {
+ File f = new File(url);
+ urls.add(f.toURI().toURL());
+ }
+ }
+ return bundleClassLoader;
+ }
+
+ private static List processStringList(String stringList) {
+ String sl = stringList;
+
+ if (sl.startsWith("[") && sl.endsWith("]")) {
+ sl = sl.substring(1, sl.length() - 1);
+ }
+
+ List list = new ArrayList();
+
+ String[] stringArray = StringUtils.split(sl, ",");
+
+ for (int i = 0; i < stringArray.length; i++) {
+ list.add(stringArray[i].trim());
+ }
+ return list;
+ }
+
+ private static Properties loadProperties(File file) throws IOException {
+ Properties p = new Properties();
+
+ if (file != null && file.exists()) {
+ FileInputStream inStream = new FileInputStream(file);
+ try {
+ p.load(inStream);
+ } finally {
+ IOUtil.close(inStream);
+ }
+ }
+
+ return p;
+ }
+
+ private static void setSystemProperties(File file) throws IOException {
+ Properties p = loadProperties(file);
+
+ for (Iterator i = p.keySet().iterator(); i.hasNext();) {
+ String key = (String)i.next();
+
+ System.setProperty(key, p.getProperty(key));
+ }
+ }
+
+ private static Object[] constructParamObjects(String paramProperty, String typeProperty) {
+ Object[] paramObjects = null;
+ if (paramProperty != null) {
+ // bit of a glitch that it need sto be done twice to do an odd number of vertical bars (eg |||, |||||).
+ String[] params =
+ StringUtils.split(StringUtils.replace(StringUtils.replace(paramProperty, "||", "| |"), "||", "| |"),
+ "|");
+ String[] types =
+ StringUtils
+ .split(StringUtils.replace(StringUtils.replace(typeProperty, "||", "| |"), "||", "| |"), "|");
+
+ paramObjects = new Object[params.length];
+
+ for (int i = 0; i < types.length; i++) {
+ if (types[i].trim().length() == 0) {
+ params[i] = null;
+ } else if (types[i].equals(String.class.getName())) {
+ paramObjects[i] = params[i];
+ } else if (types[i].equals(File.class.getName())) {
+ paramObjects[i] = new File(params[i]);
+ } else if (types[i].equals(File[].class.getName())) {
+ List stringList = processStringList(params[i]);
+ File[] fileList = new File[stringList.size()];
+ for (int j = 0; j < stringList.size(); j++) {
+ fileList[j] = new File((String)stringList.get(j));
+ }
+ paramObjects[i] = fileList;
+ } else if (types[i].equals(ArrayList.class.getName())) {
+ paramObjects[i] = processStringList(params[i]);
+ } else if (types[i].equals(Boolean.class.getName())) {
+ paramObjects[i] = Boolean.valueOf(params[i]);
+ } else if (types[i].equals(Integer.class.getName())) {
+ paramObjects[i] = Integer.valueOf(params[i]);
+ } else if (types[i].equals(Properties.class.getName())) {
+ final Properties result = new Properties();
+ final String value = params[i];
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(value.getBytes("8859_1"));
+ result.load(bais);
+ } catch (Exception e) {
+ throw new RuntimeException("bug in property conversion", e);
+ }
+ paramObjects[i] = result;
+ } else {
+ // TODO: could attempt to construct with a String constructor if needed
+ throw new IllegalArgumentException("Unknown parameter type: " + types[i]);
+ }
+ }
+ }
+ return paramObjects;
+ }
+
+ /**
+ * This method is invoked when Surefire is forked - this method parses and organizes the arguments passed to it and
+ * then calls the Surefire class' run method. <p/> The system exit code will be 1 if an exception is thrown.
+ *
+ * @param args
+ */
+ public static void main(String[] args) throws Throwable {
+ // noinspection CatchGenericClass,OverlyBroadCatchBlock
+ try {
+ if (args.length > 1) {
+ setSystemProperties(new File(args[1]));
+ }
+
+ File surefirePropertiesFile = new File(args[0]);
+ Properties p = loadProperties(surefirePropertiesFile);
+
+ SortedMap classPathUrls = new TreeMap();
+
+ SortedMap surefireClassPathUrls = new TreeMap();
+
+ OSGiSurefireBooter surefireBooter = new OSGiSurefireBooter(true);
+
+ ForkConfiguration forkConfiguration = new ForkConfiguration();
+ forkConfiguration.setForkMode("never");
+ surefireBooter.setForkConfiguration(forkConfiguration);
+
+ for (Enumeration e = p.propertyNames(); e.hasMoreElements();) {
+ String name = (String)e.nextElement();
+
+ if (name.startsWith(REPORT_PROPERTY_PREFIX) && !name.endsWith(PARAMS_SUFIX)
+ && !name.endsWith(TYPES_SUFIX)) {
+ String className = p.getProperty(name);
+
+ String params = p.getProperty(name + PARAMS_SUFIX);
+ String types = p.getProperty(name + TYPES_SUFIX);
+ surefireBooter.addReport(className, constructParamObjects(params, types));
+ } else if (name.startsWith(TEST_SUITE_PROPERTY_PREFIX) && !name.endsWith(PARAMS_SUFIX)
+ && !name.endsWith(TYPES_SUFIX)) {
+ String className = p.getProperty(name);
+
+ String params = p.getProperty(name + PARAMS_SUFIX);
+ String types = p.getProperty(name + TYPES_SUFIX);
+ surefireBooter.addTestSuite(className, constructParamObjects(params, types));
+ } else if (name.startsWith("classPathUrl.")) {
+ classPathUrls.put(Integer.valueOf(name.substring(name.indexOf('.') + 1)), p.getProperty(name));
+ } else if (name.startsWith("surefireClassPathUrl.")) {
+ surefireClassPathUrls.put(Integer.valueOf(name.substring(name.indexOf('.') + 1)), p
+ .getProperty(name));
+ } else if (name.startsWith("surefireBootClassPathUrl.")) {
+ surefireBooter.addSurefireBootClassPathUrl(p.getProperty(name));
+ } else if ("childDelegation".equals(name)) {
+ surefireBooter.childDelegation = Boolean.valueOf(p.getProperty("childDelegation")).booleanValue();
+ } else if ("enableAssertions".equals(name)) {
+ surefireBooter.enableAssertions = Boolean.valueOf(p.getProperty("enableAssertions")).booleanValue();
+ } else if ("useSystemClassLoader".equals(name)) {
+ surefireBooter.forkConfiguration.setUseSystemClassLoader(Boolean.valueOf(p
+ .getProperty("useSystemClassLoader")).booleanValue());
+ } else if ("useManifestOnlyJar".equals(name)) {
+ surefireBooter.forkConfiguration.setUseManifestOnlyJar(Boolean.valueOf(p
+ .getProperty("useManifestOnlyJar")).booleanValue());
+ } else if ("failIfNoTests".equals(name)) {
+ surefireBooter.setFailIfNoTests(Boolean.valueOf(p.getProperty("failIfNoTests")).booleanValue());
+ } else if ("mainBundleName".equals(name)) {
+ surefireBooter.setMainBundleName(p.getProperty("mainBundleName"));
+ }
+ }
+
+ for (Iterator cpi = classPathUrls.keySet().iterator(); cpi.hasNext();) {
+ String url = (String)classPathUrls.get(cpi.next());
+ surefireBooter.addClassPathUrl(url);
+ }
+
+ for (Iterator scpi = surefireClassPathUrls.keySet().iterator(); scpi.hasNext();) {
+ String url = (String)surefireClassPathUrls.get(scpi.next());
+ surefireBooter.addSurefireClassPathUrl(url);
+ }
+
+ String testSet = p.getProperty("testSet");
+ int result;
+ if (testSet != null) {
+ result = surefireBooter.runSuitesInProcess(testSet, p);
+ } else {
+ result = surefireBooter.runSuitesInProcess();
+ }
+
+ surefireBooter.writePropertiesFile(surefirePropertiesFile, "surefire", p);
+
+ // noinspection CallToSystemExit
+ System.exit(result);
+ } catch (Throwable t) {
+ // Just throwing does getMessage() and a local trace - we want to call printStackTrace for a full trace
+ // noinspection UseOfSystemOutOrSystemErr
+ t.printStackTrace(System.err);
+ // noinspection ProhibitedExceptionThrown,CallToSystemExit
+ System.exit(1);
+ }
+ }
+
+ public void setChildDelegation(boolean childDelegation) {
+ this.childDelegation = childDelegation;
+ }
+
+ private ForkingStreamConsumer getForkingStreamConsumer(boolean showHeading,
+ boolean showFooter,
+ boolean redirectTestOutputToFile) {
+ OutputConsumer outputConsumer = new StandardOutputConsumer();
+
+ if (redirectTestOutputToFile) {
+ outputConsumer = new FileOutputConsumerProxy(outputConsumer, getReportsDirectory());
+ }
+
+ if (!showHeading) {
+ outputConsumer = new SupressHeaderOutputConsumerProxy(outputConsumer);
+ }
+ if (!showFooter) {
+ outputConsumer = new SupressFooterOutputConsumerProxy(outputConsumer);
+ }
+
+ return new ForkingStreamConsumer(outputConsumer);
+ }
+
+ public void setEnableAssertions(boolean enableAssertions) {
+ this.enableAssertions = enableAssertions;
+ }
+
+ public void setForkedProcessTimeoutInSeconds(int forkedProcessTimeoutInSeconds) {
+ this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
+ }
+
+ private String mainBundleName;
+
+ public void setMainBundleName(String mainBundleName) {
+ this.mainBundleName = mainBundleName;
+ }
+
+ private EquinoxHost host;
+ private BundleClassLoader bundleClassLoader;
+
+ public EquinoxHost start() {
+ Set<URL> urls = new HashSet<URL>();
+
+ // Merge the two classpaths so that all of them will be OSGi-enabled
+ Set<String> cps = new HashSet<String>(classPathUrls);
+ cps.addAll(surefireClassPathUrls);
+
+ for (String url: cps) {
+ if (url != null) {
+ File f = new File(url);
+ try {
+ urls.add(f.toURI().toURL());
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ host = new EquinoxHost(urls);
+ BundleContext context = host.start();
+ Bundle mainBundle = null;
+ for (Bundle bundle : context.getBundles()) {
+ // Fragement bundle cannot be used to load class, use the main bundle
+ if (mainBundleName.equals(bundle.getSymbolicName())) {
+ mainBundle = bundle;
+ break;
+ }
+ }
+
+ bundleClassLoader = new BundleClassLoader(mainBundle, null);
+ if (assertionStatusMethod != null) {
+ try {
+ Object[] args = new Object[] {enableAssertions ? Boolean.TRUE : Boolean.FALSE};
+ assertionStatusMethod.invoke(bundleClassLoader, args);
+ } catch (IllegalAccessException e) {
+ throw new NestedRuntimeException("Unable to access the assertion enablement method", e);
+ } catch (InvocationTargetException e) {
+ throw new NestedRuntimeException("Unable to invoke the assertion enablement method", e);
+ }
+ }
+
+ return host;
+ }
+
+ public void stop() {
+ if (host != null) {
+ host.stop();
+ host = null;
+ bundleClassLoader = null;
+ }
+ }
+
+ /**
+ * Returns a string representation of the given bundle.
+ *
+ * @param b
+ * @param verbose
+ * @return
+ */
+ static String string(Bundle bundle, boolean verbose) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(bundle.getBundleId()).append(" ").append(bundle.getSymbolicName());
+ int s = bundle.getState();
+ if ((s & Bundle.UNINSTALLED) != 0) {
+ sb.append(" UNINSTALLED");
+ }
+ if ((s & Bundle.INSTALLED) != 0) {
+ sb.append(" INSTALLED");
+ }
+ if ((s & Bundle.RESOLVED) != 0) {
+ sb.append(" RESOLVED");
+ }
+ if ((s & Bundle.STARTING) != 0) {
+ sb.append(" STARTING");
+ }
+ if ((s & Bundle.STOPPING) != 0) {
+ sb.append(" STOPPING");
+ }
+ if ((s & Bundle.ACTIVE) != 0) {
+ sb.append(" ACTIVE");
+ }
+
+ if (verbose) {
+ sb.append(" ").append(bundle.getLocation());
+ sb.append(" ").append(bundle.getHeaders());
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefirePlugin.java b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefirePlugin.java
new file mode 100644
index 0000000000..89cfdc38b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-osgi-junit/src/main/java/org/apache/tuscany/sca/maven/plugin/surefire/OSGiSurefirePlugin.java
@@ -0,0 +1,1306 @@
+/*
+ * 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.maven.plugin.surefire;
+
+import static org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION;
+import static org.osgi.framework.Constants.BUNDLE_NAME;
+import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
+import static org.osgi.framework.Constants.BUNDLE_VERSION;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.booter.SurefireExecutionException;
+import org.apache.maven.surefire.booter.shade.org.codehaus.plexus.util.StringUtils;
+import org.apache.maven.surefire.report.BriefConsoleReporter;
+import org.apache.maven.surefire.report.BriefFileReporter;
+import org.apache.maven.surefire.report.ConsoleReporter;
+import org.apache.maven.surefire.report.DetailedConsoleReporter;
+import org.apache.maven.surefire.report.FileReporter;
+import org.apache.maven.surefire.report.ForkingConsoleReporter;
+import org.apache.maven.surefire.report.XMLReporter;
+import org.apache.maven.toolchain.Toolchain;
+import org.apache.maven.toolchain.ToolchainManager;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/**
+ * Derived from maven-surefire-plugin 2.4.3
+ * Run tests using Surefire.
+ *
+ * @requiresDependencyResolution test
+ * @goal test
+ * @phase test
+ */
+public class OSGiSurefirePlugin extends AbstractMojo {
+
+ /**
+ * Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
+ * convenient on occasion.
+ *
+ * @parameter expression="${skipTests}"
+ * @since 2.4
+ */
+ protected boolean skipTests;
+
+ /**
+ * DEPRECATED This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
+ * Use -DskipTests instead; it's shorter.
+ *
+ * @deprecated
+ * @parameter expression="${maven.test.skip.exec}"
+ * @since 2.3
+ */
+ protected boolean skipExec;
+
+ /**
+ * Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
+ * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
+ * tests and compiling the tests. Consider using the skipTests parameter instead.
+ *
+ * @parameter expression="${maven.test.skip}"
+ */
+ protected boolean skip;
+
+ /**
+ * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
+ * occasion.
+ *
+ * @parameter expression="${maven.test.failure.ignore}"
+ */
+ protected boolean testFailureIgnore;
+
+ /**
+ * The base directory of the project being tested. This can be obtained in your unit test by
+ * System.getProperty("basedir").
+ *
+ * @parameter expression="${basedir}"
+ * @required
+ */
+ protected File basedir;
+
+ /**
+ * The directory containing generated test classes of the project being tested.
+ *
+ * @parameter expression="${project.build.testOutputDirectory}"
+ * @required
+ */
+ protected File testClassesDirectory;
+
+ /**
+ * The directory containing generated classes of the project being tested.
+ *
+ * @parameter expression="${project.build.outputDirectory}"
+ * @required
+ */
+ protected File classesDirectory;
+
+ /**
+ * The Maven Project Object
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ protected MavenProject project;
+
+ /**
+ * The classpath elements of the project being tested.
+ *
+ * @parameter expression="${project.testClasspathElements}"
+ * @required
+ * @readonly
+ */
+ protected List classpathElements;
+
+ /**
+ * Additional elements to be appended to the classpath.
+ *
+ * @parameter
+ * @since 2.4
+ */
+ protected List additionalClasspathElements;
+
+ /**
+ * Base directory where all reports are written to.
+ *
+ * @parameter expression="${project.build.directory}/surefire-osgi-reports"
+ */
+ protected File reportsDirectory;
+
+ /**
+ * The test source directory containing test class sources.
+ *
+ * @parameter expression="${project.build.testSourceDirectory}"
+ * @required
+ * @since 2.2
+ */
+ protected File testSourceDirectory;
+
+ /**
+ * Specify this parameter to run individual tests by file name, overriding the <code>includes/excludes</code>
+ * parameters. Each pattern you specify here will be used to create an
+ * include pattern formatted like <code>**&#47;${test}.java</code>, so you can just type "-Dtest=MyTest"
+ * to run a single test called "foo/MyTest.java". This parameter will override the TestNG suiteXmlFiles
+ * parameter.
+ *
+ * @parameter expression="${test}"
+ */
+ protected String test;
+
+ /**
+ * List of patterns (separated by commas) used to specify the tests that should be included in testing. When not
+ * specified and when the <code>test</code> parameter is not specified, the default includes will be
+ * <code>**&#47;Test*.java **&#47;*Test.java **&#47;*TestCase.java</code>. This parameter is ignored if
+ * TestNG suiteXmlFiles are specified.
+ *
+ * @parameter
+ */
+ protected List includes;
+
+ /**
+ * List of patterns (separated by commas) used to specify the tests that should be excluded in testing. When not
+ * specified and when the <code>test</code> parameter is not specified, the default excludes will be
+ * <code>**&#47;*$*</code> (which excludes all inner classes). This parameter is ignored if
+ * TestNG suiteXmlFiles are specified.
+ *
+ * @parameter
+ */
+ protected List excludes;
+
+ /**
+ * ArtifactRepository of the localRepository. To obtain the directory of localRepository in unit tests use
+ * System.setProperty( "localRepository").
+ *
+ * @parameter expression="${localRepository}"
+ * @required
+ * @readonly
+ */
+ protected ArtifactRepository localRepository;
+
+ /**
+ * List of System properties to pass to the JUnit tests.
+ *
+ * @parameter
+ */
+ protected Properties systemProperties;
+
+ /**
+ * List of properties for configuring all TestNG related configurations. This is the new
+ * preferred method of configuring TestNG.
+ *
+ * @parameter
+ * @since 2.4
+ */
+ protected Properties properties;
+
+ /**
+ * Map of of plugin artifacts.
+ *
+ * @parameter expression="${plugin.artifactMap}"
+ * @required
+ * @readonly
+ */
+ protected Map pluginArtifactMap;
+
+ /**
+ * @parameter expression="${plugin.groupId}"
+ * @required
+ * @readonly
+ */
+ protected String pluginGroupId;
+ /**
+ * @parameter expression="${plugin.artifactId}"
+ * @required
+ * @readonly
+ */
+ protected String pluginArtifactId;
+ /**
+ * @parameter expression="${plugin.version}"
+ * @required
+ * @readonly
+ */
+ protected String pluginVersion;
+
+ /**
+ * Map of of project artifacts.
+ *
+ * @parameter expression="${project.artifactMap}"
+ * @required
+ * @readonly
+ */
+ protected Map projectArtifactMap;
+
+ /**
+ * Option to print summary of test suites or just print the test cases that has errors.
+ *
+ * @parameter expression="${surefire.printSummary}" default-value="true"
+ */
+ protected boolean printSummary;
+
+ /**
+ * Selects the formatting for the test report to be generated. Can be set as brief or plain.
+ *
+ * @parameter expression="${surefire.reportFormat}" default-value="brief"
+ */
+ protected String reportFormat;
+
+ /**
+ * Option to generate a file test report or just output the test report to the console.
+ *
+ * @parameter expression="${surefire.useFile}" default-value="true"
+ */
+ protected boolean useFile;
+
+ /**
+ * When forking, set this to true to redirect the unit test standard output to a file (found in
+ * reportsDirectory/testName-output.txt).
+ *
+ * @parameter expression="${maven.test.redirectTestOutputToFile}" default-value="false"
+ * @since 2.3
+ */
+ protected boolean redirectTestOutputToFile;
+
+ /**
+ * Set this to "true" to cause a failure if there are no tests to run. Defaults to false.
+ *
+ * @parameter expression="${failIfNoTests}"
+ * @since 2.4
+ */
+ protected Boolean failIfNoTests;
+
+ /**
+ * Option to specify the forking mode. Can be "never", "once" or "always". "none" and "pertest" are also accepted
+ * for backwards compatibility.
+ *
+ * @parameter expression="${forkMode}" default-value="once"
+ * @since 2.1
+ */
+ protected String forkMode;
+
+ /**
+ * Option to specify the jvm (or path to the java executable) to use with the forking options. For the default, the
+ * jvm will be the same as the one used to run Maven.
+ *
+ * @parameter expression="${jvm}"
+ * @since 2.1
+ */
+ protected String jvm;
+
+ /**
+ * Arbitrary JVM options to set on the command line.
+ *
+ * @parameter expression="${argLine}"
+ * @since 2.1
+ */
+ protected String argLine;
+
+ /**
+ * Attach a debugger to the forked JVM. If set to "true", the process will suspend and
+ * wait for a debugger to attach on port 5005. If set to some other string, that
+ * string will be appended to the argLine, allowing you to configure arbitrary
+ * debuggability options (without overwriting the other options specified in the argLine).
+ *
+ * @parameter expression="${maven.surefire.debug}"
+ * @since 2.4
+ */
+ protected String debugForkedProcess;
+
+ /**
+ * Kill the forked test process after a certain number of seconds. If set to 0,
+ * wait forever for the process, never timing out.
+ *
+ * @parameter expression="${surefire.timeout}"
+ * @since 2.4
+ */
+ protected int forkedProcessTimeoutInSeconds;
+
+ /**
+ * Additional environments to set on the command line.
+ *
+ * @parameter
+ * @since 2.1.3
+ */
+ protected Map environmentVariables = new HashMap();
+
+ /**
+ * Command line working directory.
+ *
+ * @parameter expression="${basedir}"
+ * @since 2.1.3
+ */
+ protected File workingDirectory;
+
+ /**
+ * When false it makes tests run using the standard classloader delegation instead of the default Maven isolated
+ * classloader. Only used when forking (forkMode is not "none").<br/> Setting it to false helps with some problems
+ * caused by conflicts between xml parsers in the classpath and the Java 5 provider parser.
+ *
+ * @parameter expression="${childDelegation}" default-value="false"
+ * @since 2.1
+ */
+ protected boolean childDelegation;
+
+ /**
+ * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will be included
+ * in test run, if specified. This parameter is overridden if suiteXmlFiles are specified.
+ *
+ * @parameter expression="${groups}"
+ * @since 2.2
+ */
+ protected String groups;
+
+ /**
+ * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will specifically not be
+ * run. This parameter is overridden if suiteXmlFiles are specified.
+ *
+ * @parameter expression="${excludedGroups}"
+ * @since 2.2
+ */
+ protected String excludedGroups;
+
+ /**
+ * (TestNG only) List of TestNG suite xml file locations, seperated by commas. Note that suiteXmlFiles is incompatible
+ * with several other parameters on this plugin, like includes/excludes. This parameter is ignored if
+ * the "test" parameter is specified (allowing you to run a single test instead of an entire suite).
+ *
+ * @parameter
+ * @since 2.2
+ */
+ protected File[] suiteXmlFiles;
+
+ /**
+ * Allows you to specify the name of the JUnit artifact. If not set, <code>junit:junit</code> will be used.
+ *
+ * @parameter expression="${junitArtifactName}" default-value="junit:junit"
+ * @since 2.3.1
+ */
+ protected String junitArtifactName;
+
+ /**
+ * Allows you to specify the name of the TestNG artifact. If not set, <code>org.testng:testng</code> will be used.
+ *
+ * @parameter expression="${testNGArtifactName}" default-value="org.testng:testng"
+ * @since 2.3.1
+ */
+ protected String testNGArtifactName;
+
+ /**
+ * (TestNG only) The attribute thread-count allows you to specify how many threads should be allocated for this execution. Only
+ * makes sense to use in conjunction with parallel.
+ *
+ * @parameter expression="${threadCount}"
+ * @since 2.2
+ */
+ protected int threadCount;
+
+ /**
+ * (TestNG only) When you use the parallel attribute, TestNG will try to run all your test methods in separate threads, except for
+ * methods that depend on each other, which will be run in the same thread in order to respect their order of
+ * execution.
+ *
+ * @parameter expression="${parallel}"
+ * @todo test how this works with forking, and console/file output parallelism
+ * @since 2.2
+ */
+ protected String parallel;
+
+ /**
+ * Whether to trim the stack trace in the reports to just the lines within the test, or show the full trace.
+ *
+ * @parameter expression="${trimStackTrace}" default-value="true"
+ * @since 2.2
+ */
+ protected boolean trimStackTrace;
+
+ /**
+ * Resolves the artifacts needed.
+ *
+ * @component
+ */
+ protected ArtifactResolver artifactResolver;
+
+ /**
+ * Creates the artifact
+ *
+ * @component
+ */
+ protected ArtifactFactory artifactFactory;
+
+ /**
+ * The plugin remote repositories declared in the pom.
+ *
+ * @parameter expression="${project.pluginArtifactRepositories}"
+ * @since 2.2
+ */
+ protected List remoteRepositories;
+
+ /**
+ * For retrieval of artifact's metadata.
+ *
+ * @component
+ */
+ protected ArtifactMetadataSource metadataSource;
+
+ protected static final String BRIEF_REPORT_FORMAT = "brief";
+
+ protected static final String PLAIN_REPORT_FORMAT = "plain";
+
+ protected Properties originalSystemProperties;
+
+ /**
+ * Flag to disable the generation of report files in xml format.
+ *
+ * @parameter expression="${disableXmlReport}" default-value="false"
+ * @since 2.2
+ */
+ protected boolean disableXmlReport;
+
+ /**
+ * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
+ * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
+ * classloader. Default value is "true".
+ *
+ * @parameter expression="${surefire.useSystemClassLoader}"
+ * @since 2.3
+ */
+ protected Boolean useSystemClassLoader;
+
+ /**
+ * By default, Surefire forks your tests using a manifest-only jar; set this parameter
+ * to "false" to force it to launch your tests with a plain old Java classpath.
+ * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
+ * for a more detailed explanation of manifest-only jars and their benefits.)
+ *
+ * Default value is "true". Beware, setting this to "false" may cause your tests to
+ * fail on Windows if your classpath is too long.
+ *
+ * @parameter expression="${surefire.useManifestOnlyJar}" default-value="true"
+ * @since 2.4.3
+ */
+ protected boolean useManifestOnlyJar;
+
+ /**
+ * By default, Surefire enables JVM assertions for the execution of your test cases. To disable the assertions, set
+ * this flag to <code>false</code>.
+ *
+ * @parameter expression="${enableAssertions}" default-value="true"
+ * @since 2.3.1
+ */
+ protected boolean enableAssertions;
+
+ /**
+ * The current build session instance.
+ *
+ * @parameter expression="${session}"
+ * @required
+ * @readonly
+ */
+ protected MavenSession session;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (project.getPackaging().equals("pom")) {
+ return;
+ }
+
+ if (verifyParameters()) {
+ OSGiSurefireBooter surefireBooter = constructSurefireBooter();
+
+ Log log = getLog();
+ Set<String> jarFiles = new HashSet<String>();
+
+ /*
+ for (Object o : project.getArtifacts()) {
+ Artifact a = (Artifact)o;
+ if ("pom".equals(a.getType())) {
+ // Skip pom projects
+ continue;
+ }
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Adding: " + a);
+ }
+ jarFiles.add(a.getFile().toURI().toURL());
+ } catch (MalformedURLException e) {
+ getLog().error(e);
+ }
+ }
+ */
+
+ /*
+ * Add org.apache.tuscany.sca:tuscany-extensibility-osgi module
+ */
+ String aid = "tuscany-extensibility-equinox";
+ Artifact ext = getArtifact("org.apache.tuscany.sca", aid);
+ if (log.isDebugEnabled()) {
+ log.debug("Adding: " + ext);
+ }
+ jarFiles.add(ext.getFile().getAbsolutePath());
+
+
+ String name = project.getBuild().getFinalName();
+ String mainBundleName = null;
+ File mainJar = new File(project.getBuild().getDirectory(), name + "-osgi.jar");
+ File testJar = new File(project.getBuild().getDirectory(), name + "-osgi-tests.jar");
+ try {
+ Manifest manifest = createMainBundle();
+ mainBundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ int sc = mainBundleName.indexOf(';');
+ if (sc != -1) {
+ mainBundleName = mainBundleName.substring(0, sc);
+ }
+ generateJar(classesDirectory, mainJar, manifest);
+ Manifest testManifest = createTestFragment(manifest);
+ generateJar(testClassesDirectory, testJar, testManifest);
+ jarFiles.add(mainJar.getAbsolutePath());
+ jarFiles.add(testJar.getAbsolutePath());
+ } catch (IOException e) {
+ getLog().error(e);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Main bundle: " + mainBundleName);
+ }
+ surefireBooter.setMainBundleName(mainBundleName);
+ for (String url : jarFiles) {
+ surefireBooter.addClassPathUrl(url);
+ }
+
+ getLog().info("Surefire report directory: " + reportsDirectory);
+
+ int result;
+ try {
+ result = surefireBooter.run();
+ } catch (SurefireBooterForkException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ } catch (SurefireExecutionException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ if (originalSystemProperties != null && !surefireBooter.isForking()) {
+ // restore system properties, only makes sense when not forking..
+ System.setProperties(originalSystemProperties);
+ }
+
+ if (result == 0)
+ return;
+
+ String msg;
+
+ if (result == OSGiSurefireBooter.NO_TESTS_EXIT_CODE) {
+ if ((failIfNoTests == null) || !failIfNoTests.booleanValue())
+ return;
+ // TODO: i18n
+ throw new MojoFailureException(
+ "No tests were executed! (Set -DfailIfNoTests=false to ignore this error.)");
+ } else {
+ // TODO: i18n
+ msg =
+ "There are test failures.\n\nPlease refer to " + reportsDirectory
+ + " for the individual test results.";
+
+ }
+
+ if (testFailureIgnore) {
+ getLog().error(msg);
+ } else {
+ throw new MojoFailureException(msg);
+ }
+ }
+ }
+
+ protected boolean verifyParameters() throws MojoFailureException {
+ if (skip || skipTests || skipExec) {
+ getLog().info("Tests are skipped.");
+ return false;
+ }
+
+ if (!testClassesDirectory.exists()) {
+ if (failIfNoTests != null && failIfNoTests.booleanValue()) {
+ throw new MojoFailureException("No tests to run!");
+ }
+ getLog().info("No tests to run.");
+ return false;
+ }
+
+ if (useSystemClassLoader != null && ForkConfiguration.FORK_NEVER.equals(forkMode)) {
+ getLog().warn("useSystemClassloader setting has no effect when not forking");
+ }
+
+ return true;
+ }
+
+ /**
+ * Converts old TestNG configuration parameters over to new properties based configuration
+ * method. (if any are defined the old way)
+ */
+ private void convertTestNGParameters() {
+ if (properties == null) {
+ properties = new Properties();
+ }
+
+ if (this.parallel != null) {
+ properties.setProperty("parallel", this.parallel);
+ }
+ if (this.excludedGroups != null) {
+ properties.setProperty("excludegroups", this.excludedGroups);
+ }
+ if (this.groups != null) {
+ properties.setProperty("groups", this.groups);
+ }
+
+ if (this.threadCount > 0) {
+ properties.setProperty("threadcount", new Integer(this.threadCount).toString());
+ }
+ }
+
+ private OSGiSurefireBooter constructSurefireBooter() throws MojoExecutionException, MojoFailureException {
+ OSGiSurefireBooter surefireBooter = new OSGiSurefireBooter();
+
+ // Build up the surefire boot classpath
+ // * org.apache.tuscany.sca:tuscany-maven-surefire-osgi-plugin (non-transitive
+ // to exclude maven dependencies
+ // * org.apache.tuscany.sca:tuscany-node-launcher-equinox (transitive)
+ // * org.apache.maven.surefire:surefire-booter (transitive)
+ // Get the artifact for the OSGi surefire plugin
+ Artifact osgiArtifact =
+ artifactFactory.createArtifact(pluginGroupId,
+ pluginArtifactId,
+ pluginVersion,
+ Artifact.SCOPE_TEST,
+ "maven-plugin");
+ try {
+ artifactResolver.resolve(osgiArtifact, remoteRepositories, localRepository);
+ surefireBooter.addSurefireBootClassPathUrl(osgiArtifact.getFile().getAbsolutePath());
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to resolve " + osgiArtifact);
+ }
+
+ Artifact launcher = (Artifact) pluginArtifactMap.get("org.apache.tuscany.sca:tuscany-node-launcher-equinox");
+
+ // Look up the surefire-booter
+ Artifact surefireArtifact = (Artifact)pluginArtifactMap.get("org.apache.maven.surefire:surefire-booter");
+ if (surefireArtifact == null) {
+ throw new MojoExecutionException("Unable to locate surefire-booter in the list of plugin artifacts");
+ }
+
+ surefireArtifact.isSnapshot(); // TODO: this is ridiculous, but it fixes getBaseVersion to be -SNAPSHOT if
+ // needed
+
+ Artifact junitArtifact;
+ Artifact testNgArtifact;
+ try {
+ addArtifact(surefireBooter, surefireArtifact);
+ addArtifact(surefireBooter, launcher);
+
+ junitArtifact = (Artifact)projectArtifactMap.get(junitArtifactName);
+ // SUREFIRE-378, junit can have an alternate artifact name
+ if (junitArtifact == null && "junit:junit".equals(junitArtifactName)) {
+ junitArtifact = (Artifact)projectArtifactMap.get("junit:junit-dep");
+ }
+
+ // TODO: this is pretty manual, but I'd rather not require the plugin > dependencies section right now
+ testNgArtifact = (Artifact)projectArtifactMap.get(testNGArtifactName);
+
+ if (testNgArtifact != null) {
+ VersionRange range = VersionRange.createFromVersionSpec("[4.7,)");
+ if (!range.containsVersion(new DefaultArtifactVersion(testNgArtifact.getVersion()))) {
+ throw new MojoFailureException(
+ "TestNG support requires version 4.7 or above. You have declared version " + testNgArtifact
+ .getVersion());
+ }
+
+ convertTestNGParameters();
+
+ if (this.testClassesDirectory != null) {
+ properties.setProperty("testng.test.classpath", testClassesDirectory.getAbsolutePath());
+ }
+
+ addArtifact(surefireBooter, testNgArtifact);
+
+ // The plugin uses a JDK based profile to select the right testng. We might be explicity using a
+ // different one since its based on the source level, not the JVM. Prune using the filter.
+ addProvider(surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact);
+ } else if (junitArtifact != null && junitArtifact.getBaseVersion().startsWith("4")) {
+ addProvider(surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null);
+ } else {
+ // add the JUnit provider as default - it doesn't require JUnit to be present,
+ // since it supports POJO tests.
+ addProvider(surefireBooter, "surefire-junit", surefireArtifact.getBaseVersion(), null);
+ }
+ } catch (ArtifactNotFoundException e) {
+ throw new MojoExecutionException("Unable to locate required surefire provider dependency: " + e
+ .getMessage(), e);
+ } catch (InvalidVersionSpecificationException e) {
+ throw new MojoExecutionException("Error determining the TestNG version requested: " + e.getMessage(), e);
+ } catch (ArtifactResolutionException e) {
+ throw new MojoExecutionException("Error to resolving surefire provider dependency: " + e.getMessage(), e);
+ }
+
+ if (suiteXmlFiles != null && suiteXmlFiles.length > 0 && test == null) {
+ if (testNgArtifact == null) {
+ throw new MojoExecutionException("suiteXmlFiles is configured, but there is no TestNG dependency");
+ }
+
+ // TODO: properties should be passed in here too
+ surefireBooter.addTestSuite("org.apache.maven.surefire.testng.TestNGXmlTestSuite",
+ new Object[] {suiteXmlFiles, testSourceDirectory.getAbsolutePath(),
+ testNgArtifact.getVersion(), testNgArtifact.getClassifier(),
+ properties, reportsDirectory});
+ } else {
+ List includes;
+ List excludes;
+
+ if (test != null) {
+ // Check to see if we are running a single test. The raw parameter will
+ // come through if it has not been set.
+
+ // FooTest -> **/FooTest.java
+
+ includes = new ArrayList();
+
+ excludes = new ArrayList();
+
+ if (failIfNoTests == null) {
+ failIfNoTests = Boolean.TRUE;
+ }
+
+ String[] testRegexes = StringUtils.split(test, ",");
+
+ for (int i = 0; i < testRegexes.length; i++) {
+ String testRegex = testRegexes[i];
+ if (testRegex.endsWith(".java")) {
+ testRegex = testRegex.substring(0, testRegex.length() - 5);
+ }
+ // Allow paths delimited by '.' or '/'
+ testRegex = testRegex.replace('.', '/');
+ includes.add("**/" + testRegex + ".java");
+ }
+ } else {
+ includes = this.includes;
+
+ excludes = this.excludes;
+
+ // defaults here, qdox doesn't like the end javadoc value
+ // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
+ if (includes == null || includes.size() == 0) {
+ includes =
+ new ArrayList(Arrays
+ .asList(new String[] {"**/Test*.java", "**/*Test.java", "**/*TestCase.java"}));
+ }
+ if (excludes == null || excludes.size() == 0) {
+ excludes = new ArrayList(Arrays.asList(new String[] {"**/*$*"}));
+ }
+ }
+
+ if (testNgArtifact != null) {
+ surefireBooter.addTestSuite("org.apache.maven.surefire.testng.TestNGDirectoryTestSuite",
+ new Object[] {testClassesDirectory, includes, excludes,
+ testSourceDirectory.getAbsolutePath(),
+ testNgArtifact.getVersion(), testNgArtifact.getClassifier(),
+ properties, reportsDirectory});
+ } else {
+ String junitDirectoryTestSuite;
+ if (junitArtifact != null && junitArtifact.getBaseVersion() != null
+ && junitArtifact.getBaseVersion().startsWith("4")) {
+ junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
+ } else {
+ junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite";
+ }
+
+ // fall back to JUnit, which also contains POJO support. Also it can run
+ // classes compiled against JUnit since it has a dependency on JUnit itself.
+ surefireBooter.addTestSuite(junitDirectoryTestSuite, new Object[] {testClassesDirectory, includes,
+ excludes});
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ getLog().debug("Test Classpath :");
+
+ classpathElements.remove(classesDirectory.getAbsolutePath());
+ classpathElements.remove(testClassesDirectory.getAbsolutePath());
+ /*
+ // Check if we need to add configured classes/test classes directories here.
+ // If they are configured, we should remove the default to avoid conflicts.
+ if (!project.getBuild().getOutputDirectory().equals(classesDirectory.getAbsolutePath())) {
+ classpathElements.remove(project.getBuild().getOutputDirectory());
+ classpathElements.add(classesDirectory.getAbsolutePath());
+ }
+ if (!project.getBuild().getTestOutputDirectory().equals(testClassesDirectory.getAbsolutePath())) {
+ classpathElements.remove(project.getBuild().getTestOutputDirectory());
+ classpathElements.add(testClassesDirectory.getAbsolutePath());
+ }
+ */
+
+ for (Iterator i = classpathElements.iterator(); i.hasNext();) {
+ String classpathElement = (String)i.next();
+
+ getLog().debug(" " + classpathElement);
+
+ surefireBooter.addClassPathUrl(classpathElement);
+ }
+
+ Toolchain tc = getToolchain();
+
+ if (tc != null) {
+ getLog().info("Toolchain in surefire-plugin: " + tc);
+ if (ForkConfiguration.FORK_NEVER.equals(forkMode)) {
+ forkMode = ForkConfiguration.FORK_ONCE;
+ }
+ if (jvm != null) {
+ getLog().warn("Toolchains are ignored, 'executable' parameter is set to " + jvm);
+ } else {
+ jvm = tc.findTool("java"); //NOI18N
+ }
+ }
+
+ if (additionalClasspathElements != null) {
+ for (Iterator i = additionalClasspathElements.iterator(); i.hasNext();) {
+ String classpathElement = (String)i.next();
+
+ getLog().debug(" " + classpathElement);
+
+ surefireBooter.addClassPathUrl(classpathElement);
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Forking
+ // ----------------------------------------------------------------------
+
+ ForkConfiguration fork = new ForkConfiguration();
+
+ fork.setForkMode(forkMode);
+
+ processSystemProperties(!fork.isForking());
+
+ if (getLog().isDebugEnabled()) {
+ showMap(systemProperties, "system property");
+ }
+
+ if (fork.isForking()) {
+ useSystemClassLoader = useSystemClassLoader == null ? Boolean.TRUE : useSystemClassLoader;
+ fork.setUseSystemClassLoader(useSystemClassLoader.booleanValue());
+ fork.setUseManifestOnlyJar(useManifestOnlyJar);
+
+ fork.setSystemProperties(systemProperties);
+
+ if ("true".equals(debugForkedProcess)) {
+ debugForkedProcess =
+ "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
+ }
+
+ fork.setDebugLine(debugForkedProcess);
+
+ if (jvm == null || "".equals(jvm)) {
+ // use the same JVM as the one used to run Maven (the "java.home" one)
+ jvm = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
+ getLog().debug("Using JVM: " + jvm);
+ }
+
+ fork.setJvmExecutable(jvm);
+
+ if (workingDirectory != null) {
+ fork.setWorkingDirectory(workingDirectory);
+ } else {
+ fork.setWorkingDirectory(basedir);
+ }
+
+ fork.setArgLine(argLine);
+
+ fork.setEnvironmentVariables(environmentVariables);
+
+ if (getLog().isDebugEnabled()) {
+ showMap(environmentVariables, "environment variable");
+
+ fork.setDebug(true);
+ }
+
+ if (argLine != null) {
+ List args = Arrays.asList(argLine.split(" "));
+ if (args.contains("-da") || args.contains("-disableassertions")) {
+ enableAssertions = false;
+ }
+ }
+ }
+
+ surefireBooter.setFailIfNoTests(failIfNoTests == null ? false : failIfNoTests.booleanValue());
+
+ surefireBooter.setForkedProcessTimeoutInSeconds(forkedProcessTimeoutInSeconds);
+
+ surefireBooter.setRedirectTestOutputToFile(redirectTestOutputToFile);
+
+ surefireBooter.setForkConfiguration(fork);
+
+ surefireBooter.setChildDelegation(childDelegation);
+
+ surefireBooter.setEnableAssertions(enableAssertions);
+
+ surefireBooter.setReportsDirectory(reportsDirectory);
+
+ addReporters(surefireBooter, fork.isForking());
+
+ return surefireBooter;
+ }
+
+ private void showMap(Map map, String setting) {
+ for (Iterator i = map.keySet().iterator(); i.hasNext();) {
+ String key = (String)i.next();
+ String value = (String)map.get(key);
+ getLog().debug("Setting " + setting + " [" + key + "]=[" + value + "]");
+ }
+ }
+
+ private void addProvider(OSGiSurefireBooter surefireBooter,
+ String provider,
+ String version,
+ Artifact filteredArtifact) throws ArtifactNotFoundException, ArtifactResolutionException {
+ Artifact providerArtifact =
+ artifactFactory.createDependencyArtifact("org.apache.maven.surefire", provider, VersionRange
+ .createFromVersion(version), "jar", null, Artifact.SCOPE_TEST);
+ ArtifactResolutionResult result = resolveArtifact(filteredArtifact, providerArtifact);
+
+ for (Iterator i = result.getArtifacts().iterator(); i.hasNext();) {
+ Artifact artifact = (Artifact)i.next();
+
+ String key = ArtifactUtils.versionlessKey(artifact);
+ if("junit:junit".equals(key) || "jnuit:junit-dep".equals(key)) {
+ // Skip junit as it will be pulled from the test case dependencies
+ continue;
+ }
+ getLog().debug("Adding to surefire test classpath: " + artifact.getFile().getAbsolutePath());
+
+ surefireBooter.addSurefireClassPathUrl(artifact.getFile().getAbsolutePath());
+ }
+ }
+
+ private ArtifactResolutionResult resolveArtifact(Artifact filteredArtifact, Artifact providerArtifact)
+ throws ArtifactResolutionException, ArtifactNotFoundException {
+ ArtifactFilter filter = null;
+ if (filteredArtifact != null) {
+ filter =
+ new ExcludesArtifactFilter(Collections.singletonList(filteredArtifact.getGroupId() + ":"
+ + filteredArtifact.getArtifactId()));
+ }
+
+ Artifact originatingArtifact = artifactFactory.createBuildArtifact("dummy", "dummy", "1.0", "jar");
+
+ return artifactResolver.resolveTransitively(Collections.singleton(providerArtifact),
+ originatingArtifact,
+ localRepository,
+ remoteRepositories,
+ metadataSource,
+ filter);
+ }
+
+ private void addArtifact(OSGiSurefireBooter surefireBooter, Artifact surefireArtifact)
+ throws ArtifactNotFoundException, ArtifactResolutionException {
+ ArtifactResolutionResult result = resolveArtifact(null, surefireArtifact);
+
+ for (Iterator i = result.getArtifacts().iterator(); i.hasNext();) {
+ Artifact artifact = (Artifact)i.next();
+
+ getLog().debug("Adding to surefire booter test classpath: " + artifact.getFile().getAbsolutePath());
+
+ surefireBooter.addSurefireBootClassPathUrl(artifact.getFile().getAbsolutePath());
+ }
+ }
+
+ protected void processSystemProperties(boolean setInSystem) {
+ if (systemProperties == null) {
+ systemProperties = new Properties();
+ }
+
+ originalSystemProperties = (Properties)System.getProperties().clone();
+
+ // We used to take all of our system properties and dump them in with the
+ // user specified properties for SUREFIRE-121, causing SUREFIRE-491.
+ // Not gonna do THAT any more... but I'm leaving this code here in case
+ // we need it later when we try to fix SUREFIRE-121 again.
+
+ // Get the properties from the MavenSession instance to make embedded use work correctly
+ Properties userSpecifiedProperties = (Properties)session.getExecutionProperties().clone();
+ userSpecifiedProperties.putAll(systemProperties);
+ //systemProperties = userSpecifiedProperties;
+
+ systemProperties.setProperty("basedir", basedir.getAbsolutePath());
+ systemProperties.setProperty("user.dir", workingDirectory.getAbsolutePath());
+
+ systemProperties.setProperty("localRepository", localRepository.getBasedir());
+
+ if (setInSystem) {
+ // Add all system properties configured by the user
+ Iterator iter = systemProperties.keySet().iterator();
+
+ while (iter.hasNext()) {
+ String key = (String)iter.next();
+
+ String value = systemProperties.getProperty(key);
+
+ System.setProperty(key, value);
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Adds Reporters that will generate reports with different formatting.
+ * <p>
+ * The Reporter that will be added will be based on the value of the parameter useFile, reportFormat, and
+ * printSummary.
+ *
+ * @param surefireBooter The surefire booter that will run tests.
+ * @param forking
+ */
+ private void addReporters(OSGiSurefireBooter surefireBooter, boolean forking) {
+ Boolean trimStackTrace = Boolean.valueOf(this.trimStackTrace);
+ if (useFile) {
+ if (printSummary) {
+ if (forking) {
+ surefireBooter.addReport(ForkingConsoleReporter.class.getName(), new Object[] {trimStackTrace});
+ } else {
+ surefireBooter.addReport(ConsoleReporter.class.getName(), new Object[] {trimStackTrace});
+ }
+ }
+
+ if (BRIEF_REPORT_FORMAT.equals(reportFormat)) {
+ surefireBooter.addReport(BriefFileReporter.class.getName(), new Object[] {reportsDirectory,
+ trimStackTrace});
+ } else if (PLAIN_REPORT_FORMAT.equals(reportFormat)) {
+ surefireBooter.addReport(FileReporter.class.getName(), new Object[] {reportsDirectory, trimStackTrace});
+ }
+ } else {
+ if (BRIEF_REPORT_FORMAT.equals(reportFormat)) {
+ surefireBooter.addReport(BriefConsoleReporter.class.getName(), new Object[] {trimStackTrace});
+ } else if (PLAIN_REPORT_FORMAT.equals(reportFormat)) {
+ surefireBooter.addReport(DetailedConsoleReporter.class.getName(), new Object[] {trimStackTrace});
+ }
+ }
+
+ if (!disableXmlReport) {
+ surefireBooter.addReport(XMLReporter.class.getName(), new Object[] {reportsDirectory, trimStackTrace});
+ }
+ }
+
+ /**
+ * @return SurefirePlugin Returns the skipExec.
+ */
+ public boolean isSkipExec() {
+ return this.skipTests;
+ }
+
+ /**
+ * @param skipExec the skipExec to set
+ */
+ public void setSkipExec(boolean skipExec) {
+ this.skipTests = skipExec;
+ }
+
+ //TODO remove the part with ToolchainManager lookup once we depend on
+ //3.0.9 (have it as prerequisite). Define as regular component field then.
+ private Toolchain getToolchain() {
+ Toolchain tc = null;
+ try {
+ if (session != null) //session is null in tests..
+ {
+ ToolchainManager toolchainManager =
+ (ToolchainManager)session.getContainer().lookup(ToolchainManager.ROLE);
+ if (toolchainManager != null) {
+ tc = toolchainManager.getToolchainFromBuildContext("jdk", session);
+ }
+ }
+ } catch (ComponentLookupException componentLookupException) {
+ //just ignore, could happen in pre-3.0.9 builds..
+ }
+ return tc;
+ }
+
+ protected Artifact getArtifact(String groupId, String artifactId) throws MojoExecutionException {
+ Artifact artifact;
+ VersionRange vr;
+ try {
+ vr = VersionRange.createFromVersionSpec(project.getVersion());
+ } catch (InvalidVersionSpecificationException e1) {
+ vr = VersionRange.createFromVersion(project.getVersion());
+ }
+ artifact = artifactFactory.createDependencyArtifact(groupId, artifactId, vr, "jar", null, Artifact.SCOPE_TEST);
+
+ try {
+ artifactResolver.resolve(artifact, remoteRepositories, localRepository);
+ } catch (ArtifactResolutionException e) {
+ throw new MojoExecutionException("Unable to resolve artifact.", e);
+ } catch (ArtifactNotFoundException e) {
+ throw new MojoExecutionException("Unable to find artifact.", e);
+ }
+
+ return artifact;
+ }
+
+ private void generateJar(File root, File jar, Manifest mf) throws IOException {
+ getLog().info("Generating " + jar.toString());
+ FileOutputStream fos = new FileOutputStream(jar);
+ JarOutputStream jos = mf != null ? new JarOutputStream(fos, mf) : new JarOutputStream(fos);
+ addDir(jos, root, root);
+ jos.close();
+ }
+
+ /**
+ * Convert the maven version into OSGi version
+ * @param mavenVersion
+ * @return
+ */
+ static String osgiVersion(String mavenVersion) {
+ ArtifactVersion ver = new DefaultArtifactVersion(mavenVersion);
+ String qualifer = ver.getQualifier();
+ if (qualifer != null) {
+ StringBuffer buf = new StringBuffer(qualifer);
+ for (int i = 0; i < buf.length(); i++) {
+ char c = buf.charAt(i);
+ if (Character.isLetterOrDigit(c) || c == '-' || c == '_') {
+ // Keep as-is
+ } else {
+ buf.setCharAt(i, '_');
+ }
+ }
+ qualifer = buf.toString();
+ }
+ Version osgiVersion =
+ new Version(ver.getMajorVersion(), ver.getMinorVersion(), ver.getIncrementalVersion(), qualifer);
+ String version = osgiVersion.toString();
+ return version;
+ }
+
+ private Manifest createMainBundle() throws IOException {
+ File mf = new File(project.getBasedir(), "META-INF/MANIFEST.MF");
+ Manifest manifest = null;
+ if (mf.isFile()) {
+ manifest = new Manifest(new FileInputStream(mf));
+ String bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ if (bundleName != null) {
+ return manifest;
+ }
+ }
+ if (manifest == null) {
+ manifest = new Manifest();
+ }
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.putValue("Manifest-Version", "1.0");
+ attributes.putValue(BUNDLE_MANIFESTVERSION, "2");
+ attributes.putValue(BUNDLE_SYMBOLICNAME, project.getGroupId() + "." + project.getArtifactId());
+ attributes.putValue(BUNDLE_NAME, project.getName());
+ attributes.putValue(BUNDLE_VERSION, osgiVersion(project.getVersion()));
+ attributes.putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
+ return manifest;
+ }
+
+ private Manifest createTestFragment(Manifest mf) {
+ // Create a manifest
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.putValue("Manifest-Version", "1.0");
+ attributes.putValue(BUNDLE_MANIFESTVERSION, "2");
+ String host = mf.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
+ int sc = host.indexOf(';');
+ if (sc != -1) {
+ host = host.substring(0, sc);
+ }
+ attributes.putValue(BUNDLE_SYMBOLICNAME, host + ".tests");
+ attributes.putValue(BUNDLE_NAME, mf.getMainAttributes().getValue(BUNDLE_NAME) + " Tests");
+ attributes.putValue(BUNDLE_VERSION, mf.getMainAttributes().getValue(BUNDLE_VERSION));
+ attributes.putValue(Constants.FRAGMENT_HOST, host + ";bundle-version=\""
+ + mf.getMainAttributes().getValue(BUNDLE_VERSION)
+ + "\"");
+ // The main bundle may not have the dependency on JUNIT
+ attributes.putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
+ return manifest;
+ }
+
+ private void addDir(JarOutputStream jos, File root, File dir) throws IOException, FileNotFoundException {
+ for (File file : dir.listFiles()) {
+ if (file.isDirectory()) {
+ addDir(jos, root, file);
+ } else if (file.isFile()) {
+ // getLog().info(file.toString());
+ String uri = root.toURI().relativize(file.toURI()).toString();
+ if ("META-INF/MANIFEST.MF".equals(uri)) {
+ continue;
+ }
+ ZipEntry entry = new ZipEntry(uri);
+ jos.putNextEntry(entry);
+ byte[] buf = new byte[4096];
+ FileInputStream in = new FileInputStream(file);
+ for (;;) {
+ int len = in.read(buf);
+ if (len > 0) {
+ jos.write(buf, 0, len);
+ } else {
+ break;
+ }
+ }
+ in.close();
+ jos.closeEntry();
+ }
+ }
+ }
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/LICENSE
new file mode 100644
index 0000000000..6e529a25c4
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/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/2.0-M1/tools/maven/maven-web-junit/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/NOTICE
new file mode 100644
index 0000000000..51042eab05
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/pom.xml
new file mode 100644
index 0000000000..d8f910ed17
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/pom.xml
@@ -0,0 +1,52 @@
+<?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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-web-junit</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA Web JUnit Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.0-alpha2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitGeneratorMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitGeneratorMojo.java
new file mode 100644
index 0000000000..d1afe2c995
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitGeneratorMojo.java
@@ -0,0 +1,181 @@
+/*
+ * 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.tools.sca.web.junit.plugin;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @version $Rev$ $Date$
+ * @goal generate
+ * @phase process-resources
+ * @requiresDependencyResolution runtime
+ * @description Generate the web.xml and geronimo-web.xml
+ */
+public class WebJUnitGeneratorMojo extends AbstractMojo {
+ private final static String ASL_HEADER =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n<!--"
+ + "\n * Licensed to the Apache Software Foundation (ASF) under one"
+ + "\n * or more contributor license agreements. See the NOTICE file"
+ + "\n * distributed with this work for additional information"
+ + "\n * regarding copyright ownership. The ASF licenses this file"
+ + "\n * to you under the Apache License, Version 2.0 (the"
+ + "\n * \"License\"); you may not use this file except in compliance"
+ + "\n * with the License. You may obtain a copy of the License at"
+ + "\n * "
+ + "\n * http://www.apache.org/licenses/LICENSE-2.0"
+ + "\n * "
+ + "\n * Unless required by applicable law or agreed to in writing,"
+ + "\n * software distributed under the License is distributed on an"
+ + "\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY"
+ + "\n * KIND, either express or implied. See the License for the"
+ + "\n * specific language governing permissions and limitations"
+ + "\n * under the License. "
+ + "\n-->";
+
+ private final static String GERONIMO_WEB_XML =
+ ASL_HEADER + "\n<web-app xmlns=\"http://geronimo.apache.org/xml/ns/j2ee/web-2.0\""
+ + "\n xmlns:d=\"http://geronimo.apache.org/xml/ns/deployment-1.2\">"
+ // + "\n <context-root>${context.root}</context-root>"
+ + "\n <d:environment>"
+ + "\n <d:moduleId>"
+ + "\n <d:groupId>${groupId}</d:groupId>"
+ + "\n <d:artifactId>${artifactId}</d:artifactId>"
+ + "\n <d:version>${version}</d:version>"
+ + "\n <d:type>war</d:type>"
+ + "\n </d:moduleId>"
+ + "\n <d:inverse-classloading />"
+ + "\n </d:environment>"
+ + "\n</web-app>\n";
+
+ private final static String WEB_XML =
+ ASL_HEADER + "\n<!DOCTYPE web-app PUBLIC \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\" \"http://java.sun.com/dtd/web-app_2_3.dtd\">"
+ + "\n<web-app>"
+ + "\n <display-name>${display-name}</display-name>"
+ + "\n <filter>"
+ + "\n <filter-name>tuscany</filter-name>"
+ + "\n <filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter</filter-class>"
+ + "\n </filter>"
+ + "\n <filter>"
+ + "\n <filter-name>junit</filter-name>"
+ + "\n <filter-class>org.apache.tuscany.sca.host.webapp.junit.JUnitServletFilter</filter-class>"
+ + "\n <init-param>"
+ + "\n <param-name>junit.tests.path</param-name>"
+ + "\n <param-value>${junit.tests.path}</param-value>"
+ + "\n </init-param>"
+ + "\n </filter>"
+ + "\n <filter-mapping>"
+ + "\n <filter-name>tuscany</filter-name>"
+ + "\n <url-pattern>/*</url-pattern>"
+ + "\n </filter-mapping>"
+ + "\n <filter-mapping>"
+ + "\n <filter-name>junit</filter-name>"
+ + "\n <url-pattern>/junit/*</url-pattern>"
+ + "\n </filter-mapping>"
+ + "\n</web-app>\n";
+
+ /**
+ * @parameter
+ */
+ private String testsPath;
+
+ /**
+ * @parameter
+ */
+ private boolean geronimo;
+
+ /**
+ * The project to create a build for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ public void execute() throws MojoExecutionException {
+ File base =
+ new File(project.getBasedir(), "target" + File.separator
+ + project.getBuild().getFinalName()
+ + File.separator
+ + "WEB-INF");
+ base.mkdirs();
+ // Create the dir to work around the complaint from maven-war-plugin on non-existent folders
+ new File(project.getBasedir(), "target/classes/META-INF".replace('/', File.separatorChar)).mkdirs();
+ File webxml = new File(base, "web.xml");
+ getLog().info("Generating " + webxml.toString());
+
+ String name = project.getName();
+ if (name == null) {
+ name = project.getGroupId() + "-" + project.getArtifactId();
+ }
+ String content = setParameter(WEB_XML, "display-name", name);
+
+ if (testsPath == null) {
+ testsPath = "/WEB-INF/classes/";
+ }
+ content = setParameter(content, "junit.tests.path", testsPath);
+
+ try {
+ FileWriter writer = new FileWriter(webxml);
+ writer.append(content);
+ writer.close();
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+
+ if (geronimo) {
+ File geronimoxml = new File(base, "geronimo-web.xml");
+ getLog().info("Generating " + geronimoxml.toString());
+ content = setParameter(GERONIMO_WEB_XML, "groupId", project.getGroupId());
+ content = setParameter(content, "artifactId", project.getArtifactId());
+ content = setParameter(content, "version", project.getVersion());
+ // content = setParameter(content, "context.root", "/" + project.getBuild().getFinalName());
+ try {
+ geronimoxml.getParentFile().mkdirs();
+ FileWriter writer = new FileWriter(geronimoxml);
+ writer.append(content);
+ writer.close();
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+ // Workaround: maven-war-plugin doesn't like non-existing folders
+ // create target/test-classes
+ new File(project.getBasedir(), "target" + File.separator + "test-classes").mkdirs();
+
+ }
+
+ private String setParameter(String xml, String name, String value) {
+ String pattern = "${" + name + "}";
+ int index = xml.indexOf(pattern);
+ if (index != -1) {
+ String content = xml.substring(0, index) + value + xml.substring(index + pattern.length());
+ return content;
+ }
+ return xml;
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitMojo.java
new file mode 100644
index 0000000000..658d65d7c3
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-web-junit/src/main/java/org/apache/tuscany/tools/sca/web/junit/plugin/WebJUnitMojo.java
@@ -0,0 +1,205 @@
+/*
+ * 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.tools.sca.web.junit.plugin;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @version $Rev$ $Date$
+ * @goal test
+ * @phase integration-test
+ * @requiresDependencyResolution test
+ * @description Run the unit test over HTTP
+ */
+public class WebJUnitMojo extends AbstractMojo {
+ /**
+ * The project to create a build for.
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ /**
+ * The test cases to run
+ * @parameter
+ */
+ private String testCases[];
+
+ /**
+ * The URL for the web site
+ * @parameter
+ */
+ private String url;
+
+ /**
+ * Timeout for the HTTP connection
+ * @parameter
+ */
+ private int timeout = 300000; // 5 minutes
+
+ /**
+ * To avoid throwing exceptions because we want the stop container plugin to be executed
+ * @parameter
+ */
+ private boolean ignoreErrors = true;
+
+ public void execute() throws MojoExecutionException {
+ if (project.getPackaging().equals("pom")) {
+ return;
+ }
+
+ reset();
+
+ if (url == null) {
+ url = "http://localhost:8080/" + project.getBuild().getFinalName() + "/junit?op=runAll";
+ }
+
+ if (testCases != null) {
+ StringBuffer buf = new StringBuffer(url);
+ for (int i = 0; i < testCases.length; i++) {
+ if (i == 0) {
+ buf.append('?');
+ }
+ buf.append(testCases[i]);
+ if (i != testCases.length - 1) {
+ buf.append(',');
+ }
+ }
+ url = buf.toString();
+ }
+
+ getLog().info("Connecting to " + url);
+
+ int runs = 0, errors = 0, failures = 0;
+ String xml = "";
+
+ try {
+ HttpClient client = new DefaultHttpClient();
+ HttpGet httpget = new HttpGet(url);
+ httpget.getParams().setParameter("http.socket.timeout", new Integer(timeout));
+
+ // Execute HTTP request
+ HttpResponse response = client.execute(httpget);
+
+ StatusLine status = response.getStatusLine();
+ if (status.getStatusCode() != HttpStatus.SC_OK) {
+ if (!ignoreErrors) {
+ throw new MojoExecutionException(status.getStatusCode() + ": " + status.getReasonPhrase());
+ }
+ getLog().error(status.getStatusCode() + ": " + status.getReasonPhrase());
+ return;
+ }
+ Header header = response.getFirstHeader("junit.errors");
+ errors = header == null ? 0 : Integer.parseInt(header.getValue());
+ header = response.getFirstHeader("junit.failures");
+ failures = header == null ? 0 : Integer.parseInt(header.getValue());
+ header = response.getFirstHeader("junit.runs");
+ runs = header == null ? 0 : Integer.parseInt(header.getValue());
+ getLog().info("Runs: " + runs + ", Failures: " + failures + ", Errors: " + errors);
+
+ // Get hold of the response entity
+ HttpEntity entity = response.getEntity();
+
+ // If the response does not enclose an entity, there is no need
+ // to bother about connection release
+ if (entity != null) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
+ try {
+ StringBuffer sb = new StringBuffer();
+ while (true) {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ sb.append(line);
+ }
+ xml = sb.toString();
+ getLog().debug(xml);
+
+ } catch (IOException ex) {
+
+ // In case of an IOException the connection will be released
+ // back to the connection manager automatically
+ throw ex;
+
+ } catch (RuntimeException ex) {
+
+ // In case of an unexpected exception you may want to abort
+ // the HTTP request in order to shut down the underlying
+ // connection and release it back to the connection manager.
+ httpget.abort();
+ throw ex;
+
+ } finally {
+
+ // Closing the input stream will trigger connection release
+ reader.close();
+
+ }
+
+ }
+ } catch (Exception e) {
+ if (!ignoreErrors) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ getLog().error(e);
+ }
+ if (errors != 0 || failures != 0) {
+ if (!ignoreErrors) {
+ throw new MojoExecutionException(xml);
+ }
+ getLog().error(xml);
+ }
+
+ }
+
+ /**
+ * A workaround to avoid logging conflict with Geronimo
+ */
+ private static void reset() {
+ LogFactory.releaseAll();
+
+ // Restore a reasonable default log impl
+ System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
+
+ // Make SimpleLog look more like Maven logs
+ System.setProperty("org.apache.commons.logging.simplelog.showShortLogname", "false");
+
+ // Restore default Geronimo bootstrap behavior
+ System.getProperties().remove("geronimo.bootstrap.logging.enabled");
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/LICENSE b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/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/2.0-M1/tools/maven/maven-wsdl2java/NOTICE b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/pom.xml b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/pom.xml
new file mode 100644
index 0000000000..0ce2fdcbaa
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/pom.xml
@@ -0,0 +1,45 @@
+<?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-sca-maven-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-maven-wsdl2java</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Tuscany SCA WSDL2Java Maven Plugin</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-wsdl2java</artifactId>
+ <version>2.0-M1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDL2JavaGeneratorMojo.java b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDL2JavaGeneratorMojo.java
new file mode 100644
index 0000000000..8021692521
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDL2JavaGeneratorMojo.java
@@ -0,0 +1,152 @@
+/*
+ * 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.tools.wsdl2java.plugin;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.tuscany.tools.wsdl2java.generate.WSDL2JavaGenerator;
+
+/**
+ * @version $Rev$ $Date$
+ * @goal generate
+ * @phase generate-sources
+ * @description Generate SDO interface classes from an XML Schema
+ */
+public class WSDL2JavaGeneratorMojo extends AbstractMojo {
+ /**
+ * The directory containing WSDL files; defaults to ${basedir}/src/main/wsdl
+ * @parameter expression="${basedir}/src/main/wsdl"
+ */
+ private String wsdlDir;
+
+ /**
+ * Name of the WSDL file; if omitted all files in the directory are processed
+ * @parameter
+ */
+ private File wsdlFile;
+
+ /**
+ * The Java package to generate into. By default the value is derived from the schema URI.
+ *
+ * @parameter
+ */
+ private String javaPackage;
+
+ /**
+ * The directory to generate into; defaults to ${project.build.directory}/wsdl2java-source
+ *
+ * @parameter expression="${project.build.directory}/wsdl2java-source"
+ */
+ private String targetDirectory;
+
+ /**
+ * The directory to generate into; defaults to ${project.build.directory}/wsdl2java-source
+ *
+ * @parameter
+ */
+ private WSDLFileOption[] wsdlFiles;
+
+ /**
+ * @parameter expression="${project.compileSourceRoots}"
+ * @readonly
+ */
+ private List compilerSourceRoots;
+
+ public void execute() throws MojoExecutionException {
+
+ if(null != wsdlFiles){
+ for(int i=0; i< wsdlFiles.length ; ++i ){
+ System.err.println("wsdlFiles" + wsdlFiles[i].getFileName());
+ WSDLFileOption wf = wsdlFiles[i];
+
+ if(null == wf.getTargetDirectory())
+ wf.setTargetDirectory(targetDirectory);
+ if(null == wf.getJavaPackage()){
+ wf.setJavaPackage(javaPackage);
+ }
+ if(wf.getFileName() == null || wf.getFileName().length() ==0){
+ throw new MojoExecutionException("no fileName specfied for wsdl.");
+ }
+ if(!wf.getFileName().canRead() || !wf.getFileName().isFile()){
+
+ throw new MojoExecutionException("file can not be read:"+wf.getFileName());
+ }
+
+ }
+ }else{
+
+
+
+ if (wsdlFile == null) {
+
+ File[] files = new File(wsdlDir).listFiles(FILTER);
+
+ wsdlFiles= new WSDLFileOption[files.length];
+ for(int i= files.length -1; i> -1; --i){
+
+
+ wsdlFiles[i] = new WSDLFileOption();
+ wsdlFiles[i].setFileName(files[i]);
+ wsdlFiles[i].setJavaPackage(javaPackage);
+ wsdlFiles[i].setPorts(null);
+ wsdlFiles[i].setTargetDirectory(targetDirectory);
+
+
+ }
+
+ } else {
+ wsdlFiles= new WSDLFileOption[]{new WSDLFileOption()};
+ wsdlFiles[0].setFileName(wsdlFile);
+ wsdlFiles[0].setJavaPackage(javaPackage);
+ wsdlFiles[0].setPorts(null);
+ wsdlFiles[0].setTargetDirectory(targetDirectory);
+ }
+ }
+
+ int genOptions = 0;
+
+ for (int i = 0; i < wsdlFiles.length; i++) {
+ File file = wsdlFiles[i].getFileName();
+ File marker = new File(targetDirectory, ".gen#" + file.getName()+".wsdl2java");
+ if (file.lastModified() > marker.lastModified()) {
+ getLog().info("Generating Java service interfaces from " + file);
+ WSDL2JavaGenerator.generateFromWSDL(file.toString(), wsdlFiles[i].getPorts(), wsdlFiles[i].getTargetDirectory(), wsdlFiles[i].getJavaPackage(), null, genOptions);
+ }
+ try {
+ marker.createNewFile();
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ marker.setLastModified(System.currentTimeMillis());
+ }
+
+ compilerSourceRoots.add(targetDirectory);
+ }
+
+ private static final FileFilter FILTER = new FileFilter() {
+ public boolean accept(File pathname) {
+ return (pathname.isFile() || !pathname.isHidden());
+ }
+ };
+} \ No newline at end of file
diff --git a/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDLFileOption.java b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDLFileOption.java
new file mode 100644
index 0000000000..cc10c351b1
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/maven-wsdl2java/src/main/java/org/apache/tuscany/tools/wsdl2java/plugin/WSDLFileOption.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.tools.wsdl2java.plugin;
+
+import java.io.File;
+
+public class WSDLFileOption {
+ /**
+ * Name of the WSDL file; if omitted all files in the directory are processed
+ *
+ */
+ private File fileName;
+
+ /**
+ * The Java package to generate into. By default the value is derived from the schema URI.
+ *
+ *
+ */
+ private String javaPackage;
+
+ /**
+ * The directory to generate into; defaults to ${project.build.directory}/wsdl2java-source
+ *
+ *
+ */
+ private String targetDirectory;
+
+ /**
+ * @parameter expression="${project.compileSourceRoots}"
+ * @readonly
+ */
+
+ private String ports[];
+
+ /**
+ * @parameter expression="${project.compileSourceRoots}"
+ * @readonly
+ */
+
+
+ public WSDLFileOption(){}
+
+ public String getJavaPackage() {
+ return javaPackage;
+ }
+
+ public void setJavaPackage(String javaPackage) {
+ this.javaPackage = javaPackage;
+ }
+
+
+ public String[] getPorts() {
+ return ports;
+ }
+
+ public void setPorts(String[] ports) {
+ this.ports = ports;
+ }
+
+ public String getTargetDirectory() {
+ return targetDirectory;
+ }
+
+ public void setTargetDirectory(String targetDirectory) {
+ this.targetDirectory = targetDirectory;
+ }
+
+ public File getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(File fileName) {
+ this.fileName = fileName;
+ }
+
+}
diff --git a/tags/java/sca/2.0-M1/tools/maven/pom.xml b/tags/java/sca/2.0-M1/tools/maven/pom.xml
new file mode 100644
index 0000000000..cf7b01b30a
--- /dev/null
+++ b/tags/java/sca/2.0-M1/tools/maven/pom.xml
@@ -0,0 +1,62 @@
+<?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-sca-tools</artifactId>
+ <version>2.0-M1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <artifactId>tuscany-sca-maven-tools</artifactId>
+ <name>Apache Tuscany SCA Maven Tools</name>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>maven-ant-generator</module>
+ <module>maven-bundle-plugin</module>
+ <module>maven-osgi-junit</module>
+ <module>maven-dependency-lister</module>
+ <module>maven-eclipse-compiler</module>
+ <module>maven-incremental-build</module>
+ <module>maven-java2wsdl</module>
+ <module>maven-web-junit</module>
+ <module>maven-wsdl2java</module>
+ </modules>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>