blob: 49a0fec4050e43a6bd1b858553440a8fe1124b6e [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 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.progress;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
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 javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wtp.releng.tools.component.CommandOptionParser;
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.api.ComponentAPI;
import org.eclipse.wtp.releng.tools.component.api.ComponentXMLVisitor;
import org.eclipse.wtp.releng.tools.component.api.violation.PluginVisitor;
import org.eclipse.wtp.releng.tools.component.images.ImagesUtil;
import org.eclipse.wtp.releng.tools.component.internal.AbstractEmitter;
import org.eclipse.wtp.releng.tools.component.internal.ComponentXML;
import org.eclipse.wtp.releng.tools.component.internal.Location;
import org.eclipse.wtp.releng.tools.component.internal.Plugin;
import org.eclipse.wtp.releng.tools.component.xsl.XSLUtil;
public class APIProgressScanner extends AbstractEmitter
{
private Collection api;
private Collection src;
private String timestamp;
private String progressDir;
private String outputDir;
private Collection includes;
private Collection excludes;
public String getTimestamp()
{
return timestamp;
}
public void setTimestamp(String timestamp)
{
this.timestamp = timestamp;
}
public String getProgressDir()
{
return progressDir;
}
public void setProgressDir(String progressDir)
{
this.progressDir = addTrailingSeperator(progressDir);
}
public Collection getApi()
{
return api;
}
public void setApi(Collection api)
{
this.api = api;
}
public String getOutputDir()
{
return outputDir;
}
public void setOutputDir(String outputDir)
{
this.outputDir = addTrailingSeperator(outputDir);
}
public Collection getSrc()
{
return src;
}
public void setSrc(Collection src)
{
this.src = src;
}
public Collection getIncludes()
{
return includes;
}
public void setIncludes(Collection includes)
{
this.includes = includes;
}
public Collection getExcludes()
{
return excludes;
}
public void setExcludes(Collection excludes)
{
this.excludes = excludes;
}
public void execute()
{
genAPIInfoSummary();
if (timestamp != null && progressDir != null)
genSVG();
}
private void genAPIInfoSummary()
{
final StringBuffer apiProgress = new StringBuffer();
apiProgress.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
apiProgress.append("<root>");
if (src != null && api != null)
apiProgress.append(validatePlugins());
ILocation loc = Location.createLocation(new File(outputDir));
loc.accept(
new ILocationVisitor()
{
public boolean accept(ILocation location)
{
if (location.getName().endsWith("api-info.xml"))
{
apiProgress.append("<api-info file=\"./");
apiProgress.append(location.getAbsolutePath().substring(outputDir.length()));
try
{
ComponentAPI compAPI = new ComponentAPI();
compAPI.setLocation(location);
compAPI.load();
String id = compAPI.getName();
if (id != null)
{
String compName = (String)pluginId2CompName.get(id);
if (compName != null)
{
OverviewDocLoader loader = new OverviewDocLoader(compName);
String url = loader.getOverviewDocURL();
if (url != null)
{
apiProgress.append("\" overviewDoc=\"");
apiProgress.append(url);
}
}
}
}
catch (Throwable t)
{
}
apiProgress.append("\"/>");
}
return true;
}
});
apiProgress.append("</root>");
try
{
ImagesUtil.copyAll(outputDir);
XSLUtil.transform
(
ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/xsl/api-progress.xsl"),
new ByteArrayInputStream(apiProgress.toString().getBytes()),
new FileOutputStream(new File(outputDir + "api-progress.html")),
outputDir
);
XSLUtil.transform
(
ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/xsl/api-progress-summary.xsl"),
new ByteArrayInputStream(apiProgress.toString().getBytes()),
new FileOutputStream(new File(outputDir + "api-info-summary.xml")),
outputDir
);
}
catch (Throwable e)
{
try
{
XSLUtil.transform
(
Platform.getBundle("org.eclipse.wtp.releng.tools.component.core").getResource("org/eclipse/wtp/releng/tools/component/xsl/api-progress.xsl").openStream(),
new ByteArrayInputStream(apiProgress.toString().getBytes()),
new FileOutputStream(new File(outputDir + "api-progress.html")),
outputDir
);
XSLUtil.transform
(
Platform.getBundle("org.eclipse.wtp.releng.tools.component.core").getResource("org/eclipse/wtp/releng/tools/component/xsl/api-progress-summary.xsl").openStream(),
new ByteArrayInputStream(apiProgress.toString().getBytes()),
new FileOutputStream(new File(outputDir + "api-info-summary.xml")),
outputDir
);
}
catch (Throwable e2)
{
e2.printStackTrace();
}
}
}
private Map pluginId2CompName = new HashMap();
private String validatePlugins()
{
StringBuffer sb = new StringBuffer();
List pluginsWithoutComp = new ArrayList();
List pluginsNotFoundInSrc = new ArrayList();
List pluginsInMoreThan1Comp = new ArrayList();
List pluginIds = new ArrayList();
// Collection component.xml files
for (Iterator i = api.iterator(); i.hasNext();)
{
ILocation apiLocation = Location.createLocation(new File((String)i.next()));
ComponentXMLVisitor compXMLVisitor = new ComponentXMLVisitor();
apiLocation.accept(compXMLVisitor);
for (Iterator it = compXMLVisitor.getCompXMLs().iterator(); it.hasNext();)
{
ComponentXML compXML = (ComponentXML)it.next();
String compName = compXML.getName();
for (Iterator it2 = compXML.getPlugins().iterator(); it2.hasNext();)
{
String id = ((Plugin)it2.next()).getId();
pluginId2CompName.put(id, compName);
if (pluginIds.contains(id))
pluginsInMoreThan1Comp.add(id);
else
pluginIds.add(id);
}
}
}
// Visit Src
for (Iterator it = src.iterator(); it.hasNext();)
{
ILocation srcLocation = Location.createLocation(new File((String)it.next()));
PluginVisitor v = new PluginVisitor();
srcLocation.accept(v);
for (Iterator it2 = v.getPluginIds().iterator(); it2.hasNext();)
{
String id = (String)it2.next();
if (!pluginIds.remove(id))
{
if (include(id))
{
pluginsWithoutComp.add(id);
}
}
}
}
for (Iterator it = pluginIds.iterator(); it.hasNext();)
pluginsNotFoundInSrc.add((String)it.next());
// Print results
for (Iterator it = pluginsWithoutComp.iterator(); it.hasNext();)
{
sb.append("<plugin-without-comp id=\"");
sb.append((String)it.next());
sb.append("\"/>");
}
for (Iterator it = pluginsNotFoundInSrc.iterator(); it.hasNext();)
{
sb.append("<missing-plugin id=\"");
sb.append((String)it.next());
sb.append("\"/>");
}
for (Iterator it = pluginsInMoreThan1Comp.iterator(); it.hasNext();)
{
sb.append("<dup-plugin id=\"");
sb.append((String)it.next());
sb.append("\"/>");
}
return sb.toString();
}
private void genSVG()
{
File src = new File(outputDir + "api-info-summary.xml");
File dest = new File(progressDir + timestamp + "/api-info-summary.xml");
try
{
copy(src, dest);
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
final StringBuffer content = new StringBuffer();
content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
content.append("<root name=\"#name\">");
ILocation progress = Location.createLocation(new File(progressDir));
ILocationChildrenIterator it = progress.childIterator();
ILocation child = it.next();
while (child != null)
{
content.append("<summary timestamp=\"");
content.append(child.getName());
content.append("\"/>");
child = it.next();
}
content.append("</root>");
ILocation loc = Location.createLocation(new File(outputDir));
loc.accept(
new ILocationVisitor()
{
public boolean accept(ILocation location)
{
if (location.getName().endsWith("api-info.xml"))
{
try
{
ComponentAPI compAPI = new ComponentAPI();
compAPI.setLocation(location);
compAPI.load();
String compName = compAPI.getName();
StringBuffer sb = new StringBuffer();
sb.append(outputDir);
sb.append("svg/");
new File(sb.toString()).mkdirs();
genSVG(content.toString(), compName, sb.toString());
}
catch (Throwable t)
{
t.printStackTrace();
}
}
return true;
}
});
try
{
genSVG(content.toString(), "total", outputDir + "svg/");
}
catch (Throwable t)
{
t.printStackTrace();
}
}
private void genSVG(String content, String name, String outDir) throws IOException, TransformerConfigurationException, TransformerException
{
XSLUtil.transform
(
ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/xsl/api-progress-svg.xsl"),
new ByteArrayInputStream(content.replaceAll("#name", name).getBytes()),
new FileOutputStream(outDir + name + ".svg"),
progressDir
);
}
private void copy(File src, File dest) throws IOException
{
dest.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(dest);
FileInputStream fis = new FileInputStream(src);
byte[] b = new byte[2048];
int read = fis.read(b);
while (read != -1)
{
fos.write(b, 0, read);
read = fis.read(b);
}
fis.close();
fos.close();
}
private boolean include(String name)
{
name = name.replace('/', '.');
name = name.replace('\\', '.');
if (excludes != null && !excludes.isEmpty())
for (Iterator it = excludes.iterator(); it.hasNext();)
if (name.matches((String)it.next()))
return false;
if (includes != null && !includes.isEmpty())
{
for (Iterator it = includes.iterator(); it.hasNext();)
if (name.matches((String)it.next()))
return true;
return false;
}
return true;
}
public static void main(String[] args)
{
CommandOptionParser optionParser = new CommandOptionParser(args);
Map options = optionParser.getOptions();
List api = (List)options.get("api");
List src = (List)options.get("src");
List timestamp = (List)options.get("timestamp");
List progressDir = (List)options.get("progressDir");
List outputDir = (List)options.get("outputDir");
Collection includes = (Collection)options.get("includes");
Collection excludes = (Collection)options.get("excludes");
if (outputDir == null || outputDir.size() < 1)
{
printUsage();
System.exit(-1);
}
APIProgressScanner scanner = new APIProgressScanner();
if (api != null && api.size() > 0)
scanner.setApi(api);
if (src != null && src.size() > 0)
scanner.setSrc(src);
if (timestamp != null && timestamp.size() > 0)
scanner.setTimestamp((String)timestamp.iterator().next());
if (progressDir != null && progressDir.size() > 0)
scanner.setProgressDir((String)progressDir.iterator().next());
scanner.setOutputDir((String)outputDir.iterator().next());
scanner.setIncludes(includes);
scanner.setExcludes(excludes);
scanner.execute();
}
private static void printUsage()
{
System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.progress.APIProgressScanner -compIndex <compIndex> -eclipseDir <eclipseDir> -compXMLDir <compXMLDir> -outputDir <outputDir>");
System.out.println("");
System.out.println("\t-outputDir\t<outputDir>\toutput directory of component.xml files");
System.out.println("");
System.out.println("where options include:");
System.out.println("");
System.out.println("\t-api\t\t<api>\t\tlocation of your component.xml");
System.out.println("\t-src\t\t<src>\t\tlocation of a Eclipse-based product");
System.out.println("\t-timestamp\t<timestamp>\ttimestamp");
System.out.println("\t-progressDir\t<progressDir>\tdirectory containing API progress documents");
System.out.println("\t-includes\t<includes>\tspace seperated plug-ins to include");
System.out.println("\t-excludes\t<excludes>\tspace seperated plug-ins to exclude");
}
private class OverviewDocLoader
{
private String componentName;
public OverviewDocLoader(String componentName)
{
this.componentName = componentName;
}
public String getOverviewDocURL()
{
InputStream is = null;
try
{
StringBuffer url = new StringBuffer("http://www.eclipse.org/webtools/components/");
url.append(componentName);
url.append("/");
URL overviewDoc = new URL(url.toString());
is = overviewDoc.openStream();
return url.toString();
}
catch (Throwable t)
{
}
finally
{
try
{
if (is != null)
is.close();
}
catch (Throwable t)
{
t.printStackTrace();
}
}
return null;
}
}
}