]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/ModularDistributionIndexer.java
Clean repo indexer, update modular distribution management, remove binaries concepts.
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / ModularDistributionIndexer.java
index 59c6b31f37b775cd6f9416acd0dff203135efe2a..3f9f7dcc5e25150ab7cb5dcf4c6afe855ae18fd8 100644 (file)
@@ -1,16 +1,11 @@
 package org.argeo.slc.repo;
 
 import java.io.BufferedReader;
-import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Properties;
-import java.util.Set;
 import java.util.StringTokenizer;
-import java.util.TreeSet;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
@@ -18,9 +13,8 @@ import java.util.jar.Manifest;
 import javax.jcr.Binary;
 import javax.jcr.Node;
 import javax.jcr.Property;
+import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeType;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
@@ -29,25 +23,23 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.slc.CategorizedNameVersion;
 import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.NameVersion;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.aether.AetherUtils;
-import org.argeo.slc.aether.ArtifactIdComparator;
+import org.argeo.slc.build.Distribution;
 import org.argeo.slc.jcr.SlcNames;
 import org.argeo.slc.jcr.SlcTypes;
 import org.osgi.framework.Constants;
 import org.sonatype.aether.artifact.Artifact;
 import org.sonatype.aether.util.artifact.DefaultArtifact;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
 
 /**
  * Create or update JCR meta-data for an SLC Modular Distribution
  * 
  * Currently, following types are managed: <list><li>* .jar: dependency
- * artifacts with csv index</li> <li>.pom: artifact (binaries) that indexes a
- * group, the .pom file contains a tag "dependencyManagement" that list all
- * modules</li> </list>
+ * artifacts with csv index</li> <li>@Deprecated : .pom: artifact (binaries)
+ * that indexes a group, the .pom file contains a tag "dependencyManagement"
+ * that list all modules</li> </list>
  */
 public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
        private final static Log log = LogFactory
@@ -57,39 +49,30 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
        private final static String INDEX_FILE_NAME = "modularDistribution.csv";
        private String separator = ",";
 
-       // Artifact indexing
-       private final static List<String> BINARIES_ARTIFACTS_NAME;
-       static {
-               List<String> tmpList = new ArrayList<String>();
-               tmpList.add(RepoConstants.BINARIES_ARTIFACT_ID);
-               // tmpList.add(RepoConstants.SOURCES_ARTIFACT_ID);
-               // tmpList.add(RepoConstants.SDK_ARTIFACT_ID);
-               BINARIES_ARTIFACTS_NAME = Collections.unmodifiableList(tmpList);
-       }
+       // TODO remove this: binaries have been replaced by modular distribution
+       // // Artifact indexing
+       // private final static List<String> BINARIES_ARTIFACTS_NAME;
+       // static {
+       // List<String> tmpList = new ArrayList<String>();
+       // tmpList.add(RepoConstants.BINARIES_ARTIFACT_ID);
+       // // tmpList.add(RepoConstants.SOURCES_ARTIFACT_ID);
+       // // tmpList.add(RepoConstants.SDK_ARTIFACT_ID);
+       // BINARIES_ARTIFACTS_NAME = Collections.unmodifiableList(tmpList);
+       // }
 
        private Manifest manifest;
