| /******************************************************************************* |
| * 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.adopters; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| |
| import org.eclipse.wtp.releng.tools.component.ILocation; |
| import org.eclipse.wtp.releng.tools.component.api.ComponentXMLVisitor; |
| import org.eclipse.wtp.releng.tools.component.internal.Location; |
| import org.eclipse.wtp.releng.tools.component.model.ComponentXML; |
| import org.eclipse.wtp.releng.tools.component.model.Package; |
| import org.eclipse.wtp.releng.tools.component.model.Plugin; |
| import org.eclipse.wtp.releng.tools.component.model.Type; |
| import org.eclipse.wtp.releng.tools.component.util.CommandOptionParser; |
| import org.eclipse.wtp.releng.tools.component.xsl.XSLUtil; |
| |
| /** |
| * This class is used to take the output usage.xml files generated from SimpleClass2Reference |
| * and combine them into a helpful CSV or HTML file format displaying API and non-API internal |
| * usage for each logically grouped component team in WTP. The main method can be invoked with |
| * the following three command line arguments: |
| * |
| * "src" = the zip or folder location of the usage.xml files |
| * "api" = the zip or folder location of the component.xml files defining the API base |
| * "output" = the location of the output csv and html combined files |
| */ |
| public class CombineClass2Reference implements IComponentConstants, IOutputConstants { |
| // Command Line arguments |
| public static final String ARG_SOURCE = "src"; //$NON-NLS-1$ |
| public static final String ARG_OUTPUT = "output"; //$NON-NLS-1$ |
| public static final String ARG_API = "api"; //$NON-NLS-1$ |
| |
| // Instance variables |
| private HashMap plugin2compTeam; |
| private List componentTeams; |
| private Collection src; |
| private String output; |
| private Collection api; |
| |
| // Class variables for String values |
| private static final String CLASS_CVS_FILE_EXTENSION = ".class.csv"; //$NON-NLS-1$ |
| private static final String PACKAGE_CVS_FILE_EXTENSION = ".pkg.csv"; //$NON-NLS-1$ |
| private static final String PLUGIN_CVS_FILE_EXTENSION = ".plugin.csv"; //$NON-NLS-1$ |
| private static final String CLASS_HTML_FILE_EXTENSION = ".class.html"; //$NON-NLS-1$ |
| private static final String PACKAGE_HTML_FILE_EXTENSION = ".pkg.html"; //$NON-NLS-1$ |
| private static final String PLUGIN_HTML_FILE_EXTENSION = ".plugin.html"; //$NON-NLS-1$ |
| private static final String COMBINE_PLUGINS_FILE = "org/eclipse/wtp/releng/tools/component/xsl/combine-plugin2ref.xsl"; //$NON-NLS-1$ |
| private static final String COMBINE_PACKAGES_FILE = "org/eclipse/wtp/releng/tools/component/xsl/combine-pkg2ref.xsl"; //$NON-NLS-1$ |
| private static final String COMBINE_CLASSES_FILE = "org/eclipse/wtp/releng/tools/component/xsl/combine-class2ref.xsl"; //$NON-NLS-1$ |
| |
| // Class variables for reference usage constants |
| private static final int CLASS_USAGE = 0; |
| private static final int PACKAGE_USAGE = 1; |
| private static final int PLUGIN_USAGE = 2; |
| |
| /** |
| * The ComponentTeam class manages the number of references per logical grouping of plugins at |
| * either the class, package, or plugin level. |
| */ |
| private class ComponentTeam { |
| private String teamName; |
| private TreeMap class2refCounts; |
| private TreeMap pkg2refCounts; |
| private TreeMap plugin2refCounts; |
| |
| /** |
| * Simple constructor |
| * @param aTeamName |
| */ |
| public ComponentTeam(String aTeamName) { |
| teamName = aTeamName; |
| } |
| |
| /** |
| * @return String component team's name |
| */ |
| public String getTeamName() { |
| return teamName; |
| } |
| |
| /** |
| * |
| * @return TreeMap of class reference counts |
| */ |
| public TreeMap getClassReferenceCounts() { |
| if (class2refCounts==null) |
| class2refCounts = new TreeMap(); |
| return class2refCounts; |
| } |
| |
| /** |
| * |
| * @return TreeMap of package reference counts |
| */ |
| public TreeMap getPackageReferenceCounts() { |
| if (pkg2refCounts==null) |
| pkg2refCounts = new TreeMap(); |
| return pkg2refCounts; |
| } |
| |
| /** |
| * |
| * @return TreeMap of plugin reference counts |
| */ |
| public TreeMap getPluginReferenceCounts() { |
| if (plugin2refCounts==null) |
| plugin2refCounts = new TreeMap(); |
| return plugin2refCounts; |
| } |
| } |
| |
| /** |
| * The UsageCount class is a simple caching mechanism to track API and non API usages. |
| */ |
| private class UsageCount { |
| /** |
| * Uses in an accordance with API contract |
| */ |
| public int apiUse = 0; |
| /** |
| * Internal or other non API usages outside API contract |
| */ |
| public int nonAPIUse = 0; |
| } |
| |
| /** |
| * Default Constructor |
| */ |
| public CombineClass2Reference() { |
| super(); |
| } |
| |
| /** |
| * @return Collection of source usage.xml files |
| */ |
| public Collection getSrc() { |
| return src; |
| } |
| |
| /** |
| * Cache the command line argument for where the source usage.xml files are |
| * @param src |
| */ |
| public void setSrc(Collection src) { |
| this.src = src; |
| } |
| |
| /** |
| * @return String location of the output for the generated files |
| */ |
| public String getOutput() { |
| return output; |
| } |
| |
| /** |
| * Cache the command line argument output location for the generated files |
| * @param output |
| */ |
| public void setOutput(String output) { |
| this.output = output; |
| } |
| |
| /** |
| * @return Collection of API locations for component.xml files |
| */ |
| public Collection getApi() { |
| return api; |
| } |
| |
| /** |
| * Cache the command line argument for where the API component.xml file locations are |
| * @param api |
| */ |
| public void setApi(Collection api) { |
| this.api = api; |
| } |
| |
| /** |
| * This is a helper method to create a map of plugin ids and associated component.xml files. |
| * These component.xml files are the one specified by the collection in the "api" command |
| * line argument. |
| * |
| * @return Map of plugin ids to component.xml files |
| */ |
| private Map collectComponentXMLFiles() { |
| Map pluginId2CompXML = new HashMap(); |
| if (getApi() != null) { |
| for (Iterator i = getApi().iterator(); i.hasNext();) { |
| // For each API file or location, create a Location object |
| ILocation apiLocation = Location.createLocation(new File((String)i.next())); |
| // Create a visitor to traverse the location and collect all contained component.xml files |
| ComponentXMLVisitor compXMLVisitor = new ComponentXMLVisitor(); |
| apiLocation.accept(compXMLVisitor); |
| // For each component.xml found, find the plugins it corresponds to |
| for (Iterator it = compXMLVisitor.getCompXMLs().iterator(); it.hasNext();) { |
| ComponentXML compXML = (ComponentXML)it.next(); |
| // For each plugin, add a mapping for the plugin to the component.xml file |
| for (Iterator it2 = compXML.getPlugins().iterator(); it2.hasNext();) { |
| pluginId2CompXML.put(((Plugin)it2.next()).getId(), compXML); |
| } |
| } |
| } |
| } |
| return pluginId2CompXML; |
| } |
| |
| /** |
| * This method drives the combination of the usages in the usage.xml files and based on the |
| * API information in the component.xml files in the given map, it will appropriately |
| * tabulate non-API and API usage information for class references, package references, and |
| * plugin references. |
| * |
| * @param pluginId2CompXML |
| */ |
| private void processUsages(Map pluginId2CompXML) { |
| // Iterate over all of the source usage.xml files provided by the "src" collection argument |
| for (Iterator it = getSrc().iterator(); it.hasNext();) { |
| FileInputStream fis = null; |
| try { |
| // Open a file input stream on the current source usage.xml file |
| String file = (String)it.next(); |
| fis = new FileInputStream(file); |
| // Create a references object to parse the usage.xml file and cache the references |
| References refs = new References(); |
| refs.load(fis); |
| // Iterate through the list of plugins referenced in usage.xml file |
| for (Iterator it2 = refs.getPluginRefs().iterator(); it2.hasNext();) { |
| PluginRef pluginRef = (PluginRef)it2.next(); |
| String pluginId = pluginRef.getId(); |
| // Retrieve the corresponding component.xml file for the current plugin referenced |
| ComponentXML compXML = (ComponentXML)pluginId2CompXML.get(pluginId); |
| // Get the corresponding component team from that plugin id |
| ComponentTeam compTeam = getComponentTeam(pluginId); |
| // Iterate through the class references in that plugin reference |
| for (Iterator it3 = pluginRef.getClassRefs().iterator(); it3.hasNext();) { |
| ClassRef classRef = (ClassRef)it3.next(); |
| // Update the component team's cached reference counts with the current class reference |
| updateComponentTeamUsageCounts(compTeam,compXML,classRef,pluginId); |
| } |
| } |
| } catch (Throwable t) { |
| throw new RuntimeException(t); |
| } finally { |
| // Close the current file input stream |
| if (fis != null) { |
| try { |
| fis.close(); |
| } catch (IOException ioe) {} |
| } |
| } |
| } |
| } |
| |
| /** |
| * The execute method drives the combination operation by collecting component.xml files |
| * from the "api" command line arugment, processing references in usage.xml files from the |
| * "src" command line argument, and then writing them out in CSV and HTML file format to |
| * a location specified by the "output" command line argument. |
| */ |
| private void execute() { |
| // Collect the plugin to component.xml file map from the specified collection of |
| // component.xml files in the "api" command line argument. |
| Map pluginId2CompXML = collectComponentXMLFiles(); |
| // Process the usages in the usage.xml files provided by the "src" collection command arg |
| processUsages(pluginId2CompXML); |
| // Generate the output files for combined usage in CSV format |
| generateCSVFiles(); |
| // Generate the output files for combined usage in HTML format |
| generateHTMLFiles(); |
| } |
| |
| private List getOrderedReferencedCountKeys(final TreeMap referenceCounts) { |
| String[] keys = (String[]) referenceCounts.keySet().toArray(new String[referenceCounts.keySet().size()]); |
| Comparator nonAPIComparator = new Comparator() { |
| public int compare(Object o1, Object o2) { |
| UsageCount usageCount1 = (UsageCount) referenceCounts.get(o1); |
| UsageCount usageCount2 = (UsageCount) referenceCounts.get(o2); |
| return usageCount2.nonAPIUse-usageCount1.nonAPIUse; |
| } |
| }; |
| Arrays.sort(keys,nonAPIComparator); |
| return Arrays.asList(keys); |
| } |
| |
| /** |
| * Helper method to update the passed in component team's cached usage counts based on the |
| * given class reference and known API's in the provided component.xml file. |
| * |
| * @param compTeam |
| * @param compXML |
| * @param classRef |
| * @param pluginId |
| */ |
| private void updateComponentTeamUsageCounts(ComponentTeam compTeam, ComponentXML compXML, ClassRef classRef, String pluginId) { |
| String name = classRef.getName(); |
| String pkgName = getPackageName(name); |
| // Get the usage count object for the current referenced class |
| UsageCount usageCount = getUsageCount(compXML, classRef, pkgName, name.substring(pkgName.length() + 1)); |
| // Get the component team's cached class reference usage count |
| UsageCount classUsageCount = (UsageCount)compTeam.getClassReferenceCounts().get(name); |
| if (classUsageCount == null) |
| classUsageCount = new UsageCount(); |
| // Update the component team's cached class usage count with the current usage count |
| classUsageCount.apiUse += usageCount.apiUse; |
| classUsageCount.nonAPIUse += usageCount.nonAPIUse; |
| // Put the updated class Usage count back into the cache on the component team |
| compTeam.getClassReferenceCounts().put(name, classUsageCount); |
| // Get the component team's cached package reference usage count |
| UsageCount pkgUsageCount = (UsageCount)compTeam.getPackageReferenceCounts().get(pkgName); |
| if (pkgUsageCount == null) |
| pkgUsageCount = new UsageCount(); |
| // Update the component team's cached package reference count with current usage count |
| pkgUsageCount.apiUse += usageCount.apiUse; |
| pkgUsageCount.nonAPIUse += usageCount.nonAPIUse; |
| // Put the updated package usage count back into the cache on the component team |
| compTeam.getPackageReferenceCounts().put(pkgName, pkgUsageCount); |
| // Get the component team's cached plugin reference usage count |
| UsageCount pluginUsageCount = (UsageCount)compTeam.getPluginReferenceCounts().get(pluginId); |
| if (pluginUsageCount == null) |
| pluginUsageCount = new UsageCount(); |
| // Update the component team's cached plugin reference count with current usage count |
| pluginUsageCount.apiUse += usageCount.apiUse; |
| pluginUsageCount.nonAPIUse += usageCount.nonAPIUse; |
| // Put the update plugin usage count back into the cache on the component team |
| compTeam.getPluginReferenceCounts().put(pluginId, pluginUsageCount); |
| } |
| |
| /** |
| * Helper method to find the corresponding component team for a given plugin id. If one is |
| * not found, the unknown component is returned. |
| * |
| * @param pluginId |
| * @return ComponentTeam for specified plugin |
| */ |
| private ComponentTeam getComponentTeam(String pluginId) { |
| // Try and match the proper component team to the referenced plugin from the |
| // map of plugins to component teams |
| for (Iterator it3 = getPluginComponentMap().keySet().iterator(); it3.hasNext();) { |
| String regex = (String)it3.next(); |
| if (pluginId.matches(regex)) { |
| return (ComponentTeam)getPluginComponentMap().get(regex); |
| } |
| } |
| // Otherwise return the unknown component |
| return getUnknownComponent(); |
| } |
| |
| /** |
| * This method will cache and return the usages of the class reference into a UsageCount object. |
| * It will check the passed in component.xml to see if the reference is using a qualified API |
| * or if it is an internal usage. The types of references which qualify are class references, |
| * subclasses, implementers, or instantiators. |
| * |
| * @param compXML |
| * @param classRef |
| * @param pkgName |
| * @param localName |
| * @return UsageCount |
| */ |
| private UsageCount getUsageCount(ComponentXML compXML, ClassRef classRef, String pkgName, String localName) { |
| // Create UsageCount object |
| UsageCount usageCount = new UsageCount(); |
| int refCount = classRef.getRefCount(); |
| int subclassCount = classRef.getSubclassCount(); |
| int implCount = classRef.getImplementCount(); |
| int instantiateCount = classRef.getInstantiateCount(); |
| // If the component.xml is null, or the package referenced does not exist in the component.xml |
| // we know the reference cannot be an API use, so just add all the references to the non-API |
| // count and return. |
| if (compXML==null || compXML.getPackage(pkgName)==null) { |
| usageCount.nonAPIUse = refCount + subclassCount + implCount + instantiateCount; |
| return usageCount; |
| } |
| // Get the referenced package from the component.xml file |
| Package pkg = compXML.getPackage(pkgName); |
| // Get the references type from the references pckage in the component.xml file |
| Type type = pkg.getType(localName); |
| if (type == null) { |
| // If the type is null, but the package is an API package, update the API count |
| if (pkg.isApi()) { |
| usageCount.apiUse = refCount + subclassCount + implCount + instantiateCount; |
| return usageCount; |
| } |
| // If the type is null, but the package is not API, update the non-API count |
| usageCount.nonAPIUse = refCount + subclassCount + implCount + instantiateCount; |
| return usageCount; |
| } |
| // Handle the cases where we have a valid component.xml package and type. |
| // If the type is not a valid API reference, increment the non-API ref count |
| if (!type.isReference()) { |
| usageCount.nonAPIUse += classRef.getRefCount(); |
| } else { |
| // Otherwise, increment API ref count |
| usageCount.apiUse += classRef.getRefCount(); |
| } |
| // If the type is not a valid API subclass, increment the non-API subclass count |
| if (!type.isSubclass()) { |
| usageCount.nonAPIUse += classRef.getSubclassCount(); |
| } else { |
| // Otherwise, increment API subclass count |
| usageCount.apiUse += classRef.getSubclassCount(); |
| } |
| // If the type is not a valid API implementor, increment the non-API implementor count |
| if (!type.isImplement()) { |
| usageCount.nonAPIUse += classRef.getImplementCount(); |
| } else { |
| // Otherwise increment API implementor count |
| usageCount.apiUse += classRef.getImplementCount(); |
| } |
| // If the type is not a valid API instantiation, increment the non-API instantiation count |
| if (!type.isInstantiate()) { |
| usageCount.nonAPIUse += classRef.getInstantiateCount(); |
| } else { |
| // Otherwise increment API instantation count |
| usageCount.apiUse += classRef.getInstantiateCount(); |
| } |
| // Return the usage count |
| return usageCount; |
| } |
| |
| /** |
| * Given a fully qualified class name, return the package name. |
| * |
| * @param a fully qualified className |
| * @return the package name |
| */ |
| private String getPackageName(String className) { |
| int i = className.lastIndexOf('.'); |
| if (i != -1) |
| return className.substring(0, i); |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Generate CSV format files displaying the combined internal and API usage for classes, |
| * packages, and plugins. |
| */ |
| private void generateCSVFiles() { |
| FileWriter classWriter = null; |
| FileWriter pkgWriter = null; |
| FileWriter pluginWriter = null; |
| try { |
| // Create the file writers |
| classWriter = new FileWriter(getOutput() + CLASS_CVS_FILE_EXTENSION); |
| pkgWriter = new FileWriter(getOutput() + PACKAGE_CVS_FILE_EXTENSION); |
| pluginWriter = new FileWriter(getOutput() + PLUGIN_CVS_FILE_EXTENSION); |
| // For each component team, write the CVS file content for the component's usage |
| for (int i=0; i<getComponentTeams().size(); i++) { |
| ComponentTeam compTeam = (ComponentTeam) getComponentTeams().get(i); |
| writeCompTeamCSV(compTeam, classWriter, pkgWriter, pluginWriter); |
| } |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } finally { |
| // Close the class usage file writer |
| if (classWriter != null) { |
| try { |
| classWriter.close(); |
| } catch (IOException ioe) {} |
| } |
| // Close the package usage file writer |
| if (pkgWriter != null) { |
| try { |
| pkgWriter.close(); |
| } catch (IOException ioe) {} |
| } |
| // Close the plugin usage file writer |
| if (pluginWriter != null) { |
| try { |
| pluginWriter.close(); |
| } catch (IOException ioe) {} |
| } |
| } |
| } |
| |
| /** |
| * This method drives the creation of the CSV file contents for the given component team |
| * and corresponding writers. |
| * |
| * @param compTeam |
| * @param classWriter |
| * @param pkgWriter |
| * @param pluginWriter |
| * @throws IOException |
| */ |
| private void writeCompTeamCSV(ComponentTeam compTeam, Writer classWriter, Writer pkgWriter, Writer pluginWriter) throws IOException { |
| writeCompTeamCSV(compTeam,classWriter,compTeam.getClassReferenceCounts()); |
| writeCompTeamCSV(compTeam,pkgWriter,compTeam.getPackageReferenceCounts()); |
| writeCompTeamCSV(compTeam,pluginWriter,compTeam.getPluginReferenceCounts()); |
| } |
| |
| /** |
| * This is a helper method to write out the given component team's reference counts in |
| * a CSV file format. |
| * |
| * @param compTeam |
| * @param writer |
| * @param referenceCounts |
| * @throws IOException |
| */ |
| private void writeCompTeamCSV(ComponentTeam compTeam, Writer writer, TreeMap referenceCounts) throws IOException { |
| // Write the team name |
| writer.write(compTeam.getTeamName()); |
| writer.write(LINE_BREAK); |
| // Order reference counts by usage type |
| List orderedKeys = getOrderedReferencedCountKeys(referenceCounts); |
| // For each name key, retrieve the corresponding usage count values |
| for (Iterator it = orderedKeys.iterator(); it.hasNext();) { |
| String name = (String)it.next(); |
| // Get the corresponding usage count for the name key |
| UsageCount usageCount = (UsageCount)referenceCounts.get(name); |
| // Write out the internal and api usages |
| writer.write(name); |
| writer.write(COMMA); |
| writer.write(String.valueOf(usageCount.nonAPIUse)); |
| writer.write(COMMA); |
| writer.write(String.valueOf(usageCount.apiUse)); |
| writer.write(LINE_BREAK); |
| } |
| writer.write(LINE_BREAK); |
| } |
| |
| /** |
| * Generate the HTML files for comibined usage ref counts of classes, packages, and plugins. |
| */ |
| private void generateHTMLFiles() { |
| try { |
| // Create a new output stream |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| baos.write(XML_ROOT_BEGIN.getBytes()); |
| // For each component team, write out the combined component team specific usage data |
| for (int i=0; i<getComponentTeams().size(); i++) { |
| ComponentTeam compTeam = (ComponentTeam) getComponentTeams().get(i); |
| writeCompTeamXML(compTeam, baos); |
| } |
| // Close the output stream |
| baos.write(XML_ROOT_END.getBytes()); |
| baos.close(); |
| // Create a byte array from the output stream contents |
| byte[] content = baos.toByteArray(); |
| // Write out the byte array xml to a html file output stream for the plugin references |
| // This transform will do a XSLT operation using the file combine-plugin2ref.xsl |
| XSLUtil.transform ( |
| ClassLoader.getSystemResourceAsStream(COMBINE_PLUGINS_FILE), |
| new ByteArrayInputStream(content), |
| new FileOutputStream(getOutput() + PLUGIN_HTML_FILE_EXTENSION) |
| ); |
| // Write out the byte array xml to a html file output stream for the package references |
| // This transform will do a XSLT operation using the file combine-pkg2ref.xsl |
| XSLUtil.transform ( |
| ClassLoader.getSystemResourceAsStream(COMBINE_PACKAGES_FILE), |
| new ByteArrayInputStream(content), |
| new FileOutputStream(getOutput() + PACKAGE_HTML_FILE_EXTENSION) |
| ); |
| // Write out the byte array xml to a html file output stream for the class references |
| // This transform will do a XSLT operation using the file combine-class2ref.xsl |
| XSLUtil.transform ( |
| ClassLoader.getSystemResourceAsStream(COMBINE_CLASSES_FILE), |
| new ByteArrayInputStream(content), |
| new FileOutputStream(getOutput() + CLASS_HTML_FILE_EXTENSION) |
| ); |
| } catch (Throwable t) { |
| t.printStackTrace(); |
| throw new RuntimeException(t); |
| } |
| } |
| |
| /** |
| * This method will drive the combined output file html contents for the given component |
| * team. |
| * |
| * @param compTeam |
| * @param baos |
| * @throws IOException |
| */ |
| private void writeCompTeamXML(ComponentTeam compTeam, ByteArrayOutputStream baos) throws IOException { |
| baos.write("<team lead=\"".getBytes()); //$NON-NLS-1$ |
| baos.write(compTeam.getTeamName().getBytes()); |
| baos.write("\">".getBytes()); //$NON-NLS-1$ |
| writeCompTeamXML(baos,CLASS_USAGE,compTeam.getClassReferenceCounts()); |
| writeCompTeamXML(baos,PACKAGE_USAGE,compTeam.getPackageReferenceCounts()); |
| writeCompTeamXML(baos,PLUGIN_USAGE,compTeam.getPluginReferenceCounts()); |
| baos.write("</team>".getBytes()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * This method will write in html format the combined output for the given component team for |
| * the non API and API usage for the class usage file, the package usage file, and the plugin |
| * usage file. |
| * |
| * @param baos ByteArrayOutputStream |
| * @param usage class, package, or plugin? |
| * @param referenceCounts TreeMap |
| * @throws IOException |
| */ |
| private void writeCompTeamXML(ByteArrayOutputStream baos, int usage, TreeMap referenceCounts) throws IOException { |
| // Order reference counts by usage type |
| List orderedKeys = getOrderedReferencedCountKeys(referenceCounts); |
| // Iterate over the name keys of the references tree map |
| for (Iterator it = orderedKeys.iterator(); it.hasNext();) { |
| String name = (String)it.next(); |
| // Retrieve the appropriate UsageCount from the map given the current name key |
| UsageCount usageCount = (UsageCount) referenceCounts.get(name); |
| switch (usage) { |
| // Class reference |
| case 0: |
| baos.write("<class name=\"".getBytes()); //$NON-NLS-1$ |
| break; |
| // Package reference |
| case 1: |
| baos.write("<package name=\"".getBytes()); //$NON-NLS-1$ |
| break; |
| // Plugin reference |
| case 2: |
| baos.write("<plugin id=\"".getBytes()); //$NON-NLS-1$ |
| break; |
| } |
| // Write the api and internal usage for the current reference |
| baos.write(name.getBytes()); |
| baos.write("\" api=\"".getBytes()); //$NON-NLS-1$ |
| baos.write(String.valueOf(usageCount.apiUse).getBytes()); |
| baos.write("\" internal=\"".getBytes()); //$NON-NLS-1$ |
| baos.write(String.valueOf(usageCount.nonAPIUse).getBytes()); |
| baos.write("\"/>".getBytes()); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * This is the static main method used for launching this reference usage combination |
| * application. It will create and set up the class instance and then invoke the execute |
| * method to do the combination. |
| * |
| * @param args |
| */ |
| public static void main(String[] args) { |
| // Use the command option parser to parse the command line arguments |
| CommandOptionParser optionParser = new CommandOptionParser(args); |
| Map options = optionParser.getOptions(); |
| Collection src = (Collection)options.get(ARG_SOURCE); |
| Collection output = (Collection)options.get(ARG_OUTPUT); |
| Collection api = (Collection)options.get(ARG_API); |
| // If the usage is improper or arguments are not valid, prompt for proper usage |
| if (src == null || output == null || src.isEmpty() || output.isEmpty()) { |
| printUsage(); |
| System.exit(-1); |
| } |
| // Create a new instance of the class and set the command line argument values |
| CombineClass2Reference class2Ref = new CombineClass2Reference(); |
| class2Ref.setSrc(src); |
| class2Ref.setOutput((String)output.iterator().next()); |
| class2Ref.setApi(api); |
| // Execute the combination method |
| class2Ref.execute(); |
| } |
| |
| /** |
| * This is a helper method to the user to print out an error message of the proper usage of |
| * the arguments to be passed and the location of the output files. |
| * See IOutputConstants for messages. |
| */ |
| private static void printUsage() { |
| System.out.println(PRINT_USAGE_COMBINED); |
| System.out.println(""); //$NON-NLS-1$ |
| System.out.println(PRINT_SOURCE_LOCATION); |
| System.out.println(PRINT_OUTPUT_LOCATION); |
| System.out.println(PRINT_COMPONENT_XML_API_LOCATION); |
| } |
| |
| /** |
| * @return the list of component teams |
| */ |
| private List getComponentTeams() { |
| if (componentTeams == null) |
| initializeComponentTeams(); |
| return componentTeams; |
| } |
| |
| /** |
| * Initialize the component teams list with the appropriate regular expressions to link plugins |
| * to the known set of component teams. |
| */ |
| private void initializeComponentTeams() { |
| componentTeams = new ArrayList(); |
| |
| // Create the JEE team with associated plugins |
| ComponentTeam javaEE = new ComponentTeam(COMPONENT_TEAM_JAVA_EE); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_J2EE, javaEE); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_EJB, javaEE); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_SERVLET, javaEE); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_WEB, javaEE); |
| componentTeams.add(javaEE); |
| |
| // Create the Common team with associated plugins |
| ComponentTeam common = new ComponentTeam(COMPONENT_TEAM_COMMON); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_COMMAND, common); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_COMMON, common); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_VALIDATION, common); |
| componentTeams.add(common); |
| |
| // Create the Editors team with associated plugins |
| ComponentTeam editors = new ComponentTeam(COMPONENT_TEAM_EDITORS); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_JSP, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_CSS, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_DTD, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_HTML, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_JAVASCRIPT, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_SSE, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_XML, editors); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_XSD, editors); |
| componentTeams.add(editors); |
| |
| // Create the RDB team with associated plugins |
| ComponentTeam rdb = new ComponentTeam(COMPONENT_TEAM_RDB); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_RDB, rdb); |
| componentTeams.add(rdb); |
| |
| // Create the Web Services team with associated plugins |
| ComponentTeam webServices = new ComponentTeam(COMPONENT_TEAM_WEB_SERVICES); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_WS, webServices); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_WSDL, webServices); |
| componentTeams.add(webServices); |
| |
| // Create the Server team with associated plugins |
| ComponentTeam server = new ComponentTeam(COMPONENT_TEAM_SERVER); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_SERVER, server); |
| getPluginComponentMap().put(PLUGIN_EXPRESSION_INTERNET, server); |
| componentTeams.add(server); |
| |
| // Add a "team" for the unknown references |
| ComponentTeam unknown = new ComponentTeam(COMPONENT_TEAM_UNKNOWN); |
| componentTeams.add(unknown); |
| } |
| |
| /** |
| * @return HashMap of plugin keys and associated component team values |
| */ |
| private HashMap getPluginComponentMap() { |
| if (plugin2compTeam==null) { |
| plugin2compTeam = new HashMap(); |
| initializeComponentTeams(); |
| } |
| return plugin2compTeam; |
| } |
| |
| /** |
| * @return the unknown component where a plugin's logical component is not known |
| */ |
| private ComponentTeam getUnknownComponent() { |
| for (int i=0; i<getComponentTeams().size(); i++) { |
| ComponentTeam compTeam = (ComponentTeam) getComponentTeams().get(i); |
| if (compTeam.getTeamName().equals(COMPONENT_TEAM_UNKNOWN)) |
| return compTeam; |
| } |
| return null; |
| } |
| } |