You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2014/08/25 01:38:31 UTC

git commit: First complete implementation of TAP5-2192

Repository: tapestry-5
Updated Branches:
  refs/heads/master adf7e8bd4 -> b1062f538


First complete implementation of TAP5-2192


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/b1062f53
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/b1062f53
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/b1062f53

Branch: refs/heads/master
Commit: b1062f538846cdca943d0d4615d888b2e70a1b87
Parents: adf7e8b
Author: Thiago H. de Paula Figueiredo <th...@apache.org>
Authored: Sun Aug 24 20:38:13 2014 -0300
Committer: Thiago H. de Paula Figueiredo <th...@apache.org>
Committed: Sun Aug 24 20:38:13 2014 -0300

----------------------------------------------------------------------
 .../MavenComponentLibraryInfoSource.java        | 184 +++++++++++++++++--
 .../tapestry5/modules/TapestryModule.java       |  40 +++-
 .../services/ComponentLibraryInfo.java          |  14 +-
 3 files changed, 215 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b1062f53/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MavenComponentLibraryInfoSource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MavenComponentLibraryInfoSource.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MavenComponentLibraryInfoSource.java
index 3a985b6..f80dec2 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MavenComponentLibraryInfoSource.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/MavenComponentLibraryInfoSource.java
@@ -13,17 +13,31 @@
 // limitations under the License.
 package org.apache.tapestry5.internal.services;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.Properties;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.tapestry5.ioc.services.ClasspathMatcher;
+import org.apache.tapestry5.ioc.services.ClasspathScanner;
 import org.apache.tapestry5.services.ComponentLibraryInfo;
 import org.apache.tapestry5.services.ComponentLibraryInfoSource;
 import org.apache.tapestry5.services.LibraryMapping;
 import org.slf4j.Logger;
+import org.w3c.dom.Document;
 
 /**
  * {@link ComponentLibraryInfoSource} implementation based on the pom.xml and pom.properties files 
@@ -33,36 +47,170 @@ public class MavenComponentLibraryInfoSource implements ComponentLibraryInfoSour
 {
     
     final private Logger logger;
+    
+    final private Set<String> pomPaths;
+    
+    final private Map<String, ComponentLibraryInfo> cache = new HashMap<String, ComponentLibraryInfo>();
+    
+    final private Map<String, String> pomPathToRootUrl;
+    
+    final private DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 
-    public MavenComponentLibraryInfoSource(Logger logger)
+    public MavenComponentLibraryInfoSource(Logger logger, ClasspathScanner classpathScanner)
     {
         super();
         this.logger = logger;
+        this.pomPaths = Collections.unmodifiableSet(findPomPaths(classpathScanner));
+        pomPathToRootUrl = new WeakHashMap<String, String>(pomPaths.size());
     }
 
     @Override
     public ComponentLibraryInfo find(LibraryMapping libraryMapping)
     {
+        ComponentLibraryInfo info = null;
+        if (cache.containsKey(libraryMapping.libraryName))
+        {
+            info = cache.get(libraryMapping.libraryName);
+        }
+        else
+        {
+            final String pomPath = getPomPath(libraryMapping);
+            if (pomPath != null)
+            {
+                InputStream inputStream = getClass().getResourceAsStream("/" + pomPath);
+                info = parse(inputStream);
+                cache.put(libraryMapping.libraryName, info);
+            }
+            else
+            {
+                cache.put(libraryMapping.libraryName, null);
+            }
+        }
+        return info;
+    }
+
+    /**
+     * @param inputStream
+     * @return
+     */
+    private ComponentLibraryInfo parse(InputStream inputStream)
+    {
+        ComponentLibraryInfo info = null;
+        if (inputStream != null)
+        {
+            
+            Document document;
+            
+            try
+            {
+                DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+                document = documentBuilder.parse(inputStream);
+            }
+            catch (Exception e)
+            {
+                logger.warn("Exception while parsing pom.xml", e);
+                return null;
+            }
+            
+            info = new ComponentLibraryInfo();
+            info.setGroupId(extractText(document, "(/project/groupId | /project/parent/groupId)[1]"));
+            info.setArtifactId(extractText(document, "/project/artifactId"));
+            info.setVersion(extractText(document, "/project/version"));
+            info.setName(extractText(document, "/project/name"));
+            info.setDescription(extractText(document, "/project/description"));
+            info.setDocumentationUrl(extractText(document, "/project/properties/documentationUrl"));
+            info.setHomepageUrl(extractText(document, "/project/properties/homepageUrl"));
+            info.setIssueTrackerUrl(extractText(document, "/project/issueManagement/url"));
+            info.setJavadocUrl(extractText(document, "/project/properties/javadocUrl"));
+            info.setSourceBrowseUrl(extractText(document, "/project/scm/url"));
+            info.setSourceRootUrl(extractText(document, "/project/scm/connection"));
+            String tags = extractText(document, "/project/properties/tags");
+            if (tags != null && tags.length() > 0)
+            {
+                info.setTags(Arrays.asList(tags.split(",")));
+            }
+            
+        }
         
-//        final File root = getRoot(libraryMapping);
-//        
-//        System.out.println(root);
+        return info;
         
-        return null;
     }
 
