Work on the binaries indexer.
authorBruno Sinou <bsinou@argeo.org>
Wed, 12 Mar 2014 18:20:48 +0000 (18:20 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 12 Mar 2014 18:20:48 +0000 (18:20 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6895 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/commands/NormalizeWorkspace.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/DistributionBundleIndexer.java

index ba669838355ffff40dc5bf6d1f77d6f48d5ccb66..1e1265a1d3a1b2a962527f71a62db83689c48afe 100644 (file)
@@ -200,6 +200,14 @@ public class NormalizeWorkspace extends AbstractHandler implements SlcNames {
                                                        }
                                                        monitor.worked(1);
                                                }
+                               } else if (node.getName().endsWith(".pom")) {
+                                       distBundleIndexer.index(node);
+                                       if (node.getSession().hasPendingChanges()) {
+                                               node.getSession().save();
+                                               if (log.isDebugEnabled())
+                                                       log.debug("Processed artifact " + node.getPath());
+                                       }
+                                       monitor.worked(1);
                                } else {
                                        monitor.worked(1);
                                }
index 7dfefc2a1ed9ca4f4fde3c2669004473684f512d..90d5a39807bf4f7a9caa5f2958f75a7bffe334dd 100644 (file)
@@ -1,12 +1,16 @@
 package org.argeo.slc.repo;
 
 import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 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;
@@ -14,110 +18,93 @@ import java.util.jar.Manifest;
 import javax.jcr.Binary;
 import javax.jcr.Node;
 import javax.jcr.Property;
-import javax.jcr.Session;
 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;
 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.aether.AetherUtils;
