Use local copy of latest bndlib code for pre-release testing purposes
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1347815 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
new file mode 100644
index 0000000..d9c60cd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
@@ -0,0 +1,24 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ *
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ *
+ * @author aqute
+ *
+ */
+public class JPAComponent extends XMLTypeProcessor {
+
+ protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+ List<XMLType> types = new ArrayList<XMLType>();
+ process(types,"jpa.xsl", "META-INF", "persistence.xml");
+ return types;
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
new file mode 100644
index 0000000..0109ad4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
@@ -0,0 +1,99 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.libg.header.*;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ *
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ *
+ * @author aqute
+ *
+ */
+public class SpringComponent implements AnalyzerPlugin {
+ static Transformer transformer;
+ static Pattern SPRING_SOURCE = Pattern.compile("META-INF/spring/.*\\.xml");
+ static Pattern QN = Pattern.compile("[_A-Za-z$][_A-Za-z0-9$]*(\\.[_A-Za-z$][_A-Za-z0-9$]*)*");
+
+ public static Set<CharSequence> analyze(InputStream in) throws Exception {
+ if (transformer == null) {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Source source = new StreamSource(SpringComponent.class
+ .getResourceAsStream("extract.xsl"));
+ transformer = tf.newTransformer(source);
+ }
+
+ Set<CharSequence> refers = new HashSet<CharSequence>();
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ Result r = new StreamResult(bout);
+ Source s = new StreamSource(in);
+ transformer.transform(s, r);
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ bout.close();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(bin, "UTF8"));
+
+ String line = br.readLine();
+ while (line != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ String parts[] = line.split("\\s*,\\s*");
+ for (int i = 0; i < parts.length; i++) {
+ int n = parts[i].lastIndexOf('.');
+ if (n > 0) {
+ refers.add(parts[i].subSequence(0, n));
+ }
+ }
+ }
+ line = br.readLine();
+ }
+ br.close();
+ return refers;
+ }
+
+ public boolean analyzeJar(Analyzer analyzer) throws Exception {
+ Jar jar = analyzer.getJar();
+ Map<String, Resource> dir = jar.getDirectories().get("META-INF/spring");
+ if ( dir == null || dir.isEmpty())
+ return false;
+
+ for (Iterator<Entry<String, Resource>> i = dir.entrySet().iterator(); i.hasNext();) {
+ Entry<String, Resource> entry = i.next();
+ String path = entry.getKey();
+ Resource resource = entry.getValue();
+ if (SPRING_SOURCE.matcher(path).matches()) {
+ try {
+ InputStream in = resource.openInputStream();
+ Set<CharSequence> set = analyze(in);
+ in.close();
+ for (Iterator<CharSequence> r = set.iterator(); r.hasNext();) {
+ PackageRef pack = analyzer.getPackageRef((String) r.next());
+ if ( !QN.matcher(pack.getFQN()).matches())
+ analyzer.warning("Package does not seem a package in spring resource ("+path+"): " + pack );
+ if (!analyzer.getReferred().containsKey(pack))
+ analyzer.getReferred().put(pack, new Attrs());
+ }
+ } catch( Exception e ) {
+ analyzer.error("Unexpected exception in processing spring resources("+path+"): " + e );
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java b/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java
new file mode 100644
index 0000000..60eb922
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java
@@ -0,0 +1,33 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ *
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ *
+ * @author aqute
+ *
+ */
+public class SpringXMLType extends XMLTypeProcessor {
+
+ protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+ List<XMLType> types = new ArrayList<XMLType>();
+
+ String header = analyzer.getProperty("Bundle-Blueprint", "OSGI-INF/blueprint");
+ process(types,"extract.xsl", header, ".*\\.xml");
+ header = analyzer.getProperty("Spring-Context", "META-INF/spring");
+ process(types,"extract.xsl", header, ".*\\.xml");
+
+ return types;
+ }
+
+
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java b/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java
new file mode 100644
index 0000000..f7c6b33
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java
@@ -0,0 +1,108 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+
+public class XMLType {
+
+ Transformer transformer;
+ Pattern paths;
+ String root;
+
+
+ static Pattern QN = Pattern
+ .compile("[_A-Za-z$][_A-Za-z0-9$]*(\\.[_A-Za-z$][_A-Za-z0-9$]*)*");
+
+ public XMLType(URL source, String root, String paths ) throws Exception {
+ transformer = getTransformer(source);
+ this.paths = Pattern.compile(paths);
+ this.root = root;
+ }
+
+ public Set<String> analyze(InputStream in) throws Exception {
+ Set<String> refers = new HashSet<String>();
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ Result r = new StreamResult(bout);
+ Source s = new StreamSource(in);
+ transformer.transform(s, r);
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ bout.close();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(bin, "UTF8"));
+
+ String line = br.readLine();
+ while (line != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ String parts[] = line.split("\\s*,\\s*");
+ for (int i = 0; i < parts.length; i++) {
+ int n = parts[i].lastIndexOf('.');
+ if (n > 0) {
+ refers.add(parts[i].subSequence(0, n).toString());
+ }
+ }
+ }
+ line = br.readLine();
+ }
+ br.close();
+ return refers;
+ }
+
+ public boolean analyzeJar(Analyzer analyzer) throws Exception {
+ Jar jar = analyzer.getJar();
+ Map<String,Resource> dir = jar.getDirectories().get(root);
+ if (dir == null || dir.isEmpty()) {
+ Resource resource = jar.getResource(root);
+ if ( resource != null )
+ process(analyzer, root, resource);
+ return false;
+ }
+
+ for (Iterator<Map.Entry<String,Resource>> i = dir.entrySet().iterator(); i.hasNext();) {
+ Map.Entry<String,Resource> entry = i.next();
+ String path = entry.getKey();
+ Resource resource = entry.getValue();
+ if (paths.matcher(path).matches()) {
+ process(analyzer, path, resource);
+ }
+ }
+ return false;
+ }
+
+ private void process(Analyzer analyzer, String path, Resource resource) {
+ try {
+ InputStream in = resource.openInputStream();
+ Set<String> set = analyze(in);
+ in.close();
+ for (Iterator<String> r = set.iterator(); r.hasNext();) {
+ PackageRef pack = analyzer.getPackageRef(r.next());
+ if (!QN.matcher(pack.getFQN()).matches())
+ analyzer
+ .warning("Package does not seem a package in spring resource ("
+ + path + "): " + pack);
+ if (!analyzer.getReferred().containsKey(pack))
+ analyzer.getReferred().put(pack);
+ }
+ } catch (Exception e) {
+ analyzer
+ .error("Unexpected exception in processing spring resources("
+ + path + "): " + e);
+ }
+ }
+
+ protected Transformer getTransformer(java.net.URL url) throws Exception {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Source source = new StreamSource(url.openStream());
+ return tf.newTransformer(source);
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
new file mode 100644
index 0000000..6ae0e7e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
@@ -0,0 +1,34 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+public class XMLTypeProcessor implements AnalyzerPlugin {
+
+ public boolean analyzeJar(Analyzer analyzer) throws Exception {
+ List<XMLType> types = getTypes(analyzer);
+ for ( XMLType type : types ) {
+ type.analyzeJar(analyzer);
+ }
+ return false;
+ }
+
+ protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+ return new ArrayList<XMLType>();
+ }
+
+
+ protected void process(List<XMLType> types, String resource, String paths,
+ String pattern) throws Exception {
+
+ Parameters map = Processor.parseHeader(paths,null);
+ for ( String path : map.keySet() ) {
+ types.add( new XMLType( getClass().getResource(resource), path, pattern ));
+ }
+ }
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/extract.xsl b/bundleplugin/src/main/java/aQute/lib/spring/extract.xsl
new file mode 100644
index 0000000..efad6cd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/extract.xsl
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+ <xsl:output method="text" />
+
+ <xsl:template match="/">
+
+ <!-- Match all attributes that holds a class or a comma delimited
+ list of classes and print them -->
+
+ <xsl:for-each select="
+ //beans:bean/@class
+ | //beans:*/@value-type
+ | //aop:*/@implement-interface
+ | //aop:*/@default-impl
+ | //context:load-time-weaver/@weaver-class
+ | //jee:jndi-lookup/@expected-type
+ | //jee:jndi-lookup/@proxy-interface
+ | //jee:remote-slsb/@ejbType
+ | //jee:*/@business-interface
+ | //lang:*/@script-interfaces
+ | //osgi:*/@interface
+ | //util:list/@list-class
+ | //util:set/@set-class
+ | //util:map/@map-class
+ | //webflow-config:*/@class
+ ">
+ <xsl:value-of select="." />
+ <xsl:text>
+ </xsl:text>
+ </xsl:for-each>
+
+ <!-- This seems some magic to get extra imports? -->
+
+ <xsl:for-each select="//beans:bean[@class='org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean'
+ or @class='org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean']">
+ <xsl:for-each select="beans:property[@name='interfaces']">
+ <xsl:value-of select="@value" />
+ <xsl:text>
+ </xsl:text>
+ </xsl:for-each>
+ </xsl:for-each>
+
+ </xsl:template>
+
+
+</xsl:stylesheet>
+
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/hibernate.xsl b/bundleplugin/src/main/java/aQute/lib/spring/hibernate.xsl
new file mode 100644
index 0000000..1f0a1c6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/hibernate.xsl
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+ <xsl:output method="text" />
+
+ <xsl:template match="/">
+
+ <!-- Match all attributes that holds a class or a comma delimited
+ list of classes and print them -->
+
+ <xsl:for-each select="//provider|//class">
+ <xsl:value-of select="." />
+ <xsl:text>
+ </xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+
+</xsl:stylesheet>
+
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/jpa.xsl b/bundleplugin/src/main/java/aQute/lib/spring/jpa.xsl
new file mode 100644
index 0000000..43bba60
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/jpa.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+ <xsl:output method="text" />
+
+ <xsl:template match="/">
+
+ <!-- Match all attributes that holds a class or a comma delimited
+ list of classes and print them -->
+
+ <xsl:for-each select="
+ //class/@name
+ | //composite-id/@class
+ | //component/@class
+ | //discriminator/@type
+ | //dynamic-component/@class
+ | //generator/@class
+ | //id/@type
+ | //import/@class
+ | //joined-subclass/@name
+ | //many-to-many/@class
+ | //many-to-one/@class
+ | //one-to-many/@class
+ | //one-to-one/@class
+ | //property/@type
+ | //subclass/@name
+ | //union-subclass/@name
+ | //version/@type
+ ">
+ <xsl:value-of select="." />
+ <xsl:text>
+ </xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+
+</xsl:stylesheet>
+