Improve OSGi factory
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 7 Oct 2013 15:50:35 +0000 (15:50 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 7 Oct 2013 15:50:35 +0000 (15:50 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6538 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/OsgiFactory.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ArchiveWrapper.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/BndWrapper.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/MavenWrapper.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/OsgiFactoryImpl.java

index b2299a726e65e7063a363ab2410811c4a82faf54..817849361148da6ee3e8aaf2f7d5b15c4eaa587e 100644 (file)
@@ -18,4 +18,11 @@ public interface OsgiFactory {
         */
        public Node getDist(Session distSession, String uri)
                        throws RepositoryException;
+
+       /**
+        * Provide access to a cached maven ardifact identified by its coordinates
+        * the 'dist' repository, downloading it if it is not available.
+        */
+       public Node getMaven(Session distSession, String coords)
+                       throws RepositoryException;
 }
index 438552e4b91189b192c624f06fe06145bef6126f..0adfe883f6d95ee7036dfa138c7d6da73d3061a9 100644 (file)
@@ -109,6 +109,24 @@ public class ArchiveWrapper implements Runnable, ModuleSet, Distribution {
                                                        sourceJarBytes, wrapper);
                                        addArtifactToIndex(binaries, wrapper.getGroupId(), artifact);
                                } else {
+                                       for (String wrapperKey : wrappers.keySet())
+                                               if (pathMatcher.match(wrapperKey, name)) {
+                                                       // first matched is taken
+                                                       BndWrapper wrapper = (BndWrapper) wrappers
+                                                                       .get(wrapperKey);
+                                                       // we must copy since the stream is closed by BND
+                                                       byte[] sourceJarBytes = IOUtils.toByteArray(zin);
+                                                       Artifact artifact = wrapZipEntry(javaSession,
+                                                                       zentry, sourceJarBytes, wrapper);
+                                                       addArtifactToIndex(binaries, wrapper.getGroupId(),
+                                                                       artifact);
+                                                       continue entries;
+                                               } else {
+                                                       if (log.isTraceEnabled())
+                                                               log.trace(name + " not matched by "
+                                                                               + wrapperKey);
+                                               }
+
                                        for (String exclude : excludes)
                                                if (pathMatcher.match(exclude, name))
                                                        continue entries;
index 564dd52d360d9349ea9ecde8050270e3ac15bd04..55ad84dfdcfc2cfc7de1d367b8c075b245722a7e 100644 (file)
@@ -35,26 +35,41 @@ public class BndWrapper implements Constants, CategorizedNameVersion,
                        Jar jar = new Jar(null, in);
 
                        Manifest sourceManifest = jar.getManifest();
-                       String sourceVersion = sourceManifest.getMainAttributes().getValue(
-                                       BUNDLE_VERSION);
+
                        Version versionToUse;
-                       if (version == null && sourceVersion == null) {
-                               throw new SlcException("A bundle version must be defined.");
-                       } else if (version == null && sourceVersion != null) {
-                               versionToUse = new Version(sourceVersion);
-                       } else if (version != null && sourceVersion == null) {
-                               versionToUse = new Version(version);
-                       } else {// both set
-                               versionToUse = new Version(version);
-                               Version sv = new Version(sourceVersion);
-                               if (versionToUse.getMajor() != sv.getMajor()
-                                               || versionToUse.getMinor() != sv.getMinor()
-                                               || versionToUse.getMicro() != sv.getMicro()) {
-                                       log.warn("The new version ("
-                                                       + versionToUse
-                                                       + ") is not consistant with the wrapped bundle version ("
-                                                       + sv + ")");
+                       if (sourceManifest != null) {
+                               String sourceSymbolicName = sourceManifest.getMainAttributes()
+                                               .getValue(BUNDLE_SYMBOLICNAME);
+                               if (sourceSymbolicName != null
+                                               && sourceSymbolicName.equals(name))
+                                       log.warn("The new symbolic name ("
+                                                       + name
+                                                       + ") is not consistant with the wrapped bundle symbolic name ("
+                                                       + sourceSymbolicName + ")");
+
+                               String sourceVersion = sourceManifest.getMainAttributes()
+                                               .getValue(BUNDLE_VERSION);
+                               if (version == null && sourceVersion == null) {
+                                       throw new SlcException("A bundle version must be defined.");
+                               } else if (version == null && sourceVersion != null) {
+                                       versionToUse = new Version(sourceVersion);
+                                       version = sourceVersion; // set wrapper version
+                               } else if (version != null && sourceVersion == null) {
+                                       versionToUse = new Version(version);
+                               } else {// both set
+                                       versionToUse = new Version(version);
+                                       Version sv = new Version(sourceVersion);
+                                       if (versionToUse.getMajor() != sv.getMajor()
+                                                       || versionToUse.getMinor() != sv.getMinor()
+                                                       || versionToUse.getMicro() != sv.getMicro()) {
+                                               log.warn("The new version ("
+                                                               + versionToUse
+                                                               + ") is not consistant with the wrapped bundle version ("
+                                                               + sv + ")");
+                                       }
                                }
+                       } else {
+                               versionToUse = new Version(version);
                        }
 
                        Properties properties = new Properties();
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/MavenWrapper.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/MavenWrapper.java
new file mode 100644 (file)
index 0000000..829bea4
--- /dev/null
@@ -0,0 +1,64 @@
+package org.argeo.slc.repo.osgi;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.OsgiFactory;
+import org.argeo.slc.repo.RepoUtils;
+
+public class MavenWrapper extends BndWrapper implements Runnable {
+       private final static Log log = LogFactory.getLog(MavenWrapper.class);
+
+       private String sourceCoords;
+
+       private OsgiFactory osgiFactory;
+
+       public void run() {
+               Session distSession = null;
+               Session javaSession = null;
+               InputStream in;
+               ByteArrayOutputStream out;
+               try {
+                       distSession = osgiFactory.openDistSession();
+                       javaSession = osgiFactory.openJavaSession();
+                       Node sourceArtifact = osgiFactory.getMaven(distSession,
+                                       sourceCoords);
+
+                       in = sourceArtifact.getNode(Node.JCR_CONTENT)
+                                       .getProperty(Property.JCR_DATA).getBinary().getStream();
+                       out = new ByteArrayOutputStream();
+                       wrapJar(in, out);
+                       Node newJarNode = RepoUtils
+                                       .copyBytesAsArtifact(javaSession.getRootNode(),
+                                                       getArtifact(), out.toByteArray());
+                       osgiFactory.indexNode(newJarNode);
+                       newJarNode.getSession().save();
+                       if (log.isDebugEnabled())
+                               log.debug("Wrapped Maven " + sourceCoords + " to "
+                                               + newJarNode.getPath());
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot wrap Maven " + sourceCoords, e);
+               } finally {
+                       JcrUtils.logoutQuietly(distSession);
+                       JcrUtils.logoutQuietly(javaSession);
+               }
+       }
+
+       public void setSourceCoords(String sourceCoords) {
+               this.sourceCoords = sourceCoords;
+       }
+
+       public void setOsgiFactory(OsgiFactory osgiFactory) {
+               this.osgiFactory = osgiFactory;
+       }
+
+}
index ab4f9775cf37c5ffa6a5eb48b09d5cbb86459019..e6b8b323e624f1e8dcfd3e9223f0c1211dd52da8 100644 (file)
@@ -24,9 +24,12 @@ import org.argeo.slc.jcr.SlcNames;
 import org.argeo.slc.jcr.SlcTypes;
 import org.argeo.slc.repo.NodeIndexer;
 import org.argeo.slc.repo.OsgiFactory;
+import org.argeo.slc.repo.maven.MavenConventionsUtils;
+import org.sonatype.aether.artifact.Artifact;
+import org.sonatype.aether.util.artifact.DefaultArtifact;
 
 /** Default implementation of {@link OsgiFactory}. */
-public class OsgiFactoryImpl implements OsgiFactory {
+public class OsgiFactoryImpl implements OsgiFactory, SlcNames {
        private final static Log log = LogFactory.getLog(OsgiFactoryImpl.class);
 
        private String workspace;
@@ -38,10 +41,20 @@ public class OsgiFactoryImpl implements OsgiFactory {
        /** key is URI prefix, value list of base URLs */
        private Map<String, List<String>> mirrors = new HashMap<String, List<String>>();
 
+       private List<String> mavenRepositories = new ArrayList<String>();
+       private String mavenProxyBase = "/mavenProxy";
+
        public void init() {
                if (workspace == null)
                        throw new SlcException("A workspace must be specified");
 
+               // default Maven repo
+               if (mavenRepositories.size() == 0) {
+                       // mavenRepositories
+                       // .add("http://search.maven.org/remotecontent?filepath=");
+                       mavenRepositories.add("http://repo1.maven.org/maven2");
+               }
+
                Session javaSession = null;
                Session distSession = null;
                try {
@@ -82,6 +95,45 @@ public class OsgiFactoryImpl implements OsgiFactory {
                }
        }
 
+       public Node getMaven(Session distSession, String coords)
+                       throws RepositoryException {
+               Artifact artifact = new DefaultArtifact(coords);
+               String path = MavenConventionsUtils.artifactPath(mavenProxyBase,
+                               artifact);
+
+               // exists
+               if (distSession.itemExists(path))
+                       return distSession.getNode(path);
+
+               for (String mavenRepo : mavenRepositories) {
+                       String url = mavenRepo
+                                       + MavenConventionsUtils.artifactPath("/", artifact);
+                       try {
+                               Node node = loadUrlToPath(url, distSession, path);
+                               if (node != null) {
+                                       // checksums
+                                       try {
+                                               loadUrlToPath(url + ".md5", distSession, path + ".md5");
+                                       } catch (FileNotFoundException e) {
+                                               // silent
+                                       }
+                                       try {
+                                               loadUrlToPath(url + ".sha1", distSession, path
+                                                               + ".sha1");
+                                       } catch (FileNotFoundException e) {
+                                               // silent
+                                       }
+                                       return node;
+                               }
+                       } catch (FileNotFoundException e) {
+                               if (log.isDebugEnabled())
+                                       log.debug("Maven " + coords
+                                                       + " could not be downloaded from " + url);
+                       }
+               }
+               throw new SlcException("Could not download Maven " + coords);
+       }
+
        public Node getDist(Session distSession, String uri)
                        throws RepositoryException {
                String distPath = '/' + JcrUtils.urlAsPath(uri);
@@ -125,6 +177,7 @@ public class OsgiFactoryImpl implements OsgiFactory {
                throw new SlcException("Could not download " + uri);
        }
 
+       /** Actually downloads a file to an internal location */
        protected Node loadUrlToPath(String url, Session distSession, String path)
                        throws RepositoryException, FileNotFoundException {
                if (log.isDebugEnabled())
@@ -139,8 +192,7 @@ public class OsgiFactoryImpl implements OsgiFactory {
                        Node fileNode = JcrUtils.copyStreamAsFile(folderNode,
                                        JcrUtils.nodeNameFromPath(path), in);
                        fileNode.addMixin(SlcTypes.SLC_KNOWN_ORIGIN);
-                       Node origin = fileNode.addNode(SlcNames.SLC_ORIGIN,
-                                       SlcTypes.SLC_PROXIED);
+                       Node origin = fileNode.addNode(SLC_ORIGIN, SlcTypes.SLC_PROXIED);
                        JcrUtils.urlToAddressProperties(origin, url);
                        distSession.save();
                        return fileNode;