You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2016/02/17 14:39:21 UTC

svn commit: r1730832 - in /sling/trunk/tooling/support/source: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/tooling/ src/main/java/org/apache/sling/tooling/...

Author: rombert
Date: Wed Feb 17 13:39:21 2016
New Revision: 1730832

URL: http://svn.apache.org/viewvc?rev=1730832&view=rev
Log:
SLING-5528 - Allow discovery of sources of the bundles currently
deployed in a Sling runtime

Create a new tooling/support/source bundle. This bundle contains a
servlet which allows discovery of source bundles based on pom.properties
files embedded in the bundles.

Added:
    sling/trunk/tooling/support/source/
    sling/trunk/tooling/support/source/pom.xml
    sling/trunk/tooling/support/source/src/
    sling/trunk/tooling/support/source/src/main/
    sling/trunk/tooling/support/source/src/main/java/
    sling/trunk/tooling/support/source/src/main/java/org/
    sling/trunk/tooling/support/source/src/main/java/org/apache/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/
    sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java

Added: sling/trunk/tooling/support/source/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/support/source/pom.xml?rev=1730832&view=auto
==============================================================================
--- sling/trunk/tooling/support/source/pom.xml (added)
+++ sling/trunk/tooling/support/source/pom.xml Wed Feb 17 13:39:21 2016
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>26</version>
+    </parent>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.tooling.support.source</artifactId>
+    <version>0.9.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Tooling Support Source</name>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/tooling/support/source</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/source</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/source</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+           </plugin>
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>2.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

Added: sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java?rev=1730832&view=auto
==============================================================================
--- sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java (added)
+++ sling/trunk/tooling/support/source/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java Wed Feb 17 13:39:21 2016
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.tooling.support.source.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.io.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * The <tt>SourceReferencesServlet</tt> infers and outputs source information about bundles running a Sling instance
+ */
+@Component
+@Service(value = Servlet.class)
+@Property(name="alias", value="/system/sling/tooling/sourceReferences.json")
+public class SourceReferencesServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+    
+    private static final String KEY_TYPE = "__type__";
+    private static final String KEY_GROUP_ID = "groupId";
+    private static final String KEY_ARTIFACT_ID = "artifactId";
+    private static final String KEY_VERSION = "version";
+
+    private static final String VALUE_TYPE_MAVEN = "maven";
+
+    private static final String FELIX_FW_GROUP_ID = "org.apache.felix";
+    private static final String FELIX_FW_ARTIFACT_ID = "org.apache.felix.framework";
+
+    private ComponentContext ctx;
+
+    protected void activate(ComponentContext ctx) {
+        this.ctx = ctx;
+    }    
+    
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        try {
+            response.setContentType("application/json");
+            
+            JSONWriter w = new JSONWriter(response.getWriter());
+            w.array();
+            
+            for ( Bundle bundle : ctx.getBundleContext().getBundles() ) {
+
+                Object bundleVersion = bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+                
+                w.object();
+                w.key(Constants.BUNDLE_SYMBOLICNAME);
+                w.value(bundle.getSymbolicName());
+                w.key(Constants.BUNDLE_VERSION);
+                w.value(bundleVersion);
+                
+                w.key("sourceReferences");
+                w.array();
+
+                // the system bundle is embedded by the launchpad jar so we need special handling
+                // since the pom.properties file is not located in the bundle
+                if ( bundle.getBundleId() == 0 && bundle.getSymbolicName().equals(FELIX_FW_ARTIFACT_ID) ) {
+                    w.object();
+                    w.key(KEY_TYPE).value(VALUE_TYPE_MAVEN);
+                    w.key(KEY_GROUP_ID).value(FELIX_FW_GROUP_ID);
+                    w.key(KEY_ARTIFACT_ID).value(FELIX_FW_ARTIFACT_ID);
+                    w.key(KEY_VERSION).value(bundleVersion);
+                    w.endObject();
+                }
+
+                // look for pom.properties in the bundle ( the original bundle, fragments )
+                collectMavenSourceReferences(w, bundle);
+                
+                // look for pom.properties in jars embedded in the bundle
+                for ( String jar : getEmbeddedJars(bundle)) {
+                    URL entry = bundle.getEntry(jar);
+                    // incorrect or inaccessible entry
+                    if ( entry == null ) {
+                        continue;
+                    }
+                    collectMavenSourceRerefences(w, entry);
+                }
+                w.endArray();
+                w.endObject();
+            }
+            
+            w.endArray();
+        } catch (JSONException e) {
+            throw new ServletException(e);
+        }
+    }
+
+    private void collectMavenSourceReferences(JSONWriter w, Bundle bundle) throws IOException, JSONException {
+        
+        Enumeration<?> entries = bundle.findEntries("/META-INF/maven", "pom.properties", true);
+        
+        while ( entries != null && entries.hasMoreElements()) {
+            URL entry = (URL) entries.nextElement();
+            
+            InputStream in = entry.openStream();
+            try {
+                writeMavenGav(w, in);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+        }
+    }
+    
+    private void writeMavenGav(JSONWriter w, InputStream in) throws IOException, JSONException {
+        
+        Properties p = new Properties();
+        p.load(in);
+        w.object();
+        w.key(KEY_TYPE).value(VALUE_TYPE_MAVEN);
+        for ( String prop : new String[] { KEY_GROUP_ID, KEY_ARTIFACT_ID, KEY_VERSION} ) {
+            w.key(prop).value(p.getProperty(prop));
+        }
+        w.endObject();
+    }
+    
+    private List<String> getEmbeddedJars(Bundle bundle) {
+        
+        String classPath = (String) bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
+        if ( classPath == null ) {
+            return Collections.emptyList();
+        }
+
+        List<String> embeddedJars = new ArrayList<String>();
+        
+        String[] classPathEntryNames = classPath.split("\\,");
+        for ( String classPathEntry : classPathEntryNames ) {
+            if ( classPathEntry.endsWith(".jar")) {
+                embeddedJars.add(classPathEntry);
+            }
+        }
+        
+        return embeddedJars;
+    }
+    
+    private void collectMavenSourceRerefences(JSONWriter w, URL entry) throws IOException, JSONException {
+        
+        InputStream wrappedIn = entry.openStream();
+        try {
+            JarInputStream jarIs = new JarInputStream(wrappedIn);
+            JarEntry jarEntry;
+            while ( ( jarEntry = jarIs.getNextJarEntry()) != null ) {
+                String entryName = jarEntry.getName();
+                if ( entryName.startsWith("META-INF/maven/") && entryName.endsWith("/pom.properties")) {
+                    writeMavenGav(w, jarIs);
+                }
+            }
+        } finally {
+            IOUtils.closeQuietly(wrappedIn);
+        }
+    }    
+
+}