]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java
Improve OSGi related processes
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / RepoUtils.java
index 17f9fd6436679b9c37c6e35f0f26999f94a9ff67..6d22cbe687632ebcff13c7f4df87412ab4e653fd 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.slc.repo;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -15,16 +16,26 @@ import java.util.jar.JarInputStream;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
 import org.argeo.slc.BasicNameVersion;
 import org.argeo.slc.NameVersion;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.jcr.SlcTypes;
+import org.argeo.slc.repo.maven.MavenConventionsUtils;
+import org.osgi.framework.Constants;
 import org.sonatype.aether.artifact.Artifact;
+import org.sonatype.aether.util.artifact.DefaultArtifact;
 
 /** Utilities around repo */
-public class RepoUtils {
+public class RepoUtils implements SlcNames {
        private final static Log log = LogFactory.getLog(RepoUtils.class);
 
        /** Packages a regular sources jar as PDE source. */
@@ -53,6 +64,24 @@ public class RepoUtils {
                }
        }
 
+       public static byte[] packageAsPdeSource(InputStream sourceJar,
+                       NameVersion nameVersion) {
+               String sourceSymbolicName = nameVersion.getName() + ".source";
+
+               Manifest sourceManifest = null;
+               sourceManifest = new Manifest();
+               sourceManifest.getMainAttributes().put(
+                               Attributes.Name.MANIFEST_VERSION, "1.0");
+               sourceManifest.getMainAttributes().putValue("Bundle-SymbolicName",
+                               sourceSymbolicName);
+               sourceManifest.getMainAttributes().putValue("Bundle-Version",
+                               nameVersion.getVersion());
+               sourceManifest.getMainAttributes().putValue("Eclipse-SourceBundle",
+                               nameVersion.getName() + ";version=" + nameVersion.getVersion());
+
+               return modifyManifest(sourceJar, sourceManifest);
+       }
+
        /**
         * Check whether the file as already been packaged as PDE source, in order
         * not to mess with Jar signing
@@ -127,6 +156,41 @@ public class RepoUtils {
                }
        }
 
+       /** Copy a jar changing onlythe manifest */
+       public static void copyJar(InputStream in, OutputStream out,
+                       Manifest manifest) {
+               JarInputStream jarIn = null;
+               JarOutputStream jarOut = null;
+               try {
+                       jarIn = new JarInputStream(in);
+                       jarOut = new JarOutputStream(out, manifest);
+                       JarEntry jarEntry = null;
+                       while ((jarEntry = jarIn.getNextJarEntry()) != null) {
+                               jarOut.putNextEntry(jarEntry);
+                               IOUtils.copy(jarIn, jarOut);
+                               jarIn.closeEntry();
+                               jarOut.closeEntry();
+                       }
+               } catch (IOException e) {
+                       throw new SlcException("Could not copy jar with MANIFEST "
+                                       + manifest.getMainAttributes(), e);
+               } finally {
+                       IOUtils.closeQuietly(jarIn);
+                       IOUtils.closeQuietly(jarOut);
+               }
+       }
+
+       /** Reads a jar file, modify its manifest */
+       public static byte[] modifyManifest(InputStream in, Manifest manifest) {
+               ByteArrayOutputStream out = new ByteArrayOutputStream(200 * 1024);
+               try {
+                       copyJar(in, out, manifest);
+                       return out.toByteArray();
+               } finally {
+                       IOUtils.closeQuietly(out);
+               }
+       }
+
        /** Read the OSGi {@link NameVersion} */
        public static NameVersion readNameVersion(Artifact artifact) {
                File artifactFile = artifact.getFile();
@@ -146,25 +210,10 @@ public class RepoUtils {
        /** Read the OSGi {@link NameVersion} */
        public static NameVersion readNameVersion(File artifactFile) {
                JarInputStream jarInputStream = null;
-
                try {
-                       BasicNameVersion nameVersion = new BasicNameVersion();
                        jarInputStream = new JarInputStream(new FileInputStream(
                                        artifactFile));
-                       nameVersion.setName(jarInputStream.getManifest()
-                                       .getMainAttributes().getValue("Bundle-SymbolicName"));
-
-                       // Skip additional specs such as
-                       // ; singleton:=true
-                       if (nameVersion.getName().indexOf(';') > -1) {
-                               nameVersion.setName(new StringTokenizer(nameVersion.getName(),
-                                               " ;").nextToken());
-                       }
-
-                       nameVersion.setVersion(jarInputStream.getManifest()
-                                       .getMainAttributes().getValue("Bundle-Version"));
-
-                       return nameVersion;
+                       return readNameVersion(jarInputStream.getManifest());
                } catch (Exception e) {
                        // probably not a jar, skipping
                        if (log.isDebugEnabled()) {
@@ -177,6 +226,73 @@ public class RepoUtils {
                return null;
        }
 
+       /** Read the OSGi {@link NameVersion} */
+       public static NameVersion readNameVersion(Manifest manifest) {
+               BasicNameVersion nameVersion = new BasicNameVersion();
+               nameVersion.setName(manifest.getMainAttributes().getValue(
+                               Constants.BUNDLE_SYMBOLICNAME));
+
+               // Skip additional specs such as
+               // ; singleton:=true
+               if (nameVersion.getName().indexOf(';') > -1) {
+                       nameVersion
+                                       .setName(new StringTokenizer(nameVersion.getName(), " ;")
+                                                       .nextToken());
+               }
+
+               nameVersion.setVersion(manifest.getMainAttributes().getValue(
+                               Constants.BUNDLE_VERSION));
+
+               return nameVersion;
+       }
+
+       /*
+        * DATA MODEL
+        */
+       /** The artifact described by this node */
+       public static Artifact asArtifact(Node node) throws RepositoryException {
+               if (node.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) {
+                       // FIXME update data model to store packaging at this level
+                       String extension = "jar";
+                       return new DefaultArtifact(node.getProperty(SLC_GROUP_ID)
+                                       .getString(),
+                                       node.getProperty(SLC_ARTIFACT_ID).getString(), extension,
+                                       node.getProperty(SLC_ARTIFACT_VERSION).getString());
+               } else if (node.isNodeType(SlcTypes.SLC_ARTIFACT)) {
+                       return new DefaultArtifact(node.getProperty(SLC_GROUP_ID)
+                                       .getString(),
+                                       node.getProperty(SLC_ARTIFACT_ID).getString(), node
+                                                       .getProperty(SLC_ARTIFACT_CLASSIFIER).getString(),
+                                       node.getProperty(SLC_ARTIFACT_EXTENSION).getString(), node
+                                                       .getProperty(SLC_ARTIFACT_VERSION).getString());
+               } else {
+                       throw new SlcException("Unsupported node type for " + node);
+               }
+       }
+
+       /**
+        * Copy this bytes array as an artifact, relative to the root of the
+        * repository (typically the workspace root node)
+        */
+       public static Node copyBytesAsArtifact(Node artifactsBase,
+                       Artifact artifact, byte[] bytes) throws RepositoryException {
+               String parentPath = MavenConventionsUtils.artifactParentPath(
+                               artifactsBase.getPath(), artifact);
+               Node folderNode = JcrUtils.mkfolders(artifactsBase.getSession(),
+                               parentPath);
+               return JcrUtils.copyBytesAsFile(folderNode,
+                               MavenConventionsUtils.artifactFileName(artifact), bytes);
+       }
+
        private RepoUtils() {
        }
+
+       /** If a source return the base bundle name, does not change otherwise */
+       public static String extractBundleNameFromSourceName(String sourceBundleName) {
+               if (sourceBundleName.endsWith(".source"))
+                       return sourceBundleName.substring(0, sourceBundleName.length()
+                                       - ".source".length());
+               else
+                       return sourceBundleName;
+       }
 }