-       // private String symbolicName;
-       // private String version;
-       // private List<Artifact> artifacts;
-
-       private Comparator<Artifact> artifactComparator = new ArtifactIdComparator();
-
-       // private Set<Artifact> artifacts = new
-       // TreeSet<Artifact>(artifactComparator);
 
        public Boolean support(String path) {
                if (FilenameUtils.getExtension(path).equals("jar"))
                        return true;
-
-               if (FilenameUtils.getExtension(path).equals("pom")
-                               && BINARIES_ARTIFACTS_NAME.contains(FilenameUtils.getName(path)
-                                               .split("-")[0]))
-                       return true;
+               // if (FilenameUtils.getExtension(path).equals("pom")
+               // && BINARIES_ARTIFACTS_NAME.contains(FilenameUtils.getName(path)
+               // .split("-")[0]))
+               // return true;
                return false;
        }
 
        public void index(Node fileNode) {
-               // JarInputStream jarIn = null;
                Binary fileBinary = null;
                try {
 
@@ -100,57 +83,27 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                        if (!fileNode.isNodeType(NodeType.NT_FILE))
                                return;
 
-                       // Session jcrSession = fileNode.getSession();
                        Node contentNode = fileNode.getNode(Node.JCR_CONTENT);
                        fileBinary = contentNode.getProperty(Property.JCR_DATA).getBinary();
 
-                       Set<Artifact> artifacts = new TreeSet<Artifact>(artifactComparator);
-
-                       MyCategorizedNameVersion currCatNV = null;
-
+                       MyModularDistribution currDist = null;
                        if (FilenameUtils.getExtension(fileNode.getPath()).equals("jar"))
-                               currCatNV = listModulesFromCsvIndex(artifacts, fileNode,
-                                               fileBinary);
-                       else if (FilenameUtils.getExtension(fileNode.getPath()).equals(
-                                       "pom"))
-                               currCatNV = listModulesFromPomIndex(artifacts, fileNode,
-                                               fileBinary);
-
-                       if (artifacts.isEmpty())
-                               return; // no modules found
+                               currDist = listModulesFromCsvIndex(fileNode, fileBinary);
+                       // else if (FilenameUtils.getExtension(fileNode.getPath()).equals(
+                       // "pom"))
+                       // currDist = listModulesFromPomIndex(fileNode, fileBinary);
+
+                       if (fileNode.isNodeType(SlcTypes.SLC_MODULAR_DISTRIBUTION)
+                                       || currDist == null || !currDist.nameVersions().hasNext())
+                               return; // already indexed or no modules found
                        else {
-                               Node modules;
-                               if (fileNode.isNodeType(SlcTypes.SLC_MODULAR_DISTRIBUTION)) {
-                                       modules = fileNode.getNode(SlcNames.SLC_MODULES);
-                               } else {
-                                       fileNode.addMixin(SlcTypes.SLC_MODULAR_DISTRIBUTION);
-                                       fileNode.addMixin(SlcTypes.SLC_CATEGORIZED_NAME_VERSION);
-                                       if (currCatNV.getCategory() != null)
-                                               fileNode.setProperty(SLC_CATEGORY,
-                                                               currCatNV.getCategory());
-                                       fileNode.setProperty(SLC_NAME, currCatNV.getName());
-                                       fileNode.setProperty(SLC_VERSION, currCatNV.getVersion());
-                                       modules = JcrUtils.mkdirs(fileNode, SlcNames.SLC_MODULES,
-                                                       NodeType.NT_UNSTRUCTURED);
-                               }
-
-                               for (Artifact artifact : artifacts) {
-                                       // TODO clean this once an overwrite policy has been
-                                       // decided.
-                                       if (!modules.hasNode(artifact.getArtifactId())) {
-                                               Node moduleCoord = modules.addNode(
-                                                               artifact.getArtifactId(),
-                                                               SlcTypes.SLC_MODULE_COORDINATES);
-                                               moduleCoord.setProperty(SlcNames.SLC_NAME,
-                                                               artifact.getArtifactId());
-                                               moduleCoord.setProperty(SlcNames.SLC_VERSION,
-                                                               artifact.getVersion());
-                                               String groupId = artifact.getGroupId();
-                                               if (groupId != null && !"".equals(groupId.trim()))
-                                                       moduleCoord.setProperty(SlcNames.SLC_CATEGORY,
-                                                                       artifact.getGroupId());
-                                       }
-                               }
+                               fileNode.addMixin(SlcTypes.SLC_MODULAR_DISTRIBUTION);
+                               fileNode.addMixin(SlcTypes.SLC_CATEGORIZED_NAME_VERSION);
+                               if (currDist.getCategory() != null)
+                                       fileNode.setProperty(SLC_CATEGORY, currDist.getCategory());
+                               fileNode.setProperty(SLC_NAME, currDist.getName());
+                               fileNode.setProperty(SLC_VERSION, currDist.getVersion());
+                               indexDistribution(currDist, fileNode);
                        }
 
                        if (log.isTraceEnabled())
@@ -161,26 +114,58 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                }
        }
 
