blob: e87d1863658e45240f5bba902e911098f6e58b89 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 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.internal;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.jar.Manifest;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
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.model.ComponentXML;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public abstract class AbstractEmitter
{
private SAXParser saxParser;
protected void copyImage(String imagePath, File dest) throws IOException
{
InputStream is = ClassLoader.getSystemResourceAsStream(imagePath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
copy(is, bos);
}
private void copy(InputStream is, OutputStream os) throws IOException
{
if (is != null && os != null)
{
try
{
byte[] b = new byte[2048];
int read = is.read(b);
while (read != -1)
{
os.write(b, 0, read);
read = is.read(b);
}
}
finally
{
try
{
os.close();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
protected void harvestPlugins(File file, Map pluginId2Plugin, Map fragmentId2Fragment)
{
internalHarvestPlugins(file, pluginId2Plugin, fragmentId2Fragment);
File[] children = file.listFiles();
for (int i = 0; i < children.length; i++)
{
if (children[i].isFile() && children[i].getName().endsWith(".jar"))
{
ZipLocation zipLocation = new ZipLocation(children[i]);
ILocationChildrenIterator it = zipLocation.childIterator();
boolean done = false;
ILocation childLoc = it.next();
while (!done && childLoc != null)
{
String childName = childLoc.getName();
if (PluginXML.CONST_PLUGIN_XML.equalsIgnoreCase(childName))
{
PluginXML pluginXML = getSingleJarPlugin(childLoc);
String pluginName = pluginXML.getName();
if (pluginName != null && !pluginId2Plugin.containsKey(pluginName))
{
pluginXML.addLibrary(new Library(zipLocation));
pluginId2Plugin.put(pluginName, pluginXML);
done = true;
}
}
else if (childName.indexOf(Bundle.CONST_MANIFEST_MF) != -1)
{
try
{
Manifest manifest = new Manifest(childLoc.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();
Bundle bundle = new Bundle(childLoc);
bundle.setName(bundleName);
bundle.setVersion(attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_VERSION)));
bundle.addLibrary(new Library(zipLocation));
pluginId2Plugin.put(bundleName, bundle);
done = true;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
childLoc = it.next();
}
}
}
}
private void internalHarvestPlugins(File file, Map pluginId2Plugin, Map fragmentId2Fragment)
{
if (file.isDirectory())
{
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++)
internalHarvestPlugins(files[i], pluginId2Plugin, fragmentId2Fragment);
}
else if (PluginXML.CONST_PLUGIN_XML.equalsIgnoreCase(file.getName()))
{
PluginXML plugin = getPlugin(new FileLocation(new FileLocation(file.getParentFile()), file.getName()));
String pluginName = plugin.getName();
if (pluginName != null && !pluginId2Plugin.containsKey(pluginName))
pluginId2Plugin.put(pluginName, plugin);
}
else if (FragmentXML.CONST_FRAGMENT_XML.equalsIgnoreCase(file.getName()))
{
FragmentXML fragment = getFragment(new FileLocation(new FileLocation(file.getParentFile()), file.getName()));
String fragmentName = fragment.getFragmentName();
if (fragmentName != null)
fragmentId2Fragment.put(fragmentName, fragment);
}
else if (Bundle.CONST_MANIFEST_MF.equalsIgnoreCase(file.getName()))
{
PluginXML plugin = getBundle(new FileLocation(new FileLocation(file.getParentFile()), file.getName()));
String pluginName = plugin.getName();
if (pluginName != null)
pluginId2Plugin.put(pluginName, plugin);
}
else if (PluginClasspath.CONST_DOT_CLASSPATH.equalsIgnoreCase(file.getName()))
{
PluginClasspath plugin = getPluginClasspath(new FileLocation(new FileLocation(file.getParentFile()), file.getName()), true);
String pluginName = plugin.getName();
if (pluginName != null)
pluginId2Plugin.put(pluginName, plugin);
}
}
public PluginXML getSingleJarPlugin(ILocation location)
{
SingleJaredPluginHandler handler = new SingleJaredPluginHandler(location);
try
{
parse(location, handler);
}
catch (IOException e)
{
e.printStackTrace();
}
return handler.getPlugin();
}
public PluginXML getPlugin(ILocation location)
{
PluginHandler handler = new PluginHandler(location);
try
{
parse(location, handler);
}
catch (IOException e)
{
System.err.println("Could not read " + location.getName() + ", skipping");
}
return handler.getPlugin();
}
/**
* Creates a <code>Fragment</code> from a location file
*
* @param location
* a location that points to a fragment.xml file, not
* <code>null</code>.
* @return Fragment the Fragment object representation of that file
*/
public FragmentXML getFragment(ILocation location)
{
FragmentHandler handler = new FragmentHandler(location);
try
{
parse(location, handler);
}
catch (IOException e)
{
System.err.println("Could not read " + location.getName() + ", skipping");
}
return handler.getFragment();
}
/**
* Creates a <code>Bundle</code> from a location file
*
* @param location
* a location that points to a MANIFEST.MF file, not
* <code>null</code>.
* @return Bundle the Bundle object representation of that file
*/
public Bundle getBundle(ILocation location)
{
Bundle bundle = new Bundle(location);
try
{
Manifest manifest = new Manifest(location.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)
bundle.setName((new StringTokenizer(bundleName, "; ")).nextToken());
bundle.setVersion(attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_VERSION)));
String classpathString = attrs.getValue(new java.util.jar.Attributes.Name(Bundle.CONST_BUNDLE_CLASSPATH));
if (classpathString != null && classpathString.length() > 0)
{
StringTokenizer classpath = new StringTokenizer(classpathString, ",");
while (classpath.hasMoreTokens())
bundle.addLibrary(classpath.nextToken());
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
return bundle;
}
/**
* Creates a <code>PluginClasspath</code> from a location file
*
* @param fileLocation
* a location that points to a .classpath file, not <code>null</code>.
* @return PluginClasspath the PluginClasspath object representation of that
* file
*/
public PluginClasspath getPluginClasspath(IFileLocation fileLocation, boolean validate)
{
return new PluginClasspath(fileLocation, validate);
}
protected void parse(ILocation location, DefaultHandler handler) throws IOException
{
InputStream in = null;
try
{
if (saxParser == null)
{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
saxParser = factory.newSAXParser();
}
in = location.getInputStream();
saxParser.parse(new InputSource(in), handler);
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
finally
{
if (in != null)
{
try
{
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
protected void linkPluginsAndFragments(Map pluginId2Plugin, Map fragmentId2Fragment)
{
for (Iterator it = fragmentId2Fragment.values().iterator(); it.hasNext();)
{
FragmentXML fragment = (FragmentXML)it.next();
fragment.link(pluginId2Plugin);
}
}
protected void harvestComponents(File file, Map compLoc2CompXML)
{
harvestComponents(file, compLoc2CompXML, new ArrayList());
}
private void harvestComponents(File file, Map compLoc2CompXML, List addedComps)
{
if (file.isDirectory())
{
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++)
harvestComponents(files[i], compLoc2CompXML, addedComps);
}
else if (ComponentXML.CONST_COMPONENT_XML.equalsIgnoreCase(file.getName()))
{
ComponentXML compXML = new ComponentXML();
ILocation location = new FileLocation(file);
compXML.setLocation(location);
try
{
compXML.load();
String compName = compXML.getName();
if (!addedComps.contains(compName))
{
compLoc2CompXML.put(location.getAbsolutePath(), compXML);
addedComps.add(compName);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
protected String decodeClassName(String className)
{
return className.replace('/', '.');
}
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;
}
private class SingleJaredPluginHandler extends DefaultHandler
{
protected PluginXML plugin;
public SingleJaredPluginHandler(ILocation location)
{
plugin = new PluginXML(location);
}
public PluginXML getPlugin()
{
return plugin;
}
public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
{
if (elementName.equals("plugin") || qName.equals("plugin"))
{
plugin.setName(attributes.getValue("id"));
plugin.setVersion(attributes.getValue("version"));
return;
}
}
}
private class PluginHandler extends SingleJaredPluginHandler
{
public PluginHandler(ILocation location)
{
super(location);
}
public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
{
super.startElement(uri, elementName, qName, attributes);
if (elementName.equals("library") || qName.equals("library"))
plugin.addLibrary(attributes.getValue("name"));
}
}
private class FragmentHandler extends DefaultHandler
{
private FragmentXML fragment;
public FragmentHandler(ILocation location)
{
fragment = new FragmentXML(location);
}
public FragmentXML getFragment()
{
return fragment;
}
public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
{
if (elementName.equals("fragment") || qName.equals("fragment"))
{
fragment.setFragmentName(attributes.getValue("id"));
fragment.setVersion(attributes.getValue("version"));
fragment.setName(attributes.getValue("plugin-id"));
fragment.setVersion(attributes.getValue("plugin-version"));
return;
}
if (elementName.equals("library") || qName.equals("library"))
{
fragment.addLibrary(attributes.getValue("name"));
return;
}
}
}
}