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 2017/11/07 10:23:44 UTC

[sling-org-apache-sling-tooling-support-source] annotated tag org.apache.sling.tooling.support.source-1.0.0 created (now 5510f30)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.tooling.support.source-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tooling-support-source.git.


      at 5510f30  (tag)
 tagging 0f22b43922c8835c5ea2a3d635a3f354a5bb243e (commit)
      by Robert Munteanu
      on Tue Mar 1 15:19:10 2016 +0000

- Log -----------------------------------------------------------------
org.apache.sling.tooling.support.source-1.0.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new 333e91a  SLING-5528 - Allow discovery of sources of the bundles currently deployed in a Sling runtime
     new 7fa9083  SLING-5528: Allow discovery of sources of the bundles currently deployed in a Sling runtime
     new c92496b  [maven-release-plugin] prepare release org.apache.sling.tooling.support.source-1.0.0
     new 0f22b43  [maven-release-plugin] copy for tag org.apache.sling.tooling.support.source-1.0.0

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-tooling-support-source] 03/04: [maven-release-plugin] prepare release org.apache.sling.tooling.support.source-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.tooling.support.source-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tooling-support-source.git

commit c92496b33d2446f791eff2f87a6f52d158ffe054
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 1 15:18:57 2016 +0000

    [maven-release-plugin] prepare release org.apache.sling.tooling.support.source-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/source@1733085 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 1369f2b..9b68c60 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,15 +27,15 @@
     </parent>
 
     <artifactId>org.apache.sling.tooling.support.source</artifactId>
-    <version>0.9.0-SNAPSHOT</version>
+    <version>1.0.0</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>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.tooling.support.source-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.tooling.support.source-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.tooling.support.source-1.0.0</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-tooling-support-source] 01/04: SLING-5528 - Allow discovery of sources of the bundles currently deployed in a Sling runtime

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.tooling.support.source-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tooling-support-source.git

commit 333e91a62f69866532d1430b3294f5ed81f65a41
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed Feb 17 13:39:21 2016 +0000

    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.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/source@1730832 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  90 ++++++++++
 .../source/impl/SourceReferencesServlet.java       | 190 +++++++++++++++++++++
 2 files changed, 280 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e8533ac
--- /dev/null
+++ b/pom.xml
@@ -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>
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
new file mode 100644
index 0000000..8806a2d
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
@@ -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);
+        }
+    }    
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-tooling-support-source] 04/04: [maven-release-plugin] copy for tag org.apache.sling.tooling.support.source-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.tooling.support.source-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tooling-support-source.git

commit 0f22b43922c8835c5ea2a3d635a3f354a5bb243e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 1 15:19:10 2016 +0000

    [maven-release-plugin] copy for tag org.apache.sling.tooling.support.source-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.tooling.support.source-1.0.0@1733086 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-tooling-support-source] 02/04: SLING-5528: Allow discovery of sources of the bundles currently deployed in a Sling runtime

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.tooling.support.source-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tooling-support-source.git

commit 7fa9083970ecb8fb6d35d7f16423541084dcaa70
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 1 15:11:31 2016 +0000

    SLING-5528: Allow discovery of sources of the bundles currently deployed
    in a Sling runtime
    
    - refactor the SourceReferencesServlet to allow SourceReferences to be
    contributed by SourceReferenceFinders
    - create a FelixJettySourceReferenceFinder
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/tooling/support/source@1733084 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |   5 +-
 .../impl/FelixJettySourceReferenceFinder.java      |  77 ++++++++
 .../tooling/support/source/impl/PomHandler.java    |  93 ++++++++++
 .../support/source/impl/SourceReference.java       |  43 +++++
 .../source/impl/SourceReferenceException.java      |  39 ++++
 .../support/source/impl/SourceReferenceFinder.java |  27 +++
 .../source/impl/SourceReferencesServlet.java       |  44 ++++-
 .../support/source/impl/PomHandlerTest.java        |  53 ++++++
 .../tooling/support/source/impl/felix-pom.xml      | 205 +++++++++++++++++++++
 9 files changed, 576 insertions(+), 10 deletions(-)

diff --git a/pom.xml b/pom.xml
index e8533ac..1369f2b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,6 @@
         <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>