-       protected MyCategorizedNameVersion listModulesFromCsvIndex(
-                       Set<Artifact> artifacts, Node fileNode, Binary fileBinary) {
+       private void indexDistribution(ArgeoOsgiDistribution osgiDist, Node distNode)
+                       throws RepositoryException {
+               distNode.addMixin(SlcTypes.SLC_MODULAR_DISTRIBUTION);
+               distNode.addMixin(SlcTypes.SLC_CATEGORIZED_NAME_VERSION);
+               distNode.setProperty(SlcNames.SLC_CATEGORY, osgiDist.getCategory());
+               distNode.setProperty(SlcNames.SLC_NAME, osgiDist.getName());
+               distNode.setProperty(SlcNames.SLC_VERSION, osgiDist.getVersion());
+               Node modules = JcrUtils.mkdirs(distNode, SlcNames.SLC_MODULES,
+                               NodeType.NT_UNSTRUCTURED);
+
+               for (Iterator<? extends NameVersion> it = osgiDist.nameVersions(); it
+                               .hasNext();)
+                       addModule(modules, it.next());
+       }
+
+       // Helpers
+       private Node addModule(Node modules, NameVersion nameVersion)
+                       throws RepositoryException {
+               CategorizedNameVersion cnv = (CategorizedNameVersion) nameVersion;
+               Node moduleCoord = null;
+               moduleCoord = modules.addNode(cnv.getName(),
+                               SlcTypes.SLC_MODULE_COORDINATES);
+               moduleCoord.setProperty(SlcNames.SLC_CATEGORY, cnv.getCategory());
+               moduleCoord.setProperty(SlcNames.SLC_NAME, cnv.getName());
+               moduleCoord.setProperty(SlcNames.SLC_VERSION, cnv.getVersion());
+               return moduleCoord;
+       }
+
+       private MyModularDistribution listModulesFromCsvIndex(Node fileNode,
+                       Binary fileBinary) {
                JarInputStream jarIn = null;
                BufferedReader reader = null;
                try {
                        jarIn = new JarInputStream(fileBinary.getStream());
 
+                       List<CategorizedNameVersion> modules = new ArrayList<CategorizedNameVersion>();
+
                        // meta data
                        manifest = jarIn.getManifest();
                        if (manifest == null) {
                                log.error(fileNode + " has no MANIFEST");
                                return null;
                        }
-                       String symbolicName = manifest.getMainAttributes().getValue(
+                       String category = manifest.getMainAttributes().getValue(
+                                       RepoConstants.SLC_GROUP_ID);
+                       String name = manifest.getMainAttributes().getValue(
                                        Constants.BUNDLE_SYMBOLICNAME);
                        String version = manifest.getMainAttributes().getValue(
                                        Constants.BUNDLE_VERSION);
-                       String category = manifest.getMainAttributes().getValue(
-                                       "SLC-GroupId");
 
+                       Artifact distribution = new DefaultArtifact(category, name, "jar",
+                                       version);
                        // Retrieve the index file
                        JarEntry indexEntry;
                        while ((indexEntry = jarIn.getNextJarEntry()) != null) {
@@ -193,12 +178,11 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                                } catch (SecurityException se) {
                                        log.error("Invalid signature file digest "
                                                        + "for Manifest main attributes: " + entryName
-                                                       + " while looking for an index in bundle "
-                                                       + symbolicName);
+                                                       + " while looking for an index in bundle " + name);
                                }
                        }
                        if (indexEntry == null)
-                               return null; // Not a modular definition artifact
+                               return null; // Not a modular definition
 
                        // Process the index
                        reader = new BufferedReader(new InputStreamReader(jarIn));
@@ -208,13 +192,13 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                                st.nextToken(); // moduleName
                                st.nextToken(); // moduleVersion
                                String relativeUrl = st.nextToken();
-                               artifacts.add(AetherUtils.convertPathToArtifact(relativeUrl,
-                                               null));
-                               // if (log.isTraceEnabled())
-                               // log.trace("Processed dependency: " + line);
+                               Artifact currModule = AetherUtils.convertPathToArtifact(
+                                               relativeUrl, null);
+                               modules.add(new MyCategorizedNameVersion(currModule
+                                               .getGroupId(), currModule.getArtifactId(), currModule
+                                               .getVersion()));
                        }
-
-                       return new MyCategorizedNameVersion(category, symbolicName, version);
+                       return new MyModularDistribution(distribution, modules);
                } catch (Exception e) {
                        throw new SlcException("Cannot list artifacts", e);
                } finally {
@@ -223,90 +207,67 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                }
        }
 
