| /******************************************************************************* |
| * 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.api.violation; |
| |
| import java.io.IOException; |
| import java.util.HashMap; |
| 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.wtp.releng.tools.component.IClassVisitor; |
| 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.internal.Bundle; |
| import org.eclipse.wtp.releng.tools.component.internal.Location; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| public class LibVisitor implements ILocationVisitor |
| { |
| private IClassVisitor classVisitor; |
| private Map lib2pluginId; |
| |
| public LibVisitor() |
| { |
| this.classVisitor = null; |
| this.lib2pluginId = new HashMap(); |
| } |
| |
| public Map getLib2PluginId() |
| { |
| return lib2pluginId; |
| } |
| |
| public void setClassVisitor(IClassVisitor classVisitor) |
| { |
| this.classVisitor = classVisitor; |
| } |
| |
| public boolean accept(ILocation location) |
| { |
| String locationName = location.getName(); |
| if (classVisitor == null) |
| { |
| if (locationName.endsWith("MANIFEST.MF")) |
| { |
| acceptManifest(location); |
| } |
| else if (Location.isArchive(locationName)) |
| { |
| return acceptSingleJar(location); |
| } |
| else if (locationName.endsWith(".classpath")) |
| { |
| acceptDotClasspath(location); |
| } |
| } |
| else if (classVisitor != null) |
| { |
| 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")) |
| classVisitor.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 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(); |
| 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(); |
| lib2pluginId.put(location.getName().replace('\\', '/'), bundleName); |
| return false; |
| } |
| } catch (IOException 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) { |
| 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); |
| lib.append(s); |
| lib.append('/'); |
| lib.append(path); |
| lib2pluginId.put(lib.toString(), id); |
| } |
| } |
| } |
| } |
| catch (Throwable e) |
| { |
| } |
| } |
| } |