Temporarily include bndlib 1.47 for testing purposes (not yet on central)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1185095 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..131709c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
@@ -0,0 +1,25 @@
+package aQute.lib.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import aQute.lib.osgi.Analyzer;
+
+/**
+ * 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..3318a0e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
@@ -0,0 +1,97 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.bnd.service.*;
+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 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;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean analyzeJar(Analyzer analyzer) throws Exception {
+ Jar jar = analyzer.getJar();
+ Map dir = (Map) jar.getDirectories().get("META-INF/spring");
+ if ( dir == null || dir.isEmpty())
+ return false;
+
+ for (Iterator i = dir.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String path = (String) entry.getKey();
+ Resource resource = (Resource) entry.getValue();
+ if (SPRING_SOURCE.matcher(path).matches()) {
+ try {
+ InputStream in = resource.openInputStream();
+ Set set = analyze(in);
+ in.close();
+ for (Iterator r = set.iterator(); r.hasNext();) {
+ String pack = (String) r.next();
+ if ( !QN.matcher(pack).matches())
+ analyzer.warning("Package does not seem a package in spring resource ("+path+"): " + pack );
+ if (!analyzer.getReferred().containsKey(pack))
+ analyzer.getReferred().put(pack, new LinkedHashMap());
+ }
+ } 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..35b59a9
--- /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", "META-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..9fadb35
--- /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.*;
+
+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();) {
+ String pack = r.next();
+ if (!QN.matcher(pack).matches())
+ analyzer
+ .warning("Package does not seem a package in spring resource ("
+ + path + "): " + pack);
+ if (!analyzer.getReferred().containsKey(pack))
+ analyzer.getReferred().put(pack,
+ new LinkedHashMap<String,String>());
+ }
+ } 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..dde8b7e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
@@ -0,0 +1,33 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+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 {
+
+ Map<String,Map<String,String>> map = Processor.parseHeader(paths,null);
+ for ( String path : map.keySet() ) {
+ types.add( new XMLType( getClass().getResource(resource), path, pattern ));
+ }
+ }
+
+
+}