-//    private File getRoot(LibraryMapping libraryMapping)
-//    {
-//        final String rootPackageConverted = libraryMapping.getRootPackage().replace('.', '/');
-//        final URL rootPackageUrl = getClass().getClassLoader().getResource(rootPackageConverted);
-//        final String rootPath = "jar:" + rootPackageUrl.getPath().replace(rootPackageConverted, "") + "META-INF/maven/";
-//        final URL rootUrl = getClass().getClassLoader().getResource(rootPath);
-//        return root;
-//    }
+    private String extractText(Document document, String xpathExpression)
+    {
+        XPath xpath = XPathFactory.newInstance().newXPath();
+        String text;
+        try
+        {
+            XPathExpression expression = xpath.compile(xpathExpression);
+            text = (String) expression.evaluate(document, XPathConstants.STRING);
+        }
+        catch (XPathExpressionException e)
+        {
+            throw new RuntimeException(e);
+        }
+        return text;
+    }
+
+    private String getPomPath(LibraryMapping libraryMapping)
+    {
+        final String rootPackageConverted = libraryMapping.getRootPackage().replace('.', '/');
+        final URL rootPackageUrl = getClass().getClassLoader().getResource(rootPackageConverted);
+        String path = rootPackageUrl.toString();
+        String url = null;
+        if (path.contains("!/"))
+        {
+            path = path.substring(0, path.indexOf("!/"));
+        }
+        for (String pomPath : pomPaths)
+        {
+            if (path.equals(getPomPathUrl(pomPath))) {
+                url = pomPath;
+                break;
+            }
+        }
+        return url;
+    }
     