+import org.argeo.slc.aether.ArtifactIdComparator;
 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;
 
 /**
- * Index distribution bundles that is mainly dep artifacts that have generate a
- * modular distribution csv index during maven build
+ * Create or update JCR meta-data for modularDistribution bundles: <list><li>
+ * .jar: dependency artifacts with csv index</li> <li>.pom: group index artifact
+ * (binaries, sources) with tag dependency management</li> </list>
  */
 public class DistributionBundleIndexer implements NodeIndexer {
        private final static Log log = LogFactory
                        .getLog(DistributionBundleIndexer.class);
 
        private final static String INDEX_FILE_NAME = "modularDistribution.csv";
-
-       // private final String url;
+       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;
-
-       /** can be null */
-       // private String baseUrl;
-       /** can be null */
-       // private String relativeUrl;
-
-       private List<Artifact> artifacts;
+       // private String symbolicName;
+       // private String version;
 
+       // private List<Artifact> artifacts;
        private String separator = ",";
 
-       // public DistributionBundleIndexer(String url) {
-       // this.url = url;
-       // }
-       //
-       // public DistributionBundleIndexer(String baseUrl, String relativeUrl) {
-       // if (baseUrl == null || !baseUrl.endsWith("/"))
-       // throw new SlcException("Base url " + baseUrl + " badly formatted");
-       // if (relativeUrl.startsWith("http") || relativeUrl.startsWith("file:"))
-       // throw new SlcException("Relative URL " + relativeUrl
-       // + " badly formatted");
-       // this.url = baseUrl + relativeUrl;
-       // this.baseUrl = baseUrl;
-       // this.relativeUrl = relativeUrl;
-       // }
+       private Comparator<Artifact> artifactComparator = new ArtifactIdComparator();
+
+       // private Set<Artifact> artifacts = new
+       // TreeSet<Artifact>(artifactComparator);
 
        public Boolean support(String path) {
-               return FilenameUtils.getExtension(path).equals("jar");
+               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;
+               return false;
        }
 
        public void index(Node fileNode) {
-               JarInputStream jarIn = null;
+               // JarInputStream jarIn = null;
                Binary fileBinary = null;
                try {
-                       if (!support(fileNode.getPath()))
+
+                       String fileNodePath = fileNode.getPath();
+                       if (!support(fileNodePath))
                                return;
 
                        if (!fileNode.isNodeType(NodeType.NT_FILE))
                                return;
 
-                       Session jcrSession = fileNode.getSession();
+                       // Session jcrSession = fileNode.getSession();
                        Node contentNode = fileNode.getNode(Node.JCR_CONTENT);
                        fileBinary = contentNode.getProperty(Property.JCR_DATA).getBinary();
-                       jarIn = new JarInputStream(fileBinary.getStream());
 
-                       // meta data
-                       manifest = jarIn.getManifest();
-                       if (manifest == null) {
-                               log.error(fileNode + " has no MANIFEST");
-                               return;
-                       }
-                       symbolicName = manifest.getMainAttributes().getValue(
-                                       Constants.BUNDLE_SYMBOLICNAME);
-                       version = manifest.getMainAttributes().getValue(
-                                       Constants.BUNDLE_VERSION);
+                       Set<Artifact> artifacts = new TreeSet<Artifact>(artifactComparator);
 
-                       JarEntry indexEntry;
-                       while ((indexEntry = jarIn.getNextJarEntry()) != null) {
-                               String entryName = indexEntry.getName();
-                               if (entryName.equals(INDEX_FILE_NAME)) {
-                                       break;
-                               }
-                               jarIn.closeEntry();
-                       }
-
-                       // list artifacts
-                       if (indexEntry == null)
-                               return; // Not a modular definition artifact
-
-                       // throw new SlcException("No index " + INDEX_FILE_NAME + " in "
-                       // + fileNode.getPath());
-                       //
-
-                       artifacts = listArtifacts(jarIn);
+                       if (FilenameUtils.getExtension(fileNode.getPath()).equals("jar"))
+                               listModulesFromCsvIndex(artifacts, fileNode, fileBinary);
+                       else if (FilenameUtils.getExtension(fileNode.getPath()).equals(
+                                       "pom"))
+                               listModulesFromPomIndex(artifacts, fileNode, fileBinary);
 
-                       if (artifacts == null || artifacts.isEmpty())
+                       if (artifacts.isEmpty())
                                return; // no modules found
                        else {
                                Node modules;
@@ -149,8 +136,6 @@ public class DistributionBundleIndexer implements NodeIndexer {
 
                        }
 
-                       jarIn.closeEntry();
-
                        // find base URL
                        // won't work if distribution artifact is not listed
                        // for (int i = 0; i < artifacts.size(); i++) {
@@ -168,91 +153,138 @@ public class DistributionBundleIndexer implements NodeIndexer {
                } catch (Exception e) {
                        throw new SlcException("Cannot list dependencies from " + fileNode,
                                        e);
-               } finally {
-                       if (jarIn != null)
-                               try {
-                                       jarIn.close();
-                               } catch (IOException e) {
-                                       // silent
-                               }
                }
        }
 
-       protected List<Artifact> listArtifacts(InputStream in) {
-               List<Artifact> artifacts = new ArrayList<Artifact>();
+       protected void listModulesFromCsvIndex(Set<Artifact> artifacts,
+                       Node fileNode, Binary fileBinary) {
+               // List<Artifact> artifacts = new ArrayList<Artifact>();
+               JarInputStream jarIn = null;
                BufferedReader reader = null;
+
                try {
-                       reader = new BufferedReader(new InputStreamReader(in));
+                       jarIn = new JarInputStream(fileBinary.getStream());
+
+                       // meta data
+                       // symbolicName = manifest.getMainAttributes().getValue(
+                       // Constants.BUNDLE_SYMBOLICNAME);
+                       // version = manifest.getMainAttributes().getValue(
+                       // Constants.BUNDLE_VERSION);
+
+                       manifest = jarIn.getManifest();
+                       if (manifest == null) {
+                               log.error(fileNode + " has no MANIFEST");
+                               return;
+                       }
+
+                       JarEntry indexEntry;
+                       while ((indexEntry = jarIn.getNextJarEntry()) != null) {
+                               String entryName = indexEntry.getName();
+                               if (entryName.equals(INDEX_FILE_NAME)) {
+                                       break;
+                               }
+                               jarIn.closeEntry();
+                       }
+
+                       if (indexEntry == null)
+                               return; // Not a modular definition artifact
+
+                       reader = new BufferedReader(new InputStreamReader(jarIn));
                        String line = null;
                        while ((line = reader.readLine()) != null) {
-
                                StringTokenizer st = new StringTokenizer(line, separator);
-                               // String moduleName =
-                               st.nextToken();
-                               // String moduleVersion =
-                               st.nextToken();
+                               st.nextToken(); // moduleName
+                               st.nextToken(); // moduleVersion
                                String relativeUrl = st.nextToken();
 
-                               //
-                               // String Category = getCategoryFromRelativeUrl(relativeUrl,
-                               // moduleName);
-
                                artifacts.add(AetherUtils.convertPathToArtifact(relativeUrl,
                                                null));
-
                                if (log.isTraceEnabled())
                                        log.debug("Processed dependency: " + line);
                        }
                } catch (Exception e) {
                        throw new SlcException("Cannot list artifacts", e);
+               } finally {
+                       IOUtils.closeQuietly(jarIn);
+                       IOUtils.closeQuietly(reader);
                }
-               return artifacts;
        }
 
-       // /** Relative path to the directories where the files will be stored */
-       // private String getCategoryFromRelativeUrl(String relativeUrl,
-       // String moduleName) {
-       // int index = relativeUrl.indexOf("moduleName");
-       // if (index < 1)
-       // throw new SlcException("Unvalid relative URL: " + relativeUrl
-       // + " for module " + moduleName);
-       // // Remove trailing /
-       // String result = relativeUrl.substring(0, index - 1);
-       // return result.replace('/', '.');
-       // }
-
-       /**
-        * List full URLs of the bundles, based on base URL, usable directly for
-        * download.
-        */
-       // public List/* <String> */listUrls() {
-       // if (baseUrl == null)
-       // throw new SlcException("Base URL is not set");
-       //
-       // if (artifacts == null)
-       // throw new SlcException("Artifact list not initialized");
-       //
-       // List/* <String> */urls = new ArrayList();
-       // for (int i = 0; i < artifacts.size(); i++) {
-       // OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i);
-       // urls.add(baseUrl + osgiArtifact.getRelativeUrl());
-       // }
-       // return urls;
-       // }
-       //
-       // public void setBaseUrl(String baseUrl) {
-       // this.baseUrl = baseUrl;
-       // }
+       protected void 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);
+                               // }
+                       }
+               } 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;
        }
 
-       // public String getRelativeUrl() {
-       // return relativeUrl;
-       // }
-
        /** One of the listed artifact */
        protected static class OsgiArtifact {
                private final String category;