summaryrefslogtreecommitdiffstats
path: root/tags/java
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-02-13 11:30:56 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-02-13 11:30:56 +0000
commit39a82c59fa69359281e2ec658a8792a0e2e9f070 (patch)
tree112059e3e2cce93a1947e70b6f7447e88c37579c /tags/java
parent05d000d7de3df7c2349ccd5f6f26421932b28f8d (diff)
Copy tag about to try to show we can put this wherever we like
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@744084 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'tags/java')
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/LICENSE205
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/NOTICE6
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/README56
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/pom.xml301
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/ClassLoaderNameEnvironment.java195
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/CompilerRequestor.java114
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/FileCompilationUnit.java88
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/JavaCompiler.java212
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleResolver.java490
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleUtil.java618
-rw-r--r--tags/java/maven-eclipse-compiler-1.0/src/main/resources/META-INF/plexus/components.xml28
11 files changed, 2313 insertions, 0 deletions
diff --git a/tags/java/maven-eclipse-compiler-1.0/LICENSE b/tags/java/maven-eclipse-compiler-1.0/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/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/maven-eclipse-compiler-1.0/NOTICE b/tags/java/maven-eclipse-compiler-1.0/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/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/maven-eclipse-compiler-1.0/README b/tags/java/maven-eclipse-compiler-1.0/README
new file mode 100644
index 0000000000..64d58dd57b
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/README
@@ -0,0 +1,56 @@
+This module is a Maven compiler which uses the Eclipse Java compiler which is
+used by the Tuscany SCA project build.
+
+To build, from the top maven-eclipse-compiler run maven:
+
+mvn
+
+or once all the dependencies have been downloaded and a succesful build run use:
+
+mvn clean install -o
+
+So as to avoid the Tuscany SCA project using SNAPSHOT dependencies any changes
+to this maven-eclipse-compiler module should be released and the Tuscany SCA
+project updated to use the newly released version.
+
+To release this module:
+
+mvn release:prepare
+
+followed by:
+
+mvn release:perform
+
+While running these will prompt you for the names fro the tag, release version etc.
+
+In your maven settings.xml file you must have a server defined named "apache.releases",
+and a profile named "release". For example:
+
+ <servers>
+ ...
+ <server>
+ <id>apache.releases</id>
+ <username>antelder</username>
+ <privateKey>\ant\id_dsa</privateKey>
+ <passphrase>xxx</passphrase>
+ <directoryPermissions>775</directoryPermissions>
+ <filePermissions>664</filePermissions>
+ </server>
+ </servers>
+
+ <profiles>
+ ...
+ <profile>
+ <id>release</id>
+ <properties>
+ <gpg.passphrase>...</gpg.passphrase>
+ <deploy.altRepository>apache.releases::default::scp://people.apache.org/home/antelder/public_html/tuscany/maven-eclipse-compiler-1.0</deploy.altRepository>
+ </properties>
+ </profile>
+ </profiles>
+
+
+
+
+
+
diff --git a/tags/java/maven-eclipse-compiler-1.0/pom.xml b/tags/java/maven-eclipse-compiler-1.0/pom.xml
new file mode 100644
index 0000000000..0042dfca57
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/pom.xml
@@ -0,0 +1,301 @@
+<?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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>4</version>
+ </parent>
+
+ <groupId>org.apache.tuscany.maven.plugins</groupId>
+ <artifactId>maven-eclipse-compiler</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Tuscany Maven Eclipse Compiler Plugin</name>
+ <version>1.0</version>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/tuscany/maven-plugins/tags/maven-eclipse-compiler-1.0</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tuscany/maven-plugins/tags/maven-eclipse-compiler-1.0</developerConnection>
+ <url>scm:svn:https://svn.apache.org/repos/asf/tuscany/maven-plugins/tags/maven-eclipse-compiler-1.0</url>
+ </scm>
+
+ <distributionManagement>
+ <repository>
+ <id>apache.releases</id>
+ <name>Apache Release Distribution Repository</name>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository</url>
+ </repository>
+ <snapshotRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <!-- Apache SNAPSHOT repository for unreleased artifacts -->
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache SNAPSHOT Repository</name>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <!-- Apache repository for artifacts released by Apache TLP projects -->
+ <pluginRepository>
+ <id>apache</id>
+ <name>Apache Repository</name>
+ <url>http://people.apache.org/repo/m2-ibiblio-rsync-repository</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+
+ <!-- Apache SNAPSHOT repository for unreleased artifacts -->
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache SNAPSHOT Repository</name>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+
+ </pluginRepositories>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <altDeploymentRepository>${deploy.altRepository}</altDeploymentRepository>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.0-alpha-4</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>deploy</id>
+ <build>
+ <defaultGoal>deploy</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.0.4</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <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>
+
+ </dependencies>
+
+ <build>
+ <defaultGoal>install</defaultGoal>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>.</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>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/tuscany/maven-plugins/tags</tagBase>
+ <useReleaseProfile>false</useReleaseProfile>
+ <preparationGoals>clean install</preparationGoals>
+ <goals>deploy</goals>
+ <arguments>-Prelease,deploy</arguments>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </pluginManagement>
+
+ </build>
+
+</project>
diff --git a/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/ClassLoaderNameEnvironment.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/ClassLoaderNameEnvironment.java
new file mode 100644
index 0000000000..0db6ce6fd6
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/CompilerRequestor.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/CompilerRequestor.java
new file mode 100644
index 0000000000..509bdee95d
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/FileCompilationUnit.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/FileCompilationUnit.java
new file mode 100644
index 0000000000..fa6b3c7496
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/JavaCompiler.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/JavaCompiler.java
new file mode 100644
index 0000000000..2c6bc045e9
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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.maven.compiler.osgi.BundleResolver;
+import org.apache.tuscany.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/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleResolver.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleResolver.java
new file mode 100644
index 0000000000..e31c29ead4
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleUtil.java b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/maven/compiler/osgi/BundleUtil.java
new file mode 100644
index 0000000000..ea4b3b6dff
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/src/main/java/org/apache/tuscany/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.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/maven-eclipse-compiler-1.0/src/main/resources/META-INF/plexus/components.xml b/tags/java/maven-eclipse-compiler-1.0/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000000..3cacf2e7d2
--- /dev/null
+++ b/tags/java/maven-eclipse-compiler-1.0/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.maven.compiler.JavaCompiler</implementation>
+ </component>
+ </components>
+</component-set>