blob: d580649dbb5a253b35858a01d6764fa5ad5f3ab0 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
 *
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.wtp.releng.tools.component.api;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.wtp.releng.tools.component.ILocation;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ComponentAPI
{
public static final String CONST_COMPONENT_API_XML = "component-api.xml";
private static final String NS = "http://eclipse.org/wtp/releng/tools/component-api";
private static final String ELEMENT_COMPONENT_API = "component-api";
private static final String ELEMENT_INTERNAL_API = "internal-apis";
private static final String ELEMENT_EXTERNAL_API = "external-apis";
private static final String ELEMENT_PACKAGE_API = "package-api";
private static final String ELEMENT_CLASS_API = "class-api";
private static final String ELEMENT_METHOD_API = "method-api";
private static final String ELEMENT_FIELD_API = "field-api";
private static final String ATTR_XMLNS_API = "xmlns:api";
private static final String ATTR_ACCESS = "access";
private static final String ATTR_NAME = "name";
private static final String ATTR_DESCRIPTOR = "descriptor";
private static final String ATTR_REFERENCE = "reference";
private static final String ATTR_IMPLEMENT = "implement";
private static final String ATTR_SUBCLASS = "subclass";
private static final String ATTR_INSTANTIATE = "instantiate";
private static final String ATTR_THROWS = "throws";
protected ILocation location;
protected String name;
private APIs internalAPIs;
private APIs externalAPIs;
private boolean reload;
public ComponentAPI()
{
internalAPIs = new APIs();
externalAPIs = new APIs();
reload = false;
}
/**
* @return Returns the location.
*/
public ILocation getLocation()
{
return location;
}
/**
* @param location The location to set.
*/
public void setLocation(ILocation location)
{
this.location = location;
reload = true;
}
/**
* @return Returns the name.
*/
public String getName()
{
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return Returns the externalAPIs.
*/
public APIs getExternalAPIs()
{
return externalAPIs;
}
/**
* @param externalAPIs The externalAPIs to set.
*/
public void setExternalAPIs(APIs externalAPIs)
{
this.externalAPIs = externalAPIs;
}
/**
* @return Returns the internalAPIs.
*/
public APIs getInternalAPIs()
{
return internalAPIs;
}
/**
* @param internalAPIs The internalAPIs to set.
*/
public void setInternalAPIs(APIs internalAPIs)
{
this.internalAPIs = internalAPIs;
}
public void load() throws IOException, FileNotFoundException
{
if (reload)
{
try
{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
parser.parse(new InputSource(new BufferedInputStream(location.getInputStream())), new ComponentAPIHandler(this));
}
catch (ParserConfigurationException pce)
{
pce.printStackTrace();
}
catch (SAXException saxe)
{
saxe.printStackTrace();
}
reload = false;
}
}
public void saveAsHTML(ILocation html, String xsl) throws TransformerConfigurationException, TransformerException, IOException
{
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(ClassLoader.getSystemResourceAsStream(xsl)));
transformer.transform(new StreamSource(new ByteArrayInputStream(getBytes())), new StreamResult(new FileOutputStream(new File(html.getAbsolutePath()))));
}
public void save() throws IOException
{
if (location != null)
{
File file = new File(location.getAbsolutePath());
file.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(file);
fos.write(getBytes());
fos.close();
}
}
private byte[] getBytes() throws UnsupportedEncodingException
{
StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.append("<api:component-api ");
saveAttribute(sb, ATTR_XMLNS_API, NS);
saveAttribute(sb, ATTR_NAME, getName());
sb.append(">");
saveInternalAPIs(sb, getInternalAPIs());
saveExternalAPIs(sb, getExternalAPIs());
sb.append("</api:component-api>");
return sb.toString().getBytes("UTF-8");
}
private void saveInternalAPIs(StringBuffer sb, APIs apis)
{
List pkgAPIs = apis.getPackageAPIs();
if (pkgAPIs.size() > 0)
{
sb.append("<internal-apis>");
for (Iterator it = pkgAPIs.iterator(); it.hasNext();)
savePackageAPI(sb, (PackageAPI)it.next());
sb.append("</internal-apis>");
}
}
private void saveExternalAPIs(StringBuffer sb, APIs apis)
{
List pkgAPIs = apis.getPackageAPIs();
if (pkgAPIs.size() > 0)
{
sb.append("<external-apis>");
for (Iterator it = pkgAPIs.iterator(); it.hasNext();)
savePackageAPI(sb, (PackageAPI)it.next());
sb.append("</external-apis>");
}
}
private void savePackageAPI(StringBuffer sb, PackageAPI pkgAPI)
{
sb.append("<package-api");
saveAttribute(sb, ATTR_NAME, pkgAPI.getName());
sb.append(">");
for (Iterator it = pkgAPI.getClassAPIs().iterator(); it.hasNext();)
sb.append(((ClassAPI)it.next()).toString());
sb.append("</package-api>");
}
protected void saveAttribute(StringBuffer sb, String key, String value)
{
if (key != null && value != null)
{
sb.append(" ");
sb.append(key);
sb.append("=\"");
sb.append(value);
sb.append("\"");
}
}
protected void saveAttribute(StringBuffer sb, String key, List values, String delimiter)
{
if (key != null && values != null && values.size() > 0)
{
sb.append(" ");
sb.append(key);
sb.append("=\"");
for (Iterator it = values.iterator(); it.hasNext();)
{
sb.append(it.next().toString());
if (it.hasNext())
sb.append(delimiter);
}
sb.append("\"");
}
}
protected static class ComponentAPIHandler extends DefaultHandler
{
private ComponentAPI compAPI;
private APIs apis;
private PackageAPI packageAPI;
private ClassAPI classAPI;
public ComponentAPIHandler(ComponentAPI compAPI)
{
this.compAPI = compAPI;
this.compAPI.setInternalAPIs(new APIs());
this.compAPI.setExternalAPIs(new APIs());
}
public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
{
if (elementName.equals(ELEMENT_METHOD_API) || qName.equals(ELEMENT_METHOD_API))
{
MethodAPI methodAPI = new MethodAPI();
startMethod(classAPI, methodAPI, attributes);
}
else if (elementName.equals(ELEMENT_FIELD_API) || qName.equals(ELEMENT_FIELD_API))
{
FieldAPI fieldAPI = new FieldAPI();
startField(classAPI, fieldAPI, attributes);
}
else if (elementName.equals(ELEMENT_CLASS_API) || qName.equals(ELEMENT_CLASS_API))
{
if (packageAPI != null)
{
classAPI = new ClassAPI();
classAPI.setName(attributes.getValue(ATTR_NAME));
String attrAccess = attributes.getValue(ATTR_ACCESS);
if (attrAccess != null)
classAPI.setAccess(Integer.parseInt(attrAccess));
String attrRef = attributes.getValue(ATTR_REFERENCE);
if (attrRef != null)
classAPI.setReference(Boolean.valueOf(attrRef));
String attrImpl = attributes.getValue(ATTR_IMPLEMENT);
if (attrImpl != null)
classAPI.setImplement(Boolean.valueOf(attrImpl));
String attrSubclass = attributes.getValue(ATTR_SUBCLASS);
if (attrSubclass != null)
classAPI.setSubclass(Boolean.valueOf(attrSubclass));
String attrInstantiate = attributes.getValue(ATTR_INSTANTIATE);
if (attrInstantiate != null)
classAPI.setInstantiate(Boolean.valueOf(attrInstantiate));
packageAPI.getClassAPIs().add(classAPI);
}
}
else if (elementName.equals(ELEMENT_PACKAGE_API) || qName.equals(ELEMENT_PACKAGE_API))
{
if (apis != null)
{
packageAPI = new PackageAPI();
packageAPI.setName(attributes.getValue(ATTR_NAME));
apis.getPackageAPIs().add(packageAPI);
}
}
else if (elementName.equals(ELEMENT_INTERNAL_API) || qName.equals(ELEMENT_INTERNAL_API))
{
apis = compAPI.getInternalAPIs();
}
else if (elementName.equals(ELEMENT_EXTERNAL_API) || qName.equals(ELEMENT_EXTERNAL_API))
{
apis = compAPI.getExternalAPIs();
}
else if (equalsLocalpart(elementName, ELEMENT_COMPONENT_API) || equalsLocalpart(qName, ELEMENT_COMPONENT_API))
{
compAPI.setName(attributes.getValue(ATTR_NAME));
}
}
private boolean equalsLocalpart(String fullname, String localpart)
{
int index = fullname.indexOf(':');
if (index != -1)
return fullname.substring(index + 1).equals(localpart);
else
return fullname.equals(localpart);
}
protected void startMethod(ClassAPI cAPI, MethodAPI methodAPI, Attributes attributes) throws SAXException
{
if (cAPI != null)
{
methodAPI.setName(attributes.getValue(ATTR_NAME));
methodAPI.setDescriptor(attributes.getValue(ATTR_DESCRIPTOR));
String attrAccess = attributes.getValue(ATTR_ACCESS);
if (attrAccess != null)
methodAPI.setAccess(Integer.parseInt(attrAccess));
String attrThrows = attributes.getValue(ATTR_THROWS);
if (attrThrows != null)
addToList(methodAPI.getThrows(), attrThrows, " ");
cAPI.getMethodAPIs().add(methodAPI);
}
}
protected void addToList(List list, String value, String delimiter)
{
StringTokenizer st = new StringTokenizer(value, delimiter);
while (st.hasMoreTokens())
list.add(st.nextToken());
}
protected void startField(ClassAPI cAPI, FieldAPI fAPI, Attributes attributes) throws SAXException
{
if (cAPI != null)
{
fAPI.setName(attributes.getValue(ATTR_NAME));
fAPI.setDescriptor(attributes.getValue(ATTR_DESCRIPTOR));
String attrAccess = attributes.getValue(ATTR_ACCESS);
if (attrAccess != null)
fAPI.setAccess(Integer.parseInt(attrAccess));
cAPI.getFieldAPIs().add(fAPI);
}
}
}
}