| /******************************************************************************* |
| * 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; |
| } |
| } |
| } |