Hi guys, just added a small feature (i called the module openejb-provisionning but i'm not sure it is relevant) to be able to use in our deployer something else than a file location.
i added the maven support through paxurl. to make it work: 1) download tomee 2) extract openejb-provisionning-<version>.zip in the tomee webapp 3) start tomee 4) go through the openejb webapp and browse JNDI until youget our deployer ejb 5) run deploy(String) 6) as location pass something like * mvn:org.superbiz/rest-example/1.1-SNAPSHOT/war *or* ** mvn:org.superbiz:rest-example:1.1-SNAPSHOT:war* the appli should be deployed (note if you are using this webapp it needs TomEE+). to add any other support a good place can be the provisionning module and the Resolver class. Doing it you need to take care of dependencies needed to get a cool openejb-provisionning zip without conflict with tomee. Any thoughts? - Romain ---------- Forwarded message ---------- From: <[email protected]> Date: 2012/1/17 Subject: svn commit: r1232590 - in /openejb/trunk/openejb: ./ arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/ container/openejb-core/ container/openejb-core/src/main/java/org/apache/openejb/assembler/ container/opene... To: [email protected] Author: rmannibucau Date: Tue Jan 17 21:36:23 2012 New Revision: 1232590 URL: http://svn.apache.org/viewvc?rev=1232590&view=rev Log: adding first version of openejb provisionning module (maybe the name should be changed, resolver?). it lets you deploy an app from a maven path Added: openejb/trunk/openejb/utils/openejb-provisionning/ openejb/trunk/openejb/utils/openejb-provisionning/pom.xml openejb/trunk/openejb/utils/openejb-provisionning/src/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/provisionning.xml openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/Resolver.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/AetherBasedResolver.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Connection.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Handler.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ManualWagonProvider.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Parser.java openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/package-info.java Modified: openejb/trunk/openejb/arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/MavenCache.java openejb/trunk/openejb/container/openejb-core/pom.xml openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java openejb/trunk/openejb/container/openejb-loader/src/main/java/org/apache/openejb/loader/FileUtils.java openejb/trunk/openejb/pom.xml openejb/trunk/openejb/utils/pom.xml Modified: openejb/trunk/openejb/arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/MavenCache.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/MavenCache.java?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/MavenCache.java (original) +++ openejb/trunk/openejb/arquillian-tomee/arquillian-tomee-common/src/main/java/org/apache/openejb/arquillian/common/MavenCache.java Tue Jan 17 21:36:23 2012 @@ -25,7 +25,6 @@ import org.sonatype.aether.RepositorySys import org.sonatype.aether.RepositorySystemSession; import org.sonatype.aether.artifact.Artifact; import org.sonatype.aether.installation.InstallRequest; -import org.sonatype.aether.installation.InstallationException; import org.sonatype.aether.repository.LocalRepository; import org.sonatype.aether.resolution.ArtifactRequest; import org.sonatype.aether.resolution.ArtifactResolutionException; @@ -131,15 +130,12 @@ public class MavenCache { file.deleteOnExit(); os = new FileOutputStream(file); - int bytesRead = -1; + int bytesRead; byte[] buffer = new byte[8192]; while ((bytesRead = is.read(buffer)) > -1) { os.write(buffer, 0, bytesRead); } - - is.close(); - os.close(); } catch (Exception e) { e.printStackTrace(); throw new DownloadException("Unable to download " + source + " to " + file.getAbsolutePath()); Modified: openejb/trunk/openejb/container/openejb-core/pom.xml URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/pom.xml?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/container/openejb-core/pom.xml (original) +++ openejb/trunk/openejb/container/openejb-core/pom.xml Tue Jan 17 21:36:23 2012 @@ -445,6 +445,7 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java (original) +++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java Tue Jan 17 21:36:23 2012 @@ -16,23 +16,10 @@ */ package org.apache.openejb.assembler; -import java.io.File; -import java.io.IOException; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Collection; -import java.util.Map; -import java.util.Properties; -import java.util.TreeMap; -import javax.ejb.Stateless; -import javax.ejb.Remote; -import javax.ejb.TransactionManagement; -import static javax.ejb.TransactionManagementType.BEAN; - +import org.apache.openejb.ClassLoaderUtil; import org.apache.openejb.NoSuchApplicationException; import org.apache.openejb.OpenEJBException; import org.apache.openejb.UndeployException; -import org.apache.openejb.ClassLoaderUtil; import org.apache.openejb.assembler.classic.AppInfo; import org.apache.openejb.assembler.classic.Assembler; import org.apache.openejb.config.AppModule; @@ -41,6 +28,20 @@ import org.apache.openejb.config.Deploym import org.apache.openejb.config.DeploymentModule; import org.apache.openejb.loader.SystemInstance; +import javax.ejb.Remote; +import javax.ejb.Stateless; +import javax.ejb.TransactionManagement; +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Collection; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import static javax.ejb.TransactionManagementType.BEAN; + @Stateless(name = "openejb/Deployer") @Remote(Deployer.class) @TransactionManagement(BEAN) @@ -87,12 +88,13 @@ public class DeployerEjb implements Depl return deploy(null, properties); } - public AppInfo deploy(String location, Properties properties) throws OpenEJBException { - if (location == null && properties == null) { + public AppInfo deploy(String inLocation, Properties properties) throws OpenEJBException { + String rawLocation = inLocation; + if (rawLocation == null && properties == null) { throw new NullPointerException("location and properties are null"); } - if (location == null) { - location = properties.getProperty(FILENAME); + if (rawLocation == null) { + rawLocation = properties.getProperty(FILENAME); } if (properties == null) { properties = new Properties(); @@ -100,7 +102,7 @@ public class DeployerEjb implements Depl AppModule appModule = null; try { - File file = new File(location); + File file = new File(realLocation(rawLocation)); appModule = deploymentLoader.load(file); // Add any alternate deployment descriptors to the modules @@ -174,6 +176,16 @@ public class DeployerEjb implements Depl } } + private String realLocation(String rawLocation) throws Exception { + final Class<?> clazz; + try { + clazz = DeployerEjb.class.getClassLoader().loadClass("org.apache.openejb.resolver.Resolver"); + return (String) clazz.getDeclaredMethod("resolve", String.class).invoke(null, rawLocation); + } catch (ClassNotFoundException e) { + return rawLocation; + } + } + public void undeploy(String moduleId) throws UndeployException, NoSuchApplicationException { assembler.destroyApplication(moduleId); } Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java (original) +++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java Tue Jan 17 21:36:23 2012 @@ -150,6 +150,7 @@ public class NewLoaderLogic { Filter filter = Filters.prefixes( "ApacheJMeter", "XmlSchema-", + "aether-", "activeio-", "activemq-", "antlr-", @@ -219,6 +220,7 @@ public class NewLoaderLogic { "kahadb-", "log4j-", "logkit-", + "maven-", "mbean-annotation-api-", "myfaces-", "neethi-", @@ -232,9 +234,12 @@ public class NewLoaderLogic { "opensaml-", "openwebbeans-", "openws-", + "ops4j-", "org.eclipse.", "org.junit.", "org.osgi.core-", + "pax-", + "plexus-", "quartz-", "rmock-", "saaj-", @@ -248,6 +253,7 @@ public class NewLoaderLogic { "stax-api-", "swizzle-", "testng-", + "wagon-", "webbeans-ee", "webbeans-ejb", "webbeans-impl", Modified: openejb/trunk/openejb/container/openejb-loader/src/main/java/org/apache/openejb/loader/FileUtils.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-loader/src/main/java/org/apache/openejb/loader/FileUtils.java?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/container/openejb-loader/src/main/java/org/apache/openejb/loader/FileUtils.java (original) +++ openejb/trunk/openejb/container/openejb-loader/src/main/java/org/apache/openejb/loader/FileUtils.java Tue Jan 17 21:36:23 2012 @@ -21,6 +21,8 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Hashtable; public class FileUtils { @@ -142,24 +144,21 @@ public class FileUtils { copyFile(destination, source, false); } - public static void copyFile(File destination, File source, boolean deleteSourceFile) throws java.io.IOException { - FileInputStream in = null; - FileOutputStream out = null; + public static void copy(OutputStream out, InputStream source) throws java.io.IOException { try { - in = new FileInputStream(source); - out = new FileOutputStream(destination); - int len; byte[] buffer = new byte[4096]; - while ((len = in.read(buffer)) != -1) { + while ((len = source.read(buffer)) != -1) { out.write(buffer, 0, len); } - } catch (java.io.IOException e) { - throw e; } finally { - in.close(); + source.close(); out.close(); } + } + + public static void copyFile(File destination, File source, boolean deleteSourceFile) throws java.io.IOException { + copy(new FileOutputStream(destination), new FileInputStream(source)); if (deleteSourceFile) { source.delete(); Modified: openejb/trunk/openejb/pom.xml URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/pom.xml?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/pom.xml (original) +++ openejb/trunk/openejb/pom.xml Tue Jan 17 21:36:23 2012 @@ -115,6 +115,12 @@ <!-- used mainly by jetty modules --> <openejb-cxf.version>2.5.1-SNAPSHOT</openejb-cxf.version> <jetty.version>7.5.3.v20111011</jetty.version> + <pax-url.version>1.3.5</pax-url.version> + <aether.version>1.11</aether.version> + <maven.version>3.0.3</maven.version> + <wagon.version>1.0-beta-7</wagon.version> + <plexus.version>1.5.4</plexus.version> + <plexus-utils.version>2.0.5</plexus-utils.version> <!-- - http://docs.codehaus.org/display/MAVENUSER/POM+Element+for+Source+File+Encoding Added: openejb/trunk/openejb/utils/openejb-provisionning/pom.xml URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/pom.xml?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/pom.xml (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/pom.xml Tue Jan 17 21:36:23 2012 @@ -0,0 +1,165 @@ +<?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/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>utils</artifactId> + <groupId>org.apache.openejb</groupId> + <version>4.0.0-beta-2-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>openejb-provisionning</artifactId> + <name>OpenEJB :: Utils :: Provisionning</name> + + <dependencies> + <!-- to handle mvn uris in DeployerEjb --> + <dependency> + <groupId>org.ops4j.pax.url</groupId> + <artifactId>pax-url-maven-commons</artifactId> + <version>${pax-url.version}</version> + <exclusions> + <exclusion> + <groupId>org.ops4j.pax.swissbox</groupId> + <artifactId>pax-swissbox-optional-jcl</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-api</artifactId> + <version>${aether.version}</version> + </dependency> + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-spi</artifactId> + <version>${aether.version}</version> + </dependency> + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-util</artifactId> + <version>${aether.version}</version> + </dependency> + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-impl</artifactId> + <version>${aether.version}</version> + </dependency> + <dependency> + <groupId>org.sonatype.aether</groupId> + <artifactId>aether-connector-wagon</artifactId> + <version>${aether.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-aether-provider</artifactId> + <version>${maven.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-provider-api</artifactId> + <version>${wagon.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-file</artifactId> + <version>${wagon.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-http-lightweight</artifactId> + <version>${wagon.version}</version> + <exclusions> + <exclusion> + <groupId>nekohtml</groupId> + <artifactId>nekohtml</artifactId> + </exclusion> + <exclusion> + <groupId>nekohtml</groupId> + <artifactId>xercesMinimal</artifactId> + </exclusion> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-container-default</artifactId> + <version>${plexus.version}</version> + <exclusions> + <exclusion> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </exclusion> + <exclusion> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </exclusion> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging-api</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.xbean</groupId> + <artifactId>xbean-reflect</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>${plexus-utils.version}</version> + </dependency> + + <!-- for resolver --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>openejb-loader</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>bin</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/provisionning.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + <tarLongFileMode>gnu</tarLongFileMode> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/provisionning.xml URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/provisionning.xml?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/provisionning.xml (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/assembly/provisionning.xml Tue Jan 17 21:36:23 2012 @@ -0,0 +1,43 @@ +<?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. +--> +<assembly> + <id>provisionning</id> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + <fileSets> + <fileSet> + <directory>${project.basedir}/target</directory> + <includes> + <include>${project.artifactId}-${project.version}.${project.packaging}</include> + </includes> + <outputDirectory>/</outputDirectory> + </fileSet> + </fileSets> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <scope>runtime</scope> + <excludes> + <exclude>org.apache.openejb:*</exclude> + </excludes> + </dependencySet> + </dependencySets> +</assembly> Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/Resolver.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/Resolver.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/Resolver.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/Resolver.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,44 @@ +package org.apache.openejb.resolver; + +import org.apache.openejb.loader.FileUtils; +import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.resolver.maven.Handler; +import org.apache.openejb.resolver.maven.Parser; + +import java.io.File; +import java.io.FileOutputStream; +import java.net.URL; + +public class Resolver { + public static final String MVN_PREFIX = "mvn:"; + public static final String APP_CACHE = System.getProperty("openejb.deployer.cache.folder", "temp"); + + private Resolver() { + // no-op + } + + public static String resolve(final String rawLocation) throws Exception { + if (rawLocation.startsWith(MVN_PREFIX) && rawLocation.length() > MVN_PREFIX.length()) { + final String info = rawLocation.substring(MVN_PREFIX.length()); + final Parser parser = new Parser(info); + final File file = new File(SystemInstance.get().getBase().getDirectory(), + APP_CACHE + File.separator + parser.getArtifactPath()); + if (!file.exists()) { + try { + final URL url = new URL(MVN_PREFIX.substring(MVN_PREFIX.length() - 1), "localhost", -1, info, new Handler()); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + FileUtils.copy(new FileOutputStream(file), url.openStream()); + } catch (Exception e) { + if (file.exists()) { + file.delete(); + } + throw e; + } + } + return file.getPath(); + } + return rawLocation; + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/AetherBasedResolver.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/AetherBasedResolver.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/AetherBasedResolver.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/AetherBasedResolver.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,274 @@ +package org.apache.openejb.resolver.maven; + +import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader; +import org.apache.maven.repository.internal.DefaultVersionRangeResolver; +import org.apache.maven.repository.internal.DefaultVersionResolver; +import org.apache.maven.repository.internal.MavenRepositorySystemSession; +import org.ops4j.pax.url.maven.commons.MavenConfigurationImpl; +import org.ops4j.pax.url.maven.commons.MavenRepositoryURL; +import org.sonatype.aether.RepositoryException; +import org.sonatype.aether.RepositorySystem; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.connector.wagon.WagonProvider; +import org.sonatype.aether.connector.wagon.WagonRepositoryConnectorFactory; +import org.sonatype.aether.impl.ArtifactDescriptorReader; +import org.sonatype.aether.impl.DependencyCollector; +import org.sonatype.aether.impl.Deployer; +import org.sonatype.aether.impl.Installer; +import org.sonatype.aether.impl.MetadataResolver; +import org.sonatype.aether.impl.SyncContextFactory; +import org.sonatype.aether.impl.VersionRangeResolver; +import org.sonatype.aether.impl.VersionResolver; +import org.sonatype.aether.impl.internal.DefaultDependencyCollector; +import org.sonatype.aether.impl.internal.DefaultDeployer; +import org.sonatype.aether.impl.internal.DefaultInstaller; +import org.sonatype.aether.impl.internal.DefaultMetadataResolver; +import org.sonatype.aether.impl.internal.DefaultServiceLocator; +import org.sonatype.aether.impl.internal.DefaultSyncContextFactory; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManagerFactory; +import org.sonatype.aether.repository.Authentication; +import org.sonatype.aether.repository.LocalRepository; +import org.sonatype.aether.repository.MirrorSelector; +import org.sonatype.aether.repository.Proxy; +import org.sonatype.aether.repository.ProxySelector; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.resolution.ArtifactRequest; +import org.sonatype.aether.resolution.VersionRangeRequest; +import org.sonatype.aether.resolution.VersionRangeResolutionException; +import org.sonatype.aether.resolution.VersionRangeResult; +import org.sonatype.aether.spi.connector.RepositoryConnectorFactory; +import org.sonatype.aether.spi.localrepo.LocalRepositoryManagerFactory; +import org.sonatype.aether.spi.log.Logger; +import org.sonatype.aether.spi.log.NullLogger; +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.sonatype.aether.util.repository.DefaultMirrorSelector; +import org.sonatype.aether.util.repository.DefaultProxySelector; +import org.sonatype.aether.version.Version; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AetherBasedResolver { + private static final String LATEST_VERSION_RANGE = "(0.0,]"; + private static final String REPO_TYPE = "default"; + + final private RepositorySystem m_repoSystem; + final private List<RemoteRepository> m_remoteRepos; + final private MavenConfigurationImpl m_config; + final private MirrorSelector m_mirrorSelector; + final private ProxySelector m_proxySelector; + + /** + * Create a AetherBasedResolver + * + * @param configuration (must be not null) + * @throws java.net.MalformedURLException in case of url problems in configuration. + */ + public AetherBasedResolver(final MavenConfigurationImpl configuration) throws MalformedURLException { + m_repoSystem = newRepositorySystem(); + m_config = configuration; + + m_remoteRepos = selectRepositories(getRemoteRepositories(configuration)); + m_mirrorSelector = selectMirrors(); + m_proxySelector = selectProxies(); + assignProxyAndMirrors(); + } + + private void assignProxyAndMirrors() { + Map<String, List<String>> map = new HashMap<String, List<String>>(); + Map<String, RemoteRepository> naming = new HashMap<String, RemoteRepository>(); + + for (RemoteRepository r : m_remoteRepos) { + naming.put(r.getId(), r); + + r.setProxy(m_proxySelector.getProxy(r)); + + RemoteRepository mirror = m_mirrorSelector.getMirror(r); + if (mirror != null) { + String key = mirror.getId(); + naming.put(key, mirror); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<String>()); + } + List<String> mirrored = map.get(key); + mirrored.add(r.getId()); + } + } + + for (String mirrorId : map.keySet()) { + RemoteRepository mirror = naming.get(mirrorId); + List<RemoteRepository> mirroedRepos = new ArrayList<RemoteRepository>(); + + for (String rep : map.get(mirrorId)) { + mirroedRepos.add(naming.get(rep)); + } + mirror.setMirroredRepositories(mirroedRepos); + m_remoteRepos.removeAll(mirroedRepos); + m_remoteRepos.add(0, mirror); + } + + } + + private List<MavenRepositoryURL> getRemoteRepositories(MavenConfigurationImpl configuration) + throws MalformedURLException { + List<MavenRepositoryURL> r = new ArrayList<MavenRepositoryURL>(); + for (MavenRepositoryURL s : configuration.getRepositories()) { + r.add(s); + } + return r; + } + + private ProxySelector selectProxies() { + DefaultProxySelector proxySelector = new DefaultProxySelector(); + Map<String, Map<String, String>> proxies = m_config.getProxySettings(); + for (Map<String, String> proxy : proxies.values()) { + //The fields are user, pass, host, port, nonProxyHosts, protocol. + String nonProxyHosts = proxy.get("nonProxyHosts"); + Proxy proxyObj = new Proxy(proxy.get("protocol"), + proxy.get("host"), + toInt(proxy.get("port")), + getAuthentication(proxy) + ); + proxySelector.add(proxyObj, nonProxyHosts); + } + return proxySelector; + } + + private MirrorSelector selectMirrors() { + // configure mirror + DefaultMirrorSelector selector = new DefaultMirrorSelector(); + Map<String, Map<String, String>> mirrors = m_config.getMirrors(); + + for (String mirrorName : mirrors.keySet()) { + Map<String, String> mirror = mirrors.get(mirrorName); + //The fields are id, url, mirrorOf, layout, mirrorOfLayouts. + String mirrorOf = mirror.get("mirrorOf"); + String url = mirror.get("url"); + // type can be null in this implementation (1.11) + selector.add(mirrorName, url, null, false, mirrorOf, "*"); + } + return selector; + /** + Set<RemoteRepository> mirrorRepoList = new HashSet<RemoteRepository>(); + for (RemoteRepository r : m_remoteRepos) { + RemoteRepository mirrorRepo = mirrorSelector.getMirror(r); + if (mirrorRepo != null) + { + mirrorRepoList.add(mirrorRepo); + } + } + return mirrorRepoList; + **/ + } + + private List<RemoteRepository> selectRepositories(List<MavenRepositoryURL> repos) { + List<RemoteRepository> list = new ArrayList<RemoteRepository>(); + for (MavenRepositoryURL r : repos) { + list.add(new RemoteRepository(r.getId(), REPO_TYPE, r.getURL().toExternalForm())); + } + return list; + } + + public InputStream resolve(String groupId, String artifactId, String classifier, String extension, String version) throws IOException { + // version = mapLatestToRange( version ); + final RepositorySystemSession session = newSession(); + Artifact artifact = new DefaultArtifact(groupId, artifactId, classifier, extension, version); + File resolved = resolve(session, artifact); + return new FileInputStream(resolved); + } + + private File resolve(RepositorySystemSession session, Artifact artifact) + throws IOException { + try { + artifact = resolveLatestVersionRange(session, artifact); + return m_repoSystem.resolveArtifact(session, new ArtifactRequest(artifact, m_remoteRepos, null)).getArtifact().getFile(); + } catch (RepositoryException e) { + throw new IOException("Aether Error.", e); + } + } + + /** + * Tries to resolve versions = LATEST using an open range version query. + * If it succeeds, version of artifact is set to the highest available version. + * + * @param session to be used. + * @param artifact to be used + * @return an artifact with version set properly (highest if available) + * @throws org.sonatype.aether.resolution.VersionRangeResolutionException + * in case of resolver errors. + */ + private Artifact resolveLatestVersionRange(RepositorySystemSession session, Artifact artifact) + throws VersionRangeResolutionException { + if (artifact.getVersion().equals("LATEST")) { + artifact = artifact.setVersion(LATEST_VERSION_RANGE); + + VersionRangeResult versionResult = m_repoSystem.resolveVersionRange(session, new VersionRangeRequest(artifact, m_remoteRepos, null)); + if (versionResult != null) { + Version v = versionResult.getHighestVersion(); + if (v != null) { + + artifact = artifact.setVersion(v.toString()); + } else { + throw new VersionRangeResolutionException(versionResult, "Not highest version found for " + artifact); + } + } + } + return artifact; + } + + private RepositorySystemSession newSession() { + assert m_config != null : "local repository cannot be null"; + File local = m_config.getLocalRepository().getFile(); + + MavenRepositorySystemSession session = new MavenRepositorySystemSession(); + + LocalRepository localRepo = new LocalRepository(local); + + session.setLocalRepositoryManager(m_repoSystem.newLocalRepositoryManager(localRepo)); + session.setMirrorSelector(m_mirrorSelector); + session.setProxySelector(m_proxySelector); + return session; + } + + private Authentication getAuthentication(Map<String, String> proxy) { + // user, pass + if (proxy.containsKey("user")) { + return new Authentication(proxy.get("user"), proxy.get("pass")); + } + return null; + } + + private int toInt(String intStr) { + return Integer.parseInt(intStr); + } + + private RepositorySystem newRepositorySystem() { + DefaultServiceLocator locator = new DefaultServiceLocator(); + + locator.addService(VersionResolver.class, DefaultVersionResolver.class); + locator.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class); + locator.addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class); + locator.addService(MetadataResolver.class, DefaultMetadataResolver.class); + locator.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class); + locator.addService(DependencyCollector.class, DefaultDependencyCollector.class); + locator.addService(Installer.class, DefaultInstaller.class); + locator.addService(Deployer.class, DefaultDeployer.class); + locator.addService(SyncContextFactory.class, DefaultSyncContextFactory.class); + + locator.setServices(WagonProvider.class, new ManualWagonProvider()); + locator.addService(RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class); + + locator.setService(LocalRepositoryManagerFactory.class, SimpleLocalRepositoryManagerFactory.class); + locator.setService(Logger.class, NullLogger.class); + + return locator.getService(RepositorySystem.class); + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Connection.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Connection.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Connection.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Connection.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,31 @@ +package org.apache.openejb.resolver.maven; + +import org.ops4j.pax.url.maven.commons.MavenConfigurationImpl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +public class Connection extends URLConnection { + private Parser m_parser; + private AetherBasedResolver m_aetherBasedResolver; + + public Connection( final URL url, final MavenConfigurationImpl configuration ) throws MalformedURLException { + super(url); + m_parser = new Parser( url.getPath() ); + m_aetherBasedResolver = new AetherBasedResolver( configuration ); + } + + @Override + public void connect() { + // no-op + } + + @Override + public InputStream getInputStream() throws IOException { + connect(); + return m_aetherBasedResolver.resolve( m_parser.getGroup(), m_parser.getArtifact(), m_parser.getClassifier(), m_parser.getType(), m_parser.getVersion() ); + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Handler.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Handler.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Handler.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Handler.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,21 @@ +package org.apache.openejb.resolver.maven; + +import org.ops4j.pax.url.maven.commons.MavenConfigurationImpl; +import org.ops4j.pax.url.maven.commons.MavenSettingsImpl; +import org.ops4j.util.property.PropertiesPropertyResolver; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class Handler extends URLStreamHandler { + @Override + protected URLConnection openConnection( final URL url ) throws IOException { + final MavenConfigurationImpl config = new MavenConfigurationImpl( + new PropertiesPropertyResolver( System.getProperties() ), "org.ops4j.pax.url.mvn"); + + config.setSettings( new MavenSettingsImpl( config.getSettingsFileUrl(), config.useFallbackRepositories() ) ); + return new Connection( url, config ); + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ManualWagonProvider.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ManualWagonProvider.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ManualWagonProvider.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/ManualWagonProvider.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,25 @@ +package org.apache.openejb.resolver.maven; + +import org.apache.maven.wagon.Wagon; +import org.apache.maven.wagon.providers.file.FileWagon; +import org.apache.maven.wagon.providers.http.LightweightHttpWagon; +import org.apache.maven.wagon.providers.http.LightweightHttpsWagon; +import org.sonatype.aether.connector.wagon.WagonProvider; + +public class ManualWagonProvider implements WagonProvider { + public Wagon lookup(String roleHint) + throws Exception { + if ("file".equals(roleHint)) { + return new FileWagon(); + } else if ("http".equals(roleHint)) { + return new LightweightHttpWagon(); + } else if ("https".equals(roleHint)) { + return new LightweightHttpsWagon(); + } + return null; + } + + public void release(Wagon wagon) { + // no-op + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Parser.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Parser.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Parser.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/Parser.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,185 @@ +package org.apache.openejb.resolver.maven; + +import java.net.MalformedURLException; + +public class Parser { + public static final String VERSION_LATEST = "LATEST"; + private static final String SYNTAX = "mvn:[repository_url!]groupId/artifactId[/[version]/[type]]"; + private static final String REPOSITORY_SEPARATOR = "!"; + private static final String ARTIFACT_SEPARATOR = "/"; + private static final String VERSION_SNAPSHOT = "SNAPSHOT"; + private static final String TYPE_JAR = "jar"; + private static final String FILE_SEPARATOR = "/"; + private static final String GROUP_SEPARATOR = "\\."; + private static final String VERSION_SEPARATOR = "-"; + private static final String TYPE_SEPARATOR = "."; + private static final String CLASSIFIER_SEPARATOR = "-"; + private static final String METADATA_FILE = "maven-metadata.xml"; + private static final String METADATA_FILE_LOCAL = "maven-metadata-local.xml"; + private String m_group; + private String m_artifact; + private String m_version; + private String m_type; + private String m_classifier; + private String m_fullClassifier; + + public Parser(final String rawPath) + throws MalformedURLException { + if (rawPath == null) { + throw new MalformedURLException("Path cannot be null. Syntax " + SYNTAX); + } + final String path = rawPath.replace(":", "/"); // mvn:G:A:V = mvn:G/A/V + if (path.startsWith(REPOSITORY_SEPARATOR) || path.endsWith(REPOSITORY_SEPARATOR)) { + throw new MalformedURLException( + "Path cannot start or end with " + REPOSITORY_SEPARATOR + ". Syntax " + SYNTAX + ); + } + if (path.contains(REPOSITORY_SEPARATOR)) { + int pos = path.lastIndexOf(REPOSITORY_SEPARATOR); + parseArtifactPart(path.substring(pos + 1)); + //m_repositoryURL = new MavenRepositoryURL(path.substring(0, pos) + "@snapshots"); + } else { + parseArtifactPart(path); + } + } + + private void parseArtifactPart(final String part) + throws MalformedURLException { + String[] segments = part.split(ARTIFACT_SEPARATOR); + if (segments.length < 2) { + throw new MalformedURLException("Invalid path. Syntax " + SYNTAX); + } + // we must have a valid group + m_group = segments[0]; + if (m_group.trim().length() == 0) { + throw new MalformedURLException("Invalid groupId. Syntax " + SYNTAX); + } + // valid artifact + m_artifact = segments[1]; + if (m_artifact.trim().length() == 0) { + throw new MalformedURLException("Invalid artifactId. Syntax " + SYNTAX); + } + // version is optional but we have a default value + m_version = VERSION_LATEST; + if (segments.length >= 3 && segments[2].trim().length() > 0) { + m_version = segments[2]; + } + // type is optional but we have a default value + m_type = TYPE_JAR; + if (segments.length >= 4 && segments[3].trim().length() > 0) { + m_type = segments[3]; + } + // classifier is optional (if not pressent or empty we will have a null classsifier + m_fullClassifier = ""; + if (segments.length >= 5 && segments[4].trim().length() > 0) { + m_classifier = segments[4]; + m_fullClassifier = CLASSIFIER_SEPARATOR + m_classifier; + } + } + + public String getGroup() { + return m_group; + } + + public String getArtifact() { + return m_artifact; + } + + public String getVersion() { + return m_version; + } + + public String getType() { + return m_type; + } + + public String getClassifier() { + return m_classifier; + } + + public String getArtifactPath() { + return getArtifactPath(m_version); + } + + public String getArtifactPath(final String version) { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(version) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(VERSION_SEPARATOR) + .append(version) + .append(m_fullClassifier) + .append(TYPE_SEPARATOR) + .append(m_type) + .toString(); + } + + public String getSnapshotVersion(final String version, final String timestamp, final String buildnumber) { + return version.replace(VERSION_SNAPSHOT, timestamp) + VERSION_SEPARATOR + buildnumber; + } + + public String getSnapshotPath(final String version, final String timestamp, final String buildnumber) { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(version) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(VERSION_SEPARATOR) + .append(getSnapshotVersion(version, timestamp, buildnumber)) + .append(m_fullClassifier) + .append(TYPE_SEPARATOR) + .append(m_type) + .toString(); + } + + public String getVersionMetadataPath(final String version) { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(version) + .append(FILE_SEPARATOR) + .append(METADATA_FILE) + .toString(); + } + + public String getVersionLocalMetadataPath(final String version) { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(version) + .append(FILE_SEPARATOR) + .append(METADATA_FILE_LOCAL) + .toString(); + } + + public String getArtifactLocalMetdataPath() { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(METADATA_FILE_LOCAL) + .toString(); + } + + public String getArtifactMetdataPath() { + return new StringBuilder() + .append(m_group.replaceAll(GROUP_SEPARATOR, FILE_SEPARATOR)) + .append(FILE_SEPARATOR) + .append(m_artifact) + .append(FILE_SEPARATOR) + .append(METADATA_FILE) + .toString(); + } +} Added: openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/package-info.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/package-info.java?rev=1232590&view=auto ============================================================================== --- openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/package-info.java (added) +++ openejb/trunk/openejb/utils/openejb-provisionning/src/main/java/org/apache/openejb/resolver/maven/package-info.java Tue Jan 17 21:36:23 2012 @@ -0,0 +1,2 @@ +// mainly copied from pax-url-aether +package org.apache.openejb.resolver.maven; Modified: openejb/trunk/openejb/utils/pom.xml URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/pom.xml?rev=1232590&r1=1232589&r2=1232590&view=diff ============================================================================== --- openejb/trunk/openejb/utils/pom.xml (original) +++ openejb/trunk/openejb/utils/pom.xml Tue Jan 17 21:36:23 2012 @@ -32,5 +32,6 @@ <module>openejb-logging</module> <module>openejb-spring</module> <module>openejb-core-hibernate</module> + <module>openejb-provisionning</module> </modules> </project>