-    private static InputStream open(String path)
+    private String getPomPathUrl(String pomPath)
+    {
+        String url = pomPathToRootUrl.get(pomPath);
+        if (url == null)
+        {
+            for (String path : pomPaths)
+            {
+                final URL resource = getClass().getResource("/" + path);
+                String resourcePath = null;
+                if (resource != null && resource.toString().contains("!/")) 
+                {
+                    resourcePath = resource.toString();
+                    resourcePath = resourcePath.substring(0, resourcePath.indexOf("!/"));
+                }
+                pomPathToRootUrl.put(path, resourcePath);
+                url = resourcePath;
+            }
+        }
+        return url;
+    }
+
+    private static Set<String> findPomPaths(ClasspathScanner classpathScanner)
     {
-        return MavenComponentLibraryInfoSource.class.getClassLoader().getResourceAsStream(path);
+        final ClasspathMatcher classpathMatcher = new ClasspathMatcher()
+        {
+            @Override
+            public boolean matches(String packagePath, String fileName)
+            {
+                return fileName.equals("pom.xml");
+            }
+        };
+        try
+        {
+            return classpathScanner.scan("META-INF/maven", classpathMatcher);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException("Exception while finding pom.xml files in the classpath", e);
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b1062f53/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index 195b617..bb71643 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -97,7 +97,9 @@ import org.slf4j.Logger;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -2718,9 +2720,45 @@ public final class TapestryModule
     }
 
     @Contribute(ComponentLibraryInfoSource.class)
-    public static void addMavenComponentLibraryInfoSource(OrderedConfiguration<ComponentLibraryInfoSource> configuration)
+    public static void addBuiltInComponentLibraryInfoSources(OrderedConfiguration<ComponentLibraryInfoSource> configuration)
     {
         configuration.addInstance("Maven", MavenComponentLibraryInfoSource.class);
+        configuration.add("TapestryCore", new TapestryCoreComponentLibraryInfoSource());
+    }
+    
+    private static final class TapestryCoreComponentLibraryInfoSource implements
+            ComponentLibraryInfoSource
+    {
+        @Override
+        public ComponentLibraryInfo find(LibraryMapping libraryMapping)
+        {
+            ComponentLibraryInfo info = null;
+            if (libraryMapping.libraryName.equals("core"))
+            {
+            
+                final InputStream inputStream = TapestryModule.class
+                        .getResourceAsStream("/META-INF/gradle/org.apache.tapestry/tapestry-core/project.properties");
+                
+                if (inputStream != null)
+                {
+                    Properties properties = new Properties();
+                    try
+                    {
+                        properties.load(inputStream);
+                    }
+                    catch (IOException e)
+                    {
+                        throw new RuntimeException(e);
+                    }
+                    info = new ComponentLibraryInfo();
+                    info.setArtifactId("tapestry-core");
+                    info.setGroupId("org.apache.tapestry");
+                    info.setVersion(properties.getProperty("version"));
+                    info.setDescription("Tapestry 5 core component library");
+                }
+            }
+            return info;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b1062f53/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java
index 92323af..e752e2a 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLibraryInfo.java
@@ -14,6 +14,7 @@
 package org.apache.tapestry5.services;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -35,7 +36,7 @@ public final class ComponentLibraryInfo implements Serializable
     private String name, description, homepageUrl, documentationUrl, sourceBrowseUrl, issueTrackerUrl, sourceRootUrl, 
                    javadocUrl, groupId, artifactId, version;
     
-    private List<String> tags;
+    private List<String> tags = new ArrayList<String>();
     
     /**
      * Returns the actual name of the component library (not the identifier). 
@@ -199,6 +200,11 @@ public final class ComponentLibraryInfo implements Serializable
     {
         if (this.sourceRootUrl != null) throwExceptionIfAlreadySet("sourceRootUrl", sourceRootUrl);
         this.sourceRootUrl = sourceRootUrl;
+        if (sourceUrlResolver == null)
+        {
+            sourceUrlResolver = new DefaultSourceUrlResolver();
+            sourceUrlResolver.setRootUrl(sourceRootUrl);
+        }
     }
 
     public void setJavadocUrl(String javadocUrl)
@@ -329,13 +335,13 @@ public final class ComponentLibraryInfo implements Serializable
          * Sets the source root URL. This method will be invoked by {@link ComponentLibraryInfo#setSourceBrowseUrl(String)}.
          */
         void setRootUrl(String url);
+        
     }
     
     /**
-     * {@link SourceUrlResolver} implementation based on Maven Java project conventions and 
-     * GitWeb as online Git repository viewer, which Tapestry itself uses.
+     * Default {@link SourceUrlResolver} implementation.
      */
-    public static class GitWebMavenSourceUrlResolver implements SourceUrlResolver
+    public static class DefaultSourceUrlResolver implements SourceUrlResolver
     {
 
         private String sourceRootUrl;