]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/NormalizeGroup.java
Manage automatically *-sources.jar sources
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / osgi / NormalizeGroup.java
index 0d734335bce506fc0aff79ff2e295efd41287a6b..99f31bb0414ae047c913ed7c6641ae1e09f60bee 100644 (file)
@@ -20,6 +20,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.TreeSet;
 
 import javax.jcr.Node;
@@ -38,27 +39,29 @@ import org.argeo.slc.aether.ArtifactIdComparator;
 import org.argeo.slc.jcr.SlcNames;
 import org.argeo.slc.jcr.SlcTypes;
 import org.argeo.slc.repo.ArtifactIndexer;
-import org.argeo.slc.repo.JarFileIndexer;
+import org.argeo.slc.repo.RepoConstants;
 import org.argeo.slc.repo.RepoUtils;
 import org.argeo.slc.repo.maven.MavenConventionsUtils;
 import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
 import org.sonatype.aether.artifact.Artifact;
 import org.sonatype.aether.util.artifact.DefaultArtifact;
 
 /**
  * Make sure that all JCR metadata and Maven metadata are consistent for this
  * group of OSGi bundles.
+ * 
+ * The job is now done via the various {@code NodeIndexer} of the
+ * WorkspaceManager. TODO import dependencies in the workspace.
  */
