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 ));
+        }
+    }
+
+
+}