@@ -67,6 +66,10 @@
             <artifactId>servlet-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
         </dependency>
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/FelixJettySourceReferenceFinder.java b/src/main/java/org/apache/sling/tooling/support/source/impl/FelixJettySourceReferenceFinder.java
new file mode 100644
index 0000000..b9d1ee5
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/FelixJettySourceReferenceFinder.java
@@ -0,0 +1,77 @@
+/*
+ * 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.Collections;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.io.IOUtils;
+import org.osgi.framework.Bundle;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class FelixJettySourceReferenceFinder implements SourceReferenceFinder {
+
+    @Override
+    public List<SourceReference> findSourceReferences(Bundle bundle) throws SourceReferenceException {
+        // the org.apache.felix.http.jetty bundle does not retain references to the source bundles
+        // so infer them from the X-Jetty-Version header
+        if ( !bundle.getSymbolicName().equals("org.apache.felix.http.jetty")) {
+            return Collections.emptyList();
+        }
+            
+        final Object jettyVersion = bundle.getHeaders().get("X-Jetty-Version");
+        if ( !(jettyVersion instanceof String) ) {
+            return Collections.emptyList();
+        }
+        
+        URL entry = bundle.getEntry("/META-INF/maven/org.apache.felix/org.apache.felix.http.jetty/pom.xml");
+        
+        InputStream pom = null;
+        try {
+            pom = entry.openStream();
+            
+            try {
+                SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+                SAXParser parser = parserFactory.newSAXParser();
+                PomHandler handler = new PomHandler((String) jettyVersion);
+                parser.parse(new InputSource(pom), handler);
+                
+                return handler.getReferences();
+            } catch (SAXException e) {
+                throw new SourceReferenceException(e);
+            } catch (ParserConfigurationException e) {
+                throw new SourceReferenceException(e);
+            } finally {
+                IOUtils.closeQuietly(pom);
+            }
+        } catch (IOException e) {
+            throw new SourceReferenceException(e);
+        } finally {
+            IOUtils.closeQuietly(pom);
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/PomHandler.java b/src/main/java/org/apache/sling/tooling/support/source/impl/PomHandler.java
new file mode 100644
index 0000000..bb398ca
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/PomHandler.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+final class PomHandler extends DefaultHandler {
+    private final String jettyVersion;
+    
+    // state
+    private Deque<String> elements = new LinkedList<String>();
+    private String artifactId;
+    private String groupId;
+    private String version;
+    
+    // output
+    private List<SourceReference> references = new ArrayList<SourceReference>();
+
+    PomHandler(String jettyVersion) {
+        this.jettyVersion = jettyVersion;
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes)
+            throws SAXException {
+        elements.add(qName);
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        
+        // project/dependencies/dependency/${tag}
+        if ( elements.size() != 4 ) {
+            return;
+        }
+        
+        String tagName = elements.peekLast();
+        
+        if ( tagName.equals("artifactId")) {
+            artifactId = new String(ch, start, length); 
+        } else if ( tagName.equals("groupId")) {
+            groupId = new String(ch, start, length);
+        } else if ( tagName.equals("version")) {
+            version = new String(ch, start, length);
+        }
+            
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+
+        // project/dependencies/dependency
+        if ( elements.size() == 3 && qName.equals("dependency")) {
+            if ( groupId.startsWith("org.eclipse.jetty")) {
+                references.add(new SourceReference(groupId, artifactId, jettyVersion));
+            } else if ( groupId.startsWith("org.apache.felix")) {
+                references.add(new SourceReference(groupId, artifactId, version));
+            }
+            
+            artifactId = null;
+            groupId = null;
+            version = null;
+        }
+
+        
+        elements.removeLast();
+    }
+    
+    public List<SourceReference> getReferences() {
+        return references;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReference.java b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReference.java
new file mode 100644
index 0000000..f588ce2
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReference.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+public class SourceReference {
+
+    private final String groupId;
+    private final String artifactId;
+    private final String version;
+
+    public SourceReference(String groupId, String artifactId, String version) {
+        this.groupId = groupId;
+        this.artifactId = artifactId;
+        this.version = version;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public String getArtifactId() {
+        return artifactId;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceException.java b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceException.java
new file mode 100644
index 0000000..116a93f
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceException.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+public class SourceReferenceException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public SourceReferenceException() {
+
+    }
+
+    public SourceReferenceException(String message) {
+        super(message);
+    }
+
+    public SourceReferenceException(Throwable cause) {
+        super(cause);
+    }
+
+    public SourceReferenceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceFinder.java b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceFinder.java
new file mode 100644
index 0000000..5d10f8e
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferenceFinder.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util.List;
+
+import org.osgi.framework.Bundle;
+
+public interface SourceReferenceFinder {
+    
+    public List<SourceReference> findSourceReferences(Bundle bundle) throws SourceReferenceException;
+
+}
diff --git a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
index 8806a2d..a6ffb39 100644
--- a/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
+++ b/src/main/java/org/apache/sling/tooling/support/source/impl/SourceReferencesServlet.java
@@ -42,6 +42,8 @@ import org.apache.sling.commons.json.io.JSONWriter;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The <tt>SourceReferencesServlet</tt> infers and outputs source information about bundles running a Sling instance
@@ -53,20 +55,26 @@ public class SourceReferencesServlet extends HttpServlet {
 
     private static final long serialVersionUID = 1L;
     
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    
     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";
+    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;
+    private List<SourceReferenceFinder> finders;
 
     protected void activate(ComponentContext ctx) {
         this.ctx = ctx;
+        
+        finders = new ArrayList<SourceReferenceFinder>();
+        finders.add(new FelixJettySourceReferenceFinder());
     }    
     
     @Override
@@ -74,7 +82,7 @@ public class SourceReferencesServlet extends HttpServlet {
         try {
             response.setContentType("application/json");
             
-            JSONWriter w = new JSONWriter(response.getWriter());
+            final JSONWriter w = new JSONWriter(response.getWriter());
             w.array();
             
             for ( Bundle bundle : ctx.getBundleContext().getBundles() ) {
@@ -93,14 +101,9 @@ public class SourceReferencesServlet extends HttpServlet {
                 // 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();
+                    writeMavenGav(w, FELIX_FW_GROUP_ID, FELIX_FW_ARTIFACT_ID, (String) bundleVersion);
                 }
-
+                
                 // look for pom.properties in the bundle ( the original bundle, fragments )
                 collectMavenSourceReferences(w, bundle);
                 
@@ -113,6 +116,19 @@ public class SourceReferencesServlet extends HttpServlet {
                     }
                     collectMavenSourceRerefences(w, entry);
                 }
+                
+                // query custom finders for source references
+                for ( SourceReferenceFinder finder : finders ) {
+                    try {
+                        for ( SourceReference reference : finder.findSourceReferences(bundle)) {
+                            log.debug("{} found reference {}:{}:{} in {}", new Object[] { finder, reference.getGroupId(), reference.getArtifactId(), reference.getVersion(), bundle});
+                            writeMavenGav(w, reference.getGroupId(), reference.getArtifactId(), reference.getVersion());
+                        }
+                    } catch (SourceReferenceException e) {
+                        log.warn(finder + " execution did not complete normally for " + bundle, e);
+                    }
+                }
+                
                 w.endArray();
                 w.endObject();
             }
@@ -139,6 +155,16 @@ public class SourceReferencesServlet extends HttpServlet {
         }
     }
     
+    private void writeMavenGav(JSONWriter w, String groupId, String artifactId, String version) throws JSONException {
+        
+        w.object();
+        w.key(KEY_TYPE).value(VALUE_TYPE_MAVEN);
+        w.key(KEY_GROUP_ID).value(groupId);
+        w.key(KEY_ARTIFACT_ID).value(artifactId);
+        w.key(KEY_VERSION).value(version);
+        w.endObject();
+    }
+    
     private void writeMavenGav(JSONWriter w, InputStream in) throws IOException, JSONException {
         
         Properties p = new Properties();
diff --git a/src/test/java/org/apache/sling/tooling/support/source/impl/PomHandlerTest.java b/src/test/java/org/apache/sling/tooling/support/source/impl/PomHandlerTest.java
new file mode 100644
index 0000000..15b73e0
--- /dev/null
+++ b/src/test/java/org/apache/sling/tooling/support/source/impl/PomHandlerTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class PomHandlerTest {
+
+    @Test
+    public void parseJettyPom() throws SAXException, IOException, ParserConfigurationException {
+        
+        PomHandler handler = new PomHandler("9.2.4");
+        
+        SAXParserFactory.newInstance().newSAXParser().parse(getClass().getResourceAsStream("felix-pom.xml"), handler);
+        
+        List<SourceReference> references = handler.getReferences();
+        
+        assertEquals(10, references.size());
+        
+        SourceReference jettyServlet = references.get(0);
+        assertEquals("org.eclipse.jetty", jettyServlet.getGroupId());
+        assertEquals("jetty-servlet", jettyServlet.getArtifactId());
+        assertEquals("9.2.4", jettyServlet.getVersion());
+        
+        SourceReference felixApi = references.get(8);
+        assertEquals("org.apache.felix", felixApi.getGroupId());
+        assertEquals("org.apache.felix.http.api", felixApi.getArtifactId());
+        assertEquals("3.0.0", felixApi.getVersion());
+    }
+}
diff --git a/src/test/resources/org/apache/sling/tooling/support/source/impl/felix-pom.xml b/src/test/resources/org/apache/sling/tooling/support/source/impl/felix-pom.xml
new file mode 100644
index 0000000..d48ca01
--- /dev/null
+++ b/src/test/resources/org/apache/sling/tooling/support/source/impl/felix-pom.xml
@@ -0,0 +1,205 @@
+<!--
+    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.felix</groupId>
+        <artifactId>org.apache.felix.http.parent</artifactId>
+        <version>9-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <name>Apache Felix Http Jetty</name>
+    <artifactId>org.apache.felix.http.jetty</artifactId>
+    <version>3.1.7-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/felix/trunk/http/jetty</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/trunk/http/jetty</developerConnection>
+        <url>http://svn.apache.org/viewvc/felix/trunk/http/jetty/</url>
+    </scm>
+    
+    <properties>
+        <felix.java.version>8</felix.java.version>
+        <!-- jetty.version is moved to http-parent POM -->
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <X-Jetty-Version>
+                            ${jetty.version}
+                        </X-Jetty-Version>
+                        <Bundle-Activator>
+                            org.apache.felix.http.jetty.internal.JettyActivator
+                        </Bundle-Activator>
+                        <Export-Package>
+                            org.osgi.service.http,
+                            org.osgi.service.http.context,
+                            org.osgi.service.http.runtime,
+                            org.osgi.service.http.runtime.dto,
+                            org.osgi.service.http.whiteboard,
+                            org.apache.felix.http.api,
+                            org.eclipse.jetty.*;-split-package:=merge-first;version=${version;===;${jetty.version}},
+                            org.apache.felix.http.jetty
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.felix.http.base.*,
+                            org.apache.felix.http.jetty.*
+                        </Private-Package>
+                        <Import-Package>
+                            javax.imageio;resolution:=optional,
+                            javax.sql;resolution:=optional,
+                            org.slf4j.*;resolution:=optional,
+                            org.ietf.jgss;resolution:=optional,
+                            org.mortbay.log;resolution:=optional;version="[6.1,7)",
+                            org.mortbay.util.ajax;resolution:=optional;version="[6.1,7)",
+                            org.osgi.service.cm;version="[1.3,2)",                          
+                            org.osgi.service.event;version="[1.2,2)",
+                            org.osgi.service.log;version="[1.3,2)",
+                            org.osgi.service.metatype;version="[1.1,2)";resolution:=optional,
+                            org.osgi.service.useradmin;resolution:=optional,
+                        <!-- Maven bundle plugin version 2.5.3 has a problem
+                             with correctly calculating the import ranges -->
+                            org.apache.felix.http.api;version="[2.0,2.1)",
+                            org.osgi.service.http;version="[1.2,1.3)",
+                            org.osgi.service.http.context;version="[1.0,1.1)",
+                            org.osgi.service.http.runtime;version="[1.0,1.1)",
+                            org.osgi.service.http.runtime.dto;version="[1.0,1.1)",
+                            *
+                        </Import-Package>
+                        <DynamicImport-Package>
+                            org.osgi.service.metatype;version="[1.1,2)"
+                        </DynamicImport-Package>
+                        <Provide-Capability>
+                            osgi.implementation;osgi.implementation="osgi.http";version:Version="1.0";
+                            uses:="javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard",
+                            osgi.service;objectClass:List&lt;String&gt;="org.osgi.service.http.runtime.HttpServiceRuntime";
+                            uses:="org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
+                        </Provide-Capability>
+                        <Require-Capability>
+                            osgi.contract;filter:="(&amp;(osgi.contract=JavaServlet)(version=3.1))"
+                        </Require-Capability>
+                    </instructions>
+                <!-- Skip Baselining due to Jetty API -->
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.cm</artifactId>
+            <version>1.5.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.event</artifactId>
+            <version>1.3.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.metatype</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.useradmin</artifactId>
+            <version>1.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-security</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.websocket</groupId>
+            <artifactId>websocket-servlet</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.websocket</groupId>
+            <artifactId>websocket-server</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.http.api</artifactId>
+            <version>3.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.http.base</artifactId>
+            <version>3.0.7-SNAPSHOT</version>
+        </dependency>
+  <!-- Testing -->
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.log</artifactId>
+            <version>1.3.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.