| /******************************************************************************* |
| * Copyright (c) 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wtp.releng.tools.component.adopters; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| import java.util.jar.JarInputStream; |
| import java.util.jar.Manifest; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import org.eclipse.jdt.core.util.ClassFormatException; |
| import org.eclipse.jdt.core.util.IClassFileReader; |
| import org.eclipse.jdt.internal.core.util.ClassFileReader; |
| import org.eclipse.wtp.releng.tools.component.IFileLocation; |
| import org.eclipse.wtp.releng.tools.component.ILocation; |
| import org.eclipse.wtp.releng.tools.component.ILocationChildrenIterator; |
| import org.eclipse.wtp.releng.tools.component.ILocationVisitor; |
| import org.eclipse.wtp.releng.tools.component.IZipLocation; |
| import org.eclipse.wtp.releng.tools.component.classes.IClassVisitor; |
| import org.eclipse.wtp.releng.tools.component.internal.Bundle; |
| import org.eclipse.wtp.releng.tools.component.internal.FileLocation; |
| import org.eclipse.wtp.releng.tools.component.internal.Location; |
| import org.eclipse.wtp.releng.tools.component.java.Java2API; |
| import org.eclipse.wtp.releng.tools.component.model.ComponentDepends; |
| import org.eclipse.wtp.releng.tools.component.model.ComponentXML; |
| import org.eclipse.wtp.releng.tools.component.model.Package; |
| import org.eclipse.wtp.releng.tools.component.model.Plugin; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| public class Plugin2API implements ILocationVisitor, IClassVisitor |
| { |
| private Collection src; |
| private String outputDir; |
| private Map lib2pluginId; |
| private boolean visitPlugins; |
| private List visitedPlugins; |
| |
| public Plugin2API() |
| { |
| this.lib2pluginId = new HashMap(); |
| } |
| |
| public String getOutputDir() |
| { |
| return outputDir; |
| } |
| |
| public void setOutputDir(String outputDir) |
| { |
| this.outputDir = addTrailingSeperator(outputDir); |
| } |
| |
| public Collection getSrc() |
| { |
| return src; |
| } |
| |
| public void setSrc(String src) |
| { |
| this.src = new ArrayList(1); |
| this.src.add(src); |
| } |
| |
| public void setSrc(Collection src) |
| { |
| this.src = src; |
| } |
| |
| public void execute() |
| { |
| Java2API java2API = new Java2API(); |
| java2API.setOutputDir(outputDir); |
| java2API.setDefaultExclusive(false); |
| for (Iterator it = src.iterator(); it.hasNext();) |
| { |
| java2API.setSrc((String)it.next()); |
| java2API.execute(); |
| } |
| visitedPlugins = java2API.getVisitedPlugins(); |
| for (Iterator it = src.iterator(); it.hasNext();) |
| { |
| visitPlugins = true; |
| ILocation srcLocation = Location.createLocation(new File((String)it.next())); |
| srcLocation.accept(this); |
| visitPlugins = false; |
| srcLocation.accept(this); |
| } |
| } |
| |
| public boolean visit(String pluginId, ILocation classLoc) |
| { |
| try |
| { |
| IClassFileReader reader = read(classLoc); |
| String className = new String(reader.getClassName()).replace('/', '.'); |
| int i = className.lastIndexOf('.'); |
| String pkgName = i != -1 ? className.substring(0, i) : ""; |
| ComponentXML compXML = getComponentXML(pluginId); |
| if (compXML.getPackage(pkgName) == null) |
| { |
| Package pkg = new Package(); |
| pkg.setName(pkgName); |
| pkg.setApi(Boolean.TRUE); |
| pkg.setExclusive(Boolean.FALSE); |
| compXML.addPackage(pkg); |
| } |
| } |
| catch (IOException ioe) |
| { |
| throw new RuntimeException(ioe); |
| } |
| catch (ClassFormatException cfe) |
| { |
| throw new RuntimeException(cfe); |
| } |
| return true; |
| } |
| |
| private IClassFileReader read(ILocation classLoc) throws IOException, ClassFormatException |
| { |
| InputStream is = null; |
| ByteArrayOutputStream baos = null; |
| try |
| { |
| byte[] b = new byte[8192]; |
| baos = new ByteArrayOutputStream(8192); |
| is = classLoc.getInputStream(); |
| for (int read = is.read(b); read != -1; read = is.read(b)) |
| { |
| baos.write(b, 0, read); |
| } |
| is.close(); |
| baos.close(); |
| return new ClassFileReader(baos.toByteArray(), IClassFileReader.CONSTANT_POOL | IClassFileReader.METHOD_INFOS | IClassFileReader.METHOD_BODIES | IClassFileReader.FIELD_INFOS | IClassFileReader.SUPER_INTERFACES); |
| } |
| finally |
| { |
| if (is != null) |
| { |
| try |
| { |
| is.close(); |
| } |
| catch (IOException e) |
| { |
| } |
| } |
| if (baos != null) |
| { |
| try |
| { |
| baos.close(); |
| } |
| catch (IOException e) |
| { |
| } |
| } |
| } |
| } |
| |
| private ComponentXML cachedCompXML; |
| |
| private ComponentXML getComponentXML(String id) throws IOException |
| { |
| if (cachedCompXML != null) |
| { |
| if (cachedCompXML.getName().equals(id)) |
| { |
| return cachedCompXML; |
| } |
| else |
| { |
| cachedCompXML.save(); |
| } |
| } |
| StringBuffer sb = new StringBuffer(outputDir); |
| sb.append(id); |
| sb.append("/component.xml"); |
| File file = new File(sb.toString()); |
| cachedCompXML = new ComponentXML(); |
| cachedCompXML.setName(id); |
| cachedCompXML.setLocation(new FileLocation(file)); |
| Plugin plugin = new Plugin(); |
| plugin.setId(id); |
| cachedCompXML.addPlugin(plugin); |
| ComponentDepends compDepends = new ComponentDepends(); |
| compDepends.setUnrestricted(Boolean.TRUE); |
| cachedCompXML.setComponentDepends(compDepends); |
| if (file.exists()) |
| cachedCompXML.load(); |
| return cachedCompXML; |
| } |
| |
| public boolean accept(ILocation location) |
| { |
| String locationName = location.getName(); |
| if (visitPlugins) |
| { |
| if (locationName.endsWith("plugin.xml")) |
| { |
| acceptPluginXML(location); |
| } |
| else if (locationName.endsWith("fragment.xml")) |
| { |
| acceptFragmentXML(location); |
| } |
| else if (locationName.endsWith("MANIFEST.MF")) |
| { |
| acceptManifest(location); |
| } |
| else if (Location.isArchive(locationName)) |
| { |
| return acceptSingleJar(location); |
| } |
| else if (locationName.endsWith(".classpath")) |
| { |
| acceptDotClasspath(location); |
| } |
| } |
| else |
| { |
| String idTemp = (String)lib2pluginId.get(locationName.replace('\\', '/')); |
| if (idTemp == null) |
| idTemp = (String)lib2pluginId.get(location.getAbsolutePath().replace('\\', '/')); |
| final String id = idTemp; |
| if (id != null) |
| { |
| location.accept |
| ( |
| new ILocationVisitor() |
| { |
| public boolean accept(ILocation location) |
| { |
| if (location.getName().endsWith(".class")) |
| visit(id, location); |
| return true; |
| } |
| } |
| ); |
| /* |
| ILocationChildrenIterator it = location.childIterator(); |
| for (ILocation child = it.next(); child != null; child = it.next()) |
| { |
| if (child.getName().endsWith(".class")) |
| { |
| classVisitor.visit(id, child); |
| } |
| } |
| */ |
| } |
| } |
| if (location instanceof IZipLocation) |
| return true; |
| else if ((location instanceof IFileLocation) && ((IFileLocation)location).getFile().isDirectory()) |
| return true; |
| else |
| return false; |
| } |
| |
| private void acceptPluginXML(ILocation location) |
| { |
| String locationName = location.getName(); |
| try |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.parse(location.getInputStream()); |
| Element root = doc.getDocumentElement(); |
| if (root.getTagName().equals("plugin")) |
| { |
| String pluginId = root.getAttribute("id"); |
| if (pluginId != null && pluginId.length() > 0 && !visitedPlugins.contains(pluginId)) |
| { |
| NodeList runtimes = root.getElementsByTagName("runtime"); |
| for (int i = 0; i < runtimes.getLength(); i++) |
| { |
| Element runtime = (Element)runtimes.item(i); |
| NodeList libraries = runtime.getElementsByTagName("library"); |
| for (int j = 0; j < libraries.getLength(); j++) |
| { |
| Element library = (Element)libraries.item(j); |
| String path = library.getAttribute("name"); |
| if (path != null && path.length() > 0) |
| { |
| StringBuffer sb = new StringBuffer(); |
| if (locationName.equalsIgnoreCase("plugin.xml")) |
| locationName = location.getAbsolutePath(); |
| sb.append(locationName.substring(0, locationName.length() - "plugin.xml".length() - 1)); |
| sb.append("/"); |
| sb.append(path); |
| lib2pluginId.put(sb.toString().replace('\\', '/'), pluginId); |
| } |
| } |
| } |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| |
| private void acceptFragmentXML(ILocation location) |
| { |
| String locationName = location.getName(); |
| try |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.parse(location.getInputStream()); |
| Element root = doc.getDocumentElement(); |
| if (root.getTagName().equals("fragment")) |
| { |
| String fragmentId = root.getAttribute("id"); |
| if (fragmentId != null && fragmentId.length() > 0 && !visitedPlugins.contains(fragmentId)) |
| { |
| NodeList runtimes = root.getElementsByTagName("runtime"); |
| for (int i = 0; i < runtimes.getLength(); i++) |
| { |
| Element runtime = (Element)runtimes.item(i); |
| NodeList libraries = runtime.getElementsByTagName("library"); |
| for (int j = 0; j > libraries.getLength(); j++) |
| { |
| Element library = (Element)libraries.item(j); |
| String path = library.getAttribute("name"); |
| if (path != null && path.length() > 0) |
| { |
| StringBuffer sb = new StringBuffer(); |
| if (locationName.equalsIgnoreCase("fragment.xml")) |
| locationName = location.getAbsolutePath(); |
| sb.append(locationName.substring(0, locationName.length() - "fragment.xml".length() - 1)); |
| sb.append("/"); |
| sb.append(path); |
| lib2pluginId.put(sb.toString().replace('\\', '/'), fragmentId); |
| } |
| } |
| } |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| |
| private void acceptManifest(ILocation location) |
| { |
| String locationName = location.getName(); |
| try |
| { |
| Manifest manifest = new Manifest(location.getInputStream()); |
| java.util.jar.Attributes attrs = manifest.getMainAttributes(); |
| String bundleNameAttr = attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_NAME)); |
| if (bundleNameAttr != null) |
| { |
| String bundleName = (new StringTokenizer(bundleNameAttr, ";")).nextToken().trim(); |
| if (!visitedPlugins.contains(bundleName)) |
| { |
| String bundleCPAttr = attrs.getValue(Bundle.CONST_BUNDLE_CLASSPATH); |
| if (bundleCPAttr != null) |
| { |
| StringTokenizer cp = new StringTokenizer(bundleCPAttr, ","); |
| while (cp.hasMoreTokens()) |
| { |
| String path = cp.nextToken().trim(); |
| if (path != null && path.length() > 0) |
| { |
| StringBuffer sb = new StringBuffer(); |
| if (locationName.equalsIgnoreCase("MANIFEST.MF")) |
| locationName = location.getAbsolutePath(); |
| sb.append(locationName.substring(0, locationName.length() - "META-INF/MANIFEST.MF".length() - 1)); |
| sb.append("/"); |
| sb.append(path); |
| lib2pluginId.put(sb.toString().replace('\\', '/'), bundleName); |
| } |
| } |
| } |
| } |
| } |
| } |
| catch (IOException e) |
| { |
| } |
| } |
| |
| private boolean acceptSingleJar(ILocation location) |
| { |
| ILocationChildrenIterator it = location.childIterator(); |
| for (ILocation child = it.next(); child != null; child = it.next()) |
| { |
| String name = child.getName(); |
| if (name.equalsIgnoreCase("META-INF/MANIFEST.MF")) |
| { |
| try |
| { |
| Manifest manifest = new Manifest(child.getInputStream()); |
| java.util.jar.Attributes attrs = manifest.getMainAttributes(); |
| String bundleName = attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_NAME)); |
| if (bundleName != null) |
| { |
| bundleName = (new StringTokenizer(bundleName, ";")).nextToken().trim(); |
| if (!visitedPlugins.contains(bundleName)) |
| { |
| lib2pluginId.put(location.getName().replace('\\', '/'), bundleName); |
| return false; |
| } |
| } |
| } |
| catch (IOException e) |
| { |
| } |
| } |
| else if (name.endsWith("plugin.xml")) |
| { |
| try |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.parse(location.getInputStream()); |
| Element root = doc.getDocumentElement(); |
| if (root.getTagName().equals("plugin")) |
| { |
| String id = root.getAttribute("id"); |
| if (id != null && id.length() > 0 && !visitedPlugins.contains(id)) |
| { |
| lib2pluginId.put(location.getName().replace('\\', '/'), id); |
| return false; |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| else if (name.endsWith("fragment.xml")) |
| { |
| try |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.parse(location.getInputStream()); |
| Element root = doc.getDocumentElement(); |
| if (root.getTagName().equals("fragment")) |
| { |
| String id = root.getAttribute("id"); |
| if (id != null && id.length() > 0 && !visitedPlugins.contains(id)) |
| { |
| lib2pluginId.put(location.getName().replace('\\', '/'), id); |
| return false; |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| } |
| if (Location.getExtension(location.getName()).equalsIgnoreCase("jar")) |
| { |
| try |
| { |
| JarInputStream jis = new JarInputStream(location.getInputStream()); |
| Manifest manifest = jis.getManifest(); |
| if (manifest != null) |
| { |
| java.util.jar.Attributes attrs = manifest.getMainAttributes(); |
| String bundleNameAttr = attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_NAME)); |
| if (bundleNameAttr != null && !visitedPlugins.contains(bundleNameAttr)) |
| { |
| String bundleName = (new StringTokenizer(bundleNameAttr, ";")).nextToken().trim(); |
| if (bundleName != null) |
| { |
| bundleName = (new StringTokenizer(bundleName, ";")).nextToken().trim(); |
| lib2pluginId.put(location.getName().replace('\\', '/'), bundleName); |
| return false; |
| } |
| } |
| } |
| } |
| catch (IOException ioe) |
| { |
| } |
| } |
| return true; |
| } |
| |
| private void acceptDotClasspath(ILocation location) |
| { |
| try |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = builder.parse(location.getInputStream()); |
| Element root = doc.getDocumentElement(); |
| if (root.getTagName().equals("classpath")) |
| { |
| NodeList cpEntries = root.getElementsByTagName("classpathentry"); |
| for (int i = 0; i < cpEntries.getLength(); i++) |
| { |
| Element cpEntry = (Element)cpEntries.item(i); |
| String kind = cpEntry.getAttribute("kind"); |
| if (kind != null && kind.equals("output")) |
| { |
| String path = cpEntry.getAttribute("path"); |
| String absPath = location.getAbsolutePath().replace('\\', '/'); |
| StringBuffer lib = new StringBuffer(); |
| int j = absPath.lastIndexOf('/'); |
| String s = absPath.substring(0, j); |
| String id = s.substring(s.lastIndexOf('/') + 1, j); |
| if (!visitedPlugins.contains(id)) |
| { |
| lib.append(s); |
| lib.append('/'); |
| lib.append(path); |
| lib2pluginId.put(lib.toString(), id); |
| } |
| } |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| |
| protected String addTrailingSeperator(String s) |
| { |
| if (s != null && !s.endsWith("/") && !s.endsWith("\\")) |
| { |
| StringBuffer sb = new StringBuffer(s); |
| sb.append('/'); |
| return sb.toString(); |
| } |
| else |
| { |
| return s; |
| } |
| } |
| } |