|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation,
- * 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
- package org.aspectj.internal.tools.build;
-
- import java.io.File;
- import java.io.FileFilter;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.PrintWriter;
- import java.io.Reader;
- import java.io.StringWriter;
- import java.io.Writer;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.StringTokenizer;
- import java.util.jar.Attributes;
- import java.util.jar.Attributes.Name;
- import java.util.jar.Manifest;
-
- /**
- * Build-only utilities.
- * Many mirror utils module APIs.
- */
- public class Util {
- public static class Constants {
- public static final String TESTSRC = "testsrc";
- public static final String JAVA5_SRC = "java5-src";
- public static final String JAVA5_TESTSRC = "java5-testsrc";
- }
- // XXX quick hack for Java 5 support
- public static final boolean JAVA5_VM;
- static {
- boolean java5VM = false;
- try {
- java5VM = (null != Class.forName("java.lang.annotation.Annotation"));
- } catch (Throwable t) {
- // ignore
- }
- JAVA5_VM = java5VM;
- }
-
- /**
- * Map version in long form to short,
- * e.g., replacing "alpha" with "a"
- */
- public static String shortVersion(String version) {
- version = Util.replace(version, "alpha", "a");
- version = Util.replace(version, "beta", "b");
- version = Util.replace(version, "candidate", "rc");
- version = Util.replace(version, "development", "d");
- version = Util.replace(version, "dev", "d");
- return version;
- }
-
- /**
- * Replace any instances of {replace} in {input} with {with}.
- * @param input the String to search/replace
- * @param replace the String to search for in input
- * @param with the String to replace with in input
- * @return input if it has no replace, otherwise a new String
- */
- public static String replace(String input, String replace, String with) {
- int loc = input.indexOf(replace);
- if (-1 != loc) {
- String result = input.substring(0, loc);
- result += with;
- int start = loc + replace.length();
- if (start < input.length()) {
- result += input.substring(start);
- }
- input = result;
- }
- return input;
- }
-
- /** @return false if filter returned false for any file in baseDir subtree */
- public static boolean visitFiles(File baseDir, FileFilter filter) {
- Util.iaxIfNotCanReadDir(baseDir, "baseDir");
- Util.iaxIfNull(filter, "filter");
- File[] files = baseDir.listFiles();
- boolean passed = true;
- for (int i = 0; passed && (i < files.length); i++) {
- passed = files[i].isDirectory()
- ? visitFiles(files[i], filter)
- : filter.accept(files[i]);
- }
- return passed;
- }
-
- /** @throws IllegalArgumentException if cannot read dir */
- public static void iaxIfNotCanReadDir(File dir, String name) {
- if (!canReadDir(dir)) {
- throw new IllegalArgumentException(name + " dir not readable: " + dir);
- }
- }
-
- /** @throws IllegalArgumentException if cannot read file */
- public static void iaxIfNotCanReadFile(File file, String name) {
- if (!canReadFile(file)) {
- throw new IllegalArgumentException(name + " file not readable: " + file);
- }
- }
-
- /** @throws IllegalArgumentException if cannot write dir */
- public static void iaxIfNotCanWriteDir(File dir, String name) {
- if (!canWriteDir(dir)) {
- throw new IllegalArgumentException(name + " dir not writeable: " + dir);
- }
- }
-
- /** @throws IllegalArgumentException if input is null */
- public static void iaxIfNull(Object input, String name) {
- if (null == input) {
- throw new IllegalArgumentException("null " + name);
- }
- }
-
- /** render exception to String */
- public static String renderException(Throwable thrown) {
- if (null == thrown) {
- return "(Throwable) null";
- }
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw, true);
- pw.println(thrown.getMessage());
- thrown.printStackTrace(pw);
- pw.flush();
- return sw.getBuffer().toString();
- }
-
- /** @return true if dir is a writable directory */
- public static boolean canWriteDir(File dir) {
- return (null != dir) && dir.canWrite() && dir.isDirectory();
- }
-
- public static String path(String first, String second) {
- return first + File.separator + second;
- }
-
- public static String path(String[] segments) {
- StringBuilder sb = new StringBuilder();
- if ((null != segments)) {
- for (int i = 0; i < segments.length; i++) {
- if (0 < i) {
- sb.append(File.separator);
- }
- sb.append(segments[i]);
- }
- }
- return sb.toString();
- }
-
- /** @return true if dir is a readable directory */
- public static boolean canReadDir(File dir) {
- return (null != dir) && dir.canRead() && dir.isDirectory();
- }
-
- /** @return true if dir is a readable file */
- public static boolean canReadFile(File file) {
- return (null != file) && file.canRead() && file.isFile();
- }
-
- /**
- * Delete file or directory.
- * @param dir the File file or directory to delete.
- * @return true if all contents of dir were deleted
- */
- public static boolean delete(File dir) {
- return deleteContents(dir) && dir.delete();
- }
-
- /**
- * Delete contents of directory.
- * The directory itself is not deleted.
- * @param dir the File directory whose contents should be deleted.
- * @return true if all contents of dir were deleted
- */
- public static boolean deleteContents(File dir) {
- if ((null == dir) || !dir.canWrite()) {
- return false;
- } else if (dir.isDirectory()) {
- File[] files = dir.listFiles();
- for (File file : files) {
- if (!deleteContents(file) || !file.delete()) {
- return false;
- }
- }
- }
- return true;
- }
-
- /** @return File temporary directory with the given prefix */
- public static File makeTempDir(String prefix) {
- if (null == prefix) {
- prefix = "tempDir";
- }
- File tempFile = null;
- for (int i = 0; i < 10; i++) {
- try {
- tempFile = File.createTempFile(prefix,"tmp");
- tempFile.delete();
- if (tempFile.mkdirs()) {
- break;
- }
- tempFile = null;
- } catch (IOException e) {
- }
- }
- return tempFile;
- }
- /**
- * Close stream with the usual checks.
- * @param stream the InputStream to close - ignored if null
- * @return null if closed without IOException, message otherwise
- */
- public static String close(Writer stream) {
- String result = null;
- if (null != stream) {
- try {
- stream.close();
- } catch(IOException e) {
- result = e.getMessage();
- }
- }
- return result;
- }
-
- /**
- * @param list the Object[] to test
- * @return true if list is null or empty
- */
- public static boolean isEmpty(Object[] list) {
- return ((null == list) || (0 == list.length));
- }
-
- public static void closeSilently(InputStream in) {
- if (null != in) {
- try {
- in.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
-
- public static void closeSilently(Reader in) {
- if (null != in) {
- try {
- in.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
-
- /**
- * Report whether actual has different members than expected
- * @param expected the String[] of expected members (none null)
- * @param actual the String[] of actual members
- * @param sb StringBuffer sink for any differences in membership
- * @return true if any diffs found and sink updated
- */
- public static final boolean reportMemberDiffs(String[] expected, String[] actual, StringBuffer sb) {
- expected = copy(expected);
- actual = copy(actual);
- int hits = 0;
- for (int i = 0; i < expected.length; i++) {
- int curHit = hits;
- for (int j = 0; (curHit == hits) && (j < actual.length); j++) {
- if (null == expected[i]) {
- throw new IllegalArgumentException("null at " + i);
- }
- if (expected[i].equals(actual[j])) {
- expected[i] = null;
- actual[j] = null;
- hits++;
- }
- }
- }
- if ((hits != expected.length) || (hits != actual.length)) {
- sb.append("unexpected [");
- String prefix = "";
- for (String value : actual) {
- if (null != value) {
- sb.append(prefix);
- prefix = ", ";
- sb.append("\"");
- sb.append(value);
- sb.append("\"");
- }
- }
- sb.append("] missing [");
- prefix = "";
- for (String s : expected) {
- if (null != s) {
- sb.append(prefix);
- prefix = ", ";
- sb.append("\"");
- sb.append(s);
- sb.append("\"");
- }
- }
- sb.append("]");
- return true;
- }
- return false;
- }
-
- private static final String[] copy(String[] ra) {
- if (null == ra) {
- return new String[0];
- }
- String[] result = new String[ra.length];
- System.arraycopy(ra, 0, result, 0, ra.length);
- return result;
- }
-
- /**
- * Support for OSGI bundles read from manifest files.
- * Currently very limited, and will only support the subset of
- * features that we use.
- * sources:
- * http://www-128.ibm.com/developerworks/library/os-ecl-osgi/index.html
- * http://help.eclipse.org/help30/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/Constants.html
- */
- public static class OSGIBundle {
- public static final Name BUNDLE_NAME = new Name("Bundle-Name");
-
- public static final Name BUNDLE_SYMBOLIC_NAME = new Name(
- "Bundle-SymbolicName");
-
- public static final Name BUNDLE_VERSION = new Name("Bundle-Version");
-
- public static final Name BUNDLE_ACTIVATOR = new Name("Bundle-Activator");
-
- public static final Name BUNDLE_VENDOR = new Name("Bundle-Vendor");
-
- public static final Name REQUIRE_BUNDLE = new Name("Require-Bundle");
-
- public static final Name IMPORT_PACKAGE = new Name("Import-Package");
-
- public static final Name BUNDLE_CLASSPATH = new Name("Bundle-ClassPath");
-
- /** unmodifiable list of all valid OSGIBundle Name's */
- public static final List<Name> NAMES;
- static {
- List<Name> names = new ArrayList<>();
- names.add(BUNDLE_NAME);
- names.add(BUNDLE_SYMBOLIC_NAME);
- names.add(BUNDLE_VERSION);
- names.add(BUNDLE_ACTIVATOR);
- names.add(BUNDLE_VENDOR);
- names.add(REQUIRE_BUNDLE);
- names.add(IMPORT_PACKAGE);
- names.add(BUNDLE_CLASSPATH);
- NAMES = Collections.unmodifiableList(names);
- }
-
- private final Manifest manifest;
-
- private final Attributes attributes;
-
- /**
- *
- * @param manifestInputStream
- * the InputStream of the manifest.mf - will be closed.
- * @throws IOException
- * if unable to read or close the manifest input stream.
- */
- public OSGIBundle(InputStream manifestInputStream) throws IOException {
- manifest = new Manifest();
- manifest.read(manifestInputStream);
- manifestInputStream.close();
- attributes = manifest.getMainAttributes();
- }
-
- public String getAttribute(Name attributeName) {
- return attributes.getValue(attributeName);
- }
-
- public String[] getClasspath() {
- String cp = getAttribute(OSGIBundle.BUNDLE_CLASSPATH);
- if (null == cp) {
- return new String[0];
- }
- StringTokenizer st = new StringTokenizer(cp, " ,");
- String[] result = new String[st.countTokens()];
- int i = 0;
- while (st.hasMoreTokens()) {
- result[i++] = st.nextToken();
- }
- return result;
- }
-
- /**
- * XXX ugly/weak hack only handles a single version comma
- * {name};bundle-version="[1.5.0,1.5.5]";resolution:=optional
- * @return
- */
- public RequiredBundle[] getRequiredBundles() {
- String value = getAttribute(OSGIBundle.REQUIRE_BUNDLE);
- if (null == value) {
- return new RequiredBundle[0];
- }
- StringTokenizer st = new StringTokenizer(value, " ,");
- RequiredBundle[] result = new RequiredBundle[st.countTokens()];
- int i = 0;
- int skips = 0;
- while (st.hasMoreTokens()) {
- String token = st.nextToken();
- int first = token.indexOf("\"");
- if (-1 != first) {
- if (!st.hasMoreTokens()) {
- throw new IllegalArgumentException(token);
- }
- // just assume only one quoted "," for version?
- token += "," + st.nextToken();
- skips++;
- }
- result[i++] = new RequiredBundle(token);
- }
- if (skips > 0) {
- RequiredBundle[] patch = new RequiredBundle[result.length-skips];
- System.arraycopy(result, 0, patch, 0, patch.length);
- result = patch;
- }
- return result;
- }
-
- /**
- * Wrap each dependency on another bundle
- */
- public static class RequiredBundle {
-
- /** unparsed entry text, for debugging */
- final String text;
-
- /** Symbolic name of the required bundle */
- final String name;
-
- /** if not null, then start/end versions of required bundle
- * in the format of the corresponding manifest entry
- */
- final String versions;
-
- /** if true, then required bundle is optional */
- final boolean optional;
-
- private RequiredBundle(String entry) {
- text = entry;
- StringTokenizer st = new StringTokenizer(entry, ";");
- name = st.nextToken();
- String vers = null;
- String opt = null;
- // bundle-version="[1.5.0,1.5.5]";resolution:=optiona
- final String RESOLUTION = "resolution:=";
- final String VERSION = "bundle-version=\"";
- while (st.hasMoreTokens()) {
- String token = st.nextToken();
- if (token.startsWith(VERSION)) {
- int start = VERSION.length();
- int end = token.lastIndexOf("\"");
- vers = token.substring(start, end);
- // e.g., [1.5.0,1.5.5)
- } else if (token.startsWith(RESOLUTION)) {
- int start = RESOLUTION.length();
- int end = token.length();
- opt = token.substring(start, end);
- }
- }
- versions = vers;
- optional = "optional".equals(opt);
- }
- }
- }
- }
-
|