-       protected MyCategorizedNameVersion listModulesFromPomIndex(
-                       Set<Artifact> artifacts, Node fileNode, Binary fileBinary) {
-               InputStream input = null;
-               try {
-                       input = fileBinary.getStream();
-
-                       DocumentBuilder documentBuilder = DocumentBuilderFactory
-                                       .newInstance().newDocumentBuilder();
-                       Document doc = documentBuilder.parse(input);
-
-                       // properties
-                       Properties props = new Properties();
-                       // props.setProperty("project.version",
-                       // pomArtifact.getBaseVersion());
-                       NodeList properties = doc.getElementsByTagName("properties");
-                       if (properties.getLength() > 0) {
-                               NodeList propertiesElems = properties.item(0).getChildNodes();
-                               for (int i = 0; i < propertiesElems.getLength(); i++) {
-                                       if (propertiesElems.item(i) instanceof Element) {
-                                               Element property = (Element) propertiesElems.item(i);
-                                               props.put(property.getNodeName(),
-                                                               property.getTextContent());
-                                       }
-                               }
-                       }
-
-                       // full coordinates are under <dependencyManagement><dependencies>
-                       NodeList dependencies = ((Element) doc.getElementsByTagName(
-                                       "dependencyManagement").item(0))
-                                       .getElementsByTagName("dependency");
-                       for (int i = 0; i < dependencies.getLength(); i++) {
-                               Element dependency = (Element) dependencies.item(i);
-                               String groupId = dependency.getElementsByTagName("groupId")
-                                               .item(0).getTextContent().trim();
-                               String artifactId = dependency
-                                               .getElementsByTagName("artifactId").item(0)
-                                               .getTextContent().trim();
-                               String version = dependency.getElementsByTagName("version")
-                                               .item(0).getTextContent().trim();
-                               // if (version.startsWith("${")) {
-                               // String versionKey = version.substring(0,
-                               // version.length() - 1).substring(2);
-                               // if (!props.containsKey(versionKey))
-                               // throw new SlcException("Cannot interpret version "
-                               // + version);
-                               // version = props.getProperty(versionKey);
-                               // }
-                               // NodeList scopes = dependency.getElementsByTagName("scope");
-                               // if (scopes.getLength() > 0
-                               // && scopes.item(0).getTextContent().equals("import")) {
-                               // // recurse
-                               // gatherPomDependencies(aetherTemplate, artifacts,
-                               // new DefaultArtifact(groupId, artifactId, "pom",
-                               // version));
-                               // } else {
-                               // TODO: deal with scope?
-                               // TODO: deal with type
-                               String type = "jar";
-                               Artifact artifact = new DefaultArtifact(groupId, artifactId,
-                                               type, version);
-                               artifacts.add(artifact);
-                               // }
-                       }
-
-                       String groupId = doc.getElementsByTagName("groupId").item(0)
-                                       .getTextContent().trim();
-                       String artifactId = doc.getElementsByTagName("artifactId").item(0)
-                                       .getTextContent().trim();
-                       String version = doc.getElementsByTagName("version").item(0)
-                                       .getTextContent().trim();
-
-                       return new MyCategorizedNameVersion(groupId, artifactId, version);
-
-               } catch (Exception e) {
-                       throw new SlcException("Cannot process pom " + fileNode, e);
-               } finally {
-                       IOUtils.closeQuietly(input);
-               }
-       }
-
-       /** Separator used to parse the tabular file, default is "," */
-       public void setSeparator(String modulesUrlSeparator) {
-               this.separator = modulesUrlSeparator;
-       }
+       // private MyModularDistribution listModulesFromPomIndex(Node fileNode,
+       // Binary fileBinary) {
+       // InputStream input = null;
+       // List<CategorizedNameVersion> modules = new
+       // ArrayList<CategorizedNameVersion>();
+       // try {
+       // input = fileBinary.getStream();
+       //
+       // DocumentBuilder documentBuilder = DocumentBuilderFactory
+       // .newInstance().newDocumentBuilder();
+       // Document doc = documentBuilder.parse(input);
+       // // properties
+       // Properties props = new Properties();
+       // // props.setProperty("project.version",
+       // // pomArtifact.getBaseVersion());
+       // NodeList properties = doc.getElementsByTagName("properties");
+       // if (properties.getLength() > 0) {
+       // NodeList propertiesElems = properties.item(0).getChildNodes();
+       // for (int i = 0; i < propertiesElems.getLength(); i++) {
+       // if (propertiesElems.item(i) instanceof Element) {
+       // Element property = (Element) propertiesElems.item(i);
+       // props.put(property.getNodeName(),
+       // property.getTextContent());
+       // }
+       // }
+       // }
+       //
+       // // full coordinates are under <dependencyManagement><dependencies>
+       // NodeList dependencies = ((Element) doc.getElementsByTagName(
+       // "dependencyManagement").item(0))
+       // .getElementsByTagName("dependency");
+       // for (int i = 0; i < dependencies.getLength(); i++) {
+       // Element dependency = (Element) dependencies.item(i);
+       // String groupId = dependency.getElementsByTagName("groupId")
+       // .item(0).getTextContent().trim();
+       // String artifactId = dependency
+       // .getElementsByTagName("artifactId").item(0)
+       // .getTextContent().trim();
+       // String version = dependency.getElementsByTagName("version")
+       // .item(0).getTextContent().trim();
+       // modules.add(new MyCategorizedNameVersion(groupId, artifactId,
+       // version));
+       // }
+       //
+       // String groupId = doc.getElementsByTagName("groupId").item(0)
+       // .getTextContent().trim();
+       // String artifactId = doc.getElementsByTagName("artifactId").item(0)
+       // .getTextContent().trim();
+       // String version = doc.getElementsByTagName("version").item(0)
+       // .getTextContent().trim();
+       //
+       // Artifact currDist = new DefaultArtifact(groupId, artifactId, "pom",
+       // version);
+       //
+       // return new MyModularDistribution(currDist, modules);
+       // } catch (Exception e) {
+       // throw new SlcException("Cannot process pom " + fileNode, e);
+       // } finally {
+       // IOUtils.closeQuietly(input);
+       // }
+       // }
 
        /** The created modular distribution */
        private static class MyCategorizedNameVersion extends DefaultNameVersion
@@ -323,4 +284,39 @@ public class ModularDistributionIndexer implements NodeIndexer, SlcNames {
                        return category;
                }
        }
+
+       /**
+        * A consistent and versioned OSGi distribution, which can be built and
+        * tested.
+        */
+       private class MyModularDistribution extends ArtifactDistribution implements
+                       ArgeoOsgiDistribution {
+
+               private List<CategorizedNameVersion> modules;
+
+               public MyModularDistribution(Artifact artifact,
+                               List<CategorizedNameVersion> modules) {
+                       super(artifact);
+                       this.modules = modules;
+               }
+
+               public Iterator<CategorizedNameVersion> nameVersions() {
+                       return modules.iterator();
+               }
+
+               // Modular distribution interface methods. Not yet used.
+               public Distribution getModuleDistribution(String moduleName,
+                               String moduleVersion) {
+                       return null;
+               }
+
+               public Object getModulesDescriptor(String descriptorType) {
+                       return null;
+               }
+       }
+
+       /** Separator used to parse the tabular file, default is "," */
+       public void setSeparator(String modulesUrlSeparator) {
+               this.separator = modulesUrlSeparator;
+       }
 }
\ No newline at end of file