private void writeJarOptions( String inputEntryOptionName, String outputEntryOptionName, ClassPath classPath) { if (classPath != null) { for (int index = 0; index < classPath.size(); index++) { ClassPathEntry entry = classPath.get(index); String optionName = entry.isOutput() ? outputEntryOptionName : inputEntryOptionName; writer.print(optionName); writer.print(' '); writer.print(relativeFileName(entry.getFile())); // Append the filters, if any. boolean filtered = false; // For backward compatibility, the aar and apk filters come // first. filtered = writeFilter(filtered, entry.getAarFilter()); filtered = writeFilter(filtered, entry.getApkFilter()); filtered = writeFilter(filtered, entry.getZipFilter()); filtered = writeFilter(filtered, entry.getEarFilter()); filtered = writeFilter(filtered, entry.getWarFilter()); filtered = writeFilter(filtered, entry.getJarFilter()); filtered = writeFilter(filtered, entry.getFilter()); if (filtered) { writer.print(ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD); } writer.println(); } } }
/** * Rescans the associated paths to recompute the available resources. * * @param logger status and error details are written here */ public void refresh(TreeLogger logger) { PerfLogger.start("ResourceOracleImpl.refresh"); TreeLogger refreshBranch = Messages.REFRESHING_RESOURCES.branch(logger, null); /* * Allocate fresh data structures in anticipation of needing to honor the * "new identity for the collections if anything changes" guarantee. Use a * LinkedHashMap because we do not want the order to change. */ Map<String, ResourceData> newInternalMap = new LinkedHashMap<String, ResourceData>(); /* * Walk across path roots (i.e. classpath entries) in priority order. This * is a "reverse painter's algorithm", relying on being careful never to add * a resource that has already been added to the new map under construction * to create the effect that resources founder earlier on the classpath take * precedence. * * Exceptions: super has priority over non-super; and if there are two super * resources with the same path, the one with the higher-priority path * prefix wins. */ for (ClassPathEntry pathRoot : classPath) { TreeLogger branchForClassPathEntry = Messages.EXAMINING_PATH_ROOT.branch(refreshBranch, pathRoot.getLocation(), null); Map<AbstractResource, PathPrefix> resourceToPrefixMap = pathRoot.findApplicableResources(branchForClassPathEntry, pathPrefixSet); for (Entry<AbstractResource, PathPrefix> entry : resourceToPrefixMap.entrySet()) { ResourceData newCpeData = new ResourceData(entry.getKey(), entry.getValue()); String resourcePath = newCpeData.resource.getPath(); ResourceData oldCpeData = newInternalMap.get(resourcePath); // Old wins unless the new resource has higher priority. if (oldCpeData == null || oldCpeData.compareTo(newCpeData) < 0) { newInternalMap.put(resourcePath, newCpeData); } else { Messages.IGNORING_SHADOWED_RESOURCE.log(branchForClassPathEntry, resourcePath, null); } } } /* * Update the newInternalMap to preserve identity for any resources that * have not changed; also record whether or not there are ANY changes. * * There's definitely a change if the sizes don't match; even if the sizes * do match, every new resource must match an old resource for there to be * no changes. */ boolean didChange = internalMap.size() != newInternalMap.size(); for (Map.Entry<String, ResourceData> entry : newInternalMap.entrySet()) { String resourcePath = entry.getKey(); ResourceData newData = entry.getValue(); ResourceData oldData = internalMap.get(resourcePath); if (shouldUseNewResource(logger, oldData, newData)) { didChange = true; } else { if (oldData.resource != newData.resource) { newInternalMap.put(resourcePath, oldData); } } } if (!didChange) { // Nothing to do, keep the same identities. PerfLogger.end(); return; } internalMap = newInternalMap; Map<String, Resource> externalMap = new HashMap<String, Resource>(); Set<Resource> externalSet = new HashSet<Resource>(); for (Entry<String, ResourceData> entry : internalMap.entrySet()) { String path = entry.getKey(); ResourceData data = entry.getValue(); externalMap.put(path, data.resource); externalSet.add(data.resource); } // Update exposed collections with new (unmodifiable) data structures. exposedResources = Collections.unmodifiableSet(externalSet); exposedResourceMap = Collections.unmodifiableMap(externalMap); exposedPathNames = Collections.unmodifiableSet(externalMap.keySet()); PerfLogger.end(); }
/** * Adds the contents of this class path element to the given class path. * * @param classPath the class path to be extended. * @param output specifies whether this is an output entry or not. */ public void appendClassPathEntriesTo(ClassPath classPath, boolean output) { File baseDir = getProject().getBaseDir(); String[] fileNames; if (isReference()) { // Get the referenced path or file set. Object referencedObject = getCheckedRef(DataType.class, DataType.class.getName()); if (referencedObject instanceof Path) { Path path = (Path) referencedObject; // Get the names of the files in the referenced path. fileNames = path.list(); } else if (referencedObject instanceof AbstractFileSet) { AbstractFileSet fileSet = (AbstractFileSet) referencedObject; // Get the names of the existing input files in the referenced file set. DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); baseDir = scanner.getBasedir(); fileNames = scanner.getIncludedFiles(); } else { throw new BuildException( "The refid attribute doesn't point to a <path> element or a <fileset> element"); } } else { // Get the names of the files in this path. fileNames = list(); } if (output) { if (fileNames.length != 1) { throw new BuildException( "The <outjar> element must specify exactly one file or directory [" + fileNames.length + "]"); } } // else // { // if (fileNames.length < 1) // { // throw new BuildException("The <injar> element must specify at least one file or // directory"); // } // } for (int index = 0; index < fileNames.length; index++) { // Create a new class path entry, with the proper file name and // any filters. String fileName = fileNames[index]; File file = new File(fileName); ClassPathEntry entry = new ClassPathEntry(file.isAbsolute() ? file : new File(baseDir, fileName), output); entry.setFilter(ListUtil.commaSeparatedList(filter)); entry.setApkFilter(ListUtil.commaSeparatedList(apkFilter)); entry.setJarFilter(ListUtil.commaSeparatedList(jarFilter)); entry.setAarFilter(ListUtil.commaSeparatedList(aarFilter)); entry.setWarFilter(ListUtil.commaSeparatedList(warFilter)); entry.setEarFilter(ListUtil.commaSeparatedList(earFilter)); entry.setZipFilter(ListUtil.commaSeparatedList(zipFilter)); // Add it to the class path. classPath.add(entry); } }
/** * Creates a DataEntryReader that can read the given class path entry. * * @param messagePrefix a prefix for messages that are printed out. * @param classPathEntry the input class path entry. * @param reader a data entry reader to which the reading of actual classes and resource files can * be delegated. * @return a DataEntryReader for reading the given class path entry. */ public static DataEntryReader createDataEntryReader( String messagePrefix, ClassPathEntry classPathEntry, DataEntryReader reader) { boolean isApk = classPathEntry.isApk(); boolean isJar = classPathEntry.isJar(); boolean isAar = classPathEntry.isAar(); boolean isWar = classPathEntry.isWar(); boolean isEar = classPathEntry.isEar(); boolean isZip = classPathEntry.isZip(); List filter = classPathEntry.getFilter(); List apkFilter = classPathEntry.getApkFilter(); List jarFilter = classPathEntry.getJarFilter(); List aarFilter = classPathEntry.getAarFilter(); List warFilter = classPathEntry.getWarFilter(); List earFilter = classPathEntry.getEarFilter(); List zipFilter = classPathEntry.getZipFilter(); System.out.println( messagePrefix + (isApk ? "apk" : isJar ? "jar" : isAar ? "aar" : isWar ? "war" : isEar ? "ear" : isZip ? "zip" : "directory") + " [" + classPathEntry.getName() + "]" + (filter != null || apkFilter != null || jarFilter != null || aarFilter != null || warFilter != null || earFilter != null || zipFilter != null ? " (filtered)" : "")); // Add a filter, if specified. if (filter != null) { reader = new FilteredDataEntryReader( new DataEntryNameFilter(new ListParser(new FileNameParser()).parse(filter)), reader); } // Unzip any apks, if necessary. reader = wrapInJarReader(reader, isApk, apkFilter, ".apk"); if (!isApk) { // Unzip any jars, if necessary. reader = wrapInJarReader(reader, isJar, jarFilter, ".jar"); if (!isJar) { // Unzip any aars, if necessary. reader = wrapInJarReader(reader, isAar, aarFilter, ".aar"); if (!isAar) { // Unzip any wars, if necessary. reader = wrapInJarReader(reader, isWar, warFilter, ".war"); if (!isWar) { // Unzip any ears, if necessary. reader = wrapInJarReader(reader, isEar, earFilter, ".ear"); if (!isEar) { // Unzip any zips, if necessary. reader = wrapInJarReader(reader, isZip, zipFilter, ".zip"); } } } } } return reader; }