+@Deprecated
 public class NormalizeGroup implements Runnable, SlcNames {
-       public final static String BINARIES_ARTIFACT_ID = "binaries";
-       public final static String SOURCES_ARTIFACT_ID = "sources";
-       public final static String SDK_ARTIFACT_ID = "sdk";
-
        private final static Log log = LogFactory.getLog(NormalizeGroup.class);
 
        private Repository repository;
        private String workspace;
        private String groupId;
+       private Boolean overridePoms = false;
        private String artifactBasePath = "/";
        private String version = null;
        private String parentPomCoordinates;
@@ -66,8 +69,9 @@ public class NormalizeGroup implements Runnable, SlcNames {
        private List<String> excludedSuffixes = new ArrayList<String>();
 
        private ArtifactIndexer artifactIndexer = new ArtifactIndexer();
-       private JarFileIndexer jarFileIndexer = new JarFileIndexer();
+       // private JarFileIndexer jarFileIndexer = new JarFileIndexer();
 
+       /** TODO make it more generic */
        private List<String> systemPackages = OsgiProfile.PROFILE_JAVA_SE_1_6
                        .getSystemPackages();
 
@@ -95,51 +99,93 @@ public class NormalizeGroup implements Runnable, SlcNames {
                }
        }
 
-       public synchronized void processGroupNode(Node groupNode, String version,
-                       ArgeoMonitor monitor) throws RepositoryException {
-               // FIXME better encapsulate
-               groupId = groupNode.getProperty(SlcNames.SLC_GROUP_BASE_ID).getString();
-               this.version = version;
-               processGroupNode(groupNode, monitor);
+       public static void processGroupNode(Node groupNode, String version,
+                       Boolean overridePoms, ArgeoMonitor monitor)
+                       throws RepositoryException {
+               // TODO set artifactsBase based on group node
+               NormalizeGroup ng = new NormalizeGroup();
+               String groupId = groupNode.getProperty(SlcNames.SLC_GROUP_BASE_ID)
+                               .getString();
+               ng.setGroupId(groupId);
+               ng.setVersion(version);
+               ng.setOverridePoms(overridePoms);
+               ng.processGroupNode(groupNode, monitor);
        }
 
        protected void processGroupNode(Node groupNode, ArgeoMonitor monitor)
                        throws RepositoryException {
                if (monitor != null)
                        monitor.subTask("Group " + groupId);
+               Node allArtifactsHighestVersion = null;
                Session session = groupNode.getSession();
-               for (NodeIterator artifactBases = groupNode.getNodes(); artifactBases
+               aBases: for (NodeIterator aBases = groupNode.getNodes(); aBases
                                .hasNext();) {
-                       Node artifactBase = artifactBases.nextNode();
-                       if (artifactBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
-                               for (NodeIterator artifactVersions = artifactBase.getNodes(); artifactVersions
+                       Node aBase = aBases.nextNode();
+                       if (aBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
+                               Node highestAVersion = null;
+                               for (NodeIterator aVersions = aBase.getNodes(); aVersions
                                                .hasNext();) {
-                                       Node artifactVersion = artifactVersions.nextNode();
-                                       if (artifactVersion
-                                                       .isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE))
-                                               for (NodeIterator files = artifactVersion.getNodes(); files
-                                                               .hasNext();) {
-                                                       Node file = files.nextNode();
-                                                       if (file.isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT)) {
-                                                               preProcessBundleArtifact(file);
-                                                               file.getSession().save();
-                                                               if (log.isDebugEnabled())
-                                                                       log.debug("Pre-processed " + file.getName());
+                                       Node aVersion = aVersions.nextNode();
+                                       if (aVersion.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) {
+                                               if (highestAVersion == null) {
+                                                       highestAVersion = aVersion;
+                                                       if (allArtifactsHighestVersion == null)
+                                                               allArtifactsHighestVersion = aVersion;
+
+                                                       // BS will fail if artifacts arrive in this order
+                                                       // Name1 - V1, name2 - V3, V1 will remain the
+                                                       // allArtifactsHighestVersion
+                                                       // Fixed below
+                                                       else {
+                                                               Version currVersion = extractOsgiVersion(aVersion);
+                                                               Version highestVersion = extractOsgiVersion(allArtifactsHighestVersion);
+                                                               if (currVersion.compareTo(highestVersion) > 0)
+                                                                       allArtifactsHighestVersion = aVersion;
                                                        }
 
+                                               } else {
+                                                       Version currVersion = extractOsgiVersion(aVersion);
+                                                       Version currentHighestVersion = extractOsgiVersion(highestAVersion);
+                                                       if (currVersion.compareTo(currentHighestVersion) > 0) {
+                                                               highestAVersion = aVersion;
+                                                       }
+                                                       if (currVersion
+                                                                       .compareTo(extractOsgiVersion(allArtifactsHighestVersion)) > 0) {
+                                                               allArtifactsHighestVersion = aVersion;
+                                                       }
                                                }
+
+                                       }
+
+                               }
+                               if (highestAVersion == null)
+                                       continue aBases;
+                               for (NodeIterator files = highestAVersion.getNodes(); files
+                                               .hasNext();) {
+                                       Node file = files.nextNode();
+                                       if (file.isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT)) {
+                                               preProcessBundleArtifact(file);
+                                               file.getSession().save();
+                                               if (log.isDebugEnabled())
+                                                       log.debug("Pre-processed " + file.getName());
+                                       }
+
                                }
                        }
                }
-               // NodeIterator bundlesIt = listBundleArtifacts(session);
-               //
-               // while (bundlesIt.hasNext()) {
-               // Node bundleNode = bundlesIt.nextNode();
-               // preProcessBundleArtifact(bundleNode);
-               // bundleNode.getSession().save();
-               // if (log.isDebugEnabled())
-               // log.debug("Pre-processed " + bundleNode.getName());
-               // }
+
+               // if version not set or empty, use the highest version
+               // useful when indexing a product maven repository where
+               // all artifacts have the same version for a given release
+               // => the version can then be left empty
+               if (version == null || version.trim().equals(""))
+                       if (allArtifactsHighestVersion != null)
+                               version = allArtifactsHighestVersion.getProperty(
+                                               SLC_ARTIFACT_VERSION).getString();
+                       else
+                               version = "0.0";
+               // throw new SlcException("Group version " + version
+               // + " is empty.");
 
                int bundleCount = symbolicNamesToNodes.size();
                if (log.isDebugEnabled())
@@ -158,17 +204,65 @@ public class NormalizeGroup implements Runnable, SlcNames {
                // indexes
                Set<Artifact> indexes = new TreeSet<Artifact>(
                                new ArtifactIdComparator());
-               Artifact indexArtifact = writeIndex(session, BINARIES_ARTIFACT_ID,
-                               binaries);
+               Artifact indexArtifact = writeIndex(session,
+                               RepoConstants.BINARIES_ARTIFACT_ID, binaries);
                indexes.add(indexArtifact);
-               indexArtifact = writeIndex(session, SOURCES_ARTIFACT_ID, sources);
+               indexArtifact = writeIndex(session, RepoConstants.SOURCES_ARTIFACT_ID,
+                               sources);
                indexes.add(indexArtifact);
                // sdk
-               writeIndex(session, SDK_ARTIFACT_ID, indexes);
+               writeIndex(session, RepoConstants.SDK_ARTIFACT_ID, indexes);
                if (monitor != null)
                        monitor.worked(1);
        }
 
+       private Version extractOsgiVersion(Node artifactVersion)
+                       throws RepositoryException {
+               String rawVersion = artifactVersion.getProperty(SLC_ARTIFACT_VERSION)
+                               .getString();
+               String cleanVersion = rawVersion.replace("-SNAPSHOT", ".SNAPSHOT");
+               Version osgiVersion = null;
+               // log invalid version value to enable tracking them
+               try {
+                       osgiVersion = new Version(cleanVersion);
+               } catch (IllegalArgumentException e) {
+                       log.error("Version string " + cleanVersion + " is invalid ");
+                       String twickedVersion = twickInvalidVersion(cleanVersion);
+                       osgiVersion = new Version(twickedVersion);
+                       log.error("Using " + twickedVersion + " instead");
+                       // throw e;
+               }
+               return osgiVersion;
+       }
+
+       private String twickInvalidVersion(String tmpVersion) {
+               String[] tokens = tmpVersion.split("\\.");
+               if (tokens.length == 3 && tokens[2].lastIndexOf("-") > 0) {
+                       String newSuffix = tokens[2].replaceFirst("-", ".");
+                       tmpVersion = tmpVersion.replaceFirst(tokens[2], newSuffix);
+               } else if (tokens.length > 4) {
+                       // FIXME manually remove other "."
+                       StringTokenizer st = new StringTokenizer(tmpVersion, ".", true);
+                       StringBuilder builder = new StringBuilder();
+                       // Major
+                       builder.append(st.nextToken()).append(st.nextToken());
+                       // Minor
+                       builder.append(st.nextToken()).append(st.nextToken());
+                       // Micro
+                       builder.append(st.nextToken()).append(st.nextToken());
+                       // Qualifier
+                       builder.append(st.nextToken());
+                       while (st.hasMoreTokens()) {
+                               // consume delimiter
+                               st.nextToken();
+                               if (st.hasMoreTokens())
+                                       builder.append("-").append(st.nextToken());
+                       }
+                       tmpVersion = builder.toString();
+               }
+               return tmpVersion;
+       }
+
        private Artifact writeIndex(Session session, String artifactId,
                        Set<Artifact> artifacts) throws RepositoryException {
                Artifact artifact = new DefaultArtifact(groupId, artifactId, "pom",
@@ -181,23 +275,23 @@ public class NormalizeGroup implements Runnable, SlcNames {
                                session.getNode(artifactBasePath), artifact, pom.getBytes());
                artifactIndexer.index(node);
 
-               // FIXME factorize
+               // TODO factorize
                String pomSha = JcrUtils.checksumFile(node, "SHA-1");
                JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".sha1",
                                pomSha.getBytes());
+               String pomMd5 = JcrUtils.checksumFile(node, "MD5");
+               JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".md5",
+                               pomMd5.getBytes());
                session.save();
                return artifact;
        }
 
        protected void preProcessBundleArtifact(Node bundleNode)
                        throws RepositoryException {
-               artifactIndexer.index(bundleNode);
-               jarFileIndexer.index(bundleNode);
 
                String symbolicName = JcrUtils.get(bundleNode, SLC_SYMBOLIC_NAME);
-
                if (symbolicName.endsWith(".source")) {
-                       // TODO make a shared node with classifier 'sources'
+                       // TODO make a shared node with classifier 'sources'?
                        String bundleName = RepoUtils
                                        .extractBundleNameFromSourceName(symbolicName);
                        for (String excludedSuffix : excludedSuffixes) {
@@ -233,11 +327,13 @@ public class NormalizeGroup implements Runnable, SlcNames {
                String baseName = FilenameUtils.getBaseName(bundleNode.getName());
 
                // pom
-               String pom = generatePomForBundle(bundleNode);
                String pomName = baseName + ".pom";
+               if (artifactFolder.hasNode(pomName) && !overridePoms)
+                       return;// skip
+
+               String pom = generatePomForBundle(bundleNode);
                Node pomNode = JcrUtils.copyBytesAsFile(artifactFolder, pomName,
                                pom.getBytes());
-
                // checksum
                String bundleSha = JcrUtils.checksumFile(bundleNode, "SHA-1");
                JcrUtils.copyBytesAsFile(artifactFolder,
@@ -258,7 +354,6 @@ public class NormalizeGroup implements Runnable, SlcNames {
                p.append("<modelVersion>4.0.0</modelVersion>");
 
                // Artifact
-               // p.append("<parent><groupId>org.argeo</groupId><artifactId>parent</artifactId><version>1.2.0</version></parent>\n");
                p.append("<groupId>").append(JcrUtils.get(n, SLC_GROUP_ID))
                                .append("</groupId>\n");
                p.append("<artifactId>").append(JcrUtils.get(n, SLC_ARTIFACT_ID))
@@ -359,8 +454,9 @@ public class NormalizeGroup implements Runnable, SlcNames {
                p.append("<dependency>\n");
                p.append("\t<groupId>").append(groupId).append("</groupId>\n");
                p.append("\t<artifactId>")
-                               .append(ownSymbolicName.endsWith(".source") ? SOURCES_ARTIFACT_ID
-                                               : BINARIES_ARTIFACT_ID).append("</artifactId>\n");
+                               .append(ownSymbolicName.endsWith(".source") ? RepoConstants.SOURCES_ARTIFACT_ID
+                                               : RepoConstants.BINARIES_ARTIFACT_ID)
+                               .append("</artifactId>\n");
                p.append("\t<version>").append(version).append("</version>\n");
                p.append("\t<type>pom</type>\n");
                p.append("\t<scope>import</scope>\n");
@@ -372,6 +468,7 @@ public class NormalizeGroup implements Runnable, SlcNames {
                return p.toString();
        }
 
+       /* DEPENDENCY INJECTION */
        public void setRepository(Repository repository) {
                this.repository = repository;
        }
@@ -400,4 +497,11 @@ public class NormalizeGroup implements Runnable, SlcNames {
                this.excludedSuffixes = excludedSuffixes;
        }
 
+       public void setOverridePoms(Boolean overridePoms) {
+               this.overridePoms = overridePoms;
+       }
+
+       public void setArtifactIndexer(ArtifactIndexer artifactIndexer) {
+               this.artifactIndexer = artifactIndexer;
+       }
 }