+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-//XXX INCLUDES CODE FROM ANT -- UNDER APACHE LICENSE
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringBufferInputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.zip.CRC32;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.Copy;
-import org.apache.tools.ant.taskdefs.Delete;
-import org.apache.tools.ant.taskdefs.Expand;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.PatternSet;
-
-public class AJInstaller extends MatchingTask {
- static final String INCLUDE_CLASSES = "$installer$/org/aspectj/*.class";
- static final String MAIN_CLASS = "$installer$.org.aspectj.Main";
- static final String CONTENTS_FILE = "$installer$/org/aspectj/resources/contents.txt";
- private String htmlSrc;
-
- public void setHtmlSrc(String v) { htmlSrc = v; }
-
- private String resourcesSrc;
-
- public void setResourcesSrc(String v) { resourcesSrc = v; }
-
- private String mainclass;
-
- public void setMainclass(String v) { mainclass = v; }
-
- private File installerClassJar;
-
- public void setInstallerclassjar(String v) {
- installerClassJar = project.resolveFile(v);
- }
-
- protected List contentsNames = new ArrayList();
-
- protected long contentsBytes = 0;
-
- protected void addToContents(File file, String vPath) {
- contentsNames.add(vPath);
- contentsBytes += file.length();
- }
-
- String[] getFiles(File baseDir) {
- DirectoryScanner ds = new DirectoryScanner();
- setBasedir(baseDir.getAbsolutePath());
- ds.setBasedir(baseDir);
- //ds.setIncludes(new String [] {pattern});
- ds.scan();
- return ds.getIncludedFiles();
- }
-
- protected Copy getCopyTask() {
- Copy cd = (Copy)project.createTask("copy");
- if (null == cd) {
- log("project.createTask(\"copy\") failed - direct", Project.MSG_VERBOSE);
- cd = new Copy();
- cd.setProject(getProject());
- }
- return cd;
- }
- protected void finishZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException {
- writeContents(zOut);
- writeManifest(zOut);
- File tempDir = setupTempDir();
- String tmp = tempDir.getAbsolutePath();
-
- // installer class files
- Expand expand = new Expand();
- expand.setProject(getProject());
- expand.setSrc(installerClassJar);
- expand.setDest(new File(tmp));
- PatternSet patterns = new PatternSet();
- patterns.setIncludes(INCLUDE_CLASSES);
- expand.addPatternset(patterns);
- expand.execute();
-
- // move the correct resource files into the jar
- Copy cd = getCopyTask();
- fileset = new FileSet();
- fileset.setDir(new File(resourcesSrc));
- fileset.setIncludes("*");
- fileset.setExcludes("contents.txt,properties.txt");
- cd.addFileset(fileset);
- cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
- cd.execute();
- project.getGlobalFilterSet().addFilter("installer.main.class", this.mainclass);
- Copy cf = getCopyTask();
- fileset = new FileSet();
- fileset.setDir(new File(resourcesSrc));
- fileset.setIncludes("properties.txt");
- cf.setFiltering(true);
- cf.addFileset(fileset);
- cf.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
- cf.execute();
- // move the correct resource files into the jar
- cd = getCopyTask();
- fileset = new FileSet();
- fileset.setDir(new File(htmlSrc));
- fileset.setIncludes("*");
- cd.addFileset(fileset);
- cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
- cd.execute();
- // now move these files into the jar
- setBasedir(tmp);
- writeFiles(zOut, getFiles(tempDir));
- // and delete the tmp dir
- Delete dt = (Delete)project.createTask("delete");
- if (null == dt) {
- dt = new Delete();
- dt.setProject(getProject());
- }
- dt.setDir(tempDir);
- dt.execute();
- tempDir = null;
- }
-
- static final char NEWLINE = '\n';
-
- protected void writeContents(ZipOutputStream zOut) throws IOException {
- // write to a StringBuffer
- StringBuffer buf = new StringBuffer();
- buf.append(contentsBytes);
- buf.append(NEWLINE);
- for (Iterator i = contentsNames.iterator(); i.hasNext(); ) {
- String name = (String)i.next();
- buf.append(name);
- buf.append(NEWLINE);
- }
- zipFile(new StringBufferInputStream(buf.toString()), zOut, CONTENTS_FILE, System.currentTimeMillis());
- }
-
- protected void writeManifest(ZipOutputStream zOut) throws IOException {
- // write to a StringBuffer
- StringBuffer buf = new StringBuffer();
- buf.append("Manifest-Version: 1.0");
- buf.append(NEWLINE);
- buf.append("Main-Class: " + MAIN_CLASS);
- buf.append(NEWLINE);
- zipFile(new StringBufferInputStream(buf.toString()), zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis());
- }
-
- //XXX cut-and-paste from Zip super-class (under apache license)
- private File zipFile;
- private File baseDir;
- private boolean doCompress = true;
- protected String archiveType = "zip";
-
- /**
- * This is the name/location of where to
- * create the .zip file.
- */
- public void setZipfile(String zipFilename) {
- zipFile = project.resolveFile(zipFilename);
- }
-
- /**
- * This is the base directory to look in for
- * things to zip.
- */
- public void setBasedir(String baseDirname) {
- baseDir = project.resolveFile(baseDirname);
- }
-
- /**
- * Sets whether we want to compress the files or only store them.
- */
- public void setCompress(String compress) {
- doCompress = Project.toBoolean(compress);
- }
-
- protected void initZipOutputStream(ZipOutputStream zOut)
- throws IOException, BuildException
- {
- }
-
- protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
- throws IOException
- {
- }
-
- protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
- long lastModified)
- throws IOException
- {
- ZipEntry ze = new ZipEntry(vPath);
- ze.setTime(lastModified);
-
- /*
- * XXX ZipOutputStream.putEntry expects the ZipEntry to know its
- * size and the CRC sum before you start writing the data when using
- * STORED mode.
- *
- * This forces us to process the data twice.
- *
- * I couldn't find any documentation on this, just found out by try
- * and error.
- */
- if (!doCompress) {
- long size = 0;
- CRC32 cal = new CRC32();
- if (!in.markSupported()) {
- // Store data into a byte[]
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] buffer = new byte[8 * 1024];
- int count = 0;
- do {
- size += count;
- cal.update(buffer, 0, count);
- bos.write(buffer, 0, count);
- count = in.read(buffer, 0, buffer.length);
- } while (count != -1);
- in = new ByteArrayInputStream(bos.toByteArray());
- } else {
- in.mark(Integer.MAX_VALUE);
- byte[] buffer = new byte[8 * 1024];
- int count = 0;
- do {
- size += count;
- cal.update(buffer, 0, count);
- count = in.read(buffer, 0, buffer.length);
- } while (count != -1);
- in.reset();
- }
- ze.setSize(size);
- ze.setCrc(cal.getValue());
- }
- zOut.putNextEntry(ze);
- byte[] buffer = new byte[8 * 1024];
- int count = 0;
- do {
- zOut.write(buffer, 0, count);
- count = in.read(buffer, 0, buffer.length);
- } while (count != -1);
- }
-
- protected void zipFile(File file, ZipOutputStream zOut, String vPath)
- throws IOException
- {
- if ( !vPath.startsWith("$installer$") ) {
- addToContents(file, vPath);
- }
- FileInputStream fIn = new FileInputStream(file);
- try {
- zipFile(fIn, zOut, vPath, file.lastModified());
- } finally {
- fIn.close();
- }
- }
- private File setupTempDir() throws BuildException {
- File tmpDirF = null;
- File tmpDir = null;
- try {
- tmpDirF = File.createTempFile("tgz", ".di");
- tmpDir = new File(tmpDirF.getParentFile(), "AJInstaller");
- tmpDirF.delete();
- } catch (IOException e) {
- // retrying below
- }
- if (null == tmpDir || !tmpDir.mkdirs()) {
- tmpDir = new File("AJInstaller.finishZipOutputStream.tmp");
- if (!tmpDir.mkdirs()) {
- throw new BuildException("unable to make temp dir");
- }
- }
- return tmpDir;
- }
-
- public void execute() throws BuildException {
- if (installerClassJar == null) {
- throw new BuildException("installerClassJar attribute must be set!");
- }
- if (!installerClassJar.canRead()
- || !installerClassJar.getPath().endsWith(".jar")) {
- throw new BuildException("not readable jar:" + installerClassJar);
- }
-// if (installerClassDir == null) {
-// throw new BuildException("installerClassDir attribute must be set!");
-// }
-// if (!installerClassDir.exists()) {
-// throw new BuildException("no such directory: installerClassDir=" + installerClassDir);
-// }
- if (baseDir == null) {
- throw new BuildException("basedir attribute must be set!");
- }
- if (!baseDir.exists()) {
- throw new BuildException("basedir does not exist!");
- }
- DirectoryScanner ds = super.getDirectoryScanner(baseDir);
- String[] files = ds.getIncludedFiles();
- String[] dirs = ds.getIncludedDirectories();
- log("Building installer: "+ zipFile.getAbsolutePath());
- ZipOutputStream zOut = null;
- try {
- zOut = new ZipOutputStream(new FileOutputStream(zipFile));
- if (doCompress) {
- zOut.setMethod(ZipOutputStream.DEFLATED);
- } else {
- zOut.setMethod(ZipOutputStream.STORED);
- }
- initZipOutputStream(zOut);
- writeDirs(zOut, dirs);
- writeFiles(zOut, files);
- finishZipOutputStream(zOut); // deletes temp dir
- } catch (IOException ioe) {
- String msg = "Problem creating " + archiveType + " " + ioe.getMessage();
- throw new BuildException(msg, ioe, location);
- } finally {
- if (zOut != null) {
- try {
- // close up
- zOut.close();
- }
- catch (IOException e) {}
- }
- }
- }
-
- protected void writeDirs(ZipOutputStream zOut, String[] dirs) throws IOException {
- for (int i = 0; i < dirs.length; i++) {
- File f = new File(baseDir,dirs[i]);
- String name = dirs[i].replace(File.separatorChar,'/')+"/";
- zipDir(f, zOut, name);
- }
- }
-
- protected void writeFiles(ZipOutputStream zOut, String[] files) throws IOException {
- for (int i = 0; i < files.length; i++) {
- File f = new File(baseDir,files[i]);
- String name = files[i].replace(File.separatorChar,'/');
- zipFile(f, zOut, name);
- }
- }
-
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.DecimalFormat;
-import java.util.Properties;
-
-import org.apache.tools.ant.taskdefs.Mkdir;
-
-public class AJPush extends ConditionalTask {
- private File src;
-
- public void setSrc(String v) { src = project.resolveFile(v); }
-
- private String key;
-
- public void setKey(String v) { key = v; }
-
- File releaseDir = null;
- File downloadDir = null;
- boolean waiting = false;
-
- public void execute() throws org.apache.tools.ant.BuildException {
- //File releaseDir = src.getParentFile();
- // todo: dependency on ant script variable name aj.release.dir
- releaseDir = project.resolveFile(project.getProperty("aj.release.dir"));
- // todo: dependency on ant script variable name download.dir
- downloadDir = project.resolveFile(project.getProperty("download.dir"));
- // For testing make sure these directories are made
- Mkdir mkdir = (Mkdir) project.createTask("mkdir");
- mkdir.setDir(releaseDir);
- mkdir.execute();
- mkdir = (Mkdir) project.createTask("mkdir");
- mkdir.setDir(downloadDir);
- mkdir.execute();
- log("Pushing from " + releaseDir + " to " + downloadDir);
- // add info to release.txt
- try {
- File releaseFile = new File(releaseDir, "release.txt");
- File downloadFile = new File(downloadDir, "release.txt");
- if (!releaseFile.canRead()) {
- releaseFile.createNewFile();
- }
- addReleaseInfo(src, releaseFile);
- // copy to staging web server
- project.copyFile(src, new File(downloadDir, src.getName()));
- project.copyFile(releaseFile, downloadFile);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
-
- void addReleaseInfo(File file, File propFile) throws IOException {
- Properties props = new Properties();
- if (propFile.canRead()) {
- props.load(new FileInputStream(propFile));
- }
- file.createNewFile(); // create new only if necessary
- long bytes = file.length();
- DecimalFormat df = new DecimalFormat();
- df.setGroupingSize(3);
- String bytesString = df.format(bytes);
- props.put("release." + key + ".size.bytes", bytesString);
- props.put("release." + key + ".date", project.getProperty("build.date"));
- props.put("release." + key + ".filename", file.getName());
- props.put("release.date", project.getProperty("build.date"));
- props.put("release.version", project.getProperty("build.version.short"));
- props.put("release.versionName", project.getProperty("build.version.long"));
- String userName = System.getProperty("user.name");
- if (userName != null) {
- props.put("release." + key + ".username", userName);
- }
- props.store(new FileOutputStream(propFile), null);
- }
-
-}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.taskdefs.Copy;
-import org.apache.tools.ant.taskdefs.Javac;
-import org.apache.tools.ant.taskdefs.Zip;
-import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.ZipFileSet;
-import org.aspectj.internal.tools.build.BuildSpec;
-import org.aspectj.internal.tools.build.Builder;
-import org.aspectj.internal.tools.build.Messager;
-import org.aspectj.internal.tools.build.Module;
-import org.aspectj.internal.tools.build.Result;
-import org.aspectj.internal.tools.build.Util;
-
-/**
- * Implement Builder in Ant.
- */
-public class AntBuilder extends Builder {
- private static final boolean FORCE_FORK_FOR_LIBRARIES = false;
-
- /**
- * Factory for a Builder.
- *
- * @param config the String configuration, where only substrings "verbose" and "useEclipseCompiles" are significant
- * @param project the owning Project for all tasks (not null)
- * @param tempDir the File path to a temporary dir for side effects (may be null)
- * @return a Builder for this project and configuration
- */
- public static Builder getBuilder(String config, Project project, File tempDir) {
- boolean useEclipseCompiles = false;
- boolean verbose = false;
- if (null != config) {
- if (-1 != config.indexOf("useEclipseCompiles")) {
- useEclipseCompiles = true;
- }
- if (-1 != config.indexOf("verbose")) {
- verbose = true;
- }
- }
- // Messager handler = new Messager(); // debugging
- Messager handler = new ProjectMessager(project);
- Builder result = new ProductBuilder(project, tempDir, useEclipseCompiles, handler);
- if (verbose) {
- result.setVerbose(true);
- }
- return result;
- }
-
- private static String resultToTargetName(Result result) {
- return result.getName();
- }
-
- /**
- * Ensure targets exist for this module and all antecedants, so topoSort can work.
- */
- private static void makeTargetsForResult(final Result result, final Hashtable<String,Target> targets) {
- final String resultTargetName = resultToTargetName(result);
- Target target = targets.get(resultTargetName);
- if (null == target) {
- // first add the target
- target = new Target();
- target.setName(resultTargetName);
-
- Result[] reqs = result.getRequired();
- StringBuffer depends = new StringBuffer();
- boolean first = true;
- for (int i = 0; i < reqs.length; i++) {
- Result reqResult = reqs[i];
- if (!first) {
- depends.append(",");
- } else {
- first = false;
- }
- depends.append(resultToTargetName(reqResult));
- }
- if (0 < depends.length()) {
- target.setDepends(depends.toString());
- }
- targets.put(resultTargetName, target);
-
- // then recursively add any required results
- for (int i = 0; i < reqs.length; i++) {
- Result reqResult = reqs[i];
- makeTargetsForResult(reqResult, targets);
- }
- }
- }
-
- private final Project project;
-
- protected AntBuilder(Project project, File tempDir, boolean useEclipseCompiles, Messager handler) {
- super(tempDir, useEclipseCompiles, handler);
- this.project = project;
- Util.iaxIfNull(project, "project");
- }
-
- /**
- * Initialize task with project and "ajbuild-" + name as name. (Using bm- prefix distinguishes these tasks from tasks found in
- * the build script.)
- *
- * @param task the Task to initialize - not null
- * @param name the String name suffix for the task
- * @return true unless some error
- */
- protected boolean setupTask(Task task, String name) {
- task.setProject(project);
- task.setTaskName("ajbuild-" + name);
- return true;
- }
-
- /**
- * Copy file, optionally filtering. (Filters set in project.)
- *
- * @param fromFile the readable File source to copy
- * @param toFile the writable File destination file
- * @param boolean filter if true, enable filtering
- * @see org.aspectj.internal.tools.build.Builder#copyFile(File, File, boolean)
- */
- @Override
- protected boolean copyFile(File fromFile, File toFile, boolean filter) {
- Copy copy = makeCopyTask(filter);
- copy.setFile(fromFile);
- copy.setTofile(toFile);
- executeTask(copy);
- return true;
- }
-
- /**
- * (Filters set in project.)
- *
- * @see org.aspectj.internal.tools.ant.taskdefs.Builder#copyFiles(File, File, String, String, boolean)
- */
- @Override
- protected boolean copyFiles(File fromDir, File toDir, String includes, String excludes, boolean filter) {
- Copy copy = makeCopyTask(filter);
- copy.setTodir(toDir);
- FileSet fileset = new FileSet();
- fileset.setDir(fromDir);
- if (null != includes) {
- fileset.setIncludes(includes);
- }
- if (null != excludes) {
- fileset.setExcludes(excludes);
- }
- copy.addFileset(fileset);
- executeTask(copy);
-
- return false;
- }
-
- protected void copyFileset(File toDir, FileSet fileSet, boolean filter) {
- Copy copy = makeCopyTask(filter);
- copy.addFileset(fileSet);
- copy.setTodir(toDir);
- executeTask(copy);
- }
-
- /**
- * @param filter if FILTER_ON, use filters
- */
- protected Copy makeCopyTask(boolean filter) {
- Copy copy = new Copy();
- setupTask(copy, "copy");
- if (FILTER_ON == filter) {
- copy.setFiltering(true);
- }
- return copy;
- }
-
- protected void dumpMinFile(Result result, File classesDir, List<String> errors) {
- String name = result.getName() + "-empty";
- File minFile = new File(classesDir, name);
- FileWriter fw = null;
- try {
- fw = new FileWriter(minFile);
- fw.write(name);
- } catch (IOException e) {
- errors.add("IOException writing " + name + " to " + minFile + ": " + Util.renderException(e));
- } finally {
- Util.close(fw);
- }
-
- }
-
- @Override
- protected boolean compile(Result result, File classesDir, boolean useExistingClasses, List<String> errors) {
- if (!classesDir.exists() && !classesDir.mkdirs()) {
- errors.add("compile - unable to create " + classesDir);
- return false;
- }
- if (useExistingClasses) {
- return true;
- }
- // -- source paths
- Path path = new Path(project);
- boolean hasSourceDirectories = false;
- boolean isJava5Compile = false;
- boolean isJava8Compile = false;
- for (File file: result.getSrcDirs()) {
- path.createPathElement().setLocation(file);
- if (!isJava5Compile
- && (Util.Constants.JAVA5_SRC.equals(file.getName()) ||
- Util.Constants.JAVA5_TESTSRC.equals(file.getName()) ||
- new File(file.getParent(), ".isJava5").exists())) {
- isJava5Compile = true;
- }
- if (new File(file.getParent(),".isJava8").exists()) {
- isJava8Compile = true;
- }
- if (!hasSourceDirectories) {
- hasSourceDirectories = true;
- }
- }
- if (!hasSourceDirectories) {
- return true; // nothing to compile - ok
- }
- // XXX test whether build.compiler property takes effect automatically
- // I suspect it requires the proper adapter setup.
- Javac javac = new Javac();
- setupTask(javac, "javac");
- javac.setIncludeantruntime(false);
- javac.setDestdir(classesDir);
- javac.setSrcdir(path);
- javac.setVerbose(verbose);
- path = null;
-
- // -- classpath
- Path classpath = new Path(project);
- boolean hasLibraries = setupClasspath(result, classpath);
- if (hasLibraries && FORCE_FORK_FOR_LIBRARIES) {
- javac.setFork(true); // otherwise never releases library jars
- // can we build under 1.4, but fork javac 1.5 compile?
- }
- // also fork if using 1.5?
-
- // -- set output directory
- classpath.createPathElement().setLocation(classesDir);
- javac.setClasspath(classpath);
-
- // misc
- javac.setDebug(true);
- if (isJava8Compile) {
- javac.setSource("1.8");
- javac.setTarget("1.8");
- } else if (isJava5Compile) {
- // *cough*
- javac.setSource("1.6");
- javac.setTarget("1.6");
- } else {
- javac.setTarget("1.1"); // 1.1 class files - Javac in 1.4 uses 1.4
- javac.setSource("1.3");
- }
- // compile
- boolean passed = false;
- BuildException failure = null;
- try {
- passed = executeTask(AspectJSupport.wrapIfNeeded(result, javac));
- } catch (BuildException e) {
- failure = e;
- } catch (Error e) {
- failure = new BuildException(e);
- } catch (RuntimeException e) {
- failure = new BuildException(e);
- } finally {
- if (!passed) {
- String args = "" + Arrays.asList(javac.getCurrentCompilerArgs());
- if ("[]".equals(args)) {
- args = "{" + result.toLongString() + "}";
- }
- String m = "BuildException compiling " + result.toLongString() + args
- + (null == failure ? "" : ": " + Util.renderException(failure));
- // debuglog System.err.println(m);
- errors.add(m);
- }
- javac.init(); // be nice to let go of classpath libraries...
- }
- return passed;
- }
-
- public boolean setupClasspath(Result result, Path classpath) { // XXX fix test access
- boolean hasLibraries = false;
- // required libraries
- for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
- File file = (File) iter.next();
- classpath.createPathElement().setLocation(file);
- if (!hasLibraries) {
- hasLibraries = true;
- }
- }
- // Westodo Kind kind = result.getKind();
- Result[] reqs = result.getRequired();
- // required modules and their exported libraries
- for (int i = 0; i < reqs.length; i++) {
- Result requiredResult = reqs[i];
- classpath.createPathElement().setLocation(requiredResult.getOutputFile());
- if (!hasLibraries) {
- hasLibraries = true;
- }
- // also put on classpath libraries exported from required module
- // XXX exported modules not supported
- for (Iterator iterator = requiredResult.getExportedLibJars().iterator(); iterator.hasNext();) {
- classpath.createPathElement().setLocation((File) iterator.next());
- }
- }
- return hasLibraries;
- }
-
- /**
- * Merge classes directory and any merge jars into module jar with any specified manifest file. META-INF directories are
- * excluded.
- */
- @Override
- protected boolean assemble(Result result, File classesDir, List<String> errors) {
- if (!buildingEnabled) {
- return false;
- }
- if (!result.outOfDate()) {
- return true;
- }
-
- // ---- zip result up
- Zip zip = new Zip();
- setupTask(zip, "zip");
- zip.setDestFile(result.getOutputFile());
- ZipFileSet zipfileset = null;
-
- // -- merge any resources in any of the src directories
- for (Iterator iter = result.getSrcDirs().iterator(); iter.hasNext();) {
- File srcDir = (File) iter.next();
- zipfileset = new ZipFileSet();
- zipfileset.setProject(project);
- zipfileset.setDir(srcDir);
- zipfileset.setIncludes(RESOURCE_PATTERN);
- zip.addZipfileset(zipfileset);
- }
-
- final Module module = result.getModule();
-
- File metaInfDir = new File(classesDir, "META-INF");
- Util.deleteContents(metaInfDir);
-
- // -- manifest
- File manifest = new File(module.moduleDir, module.name + ".mf.txt"); // XXXFileLiteral
- if (Util.canReadFile(manifest)) {
- if (Util.canReadDir(metaInfDir) || metaInfDir.mkdirs()) {
- // Jar spec requires a MANIFEST.MF not a manifest.mf
- copyFile(manifest, new File(metaInfDir, "MANIFEST.MF"), FILTER_ON); // XXXFileLiteral
- } else {
- errors.add("have manifest, but unable to create " + metaInfDir);
- return false;
- }
- }
-
- zipfileset = new ZipFileSet();
- zipfileset.setProject(project);
- zipfileset.setDir(classesDir);
- zipfileset.setIncludes("**/*");
- zip.addZipfileset(zipfileset);
- File[] contents = classesDir.listFiles();
- if ((null == contents) || (0 == contents.length)) {
- // *something* to zip up
- dumpMinFile(result, classesDir, errors);
- }
-
- try {
- handler.log("assemble " + module + " in " + result.getOutputFile());
- return executeTask(zip)
- // zip returns true when it doesn't create zipfile
- // because there are no entries to add, so verify done
- && Util.canReadFile(result.getOutputFile());
- } catch (BuildException e) {
- errors.add("BuildException zipping " + module + ": " + e.getMessage());
- return false;
- } finally {
- result.clearOutOfDate();
- }
- }
-
- /**
- * @see org.aspectj.internal.tools.build.Builder#buildAntecedants(Module)
- */
- @Override
- protected Result[] getAntecedantResults(Result moduleResult) {
- Hashtable<String,Target> targets = new Hashtable<String, Target>();
- makeTargetsForResult(moduleResult, targets);
- String targetName = resultToTargetName(moduleResult);
- // bug: doc says topoSort returns String, but returns Target
- Collection<Target> result = project.topoSort(targetName, targets);
- // fyi, we don't rely on topoSort to detect cycles - see buildAll
- int size = result.size();
- if (0 == result.size()) {
- return new Result[0];
- }
- ArrayList<String> toReturn = new ArrayList<String>();
- for (Iterator<Target> iter = result.iterator(); iter.hasNext();) {
- Target target = iter.next();
- String name = target.getName();
- if (null == name) {
- throw new Error("null name?");
- } else {
- toReturn.add(name);
- }
- }
- // topoSort always returns target name
- if ((1 == size) && targetName.equals(toReturn.get(0)) && !moduleResult.outOfDate()) {
- return new Result[0];
- }
- return Result.getResults(toReturn.toArray(new String[0]));
- }
-
- /**
- * Generate Module.assembledJar with merge of itself and all antecedants
- */
- @Override
- protected boolean assembleAll(Result result, Messager handler) {
- if (!buildingEnabled) {
- return false;
- }
- if (!result.outOfDate()) {
- return true;
- }
-
- Util.iaxIfNull(result, "result");
- Util.iaxIfNull(handler, "handler");
- if (!result.getKind().isAssembly()) {
- throw new IllegalStateException("not assembly: " + result);
- }
-
- // ---- zip result up
- Zip zip = new Zip();
- setupTask(zip, "zip");
- zip.setDestFile(result.getOutputFile());
- ZipFileSet zipfileset = null;
- final Module module = result.getModule();
- List<File> known = result.findJarRequirements();
- removeLibraryFilesToSkip(module, known);
- // -- merge any antecedents, less any manifest
- for (File jarFile: known) {
- zipfileset = new ZipFileSet();
- zipfileset.setProject(project);
- zipfileset.setSrc(jarFile);
- zipfileset.setIncludes("**/*");
- String name = jarFile.getName();
- name = name.substring(0, name.length() - 4); // ".jar".length()
- // required includes self - exclude manifest from others
- if (!module.name.equals(name)) {
- zipfileset.setExcludes("META-INF/MANIFEST.MF"); // XXXFileLiteral
- zipfileset.setExcludes("META-INF/manifest.mf");
- zipfileset.setExcludes("meta-inf/manifest.mf");
- zipfileset.setExcludes("meta-inf/MANIFEST.MF");
- }
- zip.addZipfileset(zipfileset);
- }
-
- try {
- handler.log("assembling all " + module + " in " + result.getOutputFile());
- if (verbose) {
- handler.log("knownAntecedants: " + known);
- }
- return executeTask(zip);
- } catch (BuildException e) {
- handler.logException("BuildException zipping " + module, e);
- return false;
- } finally {
- result.clearOutOfDate();
- }
- }
-
- /**
- * @see org.aspectj.internal.tools.ant.taskdefs.Builder#buildInstaller(BuildSpec, String)
- */
- @Override
- protected boolean buildInstaller(BuildSpec buildSpec, String targDirPath) {
- return false;
- }
-
- /** task.execute() and any advice */
- protected boolean executeTask(Task task) {
- if (!buildingEnabled) {
- return false;
- }
- task.execute();
- return true;
- }
-
- /**
- * Support for compiling basic AspectJ projects. Projects may only compile all (and only) their source directories; aspectpath,
- * inpath, etc. are not supported. To load the compiler, this assumes the user has either defined a project property
- * "aspectj.home" or that there exists <code>{module-dir}/lib/aspectj/lib/aspectj[tools|rt].jar</code>.
- */
- static class AspectJSupport {
- static final String AJCTASK = "org.aspectj.tools.ant.taskdefs.AjcTask";
- static final String ASPECTJRT_JAR_VARIABLE = "ASPECTJRT_LIB";
- static final String LIBASPECTJ_RPATH = "/lib/aspectj";
- static final Map nameToAspectjrtjar = new HashMap();
- static final String NONE = "NONE";
-
- /**
- * If this module should be compiled with AspectJ, return a task to do so.
- *
- * @param module the Module to compile
- * @param javac the Javac compile commands
- * @return javac or a Task to compile with AspectJ if needed
- */
- static Task wrapIfNeeded(Result result, Javac javac) {
- final Project project = javac.getProject();
- Path runtimeJar = null;
- final Module module = result.getModule();
- if (runtimeJarOnClasspath(result)) {
- // yes aspectjrt.jar on classpath
- } else if (result.getClasspathVariables().contains(ASPECTJRT_JAR_VARIABLE)) {
- // yes, in variables - find aspectjrt.jar to add to classpath
- runtimeJar = getAspectJLib(project, module, "aspectjrt.jar");
- } else {
- // no
- // System.out.println("javac " + result + " " + javac.getClasspath());
- return javac;
- }
- // System.out.println("aspectj " + result + " " + javac.getClasspath());
- Path aspectjtoolsJar = getAspectJLib(project, module, "aspectjtools.jar");
- return aspectJTask(javac, aspectjtoolsJar, runtimeJar);
- }
-
- /** @return true if aspectjrt.jar is on classpath */
- private static boolean runtimeJarOnClasspath(Result result) {
- for (File file: result.getLibJars()) {
- if ("aspectjrt.jar".equals(file.getName())) {
- return true;
- }
- }
- return false;
- }
-
- static Path getAspectJLib(Project project, Module module, String name) {
- Path result = null;
- String[] libDirNames = { "aspectj.home", "ASPECTJ_HOME", LIBASPECTJ_RPATH };
- String[] libDirs = new String[libDirNames.length];
- for (int i = 0; i < libDirNames.length; i++) {
- if (LIBASPECTJ_RPATH == libDirNames[i]) {
- libDirs[i] = module.getFullPath(LIBASPECTJ_RPATH);
- } else {
- libDirs[i] = project.getProperty(libDirNames[i]);
- }
- if (null != libDirs[i]) {
- libDirs[i] = Util.path(libDirs[i], "lib");
- result = new Path(project, Util.path(libDirs[i], name));
- String path = result.toString();
- if (new File(path).canRead()) {
- return result;
- }
- }
- }
- String m = "unable to find " + name + " in " + Arrays.asList(libDirs);
- throw new BuildException(m);
- }
-
- /**
- * Wrap AspectJ compiler as Task. Only works for javac-like source compilation of everything under srcDir. Written
- * reflectively to compile in the build module, which can't depend on the whole tree.
- *
- * @param javac the Javac specification
- * @param toolsJar the Path to the aspectjtools.jar
- * @param runtimeJar the Path to the aspectjrt.jar
- * @return javac or another Task invoking the AspectJ compiler
- */
- @SuppressWarnings("unchecked")
- static Task aspectJTask(Javac javac, Path toolsJar, Path runtimeJar) {
- Object task = null;
- String url = null;
- try {
- url = "file:" + toolsJar.toString().replace('\\', '/');
- URL[] cp = new URL[] { new URL(url) };
- ClassLoader parent = Task.class.getClassLoader();
- ClassLoader loader = new URLClassLoader(cp, parent);
- Class c = loader.loadClass(AJCTASK);
- task = c.newInstance();
- // Westodo Project project = javac.getProject();
- Method m = c.getMethod("setupAjc", new Class[] { Javac.class });
- m.invoke(task, new Object[] { javac });
- m = c.getMethod("setFork", new Class[] { boolean.class });
- m.invoke(task, new Object[] { Boolean.TRUE });
- m = c.getMethod("setForkclasspath", new Class[] { Path.class });
- m.invoke(task, new Object[] { toolsJar });
- m = c.getMethod("setSourceRoots", new Class[] { Path.class });
- m.invoke(task, new Object[] { javac.getSrcdir() });
- if (null != runtimeJar) {
- m = c.getMethod("setClasspath", new Class[] { Path.class });
- m.invoke(task, new Object[] { runtimeJar });
- }
- } catch (BuildException e) {
- throw e;
- } catch (Throwable t) {
- StringBuffer sb = new StringBuffer();
- sb.append("classpath=");
- sb.append(url);
- throw new BuildException(sb.toString(), t);
- }
- return (Task) task;
- }
-
- private AspectJSupport() {
- throw new Error("no instances");
- }
- }
-}
-
-// finally caught by failing to comply with proper ant initialization
-// /**
-// * Build a module that has a build script.
-// * @param buildSpec the module to build
-// * @param buildScript the script file
-// * @throws BuildException if build fails
-// */
-// private void buildByScript(BuildSpec buildSpec, File buildScript)
-// throws BuildException {
-// Ant ant = new Ant();
-// ant.setProject(getProject());
-// ant.setAntfile(buildScript.getAbsolutePath());
-// ant.setDescription("building module " + buildSpec.module);
-// ant.setDir(buildScript.getParentFile());
-// ant.setInheritAll(true);
-// ant.setInheritRefs(false);
-// ant.setLocation(getLocation());
-// ant.setOwningTarget(getOwningTarget());
-// // by convention, for build.xml, use module name to publish
-// ant.setTarget(buildSpec.module);
-// ant.setTaskName("ant");
-// loadAntProperties(ant, buildSpec);
-// ant.execute();
-// }
-//
-// /** override definitions */
-// private void loadAntProperties(Ant ant, BuildSpec buildSpec) {
-// Property property = ant.createProperty();
-// property.setName(BuildSpec.baseDir_NAME);
-// property.setFile(buildSpec.baseDir);
-// property = ant.createProperty();
-// property.setName(buildSpec.distDir_NAME);
-// property.setFile(buildSpec.distDir);
-// property = ant.createProperty();
-// property.setName(BuildSpec.tempDir_NAME);
-// property.setFile(buildSpec.tempDir);
-// property = ant.createProperty();
-// property.setName(BuildSpec.jarDir_NAME);
-// property.setFile(buildSpec.jarDir);
-// property = ant.createProperty();
-// property.setName(BuildSpec.stagingDir_NAME);
-// property.setFile(buildSpec.stagingDir);
-// }
-
-/**
- * Segregate product-building API's from module-building APIs for clarity. These are called by the superclass if the BuildSpec
- * warrants. XXX extremely brittle/arbitrary assumptions.
- *
- * @see BuildModule for assumptions
- */
-class ProductBuilder extends AntBuilder {
-
- private static String getProductInstallResourcesSrc(BuildSpec buildSpec) {
- final String resourcesName = "installer-resources"; // XXXFileLiteral
- File dir = buildSpec.productDir.getParentFile();
- if (null == dir) {
- return Util.path(new String[] { "..", "..", resourcesName });
- }
- dir = dir.getParentFile();
- if (null == dir) {
- return Util.path("..", resourcesName);
- } else {
- dir = new File(dir, resourcesName);
- return dir.getPath();
- }
- }
-
- private static String getProductInstallerFileName(BuildSpec buildSpec) { // XXXFileLiteral
- return "aspectj-" + buildSpec.productDir.getName() + "-" + Util.shortVersion(buildSpec.version) + ".jar";
- }
-
- /**
- * Calculate name of main, typically InitialCap, and hence installer class.
- *
- * @return $$installer$$.org.aspectj." + ProductName + "Installer"
- */
-
- private static String getProductInstallerMainClass(BuildSpec buildSpec) {
- String productName = buildSpec.productDir.getName();
- String initial = productName.substring(0, 1).toUpperCase();
- productName = initial + productName.substring(1);
- return "$installer$.org.aspectj." + productName + "Installer"; // XXXNameLiteral
- }
-
- /** @see Builder.getBuilder(String, Project, File) */
- ProductBuilder(Project project, File tempDir, boolean useEclipseCompiles, Messager handler) {
- super(project, tempDir, useEclipseCompiles, handler);
- }
-
- /**
- * Delegate for super.buildProduct(..) template method.
- */
- @Override
- protected boolean copyBinaries(BuildSpec buildSpec, File distDir, File targDir, String excludes) {
- Copy copy = makeCopyTask(false);
- copy.setTodir(targDir);
- FileSet fileset = new FileSet();
- fileset.setDir(distDir);
- fileset.setIncludes(Builder.BINARY_SOURCE_PATTERN);
- if (null != excludes) {
- fileset.setExcludes(excludes);
- }
- copy.addFileset(fileset);
- return executeTask(copy);
- }
-
- /**
- * Delegate for super.buildProduct(..) template method.
- */
- @Override
- protected boolean copyNonBinaries(BuildSpec buildSpec, File distDir, File targDir) {
- // filter-copy everything but the binaries
- Copy copy = makeCopyTask(true);
- copy.setTodir(targDir);
- Util.iaxIfNotCanReadDir(distDir, "product dist directory");
- FileSet fileset = new FileSet();
- fileset.setDir(distDir);
- fileset.setExcludes(Builder.BINARY_SOURCE_PATTERN);
- copy.addFileset(fileset);
- return executeTask(copy);
- }
-
- @Override
- protected boolean buildInstaller(BuildSpec buildSpec, String targDirPath) {
- if (buildSpec.verbose) {
- handler.log("creating installer for " + buildSpec);
- }
- AJInstaller installer = new AJInstaller();
- setupTask(installer, "installer");
- installer.setBasedir(targDirPath);
- // installer.setCompress();
- File installSrcDir = new File(buildSpec.productDir, "install"); // XXXFileLiteral
- Util.iaxIfNotCanReadDir(installSrcDir, "installSrcDir");
- installer.setHtmlSrc(installSrcDir.getPath());
- String resourcePath = getProductInstallResourcesSrc(buildSpec);
- File resourceSrcDir = new File(resourcePath);
- Util.iaxIfNotCanReadDir(resourceSrcDir, "resourceSrcDir");
- installer.setResourcesSrc(resourcePath);
- String name = getProductInstallerFileName(buildSpec);
- File outFile = new File(buildSpec.jarDir, name);
- installer.setZipfile(outFile.getPath());
- installer.setMainclass(getProductInstallerMainClass(buildSpec));
- installer.setInstallerclassjar(getBuildJar(buildSpec));
- return executeTask(installer);
-
- // -- test installer XXX
- // create text setup file
- // run installer with setup file
- // cleanup installed product
- }
-
- private String getBuildJar(BuildSpec buildSpec) {
- return buildSpec.baseDir.getPath() + "/lib/build/build.jar"; // XXX
- }
-
- // private Module moduleForReplaceFile(File replaceFile, Modules modules) {
- // String jarName = moduleAliasFor(replaceFile.getName().toLowerCase());
- // if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) { // XXXFileLiteral
- // jarName = jarName.substring(0, jarName.length()-4);
- // } else {
- // throw new IllegalArgumentException("can only replace .[jar|zip]");
- // }
- // boolean assembleAll = jarName.endsWith("-all");
- // String name = (!assembleAll ? jarName : jarName.substring(0, jarName.length()-4));
- // return modules.getModule(name);
- // }
- //
-}
-
-class ProjectMessager extends Messager {
- private final Project project;
-
- public ProjectMessager(Project project) {
- Util.iaxIfNull(project, "project");
- this.project = project;
- }
-
- @Override
- public boolean log(String s) {
- project.log(s);
- return true;
- }
-
- @Override
- public boolean error(String s) {
- project.log(s, Project.MSG_ERR);
- return true;
- }
-
- @Override
- public boolean logException(String context, Throwable thrown) {
- project.log(context + Util.renderException(thrown), Project.MSG_ERR);
- return true;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.File;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Location;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Path;
-import org.aspectj.internal.tools.build.BuildSpec;
-import org.aspectj.internal.tools.build.Builder;
-
-/**
- * Ant interface to build a product or module, including any required modules.
- * @see Builder
- */
-public class BuildModule extends Task { // quickie hack...
-
- public static void main(String[] args) {
- TestBuildModule.main(args);
- }
-
- private static File pathToFile(Path path) {
- if (null != path) {
- String[] list = path.list();
- if ((null == list) || (1 != list.length)) {
- throw new IllegalArgumentException("expected exactly 1 element");
- }
- return new File(list[0]);
- }
- return null;
- }
- BuildSpec buildSpec;
-
- public BuildModule() {
- buildSpec = new BuildSpec();
- setTaskName("ajbuild");
- }
-
- public void setModuledir(Path moduleDir) {
- buildSpec.moduleDir = pathToFile(moduleDir);
- }
-
- public void setModule(String module) { // XXX handle multiple modules, same builder
- buildSpec.module = module;
- }
-
- public void setVersion(String version) {
- buildSpec.version = version;
- }
- public void setBasedir(Path baseDir) {
- buildSpec.baseDir = pathToFile(baseDir);
- }
-
- public void setJardir(Path jarDir) {
- buildSpec.jarDir = pathToFile(jarDir);
- }
-
- public void setTrimtesting(boolean trimTesting) {
- buildSpec.trimTesting = trimTesting;
- }
-
- public void setAssembleall(boolean assembleAll) {
- buildSpec.assembleAll = assembleAll;
- }
-
- public void setRebuild(boolean rebuild) {
- buildSpec.rebuild = rebuild;
- }
-
- public void setFailonerror(boolean failonerror) {
- buildSpec.failonerror = failonerror;
- }
-
- public void setCreateinstaller(boolean create) {
- buildSpec.createInstaller = create;
- }
-
- public void setVerbose(boolean verbose) {
- buildSpec.verbose = verbose;
- }
-
- public void setBuildConfig(String buildConfig) {
- buildSpec.buildConfig = buildConfig;
- }
-
- // --------------------------------------------------------- product build
-
- public void setProductdir(Path productDir) {
- buildSpec.productDir = pathToFile(productDir);
- }
-
- public void setTempdir(Path tempDir) {
- buildSpec.tempDir = pathToFile(tempDir);
- }
-
- public void setDistdir(Path distdir) {
- buildSpec.distDir = pathToFile(distdir);
- }
-
- public void execute() throws BuildException {
- final BuildSpec buildSpec = this.buildSpec;
- this.buildSpec = new BuildSpec();
- build(buildSpec);
- }
-
- private void build(BuildSpec buildSpec) throws BuildException {
- final boolean failonerror = buildSpec.failonerror;
- Builder builder = null;
- try {
- // try using script first if not a product
- boolean built = false;
- if ((null == buildSpec.productDir) && (null != buildSpec.moduleDir)) {
- File buildScript = new File(buildSpec.moduleDir, "build.xml"); // XXXFileLiteral
- if (buildScript.canRead()) {
- built = buildByScript(buildSpec, buildScript);
- if (!built) {
- log("unable to build "
- + buildSpec
- + " using script: "
- + buildScript.getAbsolutePath());
- }
- }
- }
- if (!built) {
- builder = AntBuilder.getBuilder(
- buildSpec.buildConfig,
- getProject(),
- buildSpec.tempDir);
- if (!builder.build(buildSpec) && failonerror) {
- Location loc = getLocation();
- throw new BuildException("error building " + buildSpec, loc);
- }
- }
- } catch (BuildException e) {
- throw e;
- } catch (Throwable t) {
- Location loc = getLocation();
- throw new BuildException("error building " + buildSpec, t, loc);
- } finally {
- if (null != builder) {
- builder.cleanup();
- }
- }
- }
-
- boolean buildByScript(BuildSpec buildSpec, File buildScript)
- throws BuildException {
- return false;
- }
-}
-
\ No newline at end of file
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Reference;
-
-/**
- * Check that included .java files contain license and copyright strings for MPL 1.0 (default), Apache, or CPL. Use list="true" to
- * get a list of known license variants {license}-{copyrightHolder} todo reimplement with regexp and jdiff FileLine utilities
- */
-public class Checklics extends MatchingTask {
- /*
- * This does not enforce that copyrights are correct/current, only that they exist. E.g., the default behavior requires MPL but
- * permits either Xerox or PARC copyright holders and any valid year.
- */
- public static final String MPL_TAG = "mpl";
- public static final String APACHE_TAG = "apache";
- public static final String CPL_IBM_PARC_TAG = "cpl-ibm|parc";
- public static final String CPL_IBM_TAG = "cpl-ibm";
- public static final String MPL_XEROX_PARC_TAG = "mpl-parc|xerox";
- public static final String MPL_ONLY_TAG = "mpl-only";
- public static final String MPL_PARC_TAG = "mpl-parc";
- public static final String PARC_COPYRIGHT_TAG = "parc-copy";
- public static final String CPL_IBM_PARC_XEROX_TAG = "cpl-ibm|parc|xerox";
- public static final String CPL_IBM_PARC_XEROX_OTHERS_TAG = "cpl-ibm|parc|xerox|others";
- public static final String EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG = "epl-cpl-ibm|parc|xerox|vmware|others";
- public static final String DEFAULT = EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG;
-
- static final Map<String,License> LICENSES; // unmodifiable Map
-
- static {
- final String CONTRIBUTORS = "Contributors";
- final String XEROX = "Xerox";
- final String PARC = "Palo Alto Research Center";
- final String APACHE = "The Apache Software Foundation";
- final String IBM = "IBM";
- final String VMWARE = "VMware";
- final String IBM_LONG = "International Business Machines";
- final String LIC_APL = "Apache Software Foundation (http://www.apache.org/)";
- final String LIC_MPL = "http://aspectj.org/MPL/";
- final String LIC_CPL = "Eclipse Public License";
- final String LIC_ECPL = " Public License";
- License APL = new License(APACHE_TAG, LIC_APL, APACHE);
- License MPL = new License(MPL_TAG, LIC_MPL, XEROX);
- License MPL_XEROX_PARC = new License(DEFAULT, LIC_MPL, XEROX, PARC);
- License CPL_IBM_PARC = new License(CPL_IBM_PARC_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC });
- License CPL_IBM_PARC_XEROX = new License(CPL_IBM_PARC_XEROX_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC, XEROX });
-
- License CPL_IBM_PARC_XEROX_OTHERS = new License(CPL_IBM_PARC_XEROX_OTHERS_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC,
- XEROX, CONTRIBUTORS });
- License EPL_CPL_IBM_PARC_XEROX_OTHERS = new License(EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG, LIC_ECPL, new String[] { IBM_LONG,
- IBM, PARC, XEROX, VMWARE, CONTRIBUTORS });
- License CPL_IBM = new License(CPL_IBM_TAG, LIC_CPL, IBM, IBM_LONG);
- License MPL_ONLY = new License(MPL_ONLY_TAG, LIC_MPL);
- License MPL_PARC = new License(MPL_PARC_TAG, LIC_MPL, PARC);
- License PARC_COPYRIGHT = new License(PARC_COPYRIGHT_TAG, null, PARC);
- LICENSES = new Hashtable<String,License>();
- LICENSES.put(APL.tag, APL);
- LICENSES.put(MPL.tag, MPL);
- LICENSES.put(MPL_PARC.tag, MPL_PARC);
- LICENSES.put(MPL_XEROX_PARC.tag, MPL_XEROX_PARC);
- LICENSES.put(CPL_IBM_PARC.tag, CPL_IBM_PARC);
- LICENSES.put(MPL_ONLY.tag, MPL_ONLY);
- LICENSES.put(CPL_IBM.tag, CPL_IBM);
- LICENSES.put(PARC_COPYRIGHT.tag, PARC_COPYRIGHT);
- LICENSES.put(CPL_IBM_PARC_XEROX.tag, CPL_IBM_PARC_XEROX);
- LICENSES.put(CPL_IBM_PARC_XEROX_OTHERS.tag, CPL_IBM_PARC_XEROX_OTHERS);
- LICENSES.put(EPL_CPL_IBM_PARC_XEROX_OTHERS.tag, EPL_CPL_IBM_PARC_XEROX_OTHERS);
- }
-
- /** @param args String[] { < sourcepath > {, < licenseTag > } } */
- public static void main(String[] args) {
- switch (args.length) {
- case 1:
- runDirect(args[0], null, false);
- break;
- case 2:
- runDirect(args[0], args[1], false);
- break;
- default:
- String options = "{replace-headers|get-years|list|{licenseTag}}";
- System.err.println("java {me} sourcepath " + options);
- break;
- }
- }
-
- /**
- * Run the license check directly
- *
- * @param sourcepaths String[] of paths to source directories
- * @param license the String tag for the license, if any
- * @param failonerror boolean flag to pass to Checklics
- * @throws IllegalArgumentException if sourcepaths is empty
- * @return total number of failed licenses
- */
- public static int runDirect(String sourcepath, String license, boolean failonerror) {
- if ((null == sourcepath) || (1 > sourcepath.length())) {
- throw new IllegalArgumentException("bad sourcepath: " + sourcepath);
- }
- Checklics me = new Checklics();
- Project p = new Project();
- p.setName("direct interface to Checklics");
- p.setBasedir(".");
- me.setProject(p);
- me.setFailOnError(failonerror);
- me.setSourcepath(new Path(p, sourcepath));
- if (null != license) {
- if ("replace-headers".equals(license)) {
- me.setReplaceheaders(true);
- } else if ("get-years".equals(license)) {
- me.setGetYears(true);
- } else if ("list".equals(license)) {
- me.setList(true);
- } else {
- me.setLicense(license);
- }
- }
- me.execute();
- return me.failed;
- }
-
- private Path sourcepath;
- private License license;
- private boolean list;
- private String streamTag;
- private boolean failOnError;
- private boolean getYears;
- private boolean replaceHeaders;
- private int failed;
- private int passed;
-
- private boolean printDirectories;
-
- /** @param list if true, don't run but list known license tags */
- public void setList(boolean list) {
- this.list = list;
- }
-
- public void setPrintDirectories(boolean print) {
- printDirectories = print;
- }
-
- /**
- * When failOnError is true, if any file failed, throw BuildException listing number of files that file failed to pass license
- * check
- *
- * @param fail if true, report errors by throwing BuildException
- */
- public void setFailOnError(boolean fail) {
- this.failOnError = fail;
- }
-
- /** @param tl mpl | apache | cpl */
- public void setLicense(String tl) {
- License input = LICENSES.get(tl);
- if (null == input) {
- throw new BuildException("no license known for " + tl);
- }
- license = input;
- }
-
- public void setSourcepath(Path path) {
- if (sourcepath == null) {
- sourcepath = path;
- } else {
- sourcepath.append(path);
- }
- }
-
- public Path createSourcepath() {
- return sourcepath == null ? (sourcepath = new Path(project)) : sourcepath.createPath();
- }
-
- public void setSourcepathRef(Reference id) {
- createSourcepath().setRefid(id);
- }
-
- /** @param out "out" or "err" */
- public void setOutputStream(String out) {
- this.streamTag = out;
- }
-
- public void setReplaceheaders(boolean replaceHeaders) {
- this.replaceHeaders = replaceHeaders;
- }
-
- public void setGetYears(boolean getYears) {
- this.getYears = getYears;
- }
-
- /** list known licenses or check source tree */
- @Override
- public void execute() throws BuildException {
- if (list) {
- list();
- } else if (replaceHeaders) {
- replaceHeaders();
- } else if (getYears) {
- getYears();
- } else {
- checkLicenses();
- }
- }
-
- private PrintStream getOut() {
- return ("err".equals(streamTag) ? System.err : System.out);
- }
-
- interface FileVisitor {
- void visit(File file);
- }
-
- /** visit all .java files in all directories... */
- private void visitAll(FileVisitor visitor) {
- // List filelist = new ArrayList();
- String[] dirs = sourcepath.list();
- for (int i = 0; i < dirs.length; i++) {
- File dir = project.resolveFile(dirs[i]);
- String[] files = getDirectoryScanner(dir).getIncludedFiles();
- for (int j = 0; j < files.length; j++) {
- File file = new File(dir, files[j]);
- String path = file.getPath();
- if (path.endsWith(".java")) {
- visitor.visit(file);
- }
- }
- }
- }
-
- private void replaceHeaders() {
- class YearVisitor implements FileVisitor {
- @Override
- public void visit(File file) {
- HeaderInfo info = Header.checkFile(file);
- if (!Header.replaceHeader(file, info)) {
- throw new BuildException("failed to replace header for " + file + " using " + info);
- }
- }
- }
- visitAll(new YearVisitor());
- }
-
- private void getYears() {
- final PrintStream out = getOut();
- class YearVisitor implements FileVisitor {
- @Override
- public void visit(File file) {
- HeaderInfo info = Header.checkFile(file);
- out.println(info.toString());
- }
- }
- visitAll(new YearVisitor());
- }
-
- private void checkLicenses() throws BuildException {
- if (null == license) {
- setLicense(DEFAULT);
- }
- final License license = this.license; // being paranoid...
- if (null == license) {
- throw new BuildException("no license");
- }
- final PrintStream out = getOut();
-
- class Visitor implements FileVisitor {
- int failed = 0;
- int passed = 0;
-
- @Override
- public void visit(File file) {
- if (license.checkFile(file)) {
- passed++;
- } else {
- failed++;
- String path = file.getPath();
- if (!license.foundLicense()) {
- out.println(license.tag + " LICENSE FAIL: " + path);
- }
- if (!license.foundCopyright()) {
- out.println(license.tag + " COPYRIGHT FAIL: " + path);
- }
- }
- }
- }
- Visitor visitor = new Visitor();
- visitAll(visitor);
- this.failed = visitor.failed;
- this.passed = visitor.passed;
- if (0 < visitor.failed) {
- getOut().println("Total passed: " + visitor.passed + (visitor.failed == 0 ? "" : " failed: " + visitor.failed));
- if (failOnError) {
- throw new BuildException(failed + " files failed license check");
- }
- }
- }
-
- private void list() {
- Iterator enu = LICENSES.keySet().iterator();
- StringBuffer sb = new StringBuffer();
- sb.append("known license keys:");
- boolean first = true;
- while (enu.hasNext()) {
- sb.append((first ? " " : ", ") + enu.next());
- if (first) {
- first = false;
- }
- }
- getOut().println(sb.toString());
- }
-
- /**
- * Encapsulate license and copyright specifications to check files use hokey string matching.
- */
- public static class License {
- /** acceptable years for copyright prefix to company - append " " */
- static final String[] YEARS = // remove older after license xfer?
- new String[] { "2002 ", "2003 ", "2004 ", "2005", "2006", "2007", "2008",
- "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2001 ", "2000 ",
- "1999 " };
- public final String tag;
- public final String license;
- private final String[] copyright;
- private boolean gotLicense;
- private boolean gotCopyright;
-
- License(String tag, String license) {
- this(tag, license, (String[]) null);
- }
-
- License(String tag, String license, String copyright) {
- this(tag, license, new String[] { copyright });
- }
-
- License(String tag, String license, String copyright, String altCopyright) {
- this(tag, license, new String[] { copyright, altCopyright });
- }
-
- License(String tag, String license, String[] copyright) {
- this.tag = tag;
- if ((null == tag) || (0 == tag.length())) {
- throw new IllegalArgumentException("null tag");
- }
- this.license = license;
- this.copyright = copyright;
- }
-
- public final boolean gotValidFile() {
- return foundLicense() && foundCopyright();
- }
-
- /** @return true if no license sought or if some license found */
- public final boolean foundLicense() {
- return ((null == license) || gotLicense);
- }
-
- /** @return true if no copyright sought or if some copyright found */
- public final boolean foundCopyright() {
- return ((null == copyright) || gotCopyright);
- }
-
- public boolean checkFile(final File file) {
- clear();
- // boolean result = false;
- BufferedReader input = null;
- int lineNum = 0;
- try {
- input = new BufferedReader(new FileReader(file));
- String line;
- while (!gotValidFile() && (line = input.readLine()) != null) {
- lineNum++;
- checkLine(line);
- }
- } catch (IOException e) {
- System.err.println("reading line " + lineNum + " of " + file);
- e.printStackTrace(System.err);
- } finally {
- if (null != input) {
- try {
- input.close();
- } catch (IOException e) {
- } // ignore
- }
- }
- return gotValidFile();
- }
-
- @Override
- public String toString() {
- return tag;
- }
-
- private void checkLine(String line) {
- if ((null == line) || (0 == line.length())) {
- return;
- }
- if (!gotLicense && (null != license) && (-1 != line.indexOf(license))) {
- gotLicense = true;
- }
- if (!gotCopyright && (null != copyright)) {
- int loc;
- for (int j = 0; !gotCopyright && (j < YEARS.length); j++) {
- if (-1 != (loc = line.indexOf(YEARS[j]))) {
- loc += YEARS[j].length();
- String afterLoc = line.substring(loc).trim();
- for (int i = 0; !gotCopyright && (i < copyright.length); i++) {
- if (0 == afterLoc.indexOf(copyright[i])) {
- gotCopyright = true;
- }
- }
- }
- }
- }
- }
-
- private void clear() {
- if (gotLicense) {
- gotLicense = false;
- }
- if (gotCopyright) {
- gotCopyright = false;
- }
- }
- } // class License
-}
-
-class HeaderInfo {
- /** File for which this is the info */
- public final File file;
-
- /** unmodifiable List of String years */
- public final List years;
-
- /** last line of license */
- public final int lastLine;
-
- /** last line of license */
- public final boolean hasLicense;
-
- public HeaderInfo(File file, int lastLine, List<String> years, boolean hasLicense) {
- this.lastLine = lastLine;
- this.file = file;
- this.hasLicense = hasLicense;
- List<String> newYears = new ArrayList<String>();
- newYears.addAll(years);
- Collections.sort(newYears);
- this.years = Collections.unmodifiableList(newYears);
- if ((null == file) || !file.canWrite()) {
- throw new IllegalArgumentException("bad file: " + this);
- }
- if (!hasLicense) {
- if ((0 > lastLine) || (65 < lastLine)) {
- throw new IllegalArgumentException("bad last line: " + this);
- }
- } else {
- if ((null == years) || (1 > years.size())) {
- throw new IllegalArgumentException("no years: " + this);
- }
- if ((20 > lastLine) || (65 < lastLine)) {
- throw new IllegalArgumentException("bad last line: " + this);
- }
- }
- }
-
- @Override
- public String toString() {
- return file.getPath() + ":" + lastLine + " " + years;
- }
-
- public void writeHeader(PrintWriter writer) {
- if (!hasLicense) {
- writer.println(TOP);
- writer.println(PARC_ONLY);
- writeRest(writer);
- } else {
- final int size = years.size();
- if (1 > size) {
- throw new Error("no years found in " + toString());
- }
- String first = (String) years.get(0);
- String last = (String) years.get(size - 1);
- boolean lastIs2002 = "2002".equals(last);
- String xlast = last;
- if (lastIs2002) { // 2002 was PARC
- xlast = (String) (size > 1 ? years.get(size - 2) : null);
- // 1999-2002 Xerox implies 1999-2001 Xerox
- if (first.equals(xlast) && !"2001".equals(xlast)) {
- xlast = "2001";
- }
- }
- String xyears = first + "-" + xlast;
- if (first.equals(last)) {
- xyears = first;
- }
-
- writer.println(TOP);
- if (!lastIs2002) { // Xerox only
- writer.println(XEROX_PREFIX + xyears + XEROX_SUFFIX + ". ");
- } else if (size == 1) { // PARC only
- writer.println(PARC_ONLY);
- } else { // XEROX plus PARC
- writer.println(XEROX_PREFIX + xyears + XEROX_SUFFIX + ", ");
- writer.println(PARC);
- }
- writeRest(writer);
- }
- }
-
- void writeRest(PrintWriter writer) {
- writer.println(" * All rights reserved. ");
- writer.println(" * This program and the accompanying materials are made available ");
- writer.println(" * under the terms of the Eclipse Public License v1.0 ");
- writer.println(" * which accompanies this distribution and is available at ");
- writer.println(" * http://www.eclipse.org/legal/epl-v10.html ");
- writer.println(" * ");
- writer.println(" * Contributors: ");
- writer.println(" * Xerox/PARC initial implementation ");
- writer.println(" * ******************************************************************/");
- writer.println("");
- }
-
- public static final String TOP = "/* *******************************************************************";
- public static final String PARC = " * 2002 Palo Alto Research Center, Incorporated (PARC).";
- public static final String PARC_ONLY = " * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).";
- public static final String XEROX_PREFIX = " * Copyright (c) ";
- public static final String XEROX_SUFFIX = " Xerox Corporation";
- /*
- * /* ******************************************************************* Copyright (c) 1998-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 v1.0 which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Xerox/PARC initial implementation ******************************************************************
- */
-}
-
-/**
- * header search/replace using hokey string matching
- */
-class Header {
-
- /** replace the header in file */
- public static boolean replaceHeader(File file, HeaderInfo info) {
- // ArrayList years = new ArrayList();
- // int endLine = 0;
- BufferedReader input = null;
- PrintWriter output = null;
- FileWriter outWriter = null;
- int lineNum = 0;
- boolean result = false;
- final File inFile = new File(file.getPath() + ".tmp");
- try {
- File outFile = new File(file.getPath());
- if (!file.renameTo(inFile) || !inFile.canRead()) {
- throw new Error("unable to rename " + file + " to " + inFile);
- }
- outWriter = new FileWriter(outFile);
- input = new BufferedReader(new FileReader(inFile));
- output = new PrintWriter(outWriter, true);
- info.writeHeader(output);
- String line;
- while (null != (line = input.readLine())) {
- lineNum++;
- if (lineNum > info.lastLine) {
- output.println(line);
- }
- }
- } catch (IOException e) {
- System.err.println("writing line " + lineNum + " of " + file);
- e.printStackTrace(System.err);
- result = false;
- } finally {
- if (null != input) {
- try {
- input.close();
- } catch (IOException e) {
- result = false;
- }
- }
- if (null != outWriter) {
- try {
- outWriter.close();
- } catch (IOException e) {
- result = false;
- }
- }
- result = inFile.delete();
- }
- return result;
- }
-
- public static HeaderInfo checkFile(final File file) {
- ArrayList<String> years = new ArrayList<String>();
- int endLine = 0;
- BufferedReader input = null;
- int lineNum = 0;
- try {
- input = new BufferedReader(new FileReader(file));
- String line;
- while (null != (line = input.readLine())) {
- lineNum++;
- String ll = line.trim();
- if (ll.startsWith("package ") || ll.startsWith("import ")) {
- break; // ignore default package w/o imports
- }
- if (checkLine(line, years)) {
- endLine = lineNum;
- break;
- }
- }
- } catch (IOException e) {
- System.err.println("reading line " + lineNum + " of " + file);
- e.printStackTrace(System.err);
- } finally {
- if (null != input) {
- try {
- input.close();
- } catch (IOException e) {
- } // ignore
- }
- }
- return new HeaderInfo(file, endLine, years, endLine > 0);
- }
-
- /**
- * Add any years found (as String) to years, and return true at the first end-of-comment
- *
- * @return true if this line has end-of-comment
- */
- private static boolean checkLine(String line, ArrayList<String> years) {
- if ((null == line) || (0 == line.length())) {
- return false;
- }
- int loc;
- int start = 0;
-
- while ((-1 != (loc = line.indexOf("199", start)) || (-1 != (loc = line.indexOf("200", start))))) {
- char c = line.charAt(loc + 3);
- if ((c <= '9') && (c >= '0')) {
- years.add(line.substring(loc, loc + 4));
- }
- start = loc + 4;
- }
-
- return (-1 != line.indexOf("*/"));
- }
-
-} // class Header
-
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-
-public abstract class ConditionalTask extends Task {
-
- public final static String TRUE = "true";
-
- private List<If> ifs;
- protected List<If> ifs() {
- return ifs != null ? ifs : (ifs = new Vector<If>());
- }
-
- public If createIf() {
- If i = new If();
- ifs().add(i);
- return i;
- }
-
- public If createIf(String name, String equals, boolean strict) {
- If i = createIf();
- i.setName(name);
- i.setEquals(equals);
- i.setStrict(strict);
- return i;
- }
-
- public If createIf(String name, String equals) {
- return createIf(name, equals, false);
- }
-
- public If createIf(String name) {
- return createIf(name, TRUE, false);
- }
-
- public If createIf(String name, boolean strict) {
- return createIf(name, TRUE, strict);
- }
-
- public void setIfs(String ifs) {
- StringTokenizer tok = new StringTokenizer(ifs, ",;: ", false);
- while (tok.hasMoreTokens()) {
- String next = tok.nextToken();
- int iequals = next.lastIndexOf("=");
- String equals;
- String name;
- boolean strict;
- If i = createIf();
- if (iequals != -1) {
- name = next.substring(0, iequals);
- equals = next.substring(iequals + 1);
- strict = true;
- } else {
- name = next.substring(0);
- equals = TRUE;
- strict = false;
- }
- i.setName(name);
- i.setEquals(equals);
- i.setStrict(strict);
- }
- }
-
- public void setIf(String ifStr) {
- setIfs(ifStr);
- }
-
- public class If {
- public If() {
- this(null, null);
- }
- public If(String name) {
- this(name, TRUE);
- }
- public If(String name, String equals) {
- setName(name);
- setEquals(equals);
- }
- private String name;
- public void setName(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- private String equals;
- public void setEquals(String equals) {
- this.equals = equals;
- }
- public String getEquals() {
- return equals;
- }
- private boolean strict = false;
- public void setStrict(boolean strict) {
- this.strict = strict;
- }
- public boolean isStrict() {
- return strict;
- }
- public boolean isOk(String prop) {
- return isOk(prop, isStrict());
- }
- //XXX Need a better boolean parser
- public boolean isOk(String prop, boolean isStrict) {
- if (isStrict) {
- return prop != null && prop.equals(getEquals());
- } else {
- if (isOk(prop, true)) {
- return true;
- }
- if (prop == null || isFalse(getEquals())) {
- return true;
- }
- if ( (isTrue(getEquals()) && isTrue(prop)) ||
- (isFalse(getEquals()) && isFalse(prop)) ) {
- return true;
- }
- return false;
- }
- }
- private boolean isFalse(String prop) {
- return isOneOf(prop, falses) || isOneOf(prop, complement(trues));
- }
- private boolean isTrue(String prop) {
- return isOneOf(prop, trues) || isOneOf(prop, complement(falses));
- }
- private boolean isOneOf(String prop, String[] strings) {
- for (int i = 0; i < strings.length; i++) {
- if (strings[i].equals(prop)) {
- return true;
- }
- }
- return false;
- }
- private String[] complement(String[] strings) {
- for (int i = 0; i < strings.length; i++) {
- strings[i] = "!" + strings[i];
- }
- return strings;
- }
- }
-
- final static String[] falses = { "false", "no" };
- final static String[] trues = { "true", "yes" };
-
- protected boolean checkIfs() {
- return getFalses().size() == 0;
- }
-
- protected List<String> getFalses() {
- Iterator<If> iter = ifs().iterator();
- List<String> result = new Vector<String>();
- while (iter.hasNext()) {
- If next = (If) iter.next();
- String name = next.getName();
- String prop = project.getProperty(name);
- if (prop == null) {
- prop = project.getUserProperty(name);
- }
- if (!next.isOk(prop)) {
- result.add(name);
- }
- }
- return result;
- }
-
- public abstract void execute() throws BuildException;
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.taskdefs.Mkdir;
-
-public class CopyAndInlineStylesheet extends Task {
-
- private File file;
- public void setFile(String file) {
- this.file = project.resolveFile(file);
- }
-
- private File todir;
- public void setTodir(String todir) {
- this.todir = project.resolveFile(todir);
- }
-
-
- public void execute() throws BuildException {
- try {
- if (todir == null) {
- throw new BuildException("must set 'todir' attribute");
- }
- if (file == null) {
- throw new BuildException("must set 'file' attribute");
- }
- log("copying html from" + file + " to " + todir.getAbsolutePath());
-
- File toFile = new File(todir, file.getName());
-
- Mkdir mkdir = (Mkdir) project.createTask("mkdir");
- mkdir.setDir(todir);
- mkdir.execute();
-
- BufferedReader in = new BufferedReader(new FileReader(file));
- PrintStream out = new PrintStream(new FileOutputStream(toFile));
-
- outer:
- while (true) {
- String line = in.readLine();
- if (line == null) break;
- if (isStyleSheet(line)) {
- doStyleSheet(line, out, file);
- while (true) {
- String line2 = in.readLine();
- if (line2 == null) break outer;
- out.println(line2);
- }
- } else {
- out.println(line);
- }
- }
-
- in.close();
- out.close();
- } catch (IOException e) {
- throw new BuildException(e.getMessage());
- }
- }
-
- private static void doStyleSheet(String line, PrintStream out, File file) throws IOException {
- int srcIndex = line.indexOf("href");
- int startQuotIndex = line.indexOf('"', srcIndex);
- int endQuotIndex = line.indexOf('"', startQuotIndex + 1);
-
- String stylesheetLocation = line.substring(startQuotIndex + 1, endQuotIndex);
-
- File styleSheetFile = new File(file.getParent(), stylesheetLocation);
-
- out.println("<style type=\"text/css\">");
- out.println("<!--");
-
- BufferedReader inStyle = new BufferedReader(new FileReader(styleSheetFile));
-
- while (true) {
- String line2 = inStyle.readLine();
- if (line2 == null) break;
- out.println(line2);
- }
- inStyle.close();
-
- out.println("-->");
- out.println("</style>");
- }
-
-
- private static boolean isStyleSheet(String line) throws IOException {
- line = line.toLowerCase();
- int len = line.length();
- int i = 0;
-
- while (true) {
- if (i == len) return false;
- if (! Character.isWhitespace(line.charAt(i))) break;
- }
-
- return line.startsWith("<link", i);
- }
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-
-/**
- * Task to convert html source files into files with only body content.
- *
- * <p> This task can take the following arguments:</p>
- *
- * <ul>
- * <li>srcdir</li>
- * <li>destdir</li>
- * <li>include</li>
- * <li>exclude</li>
- * </ul>
- *
- * <p>Of these arguments, only <b>sourcedir</b> is required.</p>
- *
- * <p> When this task executes, it will scan the srcdir based on the
- * include and exclude properties.</p>
- */
-
-public class StripNonBodyHtml extends MatchingTask {
-
- private File srcDir;
- private File destDir = null;
-
- public void setSrcdir(File srcDir) {
- this.srcDir = srcDir;
- }
-
- public void setDestdir(File destDir) {
- this.destDir = destDir;
- }
-
- public void execute() throws BuildException {
- if (srcDir == null) {
- throw new BuildException("srcdir attribute must be set!");
- }
- if (!srcDir.exists()) {
- throw new BuildException("srcdir does not exist!");
- }
- if (!srcDir.isDirectory()) {
- throw new BuildException("srcdir is not a directory!");
- }
- if (destDir != null) {
- if (!destDir.exists()) {
- throw new BuildException("destdir does not exist!");
- }
- if (!destDir.isDirectory()) {
- throw new BuildException("destdir is not a directory!");
- }
- }
-
- DirectoryScanner ds = super.getDirectoryScanner(srcDir);
- String[] files = ds.getIncludedFiles();
-
- log("stripping " + files.length + " files");
- int stripped = 0;
- for (int i = 0, len = files.length; i < len; i++) {
- if (processFile(files[i])) {
- stripped++;
- } else {
- log(files[i] + " not stripped");
- }
- }
- log(stripped + " files successfully stripped");
- }
-
- boolean processFile(String filename) throws BuildException {
- File srcFile = new File(srcDir, filename);
- File destFile;
- if (destDir == null) {
- destFile = srcFile;
- } else {
- destFile = new File(destDir, filename);
- destFile.getParentFile().mkdirs();
- }
- try {
- return strip(srcFile, destFile);
- } catch (IOException e) {
- throw new BuildException(e);
- }
- }
-
- private boolean strip(File f, File g) throws IOException {
- BufferedInputStream in =
- new BufferedInputStream(new FileInputStream(f));
- String s = readToString(in);
- in.close();
- return writeBodyTo(s, g);
- }
-
- private ByteArrayOutputStream temp = new ByteArrayOutputStream();
- private byte[] buf = new byte[2048];
-
- private String readToString(InputStream in) throws IOException {
- ByteArrayOutputStream temp = this.temp;
- byte[] buf = this.buf;
- String s = "";
- try {
- while (true) {
- int i = in.read(buf, 0, 2048);
- if (i == -1) break;
- temp.write(buf, 0, i);
-
- }
- s = temp.toString();
- } finally {
- temp.reset();
- }
- return s;
- }
-
- private boolean writeBodyTo(String s, File f) throws IOException {
- int start;//, end;
- try {
- start = findStart(s);
- findEnd(s, start);
- } catch (ParseException e) {
- return false; // if we get confused, just don't write the file.
- }
- s = processBody(s,f);
- BufferedOutputStream out =
- new BufferedOutputStream(new FileOutputStream(f));
-
- out.write(s.getBytes());
- out.close();
- return true;
- }
-
- /**
- * Process body. This implemenation strips text
- * between <!-- start strip -->
- * and <!-- end strip -->
- * inclusive.
- */
- private String processBody(String body, File file) {
- if (null == body) return body;
- final String START = "<!-- start strip -->";
- final String END = "<!-- end strip -->";
- return stripTags(body, file.toString(), START, END);
- }
-
- /**
- * Strip 0..n substrings in input: "s/${START}.*${END}//g"
- * @param input the String to strip
- * @param source the name of the source for logging purposes
- * @param start the starting tag (case sensitive)
- * @param end the ending tag (case sensitive)
- */
- String stripTags(String input, final String SOURCE,
- final String START, final String END) {
- if (null == input) return input;
- StringBuffer buffer = new StringBuffer(input.length());
- String result = input;
- int curLoc = 0;
- while (true) {
- int startLoc = input.indexOf(START, curLoc);
- if (-1 == startLoc) {
- buffer.append(input.substring(curLoc));
- result = buffer.toString();
- break; // <------------ valid exit
- } else {
- int endLoc = input.indexOf(END, startLoc);
- if (-1 == endLoc) {
- log(SOURCE + " stripTags - no end tag - startLoc=" + startLoc);
- break; // <------------ invalid exit
- } else if (endLoc < startLoc) {
- log(SOURCE + " stripTags - impossible: startLoc="
- + startLoc + " > endLoc=" + endLoc);
- break; // <------------ invalid exit
- } else {
- buffer.append(input.substring(curLoc, startLoc));
- curLoc = endLoc + END.length();
- }
- }
- }
- return result;
- }
-
- private int findStart(String s) throws ParseException {
- int len = s.length();
- int start = 0;
- while (true) {
- start = s.indexOf("<body", start);
- if (start == -1) {
- start = s.indexOf("<BODY", start);
- if (start == -1) throw barf();
- }
- start = start + 5;
- if (start >= len) throw barf();
- char ch = s.charAt(start);
- if (ch == '>') return start + 1;
- if (Character.isWhitespace(ch)) {
- start = s.indexOf('>', start);
- if (start == -1) return -1;
- return start + 1;
- }
- }
- }
-
- private int findEnd(String s, int start) throws ParseException {
- int end;
- end = s.indexOf("</body>", start);
- if (end == -1) {
- end = s.indexOf("</BODY>", start);
- if (end == -1) throw barf();
- }
- return end;
- }
-
- private static class ParseException extends Exception {
- private static final long serialVersionUID = -1l;
- }
-
- private static ParseException barf() {
- return new ParseException();
- }
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.File;
-import java.util.Arrays;
-
-import org.apache.tools.ant.Project;
-import org.aspectj.internal.tools.build.BuildSpec;
-import org.aspectj.internal.tools.build.Builder;
-import org.aspectj.internal.tools.build.Util;
-
-public class TestBuildModule {
-// private static boolean REBUILD = false;
- private static final String SYNTAX = "java {classname} <[product|module]dir>";
- public static void main(String[] args) {
-
- if ((null == args) || (1 > args.length)
- || !Util.canReadDir(new File(args[0]))) {
- System.err.println(SYNTAX);
- return;
- }
- File dir = new File(args[0]);
- // create a module
- if (Util.canReadDir(new File(dir, "dist"))) {
- createProduct(args);
- } else if (Util.canReadFile(new File(dir, ".classpath"))) {
- createModule(args);
- } else {
- System.err.println(SYNTAX);
- }
- }
-
- static void createModule(String[] args) {
- File moduleDir = new File(args[0]);
- File baseDir = moduleDir.getParentFile();
- if (null == baseDir) {
- baseDir = new File(".");
- }
- File jarDir = new File(baseDir, "aj-build-jars");
- if (!(Util.canReadDir(jarDir) || jarDir.mkdirs())) {
- System.err.println("createModule unable to create " + jarDir);
- return;
- }
-
- // set module dir or basedir plus module name
- BuildSpec buildSpec = new BuildSpec();
- buildSpec.moduleDir = moduleDir;
- buildSpec.jarDir = jarDir;
- buildSpec.verbose = true;
- buildSpec.failonerror = true;
- buildSpec.trimTesting = true;
- buildSpec.rebuild = true;
-
- File tempDir = null;
- Project project = new Project();
- project.setProperty("verbose", "true");
- project.setName("TestBuildModule.createModule" + Arrays.asList(args));
- Builder builder = AntBuilder.getBuilder("", project, tempDir);
- builder.build(buildSpec);
- }
-
- static void createProduct(String[] args) {
- throw new Error("unimplemented");
- }
-}
-
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.ant.taskdefs;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-
-/**
- * Check if version source file has the specified build version,
- * and ensure a tag file reflects whether it does or not.
- */
-public class VersionUptodate extends Task {
- public VersionUptodate() {}
-
- private String buildVersion;
- private File versionSource;
- private File versionTagFile;
-
- /**
- * @param buildVersion String expected as Version.text - required
- */
- public void setVersion(String buildVersion) {
- this.buildVersion = buildVersion;
- }
-
- /**
- * @param versionSource the File Version.java containing text constant
- * - required
- */
- public void setVersionSourceFile(File versionSource) {
- this.versionSource = versionSource;
- }
-
- /**
- * @param versionTagFile the File whose existence signals that the version
- * is uptodate after this task executes - required.
- */
- public void setVersionTagFile(File versionTagFile) {
- this.versionTagFile = versionTagFile;
- }
-
- /**
- * If the Version.java source file contains the correct
- * build version, then create the output tag file,
- * else delete it if it exists.
- * @throws BuildException if tagFile not creatable and version is incorrect
- * or if version is correct and tagFile cannot be deleted.
- */
- public void execute() throws BuildException {
- if (null == buildVersion) {
- throw new BuildException("require buildVersion");
- }
- if ((null == versionSource) || !versionSource.canRead()){
- throw new BuildException("require versionSource");
- }
- if (null == versionTagFile){
- throw new BuildException("require versionTagFile");
- }
- if (sameVersion(versionSource, buildVersion)) {
- if (!versionTagFile.exists()) {
- createFile(versionTagFile, buildVersion);
- }
- } else if (null == versionTagFile) {
- throw new BuildException("no tag file, and version out of date");
- } else if (versionTagFile.exists()) {
- if (!versionTagFile.delete()) {
- throw new BuildException("version out of date, but cannot delete " + versionTagFile);
- }
- }
- }
-
- /**
- * Detect whether version is correct in Java sources.
- * @param versionSource
- * @param buildVersion
- * @return boolean
- */
- private boolean sameVersion(File versionSource, String buildVersion) {
- // XXX build and load instead of scanning?
- FileReader fileReader = null;
- try {
- fileReader = new FileReader(versionSource);
- BufferedReader reader = new BufferedReader(fileReader);
- String line;
- while (null != (line = reader.readLine())) {
- int loc = line.indexOf("static final String text = ");
- if (-1 != loc) {
- return (-1 != line.indexOf(buildVersion , loc));
- }
- }
- return false;
- } catch (IOException e) {
- return false;
- } finally {
- if (null != fileReader) {
- try {
- fileReader.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- /**
- * Create file with contents
- */
- private void createFile(File versionTagFile, String contents) {
- FileWriter writer = null;
- try {
- writer = new FileWriter(versionTagFile);
- char[] buf = new char[contents.length()];
- contents.getChars(0, buf.length, buf, 0);
- writer.write(contents);
- } catch (IOException e) {
- throw new BuildException("writing " + versionTagFile, e);
- } finally {
- if (null != writer) {
- try {
- writer.close();
- } catch (IOException e){
- // ignore
- }
- }
- }
- }
-
-}
-
+++ /dev/null
-ajinstaller=org.aspectj.internal.tools.ant.taskdefs.AJInstaller
-ajpush=org.aspectj.internal.tools.ant.taskdefs.AJPush
-ajbuild=org.aspectj.internal.tools.ant.taskdefs.BuildModule
-versionuptodate=org.aspectj.internal.tools.ant.taskdefs.VersionUptodate
-checklics=org.aspectj.internal.tools.ant.taskdefs.Checklics
-stripnonbodyhtml=org.aspectj.internal.tools.ant.taskdefs.StripNonBodyHtml
-
-# ajclean=org.aspectj.internal.tools.ant.taskdefs.AJclean
-# ajcvs=org.aspectj.internal.tools.ant.taskdefs.Ajcvs
-# ajikes=org.aspectj.internal.tools.ant.taskdefs.AJikes
-# ajinit=org.aspectj.internal.tools.ant.taskdefs.AjInit
-# checkrelease=org.aspectj.internal.tools.ant.taskdefs.Checkrelease
-# clear=org.aspectj.internal.tools.ant.taskdefs.Clear
-# inlinestylesheetaj=org.aspectj.internal.tools.ant.taskdefs.CopyAndInlineStyleshee
-# ensure=org.aspectj.internal.tools.ant.taskdefs.Ensure
-# ensureproperties=org.aspectj.internal.tools.ant.taskdefs.EnsureProperties
-# newdir=org.aspectj.internal.tools.ant.taskdefs.Newdir
-# overwrite=org.aspectj.internal.tools.ant.taskdefs.Overwrite
-# props2filters=org.aspectj.internal.tools.ant.taskdefs.Props2Filters
-# tgz=org.aspectj.internal.tools.ant.taskdefs.Tgz
-# vmcheck=org.aspectj.internal.tools.ant.taskdefs.VMCheck
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation,
- * 2002 Palo Alto Research Center, Incorporated (PARC),
- * 2005 Contributors.
- * 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:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.build;
-
-
-import java.io.File;
-
-/**
- * Open struct for specifying builds for both modules and products.
- * Separated from bulder to permit this to build many modules
- * concurrently.
- */
-public class BuildSpec {
- public static final String DEFAULT_VERSION = "DEVELOPMENT";
- // shared
- public File baseDir;
- public File moduleDir;
- public File jarDir;
- public File tempDir;
- public File stagingDir;
- public String buildConfig;
- public String version;
- public boolean rebuild;
- public boolean trimTesting;
- public boolean assembleAll;
- public boolean failonerror;
- public boolean verbose;
-
- // building products
- public File productDir;
- public boolean createInstaller;
- public File distDir;
-
- // building modules
- public String module;
- public BuildSpec() {
- version = DEFAULT_VERSION;
- }
-
- public boolean isProduct() {
- return (Util.canReadDir(productDir));
- }
-
- public boolean isModule() {
- return (!isProduct() && Util.canReadDir(moduleDir));
- }
-
- public boolean isValid() {
- return (isProduct() || isModule());
- }
-
- public String toString() {
- if (null != productDir) {
- return "product " + productDir.getName();
- } else if (null != moduleDir) {
- return "module " + moduleDir.getName();
- } else {
- return "<bad BuildSpec - "
- + " baseDir=" + baseDir
- + " jarDir=" + jarDir
- + " buildConfig=" + buildConfig
- + " module=" + module
- + ">";
- }
- }
-}
-
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC),
- * 2003 Contributors.
- * 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:
- * PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.build;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.apache.tools.ant.BuildException;
-import org.aspectj.internal.tools.build.Result.Kind;
-
-/**
- * Template class to build (eclipse) modules (and, weakly, products), including
- * any required modules. When building modules, this assumes:
- * <ul>
- * <li>the name of the module is the base name of the module directory</li>
- * <li>all module directories are in the same base (workspace) directory</li>
- * <li>the name of the target module jar is {moduleName}.jar</li>
- * <li>a module directory contains a <code>.classpath</code> file with
- * (currently line-parseable) entries per Eclipse (XML) conventions</li>
- * <li><code>Builder.RESOURCE_PATTERN</code> identifies all resources to copy
- * to output.</li>
- * <li>This can safely trim test-related code:
- * <ul>
- * <li>source directories named "testsrc"</li>
- * <li>libraries named "junit.jar"</li>
- * <li>required modules whose names start with "testing"</li>
- * </ul>
- * <li>A file <code>{moduleDir}/{moduleName}.properties</code> is a property
- * file possibly containing entries defining requirements to be merged with the
- * output jar (deprecated mechanism - use assembleAll or products)</li>
- * </ul>
- * This currently provides no control over the compile or assembly process, but
- * clients can harvest <code>{moduleDir}/bin</code> directories to re-use the
- * results of eclipse compiles.
- * <p>
- * When building products, this assumes:
- * <ul>
- * <li>the installer-resources directory is a peer of the products directory,
- * itself the parent of the particular product directory.</li>
- * <li>the dist, jar, product, and base (module) directory are set</li>
- * <li>the product distribution consists of all (and only) the files in the
- * dist sub-directory of the product directory</li>
- * <li>files in the dist sub-directory that are empty and end with .jar
- * represent modules to build, either as named or through aliases known here.</li>
- * <li>When assembling the distribution, all non-binary files are to be
- * filtered.
- * <li>
- * <li>the name of the product installer is
- * aspectj-{productName}-{version}.jar, where {productName} is the base name of
- * the product directory</li>
- * </ul>
- * <p>
- * When run using main(String[]), all relevant Ant libraries and properties must
- * be defined.
- * <p>
- * Written to compile standalone. Refactor if using utils, bridge, etc.
- */
-public abstract class Builder {
-
- /**
- * This has only weak forms for build instructions needed: - resource
- * pattern - compiler selection and control
- *
- * Both assumed and generated paths are scattered; see XXXNameLiteral and
- * XXXFileLiteral.
- *
- * Builder is supposed to be thread-safe, but currently caches build
- * properties to tunnel for filters. hmm.
- */
-
- public static final String RESOURCE_PATTERN;
-
- public static final String BINARY_SOURCE_PATTERN;
-
- public static final String ALL_PATTERN;
-
- /** enable copy filter semantics */
- protected static final boolean FILTER_ON = true;
-
- /** disable copy filter semantics */
- protected static final boolean FILTER_OFF = false;
-
- /** define libraries to skip as comma-delimited values for this key */
- private static final String SKIP_LIBRARIES_KEY = "skip.libraries";
-
- /** List (String) names of libraries to skip during assembly */
- private static final List<String> SKIP_LIBRARIES;
-
- private static final String ERROR_KEY = "error loading properties";
-
- private static final Properties PROPS;
- static {
- PROPS = new Properties();
- List<String> skips = Collections.emptyList();
- String resourcePattern = "**/*.txt,**/*.rsc,**/*.gif,**/*.properties";
- String allPattern = "**/*";
- String binarySourcePattern = "**/*.rsc,**/*.gif,**/*.jar,**/*.zip";
- String name = Builder.class.getName().replace('.', '/') + ".properties";
- try {
- InputStream in = Builder.class.getClassLoader()
- .getResourceAsStream(name);
- PROPS.load(in);
- allPattern = PROPS.getProperty("all.pattern");
- resourcePattern = PROPS.getProperty("resource.pattern");
- binarySourcePattern = PROPS.getProperty("binarySource.pattern");
- skips = commaStrings(PROPS.getProperty(SKIP_LIBRARIES_KEY));
- } catch (Throwable t) {
- if (t instanceof ThreadDeath) {
- throw (ThreadDeath) t;
- }
- String m = "error loading " + name + ": " + t.getClass() + " " + t;
- PROPS.setProperty(ERROR_KEY, m);
- }
- SKIP_LIBRARIES = skips;
- ALL_PATTERN = allPattern;
- BINARY_SOURCE_PATTERN = binarySourcePattern;
- RESOURCE_PATTERN = resourcePattern;
- }
-
- /**
- * Splits strings into an unmodifable <code>List</code> of String using
- * comma as the delimiter and trimming whitespace from the result.
- *
- * @param text
- * <code>String</code> to split.
- * @return unmodifiable List (String) of String delimited by comma in text
- */
- public static List commaStrings(String text) {
- if ((null == text) || (0 == text.length())) {
- return Collections.EMPTY_LIST;
- }
- List<String> strings = new ArrayList<String>();
- StringTokenizer tok = new StringTokenizer(text, ",");
- while (tok.hasMoreTokens()) {
- String token = tok.nextToken().trim();
- if (0 < token.length()) {
- strings.add(token);
- }
- }
- return Collections.unmodifiableList(strings);
- }
-
- /**
- * Map delivered-jar name to created-module name
- *
- * @param jarName
- * the String (lowercased) of the jar/zip to map
- */
- private String moduleAliasFor(String jarName) {
- String result = PROPS.getProperty("alias." + jarName, jarName);
- if (verbose && result.equals(jarName)) {
- String m = "expected alias for " + jarName;
- handler.error(m + PROPS.getProperty(ERROR_KEY, ""));
- }
- return result;
- }
-
- protected final Messager handler;
-
- protected boolean buildingEnabled;
-
- private final File tempDir;
-
- private final ArrayList tempFiles;
-
- private final boolean useEclipseCompiles;
-
- protected boolean verbose;
-
- protected Builder(File tempDir, boolean useEclipseCompiles, Messager handler) {
- Util.iaxIfNull(handler, "handler");
- this.useEclipseCompiles = useEclipseCompiles;
- this.handler = handler;
- this.tempFiles = new ArrayList();
- if ((null == tempDir) || !tempDir.canWrite() || !tempDir.isDirectory()) {
- this.tempDir = Util.makeTempDir("Builder");
- } else {
- this.tempDir = tempDir;
- }
- buildingEnabled = true;
- }
-
- /** tell builder to stop or that it's ok to run */
- public void setBuildingEnabled(boolean enabled) {
- buildingEnabled = enabled;
- }
-
- public void setVerbose(boolean verbose) {
- this.verbose = verbose;
- }
-
- private void verifyBuildSpec(BuildSpec buildSpec) {
- if (null == buildSpec.productDir) { // ensure module properties
- // derive moduleDir from baseDir + module
- if (null == buildSpec.moduleDir) {
- if (null == buildSpec.baseDir) {
- throw new BuildException("require baseDir or moduleDir");
- } else if (null == buildSpec.module) {
- throw new BuildException("require module with baseDir");
- } else {
- if (null == buildSpec.baseDir) {
- buildSpec.baseDir = new File("."); // user.home?
- }
- buildSpec.moduleDir = new File(buildSpec.baseDir,
- buildSpec.module);
- }
- } else if (null == buildSpec.baseDir) {
- // derive baseDir from moduleDir parent
- buildSpec.baseDir = buildSpec.moduleDir.getParentFile();
- // rule: base is parent
- if (null == buildSpec.baseDir) {
- buildSpec.baseDir = new File("."); // user.home?
- }
- handler.log("Builder using derived baseDir: "
- + buildSpec.baseDir);
- }
- Util.iaxIfNotCanReadDir(buildSpec.moduleDir, "moduleDir");
- if (null == buildSpec.module) {
- // derive module name from directory
- buildSpec.module = buildSpec.moduleDir.getName();
- if (null == buildSpec.module) {
- throw new BuildException("no name, even from "
- + buildSpec.moduleDir);
- }
- }
- }
- }
-
- /**
- * Find the Result (and hence Module and Modules) for this BuildSpec.
- */
- protected Result specifyResultFor(BuildSpec buildSpec) {
- if (buildSpec.trimTesting
- && (-1 != buildSpec.module.indexOf("testing"))) { // XXXNameLiteral
- String warning = "Warning - cannot trimTesting for testing modules: ";
- handler.log(warning + buildSpec.module);
- }
- Messager handler = new Messager();
- Modules modules = new Modules(buildSpec.baseDir, buildSpec.jarDir,
- handler);
-
- final Module moduleToBuild = modules.getModule(buildSpec.module);
- Kind kind = Result.kind(buildSpec.trimTesting,
- buildSpec.assembleAll);
- return moduleToBuild.getResult(kind);
- }
-
- public final boolean build(BuildSpec buildSpec) {
- if (!buildingEnabled) {
- return false;
- }
- verifyBuildSpec(buildSpec);
-
- if (null != buildSpec.productDir) {
- return buildProduct(buildSpec);
- }
- Result result = specifyResultFor(buildSpec);
- ArrayList<String> errors = new ArrayList<String>();
- try {
- return buildAll(result, errors);
- } finally {
- if (0 < errors.size()) {
- String label = "error building " + buildSpec + ": ";
- for (Iterator<String> iter = errors.iterator(); iter.hasNext();) {
- String m = label + iter.next();
- handler.error(m);
- }
- }
- }
- }
-
- /**
- * Clean up any temporary files, etc. after build completes
- */
- public boolean cleanup() {
- boolean noErr = true;
- for (ListIterator iter = tempFiles.listIterator(); iter.hasNext();) {
- File file = (File) iter.next();
- if (!Util.deleteContents(file) || !file.delete()) {
- if (noErr) {
- noErr = false;
- }
- handler.log("unable to clean up " + file);
- }
- }
- return noErr;
- }
-
- protected final boolean isLogging() {
- return (verbose && (null != this.handler));
- }
-
- protected Result[] skipUptodate(Result[] results) {
- if (null == results) {
- return new Result[0];
- }
- Result[] done = new Result[results.length];
- int to = 0;
- for (int i = 0; i < done.length; i++) {
- if ((null != results[i]) && results[i].outOfDate()) {
- done[to++] = results[i];
- }
- }
- if (to < results.length) {
- Result[] newdone = new Result[to];
- System.arraycopy(done, 0, newdone, 0, newdone.length);
- done = newdone;
- }
- return done;
- }
-
- /**
- * Build a result with all antecedants.
- *
- * @param result
- * the Result to build
- * @param errors
- * the List sink for errors, if any
- * @return false after successful build, when module jar should exist
- */
- protected final boolean buildAll(Result result, List errors) {
- Result[] buildList = skipUptodate(getAntecedantResults(result));
- ArrayList<String> doneList = new ArrayList<String>();
- if ((null != buildList) && (0 < buildList.length)) {
- if (isLogging()) {
- handler.log("modules to build: " + Arrays.asList(buildList));
- }
- for (int i = 0; i < buildList.length; i++) {
- Result required = buildList[i];
- if (!buildingEnabled) {
- return false;
- }
- String requiredName = required.getName();
- if (!doneList.contains(requiredName)) {
- doneList.add(requiredName);
- if (!buildOnly(required, errors)) {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /**
- * Build a module but no antecedants.
- *
- * @param module
- * the Module to build
- * @param errors
- * the List sink for errors, if any
- * @return false after successful build, when module jar should exist
- */
- protected final boolean buildOnly(Result result, List<String> errors) {
- if (!result.outOfDate()) {
- return true;
- }
- if (isLogging()) {
- handler.log("building " + result);
- }
- if (!buildingEnabled) {
- return false;
- }
- if (result.getKind().assemble) {
- return assembleAll(result, handler);
- }
- Module module = result.getModule();
- final File classesDir;
- if (useEclipseCompiles) {
- classesDir = new File(module.moduleDir, "bin"); // FileLiteral
- } else {
- String name = "classes-" + System.currentTimeMillis();
- classesDir = new File(tempDir, name);
- }
- if (verbose) {
- handler.log("buildOnly " + module);
- }
- try {
- return (compile(result, classesDir,useEclipseCompiles, errors))
- && assemble(result, classesDir, errors);
- } finally {
- if (!useEclipseCompiles && !Util.delete(classesDir)) {
- errors.add("buildOnly unable to delete " + classesDir);
- }
- }
- }
-
- /**
- * Register temporary file or directory to be deleted when the build is
- * complete, even if an Exception is thrown.
- */
- protected void addTempFile(File tempFile) {
- if (null != tempFile) {
- tempFiles.add(tempFile);
- }
- }
-
- /**
- * Build product by discovering any modules to build, building those,
- * assembling the product distribution, and optionally creating an installer
- * for it.
- *
- * @return true on success
- */
- protected final boolean buildProduct(BuildSpec buildSpec)
- throws BuildException {
- Util.iaxIfNull(buildSpec, "buildSpec");
-
- if (!buildSpec.trimTesting) {
- buildSpec.trimTesting = true;
- handler.log("testing trimmed for " + buildSpec);
- }
- Util.iaxIfNotCanReadDir(buildSpec.productDir, "productDir");
- Util.iaxIfNotCanReadDir(buildSpec.baseDir, "baseDir");
- Util.iaxIfNotCanWriteDir(buildSpec.distDir, "distDir");
-
- // ---- discover modules to build, and build them
- Modules modules = new Modules(buildSpec.baseDir, buildSpec.jarDir,
- handler);
- ProductModule[] productModules = discoverModules(buildSpec.productDir,
- modules);
- for (int i = 0; i < productModules.length; i++) {
- if (buildSpec.verbose) {
- handler.log("building product module " + productModules[i]);
- }
- if (!buildProductModule(productModules[i])) {
- return false;
- }
- }
- if (buildSpec.verbose) {
- handler.log("assembling product module for " + buildSpec);
- }
-
- // ---- assemble product distribution
- final String productName = buildSpec.productDir.getName();
- final File targDir = new File(buildSpec.distDir, productName);
- final String targDirPath = targDir.getPath();
- if (targDir.canWrite()) {
- Util.deleteContents(targDir);
- }
-
- if (!targDir.canWrite() && !targDir.mkdirs()) {
- if (buildSpec.verbose) {
- handler.log("buildProduct unable to create " + targDir);
- }
- return false;
- }
-
- // copy non-binaries (with filter)
- File distDir = new File(buildSpec.productDir, "dist");
- if (!copyNonBinaries(buildSpec, distDir, targDir)) {
- return false;
- }
-
- // copy binaries (but not module flag files)
- String excludes = null;
- {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < productModules.length; i++) {
- if (0 < buf.length()) {
- buf.append(",");
- }
- buf.append(productModules[i].relativePath);
- }
- if (0 < buf.length()) {
- excludes = buf.toString();
- }
- }
-
- if (!copyBinaries(buildSpec, distDir, targDir, excludes)) {
- return false;
- }
-
- // copy binaries associated with module flag files
- for (int i = 0; i < productModules.length; i++) {
- final ProductModule product = productModules[i];
- final Kind kind = Result.kind(Result.NORMAL, product.assembleAll);
- Result result = product.module.getResult(kind);
- String targPath = Util.path(targDirPath, product.relativePath);
- File jarFile = result.getOutputFile();
- copyFile(jarFile, new File(targPath), FILTER_OFF);
- }
- handler.log("created product in " + targDir);
-
- // ---- create installer
- if (buildSpec.createInstaller) {
- return buildInstaller(buildSpec, targDirPath);
- } else {
- return true;
- }
- }
-
- protected boolean copyBinaries(BuildSpec buildSpec, File distDir,
- File targDir, String excludes) {
- String includes = Builder.BINARY_SOURCE_PATTERN;
- return copyFiles(distDir, targDir, includes, excludes, FILTER_OFF);
- }
-
- /**
- * filter-copy everything but the binaries
- */
- protected boolean copyNonBinaries(BuildSpec buildSpec, File distDir,
- File targDir) {
- String excludes = Builder.BINARY_SOURCE_PATTERN;
- String includes = Builder.ALL_PATTERN;
- return copyFiles(distDir, targDir, includes, excludes, FILTER_ON);
- }
-
- protected final boolean buildProductModule(ProductModule module) {
- ArrayList errors = new ArrayList();
- try {
- Kind productKind = Result.kind(Result.NORMAL, Result.ASSEMBLE);
- Result result = module.module.getResult(productKind);
- return buildAll(result, errors);
- } finally {
- for (Iterator iter = errors.iterator(); iter.hasNext();) {
- handler.error("error building " + module + ": " + iter.next());
- }
- }
- }
-
- /**
- * Discover any modules that might need to be built in order to assemble the
- * product distribution. This interprets empty .jar files as module
- * deliverables.
- */
- protected ProductModule[] discoverModules(File productDir, Modules modules) {
- final ArrayList<File> found = new ArrayList<File>();
- FileFilter filter = new FileFilter() {// empty jar files
- public boolean accept(File file) {
- if ((null != file) && file.canRead()
- && file.getPath().endsWith(".jar") // XXXFileLiteral
- && (0l == file.length())) {
- found.add(file);
- }
- return true;
- }
- };
- Util.visitFiles(productDir, filter);
- ArrayList<ProductModule> results = new ArrayList<ProductModule>();
- for (File file: found) {
- String jarName = moduleAliasFor(file.getName().toLowerCase());
- if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) { // XXXFileLiteral
- jarName = jarName.substring(0, jarName.length() - 4);
- } else {
- handler.log("can only replace .[jar|zip]: " + file);
- // XXX error?
- }
- boolean assembleAll = jarName.endsWith("-all");
- // XXXFileLiteral
- String name = (!assembleAll ? jarName : jarName.substring(0,
- jarName.length() - 4));
- Module module = modules.getModule(name);
- if (null == module) {
- handler.log("unable to find module for " + file);
- } else {
- results.add(new ProductModule(productDir, file, module,
- assembleAll));
- }
- }
- return (ProductModule[]) results.toArray(new ProductModule[0]);
- }
-
- /**
- * Subclasses should query whether to include library files in the assembly.
- *
- * @param module
- * the Module being built
- * @param libraries
- * the List of File path to the jar to consider assembling
- * @return true if the jar should be included, false otherwise.
- */
- protected void removeLibraryFilesToSkip(Module module, List libraries) {
- for (ListIterator liter = libraries.listIterator(); liter.hasNext();) {
- File library = (File) liter.next();
- final String fname = library.getName();
- if (null != fname) {
- for (Iterator iter = SKIP_LIBRARIES.iterator(); iter.hasNext();) {
- String name = (String) iter.next();
- if (fname.equals(name)) {
- liter.remove();
- break;
- }
- }
- }
- }
- }
-
- /**
- * @return String[] names of results to build for this module
- */
- abstract protected Result[] getAntecedantResults(Result toBuild);
-
- /**
- * Compile module classes to classesDir, saving String errors.
- *
- * @param module
- * the Module to compile
- * @param classesDir
- * the File directory to compile to
- * @param useExistingClasses
- * if true, don't recompile and ensure classes are available
- * @param errors
- * the List to add error messages to
- */
- abstract protected boolean compile(Result result, File classesDir,
- boolean useExistingClasses, List<String> errors);
-
- /**
- * Assemble the module distribution from the classesDir, saving String
- * errors.
- *
- * @see #removeLibraryFilesToSkip(Module, File)
- */
- abstract protected boolean assemble(Result result, File classesDir,
- List<String> errors);
-
- /**
- * Assemble the module distribution from the classesDir and all
- * antecendants, saving String errors.
- *
- * @see #removeLibraryFilesToSkip(Module, File)
- */
- abstract protected boolean assembleAll(Result result, Messager handler);
-
- /**
- * Generate the installer for this product to targDirPath
- */
- abstract protected boolean buildInstaller(BuildSpec buildSpec,
- String targDirPath);
-
- /**
- * Copy fromFile to toFile, optionally filtering contents
- */
- abstract protected boolean copyFile(File fromFile, File toFile,
- boolean filter);
-
- /**
- * Copy toDir any fromDir included files without any exluded files,
- * optionally filtering contents.
- *
- * @param fromDir
- * File dir to read from - error if not readable
- * @param toDir
- * File dir to write to - error if not writable
- * @param included
- * String Ant pattern of included files (if null, include all)
- * @param excluded
- * String Ant pattern of excluded files (if null, exclude none)
- * @param filter
- * if FILTER_ON, then filter file contents using global
- * token/value pairs
- */
- abstract protected boolean copyFiles(File fromDir, File toDir,
- String included, String excluded, boolean filter);
-}
+++ /dev/null
-# documented in build/readme-build-module.html
-
-# alias product/dist/lib/{name} to project jar
-# used by Builder.moduleAliasFor(String)
-alias.aspectjtools.jar=ajbrowser-all.jar
-alias.aspectjrt.jar=aspectj5rt-all.jar
-alias.aspectjweaver.jar=loadtime5-all.jar
-# alias.aspectjlib.jar=org.aspectj.lib.jar
-alias.org.aspectj.matcher.jar=org.aspectj.matcher-all.jar
-
-# libraries to avoid bundling (IBM JRE different, etc.)
-# see build/readme-build-module.html, Builder.SKIP_LIBRARIES
-skip.libraries=asm-3.1.jar,core.jar,graphics.jar,ant.jar,tools.jar,bcel-verifier.jar,asm-3.1.jar,junit.jar,xml-apis.jar,xercesImpl.jar,commons.jar,jrockit.jar
-
-# Ant patterns to gather and omit resources
-# files copied during module jar assembly
-resource.pattern=**/*.txt,**/*.rsc,**/*.gif,**/*.properties,**/*.xml,**/*.dtd
-# files not filtered when copied during product assembly
-binarySource.pattern=**/*.rsc,**/*.gif,**/*.jar,**/*.zip
-all.pattern=**/*
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.build;
-
-/** logging stub XXX replace */
-public class Messager {
- public Messager() {
- }
- public boolean log(String s) {
- System.out.println(s);
- return true;
- }
-
- public boolean error(String s) {
- System.out.println(s);
- return true;
- }
-
- public boolean logException(String context, Throwable thrown) {
- System.err.println(context);
- thrown.printStackTrace(System.err);
- return true;
- }
-}
-
-
-
-
-
-
-
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.build;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.aspectj.internal.tools.build.Result.Kind;
-import org.aspectj.internal.tools.build.Util.OSGIBundle;
-import org.aspectj.internal.tools.build.Util.OSGIBundle.RequiredBundle;
-
-
-/**
- * This represents an (eclipse) build module/unit used by a Builder to compile
- * classes and/or assemble zip file of classes, optionally with all antecedants.
- * This implementation infers attributes from two files in the module directory:
- * <ul>
- * <li>an Eclipse project <code>.classpath</code> file containing required
- * libraries and modules (collectively, "antecedants") </li>
- * <li>a file <code>{moduleName}.mf.txt</code> is taken as the manifest of
- * any .jar file produced, after filtering. </li>
- * </ul>
- *
- * @see Builder
- * @see Modules#getModule(String)
- */
-public class Module {
- private static final String[] ATTS = new String[] { "exported", "kind",
- "path", "sourcepath" };
-
-// private static final int getATTSIndex(String key) {
-// for (int i = 0; i < ATTS.length; i++) {
-// if (ATTS[i].equals(key))
-// return i;
-// }
-// return -1;
-// }
-
- /**
- * @return true if file is null or cannot be read or was last modified after
- * time
- */
- private static boolean outOfDate(long time, File file) {
- return ((null == file) || !file.canRead() || (file.lastModified() > time));
- }
-
- /** @return all source files under srcDir */
- private static Iterator<File> sourceFiles(File srcDir) {
- ArrayList<File> result = new ArrayList<File>();
- sourceFiles(srcDir, result);
- return result.iterator();
- }
-
- private static void sourceFiles(File srcDir, List<File> result) {
- if ((null == srcDir) || !srcDir.canRead() || !srcDir.isDirectory()) {
- return;
- }
- File[] files = srcDir.listFiles();
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- sourceFiles(files[i], result);
- } else if (isSourceFile(files[i])) {
- result.add(files[i]);
- }
- }
- }
-
- private static void addIfNew(List<File> source, List<File> sink) {
- for (File item: source) {
- if (!sink.contains(item)) {
- sink.add(item);
- }
- }
- }
-
- /**
- * Recursively find antecedant jars.
- *
- * @see findKnownJarAntecedants()
- */
- static void doFindJarRequirements(Result result, List<File> known) {
- Util.iaxIfNull(result, "result");
- Util.iaxIfNull(known, "known");
- addIfNew(result.getLibJars(), known);
- addIfNew(result.getExportedLibJars(), known);
- Result[] reqs = result.getRequired();
- for (int i = 0; i < reqs.length; i++) {
- Result requiredResult = reqs[i];
- File requiredJar = requiredResult.getOutputFile();
- if (!known.contains(requiredJar)) {
- known.add(requiredJar);
- doFindJarRequirements(requiredResult, known);
- }
- }
- }
-
- /** @return true if this is a source file */
- private static boolean isSourceFile(File file) {
- String path = file.getPath();
- return (path.endsWith(".java") || path.endsWith(".aj")); // XXXFileLiteral
- }
-
-// /** @return List of File of any module or library jar ending with suffix */
-// private static ArrayList findJarsBySuffix(String suffix, Kind kind,
-// List libJars, List required) {
-// ArrayList result = new ArrayList();
-// if (null != suffix) {
-// // library jars
-// for (Iterator iter = libJars.iterator(); iter.hasNext();) {
-// File file = (File) iter.next();
-// if (file.getPath().endsWith(suffix)) {
-// result.add(file);
-// }
-// }
-// // module jars
-// for (Iterator iter = required.iterator(); iter.hasNext();) {
-// Module module = (Module) iter.next();
-// Result moduleResult = module.getResult(kind);
-// File file = moduleResult.getOutputFile();
-// if (file.getPath().endsWith(suffix)) {
-// result.add(file);
-// }
-// }
-// }
-// return result;
-// }
-
- public final boolean valid;
-
- public final File moduleDir;
-
- public final String name;
-
- /** reference back to collection for creating required modules */
- private final Modules modules;
-
- private final Result release;
-
- private final Result test;
-
- private final Result testAll;
-
- private final Result releaseAll;
-
- /** path to output jar - may not exist */
- private final File moduleJar;
-
- /** File list of library jars */
- private final List<File> libJars;
-
- /** List of classpath variables */
- private final List<String> classpathVariables;
-
- /**
- * List of library jars exported to clients (duplicates some libJars
- * entries)
- */
- private final List<File> exportedLibJars;
-
- /** File list of source directories */
- private final List<File> srcDirs;
-
- /** properties from the modules {name}.properties file */
- private final Properties properties;
-
- /** List of required modules */
- private final List<Module> requiredModules;
-
- /** logger */
- private final Messager messager;
-
- Module(File moduleDir, File jarDir, String name, Modules modules,
- Messager messager) {
- Util.iaxIfNotCanReadDir(moduleDir, "moduleDir");
- Util.iaxIfNotCanReadDir(jarDir, "jarDir");
- Util.iaxIfNull(name, "name");
- Util.iaxIfNull(modules, "modules");
- this.moduleDir = moduleDir;
- this.libJars = new ArrayList<File>();
- this.exportedLibJars = new ArrayList<File>();
- this.requiredModules = new ArrayList<Module>();
- this.srcDirs = new ArrayList<File>();
- this.classpathVariables = new ArrayList<String>();
- this.properties = new Properties();
- this.name = name;
- this.modules = modules;
- this.messager = messager;
- this.moduleJar = new File(jarDir, name + ".jar");
- this.release = new Result(Result.RELEASE, this, jarDir);
- this.releaseAll = new Result(Result.RELEASE_ALL, this, jarDir);
- this.test = new Result(Result.TEST, this, jarDir);
- this.testAll = new Result(Result.TEST_ALL, this, jarDir);
- valid = init();
- }
-
-
- /** @return Modules registry of known modules, including this one */
- public Modules getModules() {
- return modules;
- }
-
- /**
- * @param kind
- * the Kind of the result to recalculate
- * @param recalculate
- * if true, then force recalculation
- * @return true if the target jar for this module is older than any source
- * files in a source directory or any required modules or any
- * libraries or if any libraries or required modules are missing
- */
- public static boolean outOfDate(Result result) {
- File outputFile = result.getOutputFile();
- if (!(outputFile.exists() && outputFile.canRead())) {
- return true;
- }
- final long time = outputFile.lastModified();
- File file;
- for (Iterator<File> iter = result.getSrcDirs().iterator(); iter.hasNext();) {
- File srcDir = iter.next();
- for (Iterator<File> srcFiles = sourceFiles(srcDir); srcFiles.hasNext();) {
- file = srcFiles.next();
- if (outOfDate(time, file)) {
- return true;
- }
- }
- }
- // required modules
- Result[] reqs = result.getRequired();
- for (int i = 0; i < reqs.length; i++) {
- Result requiredResult = reqs[i];
- file = requiredResult.getOutputFile();
- if (outOfDate(time, file)) {
- return true;
- }
- }
- // libraries
- for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
- file = (File) iter.next();
- if (outOfDate(time, file)) {
- return true;
- }
- }
- return false;
- }
-
-
-
- public String toString() {
- return name;
- }
-
- public String toLongString() {
- return "Module [name=" + name + ", srcDirs=" + srcDirs + ", required="
- + requiredModules + ", moduleJar=" + moduleJar + ", libJars="
- + libJars + "]";
- }
-
- public Result getResult(Kind kind) {
- return kind.assemble ? (kind.normal ? releaseAll : testAll)
- : (kind.normal ? release : test);
- }
-
- List<File> srcDirs(Result result) {
- myResult(result);
- return srcDirs;
- }
-
- List<File> libJars(Result result) {
- myResult(result);
- return libJars;
- }
-
- List<String> classpathVariables(Result result) {
- myResult(result);
- return classpathVariables;
- }
-
- List<File> exportedLibJars(Result result) {
- myResult(result);
- return exportedLibJars;
- }
-
- List<Module> requiredModules(Result result) {
- myResult(result);
- return requiredModules;
- }
-
- private void myResult(Result result) {
- if ((null == result) || this != result.getModule()) {
- throw new IllegalArgumentException("not my result: " + result + ": " + this);
- }
- }
-
- private boolean init() {
- boolean cp = initClasspath();
- boolean mf = initManifest();
- if (!cp && !mf) {
- return false;
- }
- return initProperties() && reviewInit() && initResults();
- }
-
- /** read OSGI manifest.mf file XXX hacked */
- private boolean initManifest() {
- File metaInf = new File(moduleDir, "META-INF");
- if (!metaInf.canRead() || !metaInf.isDirectory()) {
- return false;
- }
- File file = new File(metaInf, "MANIFEST.MF"); // XXXFileLiteral
- if (!file.exists()) {
- return false; // ok, not OSGI
- }
- InputStream fin = null;
- OSGIBundle bundle = null;
- try {
- fin = new FileInputStream(file);
- bundle = new OSGIBundle(fin);
- } catch (IOException e) {
- messager.logException("IOException reading " + file, e);
- return false;
- } finally {
- Util.closeSilently(fin);
- }
- RequiredBundle[] bundles = bundle.getRequiredBundles();
- for (int i = 0; i < bundles.length; i++) {
- RequiredBundle required = bundles[i];
- update("src", "/" + required.name, required.text, false);
- }
- String[] libs = bundle.getClasspath();
- for (int i = 0; i < libs.length; i++) {
- update("lib", libs[i], libs[i], false);
- }
-
- return true;
- }
-
- /** read eclipse .classpath file XXX line-oriented hack */
- private boolean initClasspath() {
- // meaning testsrc directory, junit library, etc.
- File file = new File(moduleDir, ".classpath"); // XXXFileLiteral
- if (!file.exists()) {
- return false; // OSGI???
- }
- FileReader fin = null;
- try {
- fin = new FileReader(file);
- BufferedReader reader = new BufferedReader(fin);
- String line;
- XMLItem item = new XMLItem("classpathentry", new ICB());
- while (null != (line = reader.readLine())) {
- line = line.trim();
- // dumb - only handle comment-only lines
- if (!line.startsWith("<?xml") && !line.startsWith("<!--")) {
- item.acceptLine(line);
- }
- }
- return (0 < (srcDirs.size() + libJars.size()));
- } catch (IOException e) {
- messager.logException("IOException reading " + file, e);
- } finally {
- if (null != fin) {
- try {
- fin.close();
- } catch (IOException e) {
- } // ignore
- }
- }
- return false;
- }
-
-// private boolean update(String toString, String[] attributes) {
-// String kind = attributes[getATTSIndex("kind")];
-// String path = attributes[getATTSIndex("path")];
-// String exp = attributes[getATTSIndex("exported")];
-// boolean exported = ("true".equals(exp));
-// return update(kind, path, toString, exported);
-// }
-
- private boolean update(String kind, String path, String toString,
- boolean exported) {
- String libPath = null;
- if ("src".equals(kind)) {
- if (path.startsWith("/")) { // module
- String moduleName = path.substring(1);
- Module req = modules.getModule(moduleName);
- if (null != req) {
- requiredModules.add(req);
- return true;
- } else {
- messager.error("update unable to create required module: "
- + moduleName);
- }
- } else { // src dir
- String fullPath = getFullPath(path);
- File srcDir = new File(fullPath);
- if (srcDir.canRead() && srcDir.isDirectory()) {
- srcDirs.add(srcDir);
- return true;
- } else {
- messager.error("not a src dir: " + srcDir);
- }
- }
- } else if ("lib".equals(kind)) {
- libPath = path;
- } else if ("var".equals(kind)) {
- final String JAVA_HOME = "JAVA_HOME/";
- if (path.startsWith(JAVA_HOME)) {
- path = path.substring(JAVA_HOME.length());
- String home = System.getProperty("java.home");
- if (null != home) {
- libPath = Util.path(home, path);
- File f = new File(libPath);
- if (!f.exists() && home.endsWith("jre")) {
- f = new File(home).getParentFile();
- libPath = Util.path(f.getPath(), path);
- }
- }
- }
- if (null == libPath) {
- warnVariable(path, toString);
- classpathVariables.add(path);
- }
- } else if ("con".equals(kind)) {
- // 'special' for container pointing at AspectJ runtime...
- if (path.equals("org.eclipse.ajdt.core.ASPECTJRT_CONTAINER")) {
- classpathVariables.add("ASPECTJRT_LIB");
- } else {
- if (-1 == path.indexOf("JRE")) { // warn non-JRE containers
- messager.log("cannot handle con yet: " + toString);
- }
- }
- } else if ("out".equals(kind) || "output".equals(kind)) {
- // ignore output entries
- } else {
- messager.log("unrecognized kind " + kind + " in " + toString);
- }
- if (null != libPath) {
- File libJar = new File(libPath);
- if (!libJar.exists()) {
- libJar = new File(getFullPath(libPath));
- }
- if (libJar.canRead() && libJar.isFile()) {
- libJars.add(libJar);
- if (exported) {
- exportedLibJars.add(libJar);
- }
- return true;
- } else {
- messager.error("no such library jar " + libJar + " from "
- + toString);
- }
- }
- return false;
- }
-
- private void warnVariable(String path, String toString) {
- String[] known = { "JRE_LIB", "ASPECTJRT_LIB", "JRE15_LIB" };
- for (int i = 0; i < known.length; i++) {
- if (known[i].equals(path)) {
- return;
- }
- }
- messager.log("Module cannot handle var yet: " + toString);
- }
-
- /** @return true if any properties were read correctly */
- private boolean initProperties() {
- File file = new File(moduleDir, name + ".properties"); // XXXFileLiteral
- if (!Util.canReadFile(file)) {
- return true; // no properties to read
- }
- FileInputStream fin = null;
- try {
- fin = new FileInputStream(file);
- properties.load(fin);
- return true;
- } catch (IOException e) {
- messager.logException("IOException reading " + file, e);
- return false;
- } finally {
- if (null != fin) {
- try {
- fin.close();
- } catch (IOException e) {
- } // ignore
- }
- }
- }
-
- /**
- * Post-process initialization. This implementation trims java5 source dirs
- * if not running in a Java 5 VM.
- * @return true if initialization post-processing worked
- */
- protected boolean reviewInit() {
- try {
- for (ListIterator iter = srcDirs.listIterator(); iter.hasNext();) {
- File srcDir = (File) iter.next();
- String lcname = srcDir.getName().toLowerCase();
- if (!Util.JAVA5_VM
- && (Util.Constants.JAVA5_SRC.equals(lcname) || Util.Constants.JAVA5_TESTSRC
- .equals(lcname))) {
- // assume optional for pre-1.5 builds
- iter.remove();
- }
- }
- } catch (UnsupportedOperationException e) {
- return false; // failed XXX log also if verbose
- }
- return true;
- }
-
- /**
- * After reviewInit, setup four kinds of results.
- */
- protected boolean initResults() {
- return true; // results initialized lazily
- }
-
- /** resolve path absolutely, assuming / means base of modules dir */
- public String getFullPath(String path) {
- String fullPath;
- if (path.startsWith("/")) {
- fullPath = modules.baseDir.getAbsolutePath() + path;
- } else {
- fullPath = moduleDir.getAbsolutePath() + "/" + path;
- }
- // check for absolute paths (untested - none in our modules so far)
- File testFile = new File(fullPath);
- // System.out.println("Module.getFullPath: " + fullPath + " - " +
- // testFile.getAbsolutePath());
- if (!testFile.exists()) {
- testFile = new File(path);
- if (testFile.exists() && testFile.isAbsolute()) {
- fullPath = path;
- }
- }
- return fullPath;
- }
-
- class ICB implements XMLItem.ICallback {
- public void end(Properties attributes) {
- String kind = attributes.getProperty("kind");
- String path = attributes.getProperty("path");
- String exp = attributes.getProperty("exported");
- boolean exported = ("true".equals(exp));
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- attributes.list(new PrintStream(bout));
- update(kind, path, bout.toString(), exported);
- }
- }
-
- public static class XMLItem {
- public interface ICallback {
- void end(Properties attributes);
- }
-
- static final String START_NAME = "classpathentry";
-
- static final String ATT_STARTED = "STARTED";
-
- final ICallback callback;
-
- final StringBuffer input = new StringBuffer();
-
- final String[] attributes = new String[ATTS.length];
-
- final String targetEntity;
-
- String entityName;
-
- String attributeName;
-
- XMLItem(String targetEntity, ICallback callback) {
- this.callback = callback;
- this.targetEntity = targetEntity;
- reset();
-
- }
-
- private void reset() {
- input.setLength(0);
- for (int i = 0; i < attributes.length; i++) {
- attributes[i] = null;
- }
- entityName = null;
- attributeName = null;
- }
-
- String[] tokenize(String line) {
- final String DELIM = " \n\t\\<>\"=";
- StringTokenizer st = new StringTokenizer(line, DELIM, true);
- ArrayList<String> result = new ArrayList<String>();
- StringBuffer quote = new StringBuffer();
- boolean inQuote = false;
- while (st.hasMoreTokens()) {
- String s = st.nextToken();
- if ((1 == s.length()) && (-1 != DELIM.indexOf(s))) {
- if ("\"".equals(s)) { // end quote (or escaped)
- if (inQuote) {
- inQuote = false;
- quote.append("\"");
- result.add(quote.toString());
- quote.setLength(0);
- } else {
- quote.append("\"");
- inQuote = true;
- }
- } else {
- result.add(s);
- }
- } else { // not a delimiter
- if (inQuote) {
- quote.append(s);
- } else {
- result.add(s);
- }
- }
- }
- return (String[]) result.toArray(new String[0]);
- }
-
- public void acceptLine(String line) {
- String[] tokens = tokenize(line);
- for (int i = 0; i < tokens.length; i++) {
- next(tokens[i]);
- }
- }
-
- private Properties attributesToProperties() {
- Properties result = new Properties();
- for (int i = 0; i < attributes.length; i++) {
- String a = attributes[i];
- if (null != a) {
- result.setProperty(ATTS[i], a);
- }
- }
- return result;
- }
-
- void errorIfNotNull(String name, String value) {
- if (null != value) {
- error("Did not expect " + name + ": " + value);
- }
- }
-
- void errorIfNull(String name, String value) {
- if (null == value) {
- error("expected value for " + name);
- }
- }
-
- boolean activeEntity() {
- return targetEntity.equals(entityName);
- }
-
- /**
- * Assumes that comments and "<?xml"-style lines are removed.
- */
- public void next(String s) {
- if ((null == s) || (0 == s.length())) {
- return;
- }
- input.append(s);
- s = s.trim();
- if (0 == s.length()) {
- return;
- }
- if ("<".equals(s)) {
- errorIfNotNull("entityName", entityName);
- errorIfNotNull("attributeName", attributeName);
- } else if (">".equals(s)) {
- errorIfNull("entityName", entityName);
- if ("/".equals(attributeName)) {
- attributeName = null;
- } else {
- errorIfNotNull("attributeName", attributeName);
- }
- if (activeEntity()) {
- callback.end(attributesToProperties());
- }
- entityName = null;
- } else if ("=".equals(s)) {
- errorIfNull("entityName", entityName);
- errorIfNull("attributeName", attributeName);
- } else if (s.startsWith("\"")) {
- errorIfNull("entityName", entityName);
- errorIfNull("attributeName", attributeName);
- writeAttribute(attributeName, s);
- attributeName = null;
- } else {
- if (null == entityName) {
- reset();
- entityName = s;
- } else if (null == attributeName) {
- attributeName = s;
- } else {
- System.out
- .println("unknown state - not value, attribute, or entity: "
- + s);
- }
- }
- }
-
- void readAttribute(String s) {
- for (int i = 0; i < ATTS.length; i++) {
- if (s.equals(ATTS[i])) {
- attributes[i] = ATT_STARTED;
- break;
- }
- }
- }
-
- void writeAttribute(String name, String value) {
- for (int i = 0; i < ATTS.length; i++) {
- if (name.equals(ATTS[i])) {
- if (!value.startsWith("\"") || !value.endsWith("\"")) {
- error("bad attribute value: " + value);
- }
- value = value.substring(1, value.length() - 1);
- attributes[i] = value;
- return;
- }
- }
- }
-
- void error(String s) {
- throw new Error(s + " at input " + input);
- }
- }
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.build;
-
-import java.io.File;
-import java.util.Hashtable;
-
-/**
- * Registration and factory for modules
- * @see Module
- * @see Builder
- */
-public class Modules {
-
- private final Hashtable<String,Module> modules = new Hashtable<String,Module>();
- public final File baseDir;
- public final File jarDir;
- private final Messager handler;
-
- public Modules(File baseDir, File jarDir, Messager handler) {
- this.baseDir = baseDir;
- this.jarDir = jarDir;
- this.handler = handler;
- Util.iaxIfNotCanReadDir(baseDir, "baseDir");
- Util.iaxIfNotCanReadDir(jarDir, "jarDir");
- Util.iaxIfNull(handler, "handler");
- }
-
-
- /**
- * Get module associated with name.
- * @return fail if unable to find or create module {name}.
- */
- public Module getModule(String name) {
- if (null == name) {
- return null;
- }
- Module result = (Module) modules.get(name);
- if (null == result) {
- File moduleDir = new File(baseDir, name);
- if (!Util.canReadDir(moduleDir)) {
- handler.error("not a module: " + name);
- } else {
- result = new Module(moduleDir, jarDir, name, this, handler);
- if (result.valid) {
- modules.put(name, result);
- } else {
- handler.error("invalid module: " + result.toLongString());
- }
- }
- }
- return result;
- }
-}
\ No newline at end of file
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-package org.aspectj.internal.tools.build;
-
-import java.io.File;
-
-/**
- * Struct associating module with target product distribution jar
- * and assembly instructions.
- * When building product distributions, a zero-length jar file
- * in the dist directory may signify a module to be built,
- * renamed, and included in the distribution.
- */
-public class ProductModule {
- /** name of distribution directory in product directory */
- private static final String DIST = "dist";
-
- /** top-level product directory being produced */
- public final File productDir;
-
- /** path to file in distribution template dir for this module jar */
- public final File replaceFile;
-
- /** relative path within distribution of this product module jar */
- public final String relativePath;
-
- /** the module jar is the file to replace */
- public final Module module;
-
- /** if true, assemble all when building module */
- public final boolean assembleAll;
-
- public ProductModule(File productDir, File replaceFile, Module module, boolean assembleAll) {
- this.replaceFile = replaceFile;
- this.module = module;
- this.productDir = productDir;
- this.assembleAll = assembleAll;
- Util.iaxIfNull(module, "module");
- Util.iaxIfNotCanReadDir(productDir, "productDir");
- Util.iaxIfNotCanReadFile(replaceFile, "replaceFile");
- String productDirPath = productDir.getAbsolutePath();
- String replaceFilePath = replaceFile.getAbsolutePath();
- if (!replaceFilePath.startsWith(productDirPath)) {
- String m = "\"" + replaceFilePath
- + "\" does not start with \""
- + productDirPath
- + "\"";
- throw new IllegalArgumentException(m);
- }
- replaceFilePath = replaceFilePath.substring(1+productDirPath.length());
- if (!replaceFilePath.startsWith(DIST)) {
- String m = "\"" + replaceFilePath
- + "\" does not start with \"" + DIST + "\"";
- throw new IllegalArgumentException(m);
- }
- relativePath = replaceFilePath.substring(1 + DIST.length());
- }
- public String toString() {
- return "" + module + " for " + productDir;
- }
-}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2005 Contributors.
- * 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://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wes Isberg initial implementation
- * ******************************************************************/
-
-package org.aspectj.internal.tools.build;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * Represents a prospective build result and any requirements for it. Used for
- * [testing|normal][jar|assembled-jar|classesDir?].
- */
-public class Result {
- public static final boolean NORMAL = true;
-
- public static final boolean ASSEMBLE = true;
-
- static final Kind RELEASE = new Kind("RELEASE", NORMAL, !ASSEMBLE);
-
- static final Kind RELEASE_ALL = new Kind("RELEASE_ALL", NORMAL, ASSEMBLE);
-
- static final Kind TEST = new Kind("TEST", !NORMAL, !ASSEMBLE);
-
- static final Kind TEST_ALL = new Kind("TEST_ALL", !NORMAL, ASSEMBLE);
-
- private static final Kind[] KINDS = { RELEASE, TEST, RELEASE_ALL, TEST_ALL };
-
- private static final HashMap<String,Result> nameToResult = new HashMap<String, Result>();
-
- public static boolean isTestingJar(String name) {
- name = name.toLowerCase();
- return "junit.jar".equals(name);
- }
-
- public static boolean isTestingDir(String name) {
- name = name.toLowerCase();
- return (Util.Constants.TESTSRC.equals(name) || Util.Constants.JAVA5_TESTSRC
- .equals(name));
- }
-
- public static boolean isTestingModule(Module module) {
- String name = module.name.toLowerCase();
- return name.startsWith("testing") || "tests".equals(name);
- }
-
- public static synchronized Result getResult(String name) {
- if (null == name) {
- throw new IllegalArgumentException("null name");
- }
- return (Result) nameToResult.get(name);
- }
-
- public static Result[] getResults(String[] names) {
- if (null == names) {
- return new Result[0];
- }
- Result[] results = new Result[names.length];
-
- for (int i = 0; i < results.length; i++) {
- String name = names[i];
- if (null == name) {
- String m = "no name at " + i + ": " + Arrays.asList(names);
- throw new IllegalArgumentException(m);
- }
- Result r = Result.getResult(name);
- if (null == r) {
- String m = "no result [" + i + "]: " + name + ": "
- + Arrays.asList(names);
- throw new IllegalArgumentException(m);
- }
- results[i] = r;
- }
- return results;
-
- }
-
- public static Kind[] KINDS() {
- Kind[] result = new Kind[KINDS.length];
- System.arraycopy(KINDS, 0, result, 0, result.length);
- return result;
- }
-
- public static void iaxUnlessNormal(Result result) {
- if ((null == result) || !result.getKind().normal) {
- throw new IllegalArgumentException("not normal: " + result);
- }
- }
-
- public static void iaxUnlessAssembly(Result result) {
- if ((null == result) || !result.getKind().assemble) {
- throw new IllegalArgumentException("not assembly: " + result);
- }
- }
-
- public static Kind kind(boolean normal, boolean assemble) {
- return (normal == NORMAL ? (assemble == ASSEMBLE ? RELEASE_ALL
- : RELEASE) : (assemble == ASSEMBLE ? TEST_ALL : TEST));
- }
-
- public static class Kind {
- final String name;
-
- final boolean normal;
-
- final boolean assemble;
-
- private Kind(String name, boolean normal, boolean assemble) {
- this.name = name;
- this.normal = normal;
- this.assemble = assemble;
- }
-
- public final boolean isAssembly() {
- return assemble;
- }
-
- public final boolean isNormal() {
- return normal;
- }
-
- public final String toString() {
- return name;
- }
- }
-
- /** path to output jar - may not exist */
- private final File outputFile;
-
- /** List of required Result */
- private final List<Result> requiredResults;
-
- /** List of library jars */
- private final List<File> libJars;
-
- /** List of classpath variables */
- private final List<String> classpathVariables;
-
- transient String toLongString;
-
- /**
- * List of library jars exported to clients (duplicates some libJars
- * entries)
- */
- private final List<File> exportedLibJars;
-
- /** List of source directories */
- private final List<File> srcDirs;
-
- /** true if this has calculated List fields. */
- private boolean requiredDone;
-
- /** true if this has been found to be out of date */
- private boolean outOfDate;
-
- /** true if we have calculated whether this is out of date */
- private boolean outOfDateSet;
-
- private final Kind kind;
-
- private final Module module;
-
- private final String name;
-
- Result(Kind kind, Module module, File jarDir) {
- this.kind = kind;
- this.module = module;
- this.libJars = new ArrayList<File>();
- this.exportedLibJars = new ArrayList<File>();
- this.srcDirs = new ArrayList<File>();
- this.classpathVariables = new ArrayList<String>();
- this.requiredResults = new ArrayList<Result>();
- String name = module.name;
- if (!kind.normal) {
- name += "-test";
- }
- if (kind.assemble) {
- name += "-all";
- }
- this.name = name;
- this.outputFile = new File(jarDir, name + ".jar");
- nameToResult.put(name, this);
- }
-
- public String getName() {
- return name;
- }
-
- public File getOutputFile() {
- return outputFile;
- }
-
- public void clearOutOfDate() {
- outOfDateSet = false;
- outOfDate = false;
- }
-
- public boolean outOfDate() {
- if (!outOfDateSet) {
- outOfDate = Module.outOfDate(this);
- outOfDateSet = true;
- }
- return outOfDate;
- }
-
- /** @return List (File) of jar's required */
- public List<File> findJarRequirements() {
- ArrayList<File> result = new ArrayList<File>();
- Module.doFindJarRequirements(this, result);
- return result;
- }
-
- /** @return unmodifiable List of String classpath variables */
- public List<String> getClasspathVariables() {
- return safeList(classpathVariables);
- }
-
- //
- /** @return unmodifiable List of required modules String names */
- public Result[] getRequired() {
- return safeResults(requiredResults);
- }
-
- /**
- * @return unmodifiable list of exported library files, guaranteed readable
- */
- public List<File> getExportedLibJars() {
- return safeList(exportedLibJars);
- }
-
- /**
- * @return unmodifiable list of required library files, guaranteed readable
- */
- public List<File> getLibJars() {
- requiredDone();
- return safeList(libJars);
- }
-
- /**
- * @return unmodifiable list of required library files, guaranteed readable
- */
- // public List getMerges() {
- // requiredDone();
- // return safeList(merges);
- // }
- /** @return unmodifiable list of source directories, guaranteed readable */
- public List<File> getSrcDirs() {
- return safeList(srcDirs);
- }
-
- public Module getModule() {
- return module;
- }
-
- public Kind getKind() {
- return kind;
- }
-
- public String toLongString() {
- if (null == toLongString) {
- toLongString = name + "[outputFile=" + outputFile
- + ", requiredResults=" + requiredResults + ", srcDirs="
- + srcDirs + ", libJars=" + libJars + "]";
- }
- return toLongString;
- }
-
- public String toString() {
- return name;
- }
-
- private <T> List<T> safeList(List<T> l) {
- requiredDone();
- return Collections.unmodifiableList(l);
- }
-
- private Result[] safeResults(List<Result> list) {
- requiredDone();
- if (null == list) {
- return new Result[0];
- }
- return (Result[]) list.toArray(new Result[0]);
- }
-
- private void initSrcDirs() {
- srcDirs.addAll(getModule().srcDirs(this));
- if (getKind().normal) {
- // trim testing source directories
- for (ListIterator<File> iter = srcDirs.listIterator(); iter.hasNext();) {
- File srcDir = iter.next();
- if (isTestingDir(srcDir.getName())) {
- iter.remove();
- }
- }
- }
- }
-
- private void initLibJars() {
- libJars.addAll(getModule().libJars(this));
- if (getKind().normal && !isTestingModule(getModule())) {
- // trim testing libraries
- for (ListIterator<File> iter = libJars.listIterator(); iter.hasNext();) {
- File libJar = iter.next();
- if (isTestingJar(libJar.getName())) {
- iter.remove();
- }
- }
- }
- }
-
- private void assertKind(Kind kind) {
- if (kind != getKind()) {
- throw new IllegalArgumentException("expected " + getKind()
- + " got " + kind);
- }
- }
-
- private void initRequiredResults() {
- final Module module = getModule();
- final Kind kind = getKind();
- if (kind.assemble) {
- if (kind.normal) {
- assertKind(RELEASE_ALL);
- requiredResults.add(module.getResult(RELEASE));
- } else {
- assertKind(TEST_ALL);
- requiredResults.add(module.getResult(TEST));
- requiredResults.add(module.getResult(RELEASE));
- }
- } else if (!kind.normal) {
- assertKind(TEST);
- requiredResults.add(module.getResult(RELEASE));
- } else {
- assertKind(RELEASE);
- }
- // externally-required:
- List<Module> modules = module.requiredModules(this);
- final boolean adoptTests = !kind.normal || isTestingModule(module);
- for (Module required: modules) {
- if (adoptTests) {
- // testing builds can rely on other release and test results
- requiredResults.add(required.getResult(TEST));
- requiredResults.add(required.getResult(RELEASE));
- } else if (!isTestingModule(required)){
- // release builds can only rely on non-testing results
- // from non-testing modules
- requiredResults.add(required.getResult(RELEASE));
- } // else skip release dependencies on testing-* (testing-util)
- }
- }
-
- private void initClasspathVariables() {
- // no difference
- classpathVariables.addAll(getModule().classpathVariables(this));
- }
-
- private void initExportedLibJars() {
- // no difference
- exportedLibJars.addAll(getModule().exportedLibJars(this));
- }
-
- private synchronized void requiredDone() {
- if (!requiredDone) {
- initSrcDirs();
- initLibJars();
- initRequiredResults();
- initClasspathVariables();
- initExportedLibJars();
- requiredDone = true;
- }
- }
-
-}
+++ /dev/null
-/* *******************************************************************
- * Copyright (c) 2003 Contributors.
- * 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:
- * Wes Isberg initial implementation
- * ******************************************************************/
-
-/*
- * A quickie hack to extract sample code from testable sources.
- * This could reuse a lot of code from elsewhere,
- * but currently doesn't,
- * to keep it in the build module which avoids dependencies.
- * (Too bad we can't use scripting languages...)
- */
-package org.aspectj.internal.tools.build;
-
-import java.io.*;
-import java.text.DateFormat;
-import java.util.*;
-
-/**
- * This gathers sample code delimited with [START..END]-SAMPLE
- * from source files under a base directory,
- * along with any <code>@author</code> info.
- * <pre>// START-SAMPLE {anchorName} {anchorText}
- * ... sample code ...
- * // END-SAMPLE {anchorName}
- * </pre>
- * where {anchorName} need not be unique and might be
- * hierarchical wrt "-", e.g., "genus-species-individual".
- */
-public class SampleGatherer {
-
- /** EOL String for gathered lines */
- public static final String EOL = "\n"; // XXX
-
- static final String START = "START-SAMPLE";
- static final String END = "END-SAMPLE";
- static final String AUTHOR = "@author";
- static final String FLAG = "XXX";
-
-// private static void test(String[] args){
-// String[] from = new String[] { "<pre>", "</pre>" };
-// String[] to = new String[] { "<pre>", "</pre>" };
-// String source = "in this <pre> day and </pre> age of <pre and /pre>";
-// System.err.println("from " + source);
-// System.err.println(" to " + SampleUtil.replace(source, from, to));
-// source = "<pre> day and </pre>";
-// System.err.println("from " + source);
-// System.err.println(" to " + SampleUtil.replace(source, from, to));
-// source = "<pre day and </pre";
-// System.err.println("from " + source);
-// System.err.println(" to " + SampleUtil.replace(source, from, to));
-// source = "<pre> day and </pre> age";
-// System.err.println("from " + source);
-// System.err.println(" to " + SampleUtil.replace(source, from, to));
-// source = "in this <pre> day and </pre> age";
-// System.err.println("from " + source);
-// System.err.println(" to " + SampleUtil.replace(source, from, to));
-//
-// }
- /**
- * Emit samples gathered from any input args.
- * @param args the String[] of paths to files or directories to search
- * @throws IOException if unable to read a source file
- */
- public static void main(String[] args) throws IOException {
- if ((null == args) || (0 == args.length)) {
- String cname = SampleGatherer.class.getName();
- System.err.println("java " + cname + " [dir|file]");
- return;
- }
- Samples result = new Samples();
- for (int i = 0; i < args.length; i++) {
- result = gather(new File(args[i]), result);
- }
-
- StringBuffer sb = HTMLSamplesRenderer.ME.render(result, null);
-
- File out = new File("../docs/dist/doc/sample-code.html");
- FileOutputStream fos = new FileOutputStream(out);
- fos.write(sb.toString().getBytes());
- fos.close();
- System.out.println("see file:///" + out);
- }
-
- /**
- * Gather samples from a source file or directory
- * @param source the File file or directory to start with
- * @param sink the Samples collection to add to
- * @return sink or a new Samples collection with any samples found
- * @throws IOException if unable to read a source file
- */
- public static Samples gather(File source, Samples sink)
- throws IOException {
- if (null == sink) {
- sink = new Samples();
- }
- if (null == source) {
- source = new File(".");
- }
- doGather(source, sink);
- return sink;
- }
- private static String trimCommentEnd(String line, int start) {
- if (null == line) {
- return "";
- }
- if ((start > 0) && (start < line.length())) {
- line = line.substring(start);
- }
- line = line.trim();
- if (line.endsWith("*/")) {
- line = line.substring(0, line.length()-2).trim();
- } else if (line.endsWith("-->")) {
- line = line.substring(0, line.length()-3).trim();
- }
- return line;
- }
-
- private static void doGather(File source, Samples sink)
- throws IOException {
- if (source.isFile()) {
- if (isSource(source)) {
- gatherFromFile(source, sink);
- }
- } else if (source.isDirectory() && source.canRead()) {
- File[] files = source.listFiles();
- for (int i = 0; i < files.length; i++) {
- doGather(files[i], sink);
- }
- }
- }
-
- private static boolean isSource(File file) {
- if ((null == file) || !file.isFile() || !file.canRead()) {
- return false;
- }
- String path = file.getName().toLowerCase();
- String[] suffixes = Sample.Kind.SOURCE_SUFFIXES;
- for (int i = 0; i < suffixes.length; i++) {
- if (path.endsWith(suffixes[i])) {
- return true;
- }
- }
- return false;
- }
-
- private static void gatherFromFile(final File source, final Samples sink)
- throws IOException {
- Reader reader = null;
- try {
- String author = null;
- StringBuffer sampleCode = new StringBuffer();
- String anchorName = null;
- String anchorTitle = null;
- ArrayList flags = new ArrayList();
- int startLine = -1; // seeking
- int endLine = Integer.MAX_VALUE; // not seeking
- reader = new FileReader(source);
- LineNumberReader lineReader = new LineNumberReader(reader);
- String line;
-
- while (null != (line = lineReader.readLine())) { // XXX naive
- // found start?
- int loc = line.indexOf(START);
- if (-1 != loc) {
- int lineNumber = lineReader.getLineNumber();
- if (-1 != startLine) {
- abort("unexpected " + START, source, line, lineNumber);
- }
- startLine = lineNumber;
- endLine = -1;
- anchorName = trimCommentEnd(line, loc + START.length());
- loc = anchorName.indexOf(" ");
- if (-1 == loc) {
- anchorTitle = null;
- } else {
- anchorTitle = anchorName.substring(1+loc).trim();
- anchorName = anchorName.substring(0, loc);
- }
- continue;
- }
-
- // found end?
- loc = line.indexOf(END);
- if (-1 != loc) {
- int lineNumber = lineReader.getLineNumber();
- if (Integer.MAX_VALUE == endLine) {
- abort("unexpected " + END, source, line, lineNumber);
- }
- String newtag = trimCommentEnd(line, loc + END.length());
- if ((newtag.length() > 0) && !newtag.equals(anchorName)) {
- String m = "expected " + anchorName
- + " got " + newtag;
- abort(m, source, line, lineNumber);
- }
- endLine = lineNumber;
- Sample sample = new Sample(anchorName,
- anchorTitle,
- author,
- sampleCode.toString(),
- source,
- startLine,
- endLine,
- (String[]) flags.toArray(new String[flags.size()]));
- sink.addSample(sample);
-
- // back to seeking start
- sampleCode.setLength(0);
- startLine = -1;
- endLine = Integer.MAX_VALUE;
- continue;
- }
-
- // found author?
- loc = line.indexOf(AUTHOR);
- if (-1 != loc) {
- author = trimCommentEnd(line, loc + AUTHOR.length());
- }
- // found flag comment?
- loc = line.indexOf(FLAG);
- if (-1 != loc) {
- flags.add(trimCommentEnd(line, loc + FLAG.length()));
- }
-
- // reading?
- if ((-1 != startLine) && (-1 == endLine)) {
- sampleCode.append(line);
- sampleCode.append(EOL);
- }
- }
- if (-1 == endLine) {
- abort("incomplete sample", source, "", lineReader.getLineNumber());
- }
- } finally {
- if (null != reader) {
- reader.close();
- }
- }
- }
- private static void abort(String why, File file, String line, int lineNumber)
- throws Abort {
- throw new Abort(why + " at " + file + ":" + lineNumber + ": " + line);
- }
-// private static void delay(Object toDelay) {
-// synchronized (toDelay) { // XXX sleep instead?
-// toDelay.notifyAll();
-// }
-// }
- static class Abort extends IOException {
- private static final long serialVersionUID = -1l;
- Abort(String s) {
- super(s);
- }
- }
-}
-
-/**
- * Data associated with sample code - struct class.
- */
-class Sample {
- public static final String ASPECTJ_TEAM = "The AspectJ Team";
-
- /** sort by anchorName, file path, and start/end location */
- static Comparator<Sample> NAME_SOURCE_COMPARER = new Comparator<Sample>() {
- public int compare(Sample left, Sample right) {
- if (null == left) {
- return (null == right ? 0 : -1);
- }
- if (null == right) {
- return 1;
- }
- int result = left.anchorName.compareTo(right.anchorName);
- if (0 != result) {
- return result;
- }
- result = left.sourcePath.compareTo(right.sourcePath);
- if (0 != result) {
- return result;
- }
- result = right.startLine - left.startLine;
- if (0 != result) {
- return result;
- }
- return right.endLine - left.endLine;
- }
- };
-
- /** sort by author, then NAME_SOURCE_COMPARER */
- static Comparator<Sample> AUTHOR_NAME_SOURCE_COMPARER = new Comparator<Sample>() {
- public int compare(Sample left, Sample right) {
- if (null == left) {
- return (null == right ? 0 : -1);
- }
- if (null == right) {
- return 1;
- }
- int result = left.author.compareTo(right.author);
- if (0 != result) {
- return result;
- }
- return NAME_SOURCE_COMPARER.compare(left,right);
- }
- };
-
- final String anchorName;
- final String anchorTitle;
- final String author;
- final String sampleCode;
- final File sourcePath;
- final int startLine;
- final int endLine;
- final Kind kind;
- /** List of String flags found in the sample */
- final List flags;
- public Sample(
- String anchorName,
- String anchorTitle,
- String author,
- String sampleCode,
- File sourcePath,
- int startLine,
- int endLine,
- String[] flags) {
- this.anchorName = anchorName;
- this.anchorTitle = anchorTitle;
- this.author = (null != author ? author : ASPECTJ_TEAM);
- this.sampleCode = sampleCode;
- this.sourcePath = sourcePath;
- this.startLine = startLine;
- this.endLine = endLine;
- this.kind = Kind.getKind(sourcePath);
-// List theFlags;
- if ((null == flags) || (0 == flags.length)) {
- this.flags = Collections.EMPTY_LIST;
- } else {
- this.flags = Collections.unmodifiableList(Arrays.asList(flags));
- }
- }
-
- public String toString() {
- return sampleCode;
- }
-
- public static class Kind {
-
- /** lowercase source suffixes identify files to gather samples from */
- public static final String[] SOURCE_SUFFIXES = new String[]
- { ".java", ".aj", ".sh", ".ksh",
- ".txt", ".text", ".html", ".htm", ".xml" };
- static final Kind XML = new Kind();
- static final Kind HTML = new Kind();
- static final Kind PROGRAM = new Kind();
- static final Kind SCRIPT = new Kind();
- static final Kind TEXT = new Kind();
- static final Kind OTHER = new Kind();
- public static Kind getKind(File file) {
- if (null == file) {
- return OTHER;
- }
- String name = file.getName().toLowerCase();
- if ((name.endsWith(".java") || name.endsWith(".aj"))) {
- return PROGRAM;
- }
- if ((name.endsWith(".html") || name.endsWith(".htm"))) {
- return HTML;
- }
- if ((name.endsWith(".sh") || name.endsWith(".ksh"))) {
- return SCRIPT;
- }
- if ((name.endsWith(".txt") || name.endsWith(".text"))) {
- return TEXT;
- }
- if (name.endsWith(".xml")) {
- return XML;
- }
- return OTHER;
- }
- private Kind() {
- }
- }
-}
-
-/**
- * type-safe Collection of samples.
- */
-class Samples {
- private ArrayList<Sample> samples = new ArrayList<Sample>();
- int size() {
- return samples.size();
- }
- void addSample(Sample sample) {
- samples.add(sample);
- }
- /**
- * @return List copy, sorted by Sample.NAME_SOURCE_COMPARER
- */
- List<Sample> getSortedSamples() {
- return getSortedSamples(Sample.NAME_SOURCE_COMPARER);
- }
-
- List<Sample> getSortedSamples(Comparator<Sample> comparer) {
- ArrayList<Sample> result = new ArrayList<Sample>();
- result.addAll(samples);
- Collections.sort(result, comparer);
- return result;
- }
-}
-
-
-/**
- * Render samples by using method visitors.
- */
-class SamplesRenderer {
- public static SamplesRenderer ME = new SamplesRenderer();
- protected SamplesRenderer() {
- }
- public static final String EOL = "\n"; // XXX
- public static final String INFO =
- "<p>This contains contributions from the AspectJ community of "
- + "<ul><li>sample code for AspectJ programs,</li>"
- + "<li>sample code for extensions to AspectJ tools using the public API's,</li>"
- + "<li>sample scripts for invoking AspectJ tools, and </li> "
- + "<li>documentation trails showing how to do given tasks"
- + " using AspectJ, AJDT, or various IDE or deployment"
- + " environments.</li></ul></p>"
- + "<p>Find complete source files in the AspectJ CVS repository at "
- + "<code>org.aspectj/modules/docs/sandbox</code>. "
- + "For instructions on downloading code from the CVS repository, "
- + "see the <a href=\"doc/faq.html#q:buildingsource\">FAQ entry "
- + "\"buildingsource\"</a>.</p>";
-
- public static final String COPYRIGHT =
- "<p><small>Copyright 2003 Contributors. All Rights Reserved. "
- + "This sample code is made available under the Common Public "\r + "License version 1.0 available at "
- + "<a href=\"http://www.eclipse.org/legal/epl-v10.html\">"
- + "http://www.eclipse.org/legal/epl-v10.html</a>."
- + "Contributors are listed in this document as authors. "
- + "Permission to republish portions of this sample code "
- + "is hereby granted if the publication acknowledges "
- + "the author by name and "
- + "the source by reference to the AspectJ project home page "
- + " at http://eclipse.org/aspectj.</small></p>"
- + EOL;
-
- /** template algorithm to render */
- public final StringBuffer render(Samples samples, StringBuffer sink) {
- if (null == sink) {
- sink = new StringBuffer();
- }
- if ((null == samples) || (0 == samples.size())) {
- return sink;
- }
- startList(samples, sink);
- List list = samples.getSortedSamples();
- String anchorName = null;
- for (ListIterator iter = list.listIterator();
- iter.hasNext();) {
- Sample sample = (Sample) iter.next();
- String newAnchorName = sample.anchorName;
- if ((null == anchorName)
- || (!anchorName.equals(newAnchorName))) {
- endAnchorName(anchorName, sink);
- startAnchorName(newAnchorName, sample.anchorTitle, sink);
- anchorName = newAnchorName;
- }
- render(sample, sink);
- }
- endAnchorName(anchorName, sink);
- endList(samples, sink);
- return sink;
- }
- protected void startList(Samples samples, StringBuffer sink) {
- sink.append("Printing " + samples.size() + " samples");
- sink.append(EOL);
- }
-
- protected void startAnchorName(String name, String title, StringBuffer sink) {
- sink.append("anchor " + name);
- sink.append(EOL);
- }
-
- protected void render(Sample sample, StringBuffer sink) {
- SampleUtil.render(sample, "=", ", ",sink);
- sink.setLength(sink.length()-2);
- sink.append(EOL);
- }
-
- /**
- * @param name the String name being ended - ignore if null
- * @param sink
- */
- protected void endAnchorName(String name, StringBuffer sink) {
- if (null == name) {
- return;
- }
- }
-
- protected void endList(Samples samples, StringBuffer sink) {
- sink.append("Printed " + samples.size() + " samples");
- sink.append(EOL);
- }
-
-}
-
-// XXX need DocBookSamplesRenderer
-
-/**
- * Output the samples as a single HTML file, with a table of contents
- * and sorting the samples by their anchor tags.
- */
-class HTMLSamplesRenderer extends SamplesRenderer {
- public static SamplesRenderer ME = new HTMLSamplesRenderer();
- // XXX move these
- public static boolean doHierarchical = true;
- public static boolean doFlags = false;
-
-
- final StringBuffer tableOfContents;
- final StringBuffer sampleSection;
- String[] lastAnchor = new String[0];
- String currentAnchor;
- String currentAuthor;
-
- protected HTMLSamplesRenderer() {
- sampleSection = new StringBuffer();
- tableOfContents = new StringBuffer();
- }
-
- protected void startAnchorName(String name, String title, StringBuffer sink) {
- if (doHierarchical) {
- doContentTree(name);
- }
- // ---- now do anchor
- tableOfContents.append(" <li><a href=\"#" + name);
- if ((null == title) || (0 == title.length())) {
- title = name;
- }
- tableOfContents.append("\">" + title + "</a></li>");
- tableOfContents.append(EOL);
- currentAnchor = name;
- }
-
- protected void startList(Samples samples, StringBuffer sink) {
- }
-
- protected void render(Sample sample, StringBuffer sink) {
- if (null != currentAnchor) {
- if (!currentAnchor.equals(sample.anchorName)) {
- String m = "expected " + currentAnchor
- + " got " + sample.anchorName;
- throw new Error(m);
- }
- currentAnchor = null;
- }
-
- // do heading then code
- renderHeading(sample.anchorName, sample.anchorTitle, sampleSection);
- if (sample.kind == Sample.Kind.HTML) {
- renderHTML(sample);
- } else if (sample.kind == Sample.Kind.XML) {
- renderXML(sample);
- } else {
- renderPre(sample);
- }
- }
-
- protected boolean doRenderAuthor(Sample sample) {
- return (null != sample.author);
- // && !sample.author.equals(currentAuthor)
- }
-
- protected void renderStandardHeader(Sample sample) {
- // XXX starting same as pre
- if (doRenderAuthor(sample)) {
- currentAuthor = sample.author;
- sampleSection.append(" <p>| " + currentAuthor);
- sampleSection.append(EOL);
- }
- sampleSection.append(" | ");
- sampleSection.append(SampleUtil.renderCodePath(sample.sourcePath));
- sampleSection.append(":" + sample.startLine);
- sampleSection.append(" |");
- sampleSection.append(EOL);
- sampleSection.append("<p>");
- sampleSection.append(EOL);
- if (doFlags) {
- boolean flagHeaderDone = false;
- for (Iterator iter = sample.flags.iterator(); iter.hasNext();) {
- String flag = (String) iter.next();
- if (!flagHeaderDone) {
- sampleSection.append("<p>Comments flagged:<ul>");
- sampleSection.append(EOL);
- flagHeaderDone = true;
- }
- sampleSection.append("<li>");
- sampleSection.append(flag);
- sampleSection.append("</li>");
- }
- if (flagHeaderDone) {
- sampleSection.append("</ul>");
- sampleSection.append(EOL);
- }
- }
- }
-
- protected void renderXML(Sample sample) {
- renderStandardHeader(sample);
- sampleSection.append(" <pre>");
- sampleSection.append(EOL);
- sampleSection.append(prepareXMLSample(sample.sampleCode));
- sampleSection.append(EOL);
- sampleSection.append(" </pre>");
- sampleSection.append(EOL);
- }
-
- protected void renderHTML(Sample sample) {
- renderStandardHeader(sample);
- sampleSection.append(EOL);
- sampleSection.append(prepareHTMLSample(sample.sampleCode));
- sampleSection.append(EOL);
- }
-
- protected void renderPre(Sample sample) {
- renderStandardHeader(sample);
- sampleSection.append(" <pre>");
- sampleSection.append(EOL);
- sampleSection.append(prepareCodeSample(sample.sampleCode));
- sampleSection.append(" </pre>");
- sampleSection.append(EOL);
- }
-
- protected void endAnchorName(String name, StringBuffer sink) {
- if (null == name) {
- return;
- }
- currentAnchor = null;
- currentAuthor = null; // authors don't span anchors
- }
-
- protected void endList(Samples samples, StringBuffer sink) {
- sink.append("<html>");
- sink.append(EOL);
- sink.append("<title>AspectJ sample code</title>");
- sink.append(EOL);
- sink.append("<body>");
- sink.append(EOL);
- sink.append(" <a name=\"top\"></a>");
- sink.append(EOL);
- sink.append(" <h1>AspectJ sample code</h1>");
- sink.append(INFO);
- sink.append(EOL);
- sink.append(COPYRIGHT);
- sink.append(EOL);
- sink.append("<p><small>Generated on ");
- sink.append(DateFormat.getDateInstance().format(new Date()));
- sink.append(" by SamplesGatherer</small>");
- sink.append(EOL);
- sink.append(" <h2>Contents</h2>");
- sink.append(EOL);
- sink.append(" <ul>");
- sink.append(EOL);
- sink.append(tableOfContents.toString());
- // unwind to common prefix, if necessary
- for (int i = 0; i < lastAnchor.length ; i++) {
- sink.append(" </ul>");
- }
-
- sink.append(" <li><a href=\"#authorIndex\">Author Index</a></li>");
- sink.append(" </ul>");
- sink.append(" <h2>Listings</h2>");
- sink.append(EOL);
- sink.append(sampleSection.toString());
- renderAuthorIndex(samples, sink);
- sink.append("</body></html>");
- sink.append(EOL);
- }
-
- protected String prepareXMLSample(String sampleCode) {
- String[] from = new String[] {"\t", "<"};
- String[] to = new String[] {" ", "<"};
- return (SampleUtil.replace(sampleCode, from, to));
- }
-
- protected String prepareHTMLSample(String sampleCode) {
- String[] from = new String[20];
- String[] to = new String[20];
- for (int i = 0; i < to.length; i++) {
- String h = "h" + i + ">";
- from[i] = "<" + h;
- to[i] = "<p><b>";
- from[++i] = "</" + h;
- to[i] = "</b></p><p>";
- }
- return (SampleUtil.replace(sampleCode, from, to));
- }
-
- protected String prepareCodeSample(String sampleCode) {
- String[] from = new String[] { "<pre>", "</pre>" };
- String[] to = new String[] { "<pre>", "</pre>" };
- return (SampleUtil.replace(sampleCode, from, to));
- }
-
- protected void renderHeading(String anchor, String title, StringBuffer sink) {
- sink.append(" <a name=\"" + anchor + "\"></a>");
- sink.append(EOL);
- if ((null == title) || (0 == title.length())) {
- title = anchor;
- }
- sink.append(" <h3>" + title + "</h3>");
- sink.append(EOL);
- sink.append("<a href=\"#top\">back to top</a>");
- sink.append(EOL);
- }
-
- /**
- * Manage headings in both table of contents and listings.
- * @param name the String anchor
- */
- protected void doContentTree(String name) {
- if (name.equals(lastAnchor)) {
- return;
- }
- // ---- handle trees
- String[] parts = SampleUtil.splitAnchorName(name);
- //String[] lastAnchor = (String[]) lastAnchors.peek();
- int firstDiff = SampleUtil.commonPrefix(parts, lastAnchor);
- // unwind to common prefix, if necessary
- if (firstDiff+1 < lastAnchor.length) {
- for (int i = 1; i < lastAnchor.length-firstDiff ; i++) {
- tableOfContents.append(" </ul>");
- tableOfContents.append(EOL);
- }
- }
- // build up prefix
- StringBuffer branchAnchor = new StringBuffer();
- for (int i = 0; i < firstDiff;) {
- branchAnchor.append(parts[i]);
- i++;
- branchAnchor.append("-");
- }
- // emit leading headers, but not anchor itself
- for (int i = firstDiff; i < (parts.length-1); i++) {
- branchAnchor.append(parts[i]);
- String prefixName = branchAnchor.toString();
- branchAnchor.append("-");
- tableOfContents.append(" <li><a href=\"#");
- tableOfContents.append(prefixName);
- tableOfContents.append("\">" + prefixName + "</a></li>");
- tableOfContents.append(EOL);
- tableOfContents.append(" <ul>");
- tableOfContents.append(EOL);
-
- renderHeading(prefixName, prefixName, sampleSection);
- }
- lastAnchor = parts;
- }
-
- protected void renderAuthorIndex(Samples samples, StringBuffer sink) {
- sink.append("<h2><a name=\"authorIndex\"></a>Author Index</h2>");
- List list = samples.getSortedSamples(Sample.AUTHOR_NAME_SOURCE_COMPARER);
- String lastAuthor = null;
- for (ListIterator iter = list.listIterator(); iter.hasNext();) {
- Sample sample = (Sample)iter.next();
- String author = sample.author;
- if (!author.equals(lastAuthor)) {
- if (null != lastAuthor) {
- sink.append("</li></ul>");
- }
- sink.append("<li>");
- sink.append(author);
- sink.append(EOL);
- sink.append("<ul>");
- sink.append(EOL);
- lastAuthor = author;
- }
- sink.append(" <li><a href=\"#");
- sink.append(sample.anchorName);
- sink.append("\">");
- if (null == sample.anchorTitle) {
- sink.append(sample.anchorName);
- } else {
- sink.append(sample.anchorTitle);
- }
- sink.append("</a></li>");
- }
- }
-}
-
-class SampleUtil {
- public static final String SAMPLE_BASE_DIR_NAME = "sandbox";
-
- public static void simpleRender(Samples result, StringBuffer sink) {
- List sortedSamples = result.getSortedSamples();
- int i = 0;
- for (ListIterator iter = sortedSamples.listIterator();
- iter.hasNext();) {
- Sample sample = (Sample) iter.next();
- sink.append(i++ + ": " + sample);
- }
- }
-
- /** result struct for getPackagePath */
- static class JavaFile {
- /** input File possibly signifying a java file */
- final File path;
-
- /** String java path suffix in form "com/company/Bar.java"
- * null if this is not a java file
- */
- final String javaPath;
-
- /** any prefix before java path suffix in the original path */
- final String prefix;
-
- /** error handling */
- final Throwable thrown;
- JavaFile(File path, String javaPath, String prefix, Throwable thrown) {
- this.path = path;
- this.javaPath = javaPath;
- this.prefix = prefix;
- this.thrown = thrown;
- }
- }
-
- /**
- * Read any package statement in the file to determine
- * the package path of the file
- * @param path the File to seek the package in
- * @return the JavaFile with the components of the path
- */
- public static JavaFile getJavaFile(File path) {
- if (null == path) {
- throw new IllegalArgumentException("null path");
- }
- String result = path.getPath().replace('\\', '/');
- String packag = "";
- String javaPath = null;
- String prefix = null;
- Throwable thrown = null;
- if (result.endsWith(".java") || result.endsWith(".aj")) {
- FileReader reader = null;
- try {
- reader = new FileReader(path);
- BufferedReader br = new BufferedReader(reader);
- String line;
- while (null != (line = br.readLine())) {
- int loc = line.indexOf("package");
- if (-1 != loc) {
- int end = line.indexOf(";");
- if (-1 == loc) {
- String m = "unterminated package statement \"";
- throw new Error(m + line + "\" in " + path);
- }
- packag = (line.substring(loc + 7, end) + ".")
- .trim()
- .replace('.', '/');
- break;
- }
- loc = line.indexOf("import");
- if (-1 != loc) {
- break;
- }
- }
- } catch (IOException e) {
- thrown = e;
- } finally {
- if (null != reader) {
- try {
- reader.close();
- } catch (IOException e1) {
- // ignore
- }
- }
- }
- if (null == thrown) {
- javaPath = packag + path.getName();
- int loc = result.indexOf(javaPath);
- if (-1 == loc) {
- String m = "expected suffix " + javaPath + " in ";
- throw new Error(m + result);
- }
- prefix = result.substring(0, loc);
- }
- }
- return new JavaFile(path, javaPath, prefix, thrown);
- }
-
- /**
- * Extract file path relative to base of package directory
- * and directory in SAMPLE_BASE_DIR_NAME for this file.
- * @param path the File to render from SAMPLE_BASE_DIR_NAME
- * @return String "baseDir {path}"
- */
- public static String renderCodePath(File path) {
- JavaFile javaFile = getJavaFile(path);
- if (javaFile.thrown != null) {
- throw new Error(javaFile.thrown.getClass()
- + ": " + javaFile.thrown.getMessage());
- }
-
- String file = javaFile.javaPath; // can be null...
- String prefix = javaFile.prefix;
- if (prefix == null) {
- prefix = path.getPath().replace('\\', '/');
- }
- int loc = prefix.lastIndexOf(SAMPLE_BASE_DIR_NAME);
- if (-1 == loc) {
- String m = "not after " + SAMPLE_BASE_DIR_NAME;
- throw new IllegalArgumentException(m + "?: " + path);
- }
- prefix = prefix.substring(loc + 1 + SAMPLE_BASE_DIR_NAME.length());
-
- if (file == null) {
- int slash = prefix.lastIndexOf('/');
- if (-1 == slash) {
- file = prefix;
- prefix = "";
- } else {
- file = prefix.substring(slash+1);
- prefix = prefix.substring(0, slash);
- }
- }
- if (prefix.endsWith("/")) {
- prefix = prefix.substring(0, prefix.length()-1);
- }
- return (prefix + " " + file).trim();
- }
-
- public static int commonPrefix(String[] lhs, String[] rhs) {
- final int max = smallerSize(lhs, rhs);
- int firstDiff = 0;
- while (firstDiff < max) {
- if (!lhs[firstDiff].equals(rhs[firstDiff])) {
- break;
- }
- firstDiff++;
- }
- return firstDiff;
- }
-
- private static int smallerSize(Object[] one, Object[] two) {
- if ((null == one) || (null == two)) {
- return 0;
- }
- return (one.length > two.length ? two.length : one.length);
- }
-
- public static String[] splitAnchorName(Sample sample) {
- return splitAnchorName(sample.anchorName);
- }
-
- public static String[] splitAnchorName(String anchorName) {
- ArrayList<String> result = new ArrayList<String>();
- int start = 0;
- int loc = anchorName.indexOf("-", start);
- String next;
- while (loc != -1) {
- next = anchorName.substring(start, loc);
- result.add(next);
- start = loc+1;
- loc = anchorName.indexOf("-", start);
- }
- next = anchorName.substring(start);
- result.add(next);
- return (String[]) result.toArray(new String[result.size()]);
- }
- /**
- * Replace literals with literals in source string
- * @param source the String to modify
- * @param from the String[] of literals to replace
- * @param to the String[] of literals to use when replacing
- * @return the String source as modified by the replaces
- */
- public static String replace(String source, String[] from, String[] to) {
- if ((null == source) || (0 == source.length())) {
- return source;
- }
- if (from.length != to.length) {
- throw new IllegalArgumentException("unmatched from/to");
- }
- StringBuffer result = new StringBuffer();
- int LEN = source.length();
- int start = 0;
- for (int i = 0; i < LEN; i++) {
- String suffix = source.substring(i);
- for (int j = 0; j < from.length; j++) {
- if (suffix.startsWith(from[j])) {
- result.append(source.substring(start, i));
- result.append(to[j]);
- start = i + from[j].length();
- i = start-1;
- break;
- }
- }
- }
- if (start < source.length()) {
- result.append(source.substring(start));
- }
- return result.toString();
- }
-
- public static void render(
- Sample sample,
- String fieldDelim,
- String valueDelim,
- StringBuffer sink) {
- if ((null == sink) || (null == sample)) {
- return;
- }
- if (null == fieldDelim) {
- fieldDelim = "";
- }
- if (null == valueDelim) {
- valueDelim = "";
- }
- sink.append("anchorName");
- sink.append(valueDelim);
- sink.append(sample.anchorName);
- sink.append(fieldDelim);
- sink.append("author");
- sink.append(valueDelim);
- sink.append(sample.author);
- sink.append(fieldDelim);
- sink.append("sourcePath");
- sink.append(valueDelim);
- sink.append(sample.sourcePath.toString());
- sink.append(fieldDelim);
- sink.append("startLine");
- sink.append(valueDelim);
- sink.append(sample.startLine);
- sink.append(fieldDelim);
- sink.append("endLine");
- sink.append(valueDelim);
- sink.append(sample.endLine);
- sink.append(fieldDelim);
- sink.append("sampleCode");
- sink.append(valueDelim);
- sink.append(sample.sampleCode.toString());
- sink.append(fieldDelim);
- }
- private SampleUtil(){}
-}
+++ /dev/null
-/* *******************************************************************
- * 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 v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
-
-package org.aspectj.internal.tools.build;
-
-import java.io.*;
-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.Manifest;
-import java.util.jar.Attributes.Name;
-
-/**
- * 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) {
- StringBuffer sb = new StringBuffer();
- 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 (int i = 0; i < files.length; i++) {
- if (!deleteContents(files[i]) || !files[i].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 (int i = 0; i < actual.length; i++) {
- if (null != actual[i]) {
- sb.append(prefix);
- prefix = ", ";
- sb.append("\"");
- sb.append(actual[i]);
- sb.append("\"");
- }
- }
- sb.append("] missing [");
- prefix = "";
- for (int i = 0; i < expected.length; i++) {
- if (null != expected[i]) {
- sb.append(prefix);
- prefix = ", ";
- sb.append("\"");
- sb.append(expected[i]);
- 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 NAMES;
- static {
- ArrayList 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);
- }
- }
- }
-}
-
+++ /dev/null
-<html>
-<!-- todo
-- backed off on doing product installer builds directly;
- the one installer is now built using Ant.
-
--
--->
-<body>
-The build taskdef relies on the classes in this package for
-behavior independent of Ant.
-</body>
-</html>
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+//XXX INCLUDES CODE FROM ANT -- UNDER APACHE LICENSE
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Copy;
+import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.taskdefs.Expand;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+
+public class AJInstaller extends MatchingTask {
+ static final String INCLUDE_CLASSES = "$installer$/org/aspectj/*.class";
+ static final String MAIN_CLASS = "$installer$.org.aspectj.Main";
+ static final String CONTENTS_FILE = "$installer$/org/aspectj/resources/contents.txt";
+ private String htmlSrc;
+
+ public void setHtmlSrc(String v) { htmlSrc = v; }
+
+ private String resourcesSrc;
+
+ public void setResourcesSrc(String v) { resourcesSrc = v; }
+
+ private String mainclass;
+
+ public void setMainclass(String v) { mainclass = v; }
+
+ private File installerClassJar;
+
+ public void setInstallerclassjar(String v) {
+ installerClassJar = project.resolveFile(v);
+ }
+
+ protected List contentsNames = new ArrayList();
+
+ protected long contentsBytes = 0;
+
+ protected void addToContents(File file, String vPath) {
+ contentsNames.add(vPath);
+ contentsBytes += file.length();
+ }
+
+ String[] getFiles(File baseDir) {
+ DirectoryScanner ds = new DirectoryScanner();
+ setBasedir(baseDir.getAbsolutePath());
+ ds.setBasedir(baseDir);
+ //ds.setIncludes(new String [] {pattern});
+ ds.scan();
+ return ds.getIncludedFiles();
+ }
+
+ protected Copy getCopyTask() {
+ Copy cd = (Copy)project.createTask("copy");
+ if (null == cd) {
+ log("project.createTask(\"copy\") failed - direct", Project.MSG_VERBOSE);
+ cd = new Copy();
+ cd.setProject(getProject());
+ }
+ return cd;
+ }
+ protected void finishZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException {
+ writeContents(zOut);
+ writeManifest(zOut);
+ File tempDir = setupTempDir();
+ String tmp = tempDir.getAbsolutePath();
+
+ // installer class files
+ Expand expand = new Expand();
+ expand.setProject(getProject());
+ expand.setSrc(installerClassJar);
+ expand.setDest(new File(tmp));
+ PatternSet patterns = new PatternSet();
+ patterns.setIncludes(INCLUDE_CLASSES);
+ expand.addPatternset(patterns);
+ expand.execute();
+
+ // move the correct resource files into the jar
+ Copy cd = getCopyTask();
+ fileset = new FileSet();
+ fileset.setDir(new File(resourcesSrc));
+ fileset.setIncludes("*");
+ fileset.setExcludes("contents.txt,properties.txt");
+ cd.addFileset(fileset);
+ cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
+ cd.execute();
+ project.getGlobalFilterSet().addFilter("installer.main.class", this.mainclass);
+ Copy cf = getCopyTask();
+ fileset = new FileSet();
+ fileset.setDir(new File(resourcesSrc));
+ fileset.setIncludes("properties.txt");
+ cf.setFiltering(true);
+ cf.addFileset(fileset);
+ cf.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
+ cf.execute();
+ // move the correct resource files into the jar
+ cd = getCopyTask();
+ fileset = new FileSet();
+ fileset.setDir(new File(htmlSrc));
+ fileset.setIncludes("*");
+ cd.addFileset(fileset);
+ cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
+ cd.execute();
+ // now move these files into the jar
+ setBasedir(tmp);
+ writeFiles(zOut, getFiles(tempDir));
+ // and delete the tmp dir
+ Delete dt = (Delete)project.createTask("delete");
+ if (null == dt) {
+ dt = new Delete();
+ dt.setProject(getProject());
+ }
+ dt.setDir(tempDir);
+ dt.execute();
+ tempDir = null;
+ }
+
+ static final char NEWLINE = '\n';
+
+ protected void writeContents(ZipOutputStream zOut) throws IOException {
+ // write to a StringBuffer
+ StringBuffer buf = new StringBuffer();
+ buf.append(contentsBytes);
+ buf.append(NEWLINE);
+ for (Iterator i = contentsNames.iterator(); i.hasNext(); ) {
+ String name = (String)i.next();
+ buf.append(name);
+ buf.append(NEWLINE);
+ }
+ zipFile(new StringBufferInputStream(buf.toString()), zOut, CONTENTS_FILE, System.currentTimeMillis());
+ }
+
+ protected void writeManifest(ZipOutputStream zOut) throws IOException {
+ // write to a StringBuffer
+ StringBuffer buf = new StringBuffer();
+ buf.append("Manifest-Version: 1.0");
+ buf.append(NEWLINE);
+ buf.append("Main-Class: " + MAIN_CLASS);
+ buf.append(NEWLINE);
+ zipFile(new StringBufferInputStream(buf.toString()), zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis());
+ }
+
+ //XXX cut-and-paste from Zip super-class (under apache license)
+ private File zipFile;
+ private File baseDir;
+ private boolean doCompress = true;
+ protected String archiveType = "zip";
+
+ /**
+ * This is the name/location of where to
+ * create the .zip file.
+ */
+ public void setZipfile(String zipFilename) {
+ zipFile = project.resolveFile(zipFilename);
+ }
+
+ /**
+ * This is the base directory to look in for
+ * things to zip.
+ */
+ public void setBasedir(String baseDirname) {
+ baseDir = project.resolveFile(baseDirname);
+ }
+
+ /**
+ * Sets whether we want to compress the files or only store them.
+ */
+ public void setCompress(String compress) {
+ doCompress = Project.toBoolean(compress);
+ }
+
+ protected void initZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException
+ {
+ }
+
+ protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
+ throws IOException
+ {
+ }
+
+ protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
+ long lastModified)
+ throws IOException
+ {
+ ZipEntry ze = new ZipEntry(vPath);
+ ze.setTime(lastModified);
+
+ /*
+ * XXX ZipOutputStream.putEntry expects the ZipEntry to know its
+ * size and the CRC sum before you start writing the data when using
+ * STORED mode.
+ *
+ * This forces us to process the data twice.
+ *
+ * I couldn't find any documentation on this, just found out by try
+ * and error.
+ */
+ if (!doCompress) {
+ long size = 0;
+ CRC32 cal = new CRC32();
+ if (!in.markSupported()) {
+ // Store data into a byte[]
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8 * 1024];
+ int count = 0;
+ do {
+ size += count;
+ cal.update(buffer, 0, count);
+ bos.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ in = new ByteArrayInputStream(bos.toByteArray());
+ } else {
+ in.mark(Integer.MAX_VALUE);
+ byte[] buffer = new byte[8 * 1024];
+ int count = 0;
+ do {
+ size += count;
+ cal.update(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ in.reset();
+ }
+ ze.setSize(size);
+ ze.setCrc(cal.getValue());
+ }
+ zOut.putNextEntry(ze);
+ byte[] buffer = new byte[8 * 1024];
+ int count = 0;
+ do {
+ zOut.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ }
+
+ protected void zipFile(File file, ZipOutputStream zOut, String vPath)
+ throws IOException
+ {
+ if ( !vPath.startsWith("$installer$") ) {
+ addToContents(file, vPath);
+ }
+ FileInputStream fIn = new FileInputStream(file);
+ try {
+ zipFile(fIn, zOut, vPath, file.lastModified());
+ } finally {
+ fIn.close();
+ }
+ }
+ private File setupTempDir() throws BuildException {
+ File tmpDirF = null;
+ File tmpDir = null;
+ try {
+ tmpDirF = File.createTempFile("tgz", ".di");
+ tmpDir = new File(tmpDirF.getParentFile(), "AJInstaller");
+ tmpDirF.delete();
+ } catch (IOException e) {
+ // retrying below
+ }
+ if (null == tmpDir || !tmpDir.mkdirs()) {
+ tmpDir = new File("AJInstaller.finishZipOutputStream.tmp");
+ if (!tmpDir.mkdirs()) {
+ throw new BuildException("unable to make temp dir");
+ }
+ }
+ return tmpDir;
+ }
+
+ public void execute() throws BuildException {
+ if (installerClassJar == null) {
+ throw new BuildException("installerClassJar attribute must be set!");
+ }
+ if (!installerClassJar.canRead()
+ || !installerClassJar.getPath().endsWith(".jar")) {
+ throw new BuildException("not readable jar:" + installerClassJar);
+ }
+// if (installerClassDir == null) {
+// throw new BuildException("installerClassDir attribute must be set!");
+// }
+// if (!installerClassDir.exists()) {
+// throw new BuildException("no such directory: installerClassDir=" + installerClassDir);
+// }
+ if (baseDir == null) {
+ throw new BuildException("basedir attribute must be set!");
+ }
+ if (!baseDir.exists()) {
+ throw new BuildException("basedir does not exist!");
+ }
+ DirectoryScanner ds = super.getDirectoryScanner(baseDir);
+ String[] files = ds.getIncludedFiles();
+ String[] dirs = ds.getIncludedDirectories();
+ log("Building installer: "+ zipFile.getAbsolutePath());
+ ZipOutputStream zOut = null;
+ try {
+ zOut = new ZipOutputStream(new FileOutputStream(zipFile));
+ if (doCompress) {
+ zOut.setMethod(ZipOutputStream.DEFLATED);
+ } else {
+ zOut.setMethod(ZipOutputStream.STORED);
+ }
+ initZipOutputStream(zOut);
+ writeDirs(zOut, dirs);
+ writeFiles(zOut, files);
+ finishZipOutputStream(zOut); // deletes temp dir
+ } catch (IOException ioe) {
+ String msg = "Problem creating " + archiveType + " " + ioe.getMessage();
+ throw new BuildException(msg, ioe, location);
+ } finally {
+ if (zOut != null) {
+ try {
+ // close up
+ zOut.close();
+ }
+ catch (IOException e) {}
+ }
+ }
+ }
+
+ protected void writeDirs(ZipOutputStream zOut, String[] dirs) throws IOException {
+ for (int i = 0; i < dirs.length; i++) {
+ File f = new File(baseDir,dirs[i]);
+ String name = dirs[i].replace(File.separatorChar,'/')+"/";
+ zipDir(f, zOut, name);
+ }
+ }
+
+ protected void writeFiles(ZipOutputStream zOut, String[] files) throws IOException {
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(baseDir,files[i]);
+ String name = files[i].replace(File.separatorChar,'/');
+ zipFile(f, zOut, name);
+ }
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.Properties;
+
+import org.apache.tools.ant.taskdefs.Mkdir;
+
+public class AJPush extends ConditionalTask {
+ private File src;
+
+ public void setSrc(String v) { src = project.resolveFile(v); }
+
+ private String key;
+
+ public void setKey(String v) { key = v; }
+
+ File releaseDir = null;
+ File downloadDir = null;
+ boolean waiting = false;
+
+ public void execute() throws org.apache.tools.ant.BuildException {
+ //File releaseDir = src.getParentFile();
+ // todo: dependency on ant script variable name aj.release.dir
+ releaseDir = project.resolveFile(project.getProperty("aj.release.dir"));
+ // todo: dependency on ant script variable name download.dir
+ downloadDir = project.resolveFile(project.getProperty("download.dir"));
+ // For testing make sure these directories are made
+ Mkdir mkdir = (Mkdir) project.createTask("mkdir");
+ mkdir.setDir(releaseDir);
+ mkdir.execute();
+ mkdir = (Mkdir) project.createTask("mkdir");
+ mkdir.setDir(downloadDir);
+ mkdir.execute();
+ log("Pushing from " + releaseDir + " to " + downloadDir);
+ // add info to release.txt
+ try {
+ File releaseFile = new File(releaseDir, "release.txt");
+ File downloadFile = new File(downloadDir, "release.txt");
+ if (!releaseFile.canRead()) {
+ releaseFile.createNewFile();
+ }
+ addReleaseInfo(src, releaseFile);
+ // copy to staging web server
+ project.copyFile(src, new File(downloadDir, src.getName()));
+ project.copyFile(releaseFile, downloadFile);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ void addReleaseInfo(File file, File propFile) throws IOException {
+ Properties props = new Properties();
+ if (propFile.canRead()) {
+ props.load(new FileInputStream(propFile));
+ }
+ file.createNewFile(); // create new only if necessary
+ long bytes = file.length();
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(3);
+ String bytesString = df.format(bytes);
+ props.put("release." + key + ".size.bytes", bytesString);
+ props.put("release." + key + ".date", project.getProperty("build.date"));
+ props.put("release." + key + ".filename", file.getName());
+ props.put("release.date", project.getProperty("build.date"));
+ props.put("release.version", project.getProperty("build.version.short"));
+ props.put("release.versionName", project.getProperty("build.version.long"));
+ String userName = System.getProperty("user.name");
+ if (userName != null) {
+ props.put("release." + key + ".username", userName);
+ }
+ props.store(new FileOutputStream(propFile), null);
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Copy;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.taskdefs.Zip;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.aspectj.internal.tools.build.BuildSpec;
+import org.aspectj.internal.tools.build.Builder;
+import org.aspectj.internal.tools.build.Messager;
+import org.aspectj.internal.tools.build.Module;
+import org.aspectj.internal.tools.build.Result;
+import org.aspectj.internal.tools.build.Util;
+
+/**
+ * Implement Builder in Ant.
+ */
+public class AntBuilder extends Builder {
+ private static final boolean FORCE_FORK_FOR_LIBRARIES = false;
+
+ /**
+ * Factory for a Builder.
+ *
+ * @param config the String configuration, where only substrings "verbose" and "useEclipseCompiles" are significant
+ * @param project the owning Project for all tasks (not null)
+ * @param tempDir the File path to a temporary dir for side effects (may be null)
+ * @return a Builder for this project and configuration
+ */
+ public static Builder getBuilder(String config, Project project, File tempDir) {
+ boolean useEclipseCompiles = false;
+ boolean verbose = false;
+ if (null != config) {
+ if (-1 != config.indexOf("useEclipseCompiles")) {
+ useEclipseCompiles = true;
+ }
+ if (-1 != config.indexOf("verbose")) {
+ verbose = true;
+ }
+ }
+ // Messager handler = new Messager(); // debugging
+ Messager handler = new ProjectMessager(project);
+ Builder result = new ProductBuilder(project, tempDir, useEclipseCompiles, handler);
+ if (verbose) {
+ result.setVerbose(true);
+ }
+ return result;
+ }
+
+ private static String resultToTargetName(Result result) {
+ return result.getName();
+ }
+
+ /**
+ * Ensure targets exist for this module and all antecedants, so topoSort can work.
+ */
+ private static void makeTargetsForResult(final Result result, final Hashtable<String,Target> targets) {
+ final String resultTargetName = resultToTargetName(result);
+ Target target = targets.get(resultTargetName);
+ if (null == target) {
+ // first add the target
+ target = new Target();
+ target.setName(resultTargetName);
+
+ Result[] reqs = result.getRequired();
+ StringBuffer depends = new StringBuffer();
+ boolean first = true;
+ for (int i = 0; i < reqs.length; i++) {
+ Result reqResult = reqs[i];
+ if (!first) {
+ depends.append(",");
+ } else {
+ first = false;
+ }
+ depends.append(resultToTargetName(reqResult));
+ }
+ if (0 < depends.length()) {
+ target.setDepends(depends.toString());
+ }
+ targets.put(resultTargetName, target);
+
+ // then recursively add any required results
+ for (int i = 0; i < reqs.length; i++) {
+ Result reqResult = reqs[i];
+ makeTargetsForResult(reqResult, targets);
+ }
+ }
+ }
+
+ private final Project project;
+
+ protected AntBuilder(Project project, File tempDir, boolean useEclipseCompiles, Messager handler) {
+ super(tempDir, useEclipseCompiles, handler);
+ this.project = project;
+ Util.iaxIfNull(project, "project");
+ }
+
+ /**
+ * Initialize task with project and "ajbuild-" + name as name. (Using bm- prefix distinguishes these tasks from tasks found in
+ * the build script.)
+ *
+ * @param task the Task to initialize - not null
+ * @param name the String name suffix for the task
+ * @return true unless some error
+ */
+ protected boolean setupTask(Task task, String name) {
+ task.setProject(project);
+ task.setTaskName("ajbuild-" + name);
+ return true;
+ }
+
+ /**
+ * Copy file, optionally filtering. (Filters set in project.)
+ *
+ * @param fromFile the readable File source to copy
+ * @param toFile the writable File destination file
+ * @param boolean filter if true, enable filtering
+ * @see org.aspectj.internal.tools.build.Builder#copyFile(File, File, boolean)
+ */
+ @Override
+ protected boolean copyFile(File fromFile, File toFile, boolean filter) {
+ Copy copy = makeCopyTask(filter);
+ copy.setFile(fromFile);
+ copy.setTofile(toFile);
+ executeTask(copy);
+ return true;
+ }
+
+ /**
+ * (Filters set in project.)
+ *
+ * @see org.aspectj.internal.tools.ant.taskdefs.Builder#copyFiles(File, File, String, String, boolean)
+ */
+ @Override
+ protected boolean copyFiles(File fromDir, File toDir, String includes, String excludes, boolean filter) {
+ Copy copy = makeCopyTask(filter);
+ copy.setTodir(toDir);
+ FileSet fileset = new FileSet();
+ fileset.setDir(fromDir);
+ if (null != includes) {
+ fileset.setIncludes(includes);
+ }
+ if (null != excludes) {
+ fileset.setExcludes(excludes);
+ }
+ copy.addFileset(fileset);
+ executeTask(copy);
+
+ return false;
+ }
+
+ protected void copyFileset(File toDir, FileSet fileSet, boolean filter) {
+ Copy copy = makeCopyTask(filter);
+ copy.addFileset(fileSet);
+ copy.setTodir(toDir);
+ executeTask(copy);
+ }
+
+ /**
+ * @param filter if FILTER_ON, use filters
+ */
+ protected Copy makeCopyTask(boolean filter) {
+ Copy copy = new Copy();
+ setupTask(copy, "copy");
+ if (FILTER_ON == filter) {
+ copy.setFiltering(true);
+ }
+ return copy;
+ }
+
+ protected void dumpMinFile(Result result, File classesDir, List<String> errors) {
+ String name = result.getName() + "-empty";
+ File minFile = new File(classesDir, name);
+ FileWriter fw = null;
+ try {
+ fw = new FileWriter(minFile);
+ fw.write(name);
+ } catch (IOException e) {
+ errors.add("IOException writing " + name + " to " + minFile + ": " + Util.renderException(e));
+ } finally {
+ Util.close(fw);
+ }
+
+ }
+
+ @Override
+ protected boolean compile(Result result, File classesDir, boolean useExistingClasses, List<String> errors) {
+ if (!classesDir.exists() && !classesDir.mkdirs()) {
+ errors.add("compile - unable to create " + classesDir);
+ return false;
+ }
+ if (useExistingClasses) {
+ return true;
+ }
+ // -- source paths
+ Path path = new Path(project);
+ boolean hasSourceDirectories = false;
+ boolean isJava5Compile = false;
+ boolean isJava8Compile = false;
+ for (File file: result.getSrcDirs()) {
+ path.createPathElement().setLocation(file);
+ if (!isJava5Compile
+ && (Util.Constants.JAVA5_SRC.equals(file.getName()) ||
+ Util.Constants.JAVA5_TESTSRC.equals(file.getName()) ||
+ new File(file.getParent(), ".isJava5").exists())) {
+ isJava5Compile = true;
+ }
+ if (new File(file.getParent(),".isJava8").exists()) {
+ isJava8Compile = true;
+ }
+ if (!hasSourceDirectories) {
+ hasSourceDirectories = true;
+ }
+ }
+ if (!hasSourceDirectories) {
+ return true; // nothing to compile - ok
+ }
+ // XXX test whether build.compiler property takes effect automatically
+ // I suspect it requires the proper adapter setup.
+ Javac javac = new Javac();
+ setupTask(javac, "javac");
+ javac.setIncludeantruntime(false);
+ javac.setDestdir(classesDir);
+ javac.setSrcdir(path);
+ javac.setVerbose(verbose);
+ path = null;
+
+ // -- classpath
+ Path classpath = new Path(project);
+ boolean hasLibraries = setupClasspath(result, classpath);
+ if (hasLibraries && FORCE_FORK_FOR_LIBRARIES) {
+ javac.setFork(true); // otherwise never releases library jars
+ // can we build under 1.4, but fork javac 1.5 compile?
+ }
+ // also fork if using 1.5?
+
+ // -- set output directory
+ classpath.createPathElement().setLocation(classesDir);
+ javac.setClasspath(classpath);
+
+ // misc
+ javac.setDebug(true);
+ if (isJava8Compile) {
+ javac.setSource("1.8");
+ javac.setTarget("1.8");
+ } else if (isJava5Compile) {
+ // *cough*
+ javac.setSource("1.6");
+ javac.setTarget("1.6");
+ } else {
+ javac.setTarget("1.1"); // 1.1 class files - Javac in 1.4 uses 1.4
+ javac.setSource("1.3");
+ }
+ // compile
+ boolean passed = false;
+ BuildException failure = null;
+ try {
+ passed = executeTask(AspectJSupport.wrapIfNeeded(result, javac));
+ } catch (BuildException e) {
+ failure = e;
+ } catch (Error e) {
+ failure = new BuildException(e);
+ } catch (RuntimeException e) {
+ failure = new BuildException(e);
+ } finally {
+ if (!passed) {
+ String args = "" + Arrays.asList(javac.getCurrentCompilerArgs());
+ if ("[]".equals(args)) {
+ args = "{" + result.toLongString() + "}";
+ }
+ String m = "BuildException compiling " + result.toLongString() + args
+ + (null == failure ? "" : ": " + Util.renderException(failure));
+ // debuglog System.err.println(m);
+ errors.add(m);
+ }
+ javac.init(); // be nice to let go of classpath libraries...
+ }
+ return passed;
+ }
+
+ public boolean setupClasspath(Result result, Path classpath) { // XXX fix test access
+ boolean hasLibraries = false;
+ // required libraries
+ for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
+ File file = (File) iter.next();
+ classpath.createPathElement().setLocation(file);
+ if (!hasLibraries) {
+ hasLibraries = true;
+ }
+ }
+ // Westodo Kind kind = result.getKind();
+ Result[] reqs = result.getRequired();
+ // required modules and their exported libraries
+ for (int i = 0; i < reqs.length; i++) {
+ Result requiredResult = reqs[i];
+ classpath.createPathElement().setLocation(requiredResult.getOutputFile());
+ if (!hasLibraries) {
+ hasLibraries = true;
+ }
+ // also put on classpath libraries exported from required module
+ // XXX exported modules not supported
+ for (Iterator iterator = requiredResult.getExportedLibJars().iterator(); iterator.hasNext();) {
+ classpath.createPathElement().setLocation((File) iterator.next());
+ }
+ }
+ return hasLibraries;
+ }
+
+ /**
+ * Merge classes directory and any merge jars into module jar with any specified manifest file. META-INF directories are
+ * excluded.
+ */
+ @Override
+ protected boolean assemble(Result result, File classesDir, List<String> errors) {
+ if (!buildingEnabled) {
+ return false;
+ }
+ if (!result.outOfDate()) {
+ return true;
+ }
+
+ // ---- zip result up
+ Zip zip = new Zip();
+ setupTask(zip, "zip");
+ zip.setDestFile(result.getOutputFile());
+ ZipFileSet zipfileset = null;
+
+ // -- merge any resources in any of the src directories
+ for (Iterator iter = result.getSrcDirs().iterator(); iter.hasNext();) {
+ File srcDir = (File) iter.next();
+ zipfileset = new ZipFileSet();
+ zipfileset.setProject(project);
+ zipfileset.setDir(srcDir);
+ zipfileset.setIncludes(RESOURCE_PATTERN);
+ zip.addZipfileset(zipfileset);
+ }
+
+ final Module module = result.getModule();
+
+ File metaInfDir = new File(classesDir, "META-INF");
+ Util.deleteContents(metaInfDir);
+
+ // -- manifest
+ File manifest = new File(module.moduleDir, module.name + ".mf.txt"); // XXXFileLiteral
+ if (Util.canReadFile(manifest)) {
+ if (Util.canReadDir(metaInfDir) || metaInfDir.mkdirs()) {
+ // Jar spec requires a MANIFEST.MF not a manifest.mf
+ copyFile(manifest, new File(metaInfDir, "MANIFEST.MF"), FILTER_ON); // XXXFileLiteral
+ } else {
+ errors.add("have manifest, but unable to create " + metaInfDir);
+ return false;
+ }
+ }
+
+ zipfileset = new ZipFileSet();
+ zipfileset.setProject(project);
+ zipfileset.setDir(classesDir);
+ zipfileset.setIncludes("**/*");
+ zip.addZipfileset(zipfileset);
+ File[] contents = classesDir.listFiles();
+ if ((null == contents) || (0 == contents.length)) {
+ // *something* to zip up
+ dumpMinFile(result, classesDir, errors);
+ }
+
+ try {
+ handler.log("assemble " + module + " in " + result.getOutputFile());
+ return executeTask(zip)
+ // zip returns true when it doesn't create zipfile
+ // because there are no entries to add, so verify done
+ && Util.canReadFile(result.getOutputFile());
+ } catch (BuildException e) {
+ errors.add("BuildException zipping " + module + ": " + e.getMessage());
+ return false;
+ } finally {
+ result.clearOutOfDate();
+ }
+ }
+
+ /**
+ * @see org.aspectj.internal.tools.build.Builder#buildAntecedants(Module)
+ */
+ @Override
+ protected Result[] getAntecedantResults(Result moduleResult) {
+ Hashtable<String,Target> targets = new Hashtable<String, Target>();
+ makeTargetsForResult(moduleResult, targets);
+ String targetName = resultToTargetName(moduleResult);
+ // bug: doc says topoSort returns String, but returns Target
+ Collection<Target> result = project.topoSort(targetName, targets);
+ // fyi, we don't rely on topoSort to detect cycles - see buildAll
+ int size = result.size();
+ if (0 == result.size()) {
+ return new Result[0];
+ }
+ ArrayList<String> toReturn = new ArrayList<String>();
+ for (Iterator<Target> iter = result.iterator(); iter.hasNext();) {
+ Target target = iter.next();
+ String name = target.getName();
+ if (null == name) {
+ throw new Error("null name?");
+ } else {
+ toReturn.add(name);
+ }
+ }
+ // topoSort always returns target name
+ if ((1 == size) && targetName.equals(toReturn.get(0)) && !moduleResult.outOfDate()) {
+ return new Result[0];
+ }
+ return Result.getResults(toReturn.toArray(new String[0]));
+ }
+
+ /**
+ * Generate Module.assembledJar with merge of itself and all antecedants
+ */
+ @Override
+ protected boolean assembleAll(Result result, Messager handler) {
+ if (!buildingEnabled) {
+ return false;
+ }
+ if (!result.outOfDate()) {
+ return true;
+ }
+
+ Util.iaxIfNull(result, "result");
+ Util.iaxIfNull(handler, "handler");
+ if (!result.getKind().isAssembly()) {
+ throw new IllegalStateException("not assembly: " + result);
+ }
+
+ // ---- zip result up
+ Zip zip = new Zip();
+ setupTask(zip, "zip");
+ zip.setDestFile(result.getOutputFile());
+ ZipFileSet zipfileset = null;
+ final Module module = result.getModule();
+ List<File> known = result.findJarRequirements();
+ removeLibraryFilesToSkip(module, known);
+ // -- merge any antecedents, less any manifest
+ for (File jarFile: known) {
+ zipfileset = new ZipFileSet();
+ zipfileset.setProject(project);
+ zipfileset.setSrc(jarFile);
+ zipfileset.setIncludes("**/*");
+ String name = jarFile.getName();
+ name = name.substring(0, name.length() - 4); // ".jar".length()
+ // required includes self - exclude manifest from others
+ if (!module.name.equals(name)) {
+ zipfileset.setExcludes("META-INF/MANIFEST.MF"); // XXXFileLiteral
+ zipfileset.setExcludes("META-INF/manifest.mf");
+ zipfileset.setExcludes("meta-inf/manifest.mf");
+ zipfileset.setExcludes("meta-inf/MANIFEST.MF");
+ }
+ zip.addZipfileset(zipfileset);
+ }
+
+ try {
+ handler.log("assembling all " + module + " in " + result.getOutputFile());
+ if (verbose) {
+ handler.log("knownAntecedants: " + known);
+ }
+ return executeTask(zip);
+ } catch (BuildException e) {
+ handler.logException("BuildException zipping " + module, e);
+ return false;
+ } finally {
+ result.clearOutOfDate();
+ }
+ }
+
+ /**
+ * @see org.aspectj.internal.tools.ant.taskdefs.Builder#buildInstaller(BuildSpec, String)
+ */
+ @Override
+ protected boolean buildInstaller(BuildSpec buildSpec, String targDirPath) {
+ return false;
+ }
+
+ /** task.execute() and any advice */
+ protected boolean executeTask(Task task) {
+ if (!buildingEnabled) {
+ return false;
+ }
+ task.execute();
+ return true;
+ }
+
+ /**
+ * Support for compiling basic AspectJ projects. Projects may only compile all (and only) their source directories; aspectpath,
+ * inpath, etc. are not supported. To load the compiler, this assumes the user has either defined a project property
+ * "aspectj.home" or that there exists <code>{module-dir}/lib/aspectj/lib/aspectj[tools|rt].jar</code>.
+ */
+ static class AspectJSupport {
+ static final String AJCTASK = "org.aspectj.tools.ant.taskdefs.AjcTask";
+ static final String ASPECTJRT_JAR_VARIABLE = "ASPECTJRT_LIB";
+ static final String LIBASPECTJ_RPATH = "/lib/aspectj";
+ static final Map nameToAspectjrtjar = new HashMap();
+ static final String NONE = "NONE";
+
+ /**
+ * If this module should be compiled with AspectJ, return a task to do so.
+ *
+ * @param module the Module to compile
+ * @param javac the Javac compile commands
+ * @return javac or a Task to compile with AspectJ if needed
+ */
+ static Task wrapIfNeeded(Result result, Javac javac) {
+ final Project project = javac.getProject();
+ Path runtimeJar = null;
+ final Module module = result.getModule();
+ if (runtimeJarOnClasspath(result)) {
+ // yes aspectjrt.jar on classpath
+ } else if (result.getClasspathVariables().contains(ASPECTJRT_JAR_VARIABLE)) {
+ // yes, in variables - find aspectjrt.jar to add to classpath
+ runtimeJar = getAspectJLib(project, module, "aspectjrt.jar");
+ } else {
+ // no
+ // System.out.println("javac " + result + " " + javac.getClasspath());
+ return javac;
+ }
+ // System.out.println("aspectj " + result + " " + javac.getClasspath());
+ Path aspectjtoolsJar = getAspectJLib(project, module, "aspectjtools.jar");
+ return aspectJTask(javac, aspectjtoolsJar, runtimeJar);
+ }
+
+ /** @return true if aspectjrt.jar is on classpath */
+ private static boolean runtimeJarOnClasspath(Result result) {
+ for (File file: result.getLibJars()) {
+ if ("aspectjrt.jar".equals(file.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static Path getAspectJLib(Project project, Module module, String name) {
+ Path result = null;
+ String[] libDirNames = { "aspectj.home", "ASPECTJ_HOME", LIBASPECTJ_RPATH };
+ String[] libDirs = new String[libDirNames.length];
+ for (int i = 0; i < libDirNames.length; i++) {
+ if (LIBASPECTJ_RPATH == libDirNames[i]) {
+ libDirs[i] = module.getFullPath(LIBASPECTJ_RPATH);
+ } else {
+ libDirs[i] = project.getProperty(libDirNames[i]);
+ }
+ if (null != libDirs[i]) {
+ libDirs[i] = Util.path(libDirs[i], "lib");
+ result = new Path(project, Util.path(libDirs[i], name));
+ String path = result.toString();
+ if (new File(path).canRead()) {
+ return result;
+ }
+ }
+ }
+ String m = "unable to find " + name + " in " + Arrays.asList(libDirs);
+ throw new BuildException(m);
+ }
+
+ /**
+ * Wrap AspectJ compiler as Task. Only works for javac-like source compilation of everything under srcDir. Written
+ * reflectively to compile in the build module, which can't depend on the whole tree.
+ *
+ * @param javac the Javac specification
+ * @param toolsJar the Path to the aspectjtools.jar
+ * @param runtimeJar the Path to the aspectjrt.jar
+ * @return javac or another Task invoking the AspectJ compiler
+ */
+ @SuppressWarnings("unchecked")
+ static Task aspectJTask(Javac javac, Path toolsJar, Path runtimeJar) {
+ Object task = null;
+ String url = null;
+ try {
+ url = "file:" + toolsJar.toString().replace('\\', '/');
+ URL[] cp = new URL[] { new URL(url) };
+ ClassLoader parent = Task.class.getClassLoader();
+ ClassLoader loader = new URLClassLoader(cp, parent);
+ Class c = loader.loadClass(AJCTASK);
+ task = c.newInstance();
+ // Westodo Project project = javac.getProject();
+ Method m = c.getMethod("setupAjc", new Class[] { Javac.class });
+ m.invoke(task, new Object[] { javac });
+ m = c.getMethod("setFork", new Class[] { boolean.class });
+ m.invoke(task, new Object[] { Boolean.TRUE });
+ m = c.getMethod("setForkclasspath", new Class[] { Path.class });
+ m.invoke(task, new Object[] { toolsJar });
+ m = c.getMethod("setSourceRoots", new Class[] { Path.class });
+ m.invoke(task, new Object[] { javac.getSrcdir() });
+ if (null != runtimeJar) {
+ m = c.getMethod("setClasspath", new Class[] { Path.class });
+ m.invoke(task, new Object[] { runtimeJar });
+ }
+ } catch (BuildException e) {
+ throw e;
+ } catch (Throwable t) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("classpath=");
+ sb.append(url);
+ throw new BuildException(sb.toString(), t);
+ }
+ return (Task) task;
+ }
+
+ private AspectJSupport() {
+ throw new Error("no instances");
+ }
+ }
+}
+
+// finally caught by failing to comply with proper ant initialization
+// /**
+// * Build a module that has a build script.
+// * @param buildSpec the module to build
+// * @param buildScript the script file
+// * @throws BuildException if build fails
+// */
+// private void buildByScript(BuildSpec buildSpec, File buildScript)
+// throws BuildException {
+// Ant ant = new Ant();
+// ant.setProject(getProject());
+// ant.setAntfile(buildScript.getAbsolutePath());
+// ant.setDescription("building module " + buildSpec.module);
+// ant.setDir(buildScript.getParentFile());
+// ant.setInheritAll(true);
+// ant.setInheritRefs(false);
+// ant.setLocation(getLocation());
+// ant.setOwningTarget(getOwningTarget());
+// // by convention, for build.xml, use module name to publish
+// ant.setTarget(buildSpec.module);
+// ant.setTaskName("ant");
+// loadAntProperties(ant, buildSpec);
+// ant.execute();
+// }
+//
+// /** override definitions */
+// private void loadAntProperties(Ant ant, BuildSpec buildSpec) {
+// Property property = ant.createProperty();
+// property.setName(BuildSpec.baseDir_NAME);
+// property.setFile(buildSpec.baseDir);
+// property = ant.createProperty();
+// property.setName(buildSpec.distDir_NAME);
+// property.setFile(buildSpec.distDir);
+// property = ant.createProperty();
+// property.setName(BuildSpec.tempDir_NAME);
+// property.setFile(buildSpec.tempDir);
+// property = ant.createProperty();
+// property.setName(BuildSpec.jarDir_NAME);
+// property.setFile(buildSpec.jarDir);
+// property = ant.createProperty();
+// property.setName(BuildSpec.stagingDir_NAME);
+// property.setFile(buildSpec.stagingDir);
+// }
+
+/**
+ * Segregate product-building API's from module-building APIs for clarity. These are called by the superclass if the BuildSpec
+ * warrants. XXX extremely brittle/arbitrary assumptions.
+ *
+ * @see BuildModule for assumptions
+ */
+class ProductBuilder extends AntBuilder {
+
+ private static String getProductInstallResourcesSrc(BuildSpec buildSpec) {
+ final String resourcesName = "installer-resources"; // XXXFileLiteral
+ File dir = buildSpec.productDir.getParentFile();
+ if (null == dir) {
+ return Util.path(new String[] { "..", "..", resourcesName });
+ }
+ dir = dir.getParentFile();
+ if (null == dir) {
+ return Util.path("..", resourcesName);
+ } else {
+ dir = new File(dir, resourcesName);
+ return dir.getPath();
+ }
+ }
+
+ private static String getProductInstallerFileName(BuildSpec buildSpec) { // XXXFileLiteral
+ return "aspectj-" + buildSpec.productDir.getName() + "-" + Util.shortVersion(buildSpec.version) + ".jar";
+ }
+
+ /**
+ * Calculate name of main, typically InitialCap, and hence installer class.
+ *
+ * @return $$installer$$.org.aspectj." + ProductName + "Installer"
+ */
+
+ private static String getProductInstallerMainClass(BuildSpec buildSpec) {
+ String productName = buildSpec.productDir.getName();
+ String initial = productName.substring(0, 1).toUpperCase();
+ productName = initial + productName.substring(1);
+ return "$installer$.org.aspectj." + productName + "Installer"; // XXXNameLiteral
+ }
+
+ /** @see Builder.getBuilder(String, Project, File) */
+ ProductBuilder(Project project, File tempDir, boolean useEclipseCompiles, Messager handler) {
+ super(project, tempDir, useEclipseCompiles, handler);
+ }
+
+ /**
+ * Delegate for super.buildProduct(..) template method.
+ */
+ @Override
+ protected boolean copyBinaries(BuildSpec buildSpec, File distDir, File targDir, String excludes) {
+ Copy copy = makeCopyTask(false);
+ copy.setTodir(targDir);
+ FileSet fileset = new FileSet();
+ fileset.setDir(distDir);
+ fileset.setIncludes(Builder.BINARY_SOURCE_PATTERN);
+ if (null != excludes) {
+ fileset.setExcludes(excludes);
+ }
+ copy.addFileset(fileset);
+ return executeTask(copy);
+ }
+
+ /**
+ * Delegate for super.buildProduct(..) template method.
+ */
+ @Override
+ protected boolean copyNonBinaries(BuildSpec buildSpec, File distDir, File targDir) {
+ // filter-copy everything but the binaries
+ Copy copy = makeCopyTask(true);
+ copy.setTodir(targDir);
+ Util.iaxIfNotCanReadDir(distDir, "product dist directory");
+ FileSet fileset = new FileSet();
+ fileset.setDir(distDir);
+ fileset.setExcludes(Builder.BINARY_SOURCE_PATTERN);
+ copy.addFileset(fileset);
+ return executeTask(copy);
+ }
+
+ @Override
+ protected boolean buildInstaller(BuildSpec buildSpec, String targDirPath) {
+ if (buildSpec.verbose) {
+ handler.log("creating installer for " + buildSpec);
+ }
+ AJInstaller installer = new AJInstaller();
+ setupTask(installer, "installer");
+ installer.setBasedir(targDirPath);
+ // installer.setCompress();
+ File installSrcDir = new File(buildSpec.productDir, "install"); // XXXFileLiteral
+ Util.iaxIfNotCanReadDir(installSrcDir, "installSrcDir");
+ installer.setHtmlSrc(installSrcDir.getPath());
+ String resourcePath = getProductInstallResourcesSrc(buildSpec);
+ File resourceSrcDir = new File(resourcePath);
+ Util.iaxIfNotCanReadDir(resourceSrcDir, "resourceSrcDir");
+ installer.setResourcesSrc(resourcePath);
+ String name = getProductInstallerFileName(buildSpec);
+ File outFile = new File(buildSpec.jarDir, name);
+ installer.setZipfile(outFile.getPath());
+ installer.setMainclass(getProductInstallerMainClass(buildSpec));
+ installer.setInstallerclassjar(getBuildJar(buildSpec));
+ return executeTask(installer);
+
+ // -- test installer XXX
+ // create text setup file
+ // run installer with setup file
+ // cleanup installed product
+ }
+
+ private String getBuildJar(BuildSpec buildSpec) {
+ return buildSpec.baseDir.getPath() + "/lib/build/build.jar"; // XXX
+ }
+
+ // private Module moduleForReplaceFile(File replaceFile, Modules modules) {
+ // String jarName = moduleAliasFor(replaceFile.getName().toLowerCase());
+ // if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) { // XXXFileLiteral
+ // jarName = jarName.substring(0, jarName.length()-4);
+ // } else {
+ // throw new IllegalArgumentException("can only replace .[jar|zip]");
+ // }
+ // boolean assembleAll = jarName.endsWith("-all");
+ // String name = (!assembleAll ? jarName : jarName.substring(0, jarName.length()-4));
+ // return modules.getModule(name);
+ // }
+ //
+}
+
+class ProjectMessager extends Messager {
+ private final Project project;
+
+ public ProjectMessager(Project project) {
+ Util.iaxIfNull(project, "project");
+ this.project = project;
+ }
+
+ @Override
+ public boolean log(String s) {
+ project.log(s);
+ return true;
+ }
+
+ @Override
+ public boolean error(String s) {
+ project.log(s, Project.MSG_ERR);
+ return true;
+ }
+
+ @Override
+ public boolean logException(String context, Throwable thrown) {
+ project.log(context + Util.renderException(thrown), Project.MSG_ERR);
+ return true;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.aspectj.internal.tools.build.BuildSpec;
+import org.aspectj.internal.tools.build.Builder;
+
+/**
+ * Ant interface to build a product or module, including any required modules.
+ * @see Builder
+ */
+public class BuildModule extends Task { // quickie hack...
+
+ public static void main(String[] args) {
+ TestBuildModule.main(args);
+ }
+
+ private static File pathToFile(Path path) {
+ if (null != path) {
+ String[] list = path.list();
+ if ((null == list) || (1 != list.length)) {
+ throw new IllegalArgumentException("expected exactly 1 element");
+ }
+ return new File(list[0]);
+ }
+ return null;
+ }
+ BuildSpec buildSpec;
+
+ public BuildModule() {
+ buildSpec = new BuildSpec();
+ setTaskName("ajbuild");
+ }
+
+ public void setModuledir(Path moduleDir) {
+ buildSpec.moduleDir = pathToFile(moduleDir);
+ }
+
+ public void setModule(String module) { // XXX handle multiple modules, same builder
+ buildSpec.module = module;
+ }
+
+ public void setVersion(String version) {
+ buildSpec.version = version;
+ }
+ public void setBasedir(Path baseDir) {
+ buildSpec.baseDir = pathToFile(baseDir);
+ }
+
+ public void setJardir(Path jarDir) {
+ buildSpec.jarDir = pathToFile(jarDir);
+ }
+
+ public void setTrimtesting(boolean trimTesting) {
+ buildSpec.trimTesting = trimTesting;
+ }
+
+ public void setAssembleall(boolean assembleAll) {
+ buildSpec.assembleAll = assembleAll;
+ }
+
+ public void setRebuild(boolean rebuild) {
+ buildSpec.rebuild = rebuild;
+ }
+
+ public void setFailonerror(boolean failonerror) {
+ buildSpec.failonerror = failonerror;
+ }
+
+ public void setCreateinstaller(boolean create) {
+ buildSpec.createInstaller = create;
+ }
+
+ public void setVerbose(boolean verbose) {
+ buildSpec.verbose = verbose;
+ }
+
+ public void setBuildConfig(String buildConfig) {
+ buildSpec.buildConfig = buildConfig;
+ }
+
+ // --------------------------------------------------------- product build
+
+ public void setProductdir(Path productDir) {
+ buildSpec.productDir = pathToFile(productDir);
+ }
+
+ public void setTempdir(Path tempDir) {
+ buildSpec.tempDir = pathToFile(tempDir);
+ }
+
+ public void setDistdir(Path distdir) {
+ buildSpec.distDir = pathToFile(distdir);
+ }
+
+ public void execute() throws BuildException {
+ final BuildSpec buildSpec = this.buildSpec;
+ this.buildSpec = new BuildSpec();
+ build(buildSpec);
+ }
+
+ private void build(BuildSpec buildSpec) throws BuildException {
+ final boolean failonerror = buildSpec.failonerror;
+ Builder builder = null;
+ try {
+ // try using script first if not a product
+ boolean built = false;
+ if ((null == buildSpec.productDir) && (null != buildSpec.moduleDir)) {
+ File buildScript = new File(buildSpec.moduleDir, "build.xml"); // XXXFileLiteral
+ if (buildScript.canRead()) {
+ built = buildByScript(buildSpec, buildScript);
+ if (!built) {
+ log("unable to build "
+ + buildSpec
+ + " using script: "
+ + buildScript.getAbsolutePath());
+ }
+ }
+ }
+ if (!built) {
+ builder = AntBuilder.getBuilder(
+ buildSpec.buildConfig,
+ getProject(),
+ buildSpec.tempDir);
+ if (!builder.build(buildSpec) && failonerror) {
+ Location loc = getLocation();
+ throw new BuildException("error building " + buildSpec, loc);
+ }
+ }
+ } catch (BuildException e) {
+ throw e;
+ } catch (Throwable t) {
+ Location loc = getLocation();
+ throw new BuildException("error building " + buildSpec, t, loc);
+ } finally {
+ if (null != builder) {
+ builder.cleanup();
+ }
+ }
+ }
+
+ boolean buildByScript(BuildSpec buildSpec, File buildScript)
+ throws BuildException {
+ return false;
+ }
+}
+
\ No newline at end of file
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Check that included .java files contain license and copyright strings for MPL 1.0 (default), Apache, or CPL. Use list="true" to
+ * get a list of known license variants {license}-{copyrightHolder} todo reimplement with regexp and jdiff FileLine utilities
+ */
+public class Checklics extends MatchingTask {
+ /*
+ * This does not enforce that copyrights are correct/current, only that they exist. E.g., the default behavior requires MPL but
+ * permits either Xerox or PARC copyright holders and any valid year.
+ */
+ public static final String MPL_TAG = "mpl";
+ public static final String APACHE_TAG = "apache";
+ public static final String CPL_IBM_PARC_TAG = "cpl-ibm|parc";
+ public static final String CPL_IBM_TAG = "cpl-ibm";
+ public static final String MPL_XEROX_PARC_TAG = "mpl-parc|xerox";
+ public static final String MPL_ONLY_TAG = "mpl-only";
+ public static final String MPL_PARC_TAG = "mpl-parc";
+ public static final String PARC_COPYRIGHT_TAG = "parc-copy";
+ public static final String CPL_IBM_PARC_XEROX_TAG = "cpl-ibm|parc|xerox";
+ public static final String CPL_IBM_PARC_XEROX_OTHERS_TAG = "cpl-ibm|parc|xerox|others";
+ public static final String EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG = "epl-cpl-ibm|parc|xerox|vmware|others";
+ public static final String DEFAULT = EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG;
+
+ static final Map<String,License> LICENSES; // unmodifiable Map
+
+ static {
+ final String CONTRIBUTORS = "Contributors";
+ final String XEROX = "Xerox";
+ final String PARC = "Palo Alto Research Center";
+ final String APACHE = "The Apache Software Foundation";
+ final String IBM = "IBM";
+ final String VMWARE = "VMware";
+ final String IBM_LONG = "International Business Machines";
+ final String LIC_APL = "Apache Software Foundation (http://www.apache.org/)";
+ final String LIC_MPL = "http://aspectj.org/MPL/";
+ final String LIC_CPL = "Eclipse Public License";
+ final String LIC_ECPL = " Public License";
+ License APL = new License(APACHE_TAG, LIC_APL, APACHE);
+ License MPL = new License(MPL_TAG, LIC_MPL, XEROX);
+ License MPL_XEROX_PARC = new License(DEFAULT, LIC_MPL, XEROX, PARC);
+ License CPL_IBM_PARC = new License(CPL_IBM_PARC_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC });
+ License CPL_IBM_PARC_XEROX = new License(CPL_IBM_PARC_XEROX_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC, XEROX });
+
+ License CPL_IBM_PARC_XEROX_OTHERS = new License(CPL_IBM_PARC_XEROX_OTHERS_TAG, LIC_CPL, new String[] { IBM_LONG, IBM, PARC,
+ XEROX, CONTRIBUTORS });
+ License EPL_CPL_IBM_PARC_XEROX_OTHERS = new License(EPL_CPL_IBM_PARC_XEROX_OTHERS_TAG, LIC_ECPL, new String[] { IBM_LONG,
+ IBM, PARC, XEROX, VMWARE, CONTRIBUTORS });
+ License CPL_IBM = new License(CPL_IBM_TAG, LIC_CPL, IBM, IBM_LONG);
+ License MPL_ONLY = new License(MPL_ONLY_TAG, LIC_MPL);
+ License MPL_PARC = new License(MPL_PARC_TAG, LIC_MPL, PARC);
+ License PARC_COPYRIGHT = new License(PARC_COPYRIGHT_TAG, null, PARC);
+ LICENSES = new Hashtable<String,License>();
+ LICENSES.put(APL.tag, APL);
+ LICENSES.put(MPL.tag, MPL);
+ LICENSES.put(MPL_PARC.tag, MPL_PARC);
+ LICENSES.put(MPL_XEROX_PARC.tag, MPL_XEROX_PARC);
+ LICENSES.put(CPL_IBM_PARC.tag, CPL_IBM_PARC);
+ LICENSES.put(MPL_ONLY.tag, MPL_ONLY);
+ LICENSES.put(CPL_IBM.tag, CPL_IBM);
+ LICENSES.put(PARC_COPYRIGHT.tag, PARC_COPYRIGHT);
+ LICENSES.put(CPL_IBM_PARC_XEROX.tag, CPL_IBM_PARC_XEROX);
+ LICENSES.put(CPL_IBM_PARC_XEROX_OTHERS.tag, CPL_IBM_PARC_XEROX_OTHERS);
+ LICENSES.put(EPL_CPL_IBM_PARC_XEROX_OTHERS.tag, EPL_CPL_IBM_PARC_XEROX_OTHERS);
+ }
+
+ /** @param args String[] { < sourcepath > {, < licenseTag > } } */
+ public static void main(String[] args) {
+ switch (args.length) {
+ case 1:
+ runDirect(args[0], null, false);
+ break;
+ case 2:
+ runDirect(args[0], args[1], false);
+ break;
+ default:
+ String options = "{replace-headers|get-years|list|{licenseTag}}";
+ System.err.println("java {me} sourcepath " + options);
+ break;
+ }
+ }
+
+ /**
+ * Run the license check directly
+ *
+ * @param sourcepaths String[] of paths to source directories
+ * @param license the String tag for the license, if any
+ * @param failonerror boolean flag to pass to Checklics
+ * @throws IllegalArgumentException if sourcepaths is empty
+ * @return total number of failed licenses
+ */
+ public static int runDirect(String sourcepath, String license, boolean failonerror) {
+ if ((null == sourcepath) || (1 > sourcepath.length())) {
+ throw new IllegalArgumentException("bad sourcepath: " + sourcepath);
+ }
+ Checklics me = new Checklics();
+ Project p = new Project();
+ p.setName("direct interface to Checklics");
+ p.setBasedir(".");
+ me.setProject(p);
+ me.setFailOnError(failonerror);
+ me.setSourcepath(new Path(p, sourcepath));
+ if (null != license) {
+ if ("replace-headers".equals(license)) {
+ me.setReplaceheaders(true);
+ } else if ("get-years".equals(license)) {
+ me.setGetYears(true);
+ } else if ("list".equals(license)) {
+ me.setList(true);
+ } else {
+ me.setLicense(license);
+ }
+ }
+ me.execute();
+ return me.failed;
+ }
+
+ private Path sourcepath;
+ private License license;
+ private boolean list;
+ private String streamTag;
+ private boolean failOnError;
+ private boolean getYears;
+ private boolean replaceHeaders;
+ private int failed;
+ private int passed;
+
+ private boolean printDirectories;
+
+ /** @param list if true, don't run but list known license tags */
+ public void setList(boolean list) {
+ this.list = list;
+ }
+
+ public void setPrintDirectories(boolean print) {
+ printDirectories = print;
+ }
+
+ /**
+ * When failOnError is true, if any file failed, throw BuildException listing number of files that file failed to pass license
+ * check
+ *
+ * @param fail if true, report errors by throwing BuildException
+ */
+ public void setFailOnError(boolean fail) {
+ this.failOnError = fail;
+ }
+
+ /** @param tl mpl | apache | cpl */
+ public void setLicense(String tl) {
+ License input = LICENSES.get(tl);
+ if (null == input) {
+ throw new BuildException("no license known for " + tl);
+ }
+ license = input;
+ }
+
+ public void setSourcepath(Path path) {
+ if (sourcepath == null) {
+ sourcepath = path;
+ } else {
+ sourcepath.append(path);
+ }
+ }
+
+ public Path createSourcepath() {
+ return sourcepath == null ? (sourcepath = new Path(project)) : sourcepath.createPath();
+ }
+
+ public void setSourcepathRef(Reference id) {
+ createSourcepath().setRefid(id);
+ }
+
+ /** @param out "out" or "err" */
+ public void setOutputStream(String out) {
+ this.streamTag = out;
+ }
+
+ public void setReplaceheaders(boolean replaceHeaders) {
+ this.replaceHeaders = replaceHeaders;
+ }
+
+ public void setGetYears(boolean getYears) {
+ this.getYears = getYears;
+ }
+
+ /** list known licenses or check source tree */
+ @Override
+ public void execute() throws BuildException {
+ if (list) {
+ list();
+ } else if (replaceHeaders) {
+ replaceHeaders();
+ } else if (getYears) {
+ getYears();
+ } else {
+ checkLicenses();
+ }
+ }
+
+ private PrintStream getOut() {
+ return ("err".equals(streamTag) ? System.err : System.out);
+ }
+
+ interface FileVisitor {
+ void visit(File file);
+ }
+
+ /** visit all .java files in all directories... */
+ private void visitAll(FileVisitor visitor) {
+ // List filelist = new ArrayList();
+ String[] dirs = sourcepath.list();
+ for (int i = 0; i < dirs.length; i++) {
+ File dir = project.resolveFile(dirs[i]);
+ String[] files = getDirectoryScanner(dir).getIncludedFiles();
+ for (int j = 0; j < files.length; j++) {
+ File file = new File(dir, files[j]);
+ String path = file.getPath();
+ if (path.endsWith(".java")) {
+ visitor.visit(file);
+ }
+ }
+ }
+ }
+
+ private void replaceHeaders() {
+ class YearVisitor implements FileVisitor {
+ @Override
+ public void visit(File file) {
+ HeaderInfo info = Header.checkFile(file);
+ if (!Header.replaceHeader(file, info)) {
+ throw new BuildException("failed to replace header for " + file + " using " + info);
+ }
+ }
+ }
+ visitAll(new YearVisitor());
+ }
+
+ private void getYears() {
+ final PrintStream out = getOut();
+ class YearVisitor implements FileVisitor {
+ @Override
+ public void visit(File file) {
+ HeaderInfo info = Header.checkFile(file);
+ out.println(info.toString());
+ }
+ }
+ visitAll(new YearVisitor());
+ }
+
+ private void checkLicenses() throws BuildException {
+ if (null == license) {
+ setLicense(DEFAULT);
+ }
+ final License license = this.license; // being paranoid...
+ if (null == license) {
+ throw new BuildException("no license");
+ }
+ final PrintStream out = getOut();
+
+ class Visitor implements FileVisitor {
+ int failed = 0;
+ int passed = 0;
+
+ @Override
+ public void visit(File file) {
+ if (license.checkFile(file)) {
+ passed++;
+ } else {
+ failed++;
+ String path = file.getPath();
+ if (!license.foundLicense()) {
+ out.println(license.tag + " LICENSE FAIL: " + path);
+ }
+ if (!license.foundCopyright()) {
+ out.println(license.tag + " COPYRIGHT FAIL: " + path);
+ }
+ }
+ }
+ }
+ Visitor visitor = new Visitor();
+ visitAll(visitor);
+ this.failed = visitor.failed;
+ this.passed = visitor.passed;
+ if (0 < visitor.failed) {
+ getOut().println("Total passed: " + visitor.passed + (visitor.failed == 0 ? "" : " failed: " + visitor.failed));
+ if (failOnError) {
+ throw new BuildException(failed + " files failed license check");
+ }
+ }
+ }
+
+ private void list() {
+ Iterator enu = LICENSES.keySet().iterator();
+ StringBuffer sb = new StringBuffer();
+ sb.append("known license keys:");
+ boolean first = true;
+ while (enu.hasNext()) {
+ sb.append((first ? " " : ", ") + enu.next());
+ if (first) {
+ first = false;
+ }
+ }
+ getOut().println(sb.toString());
+ }
+
+ /**
+ * Encapsulate license and copyright specifications to check files use hokey string matching.
+ */
+ public static class License {
+ /** acceptable years for copyright prefix to company - append " " */
+ static final String[] YEARS = // remove older after license xfer?
+ new String[] { "2002 ", "2003 ", "2004 ", "2005", "2006", "2007", "2008",
+ "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2001 ", "2000 ",
+ "1999 " };
+ public final String tag;
+ public final String license;
+ private final String[] copyright;
+ private boolean gotLicense;
+ private boolean gotCopyright;
+
+ License(String tag, String license) {
+ this(tag, license, (String[]) null);
+ }
+
+ License(String tag, String license, String copyright) {
+ this(tag, license, new String[] { copyright });
+ }
+
+ License(String tag, String license, String copyright, String altCopyright) {
+ this(tag, license, new String[] { copyright, altCopyright });
+ }
+
+ License(String tag, String license, String[] copyright) {
+ this.tag = tag;
+ if ((null == tag) || (0 == tag.length())) {
+ throw new IllegalArgumentException("null tag");
+ }
+ this.license = license;
+ this.copyright = copyright;
+ }
+
+ public final boolean gotValidFile() {
+ return foundLicense() && foundCopyright();
+ }
+
+ /** @return true if no license sought or if some license found */
+ public final boolean foundLicense() {
+ return ((null == license) || gotLicense);
+ }
+
+ /** @return true if no copyright sought or if some copyright found */
+ public final boolean foundCopyright() {
+ return ((null == copyright) || gotCopyright);
+ }
+
+ public boolean checkFile(final File file) {
+ clear();
+ // boolean result = false;
+ BufferedReader input = null;
+ int lineNum = 0;
+ try {
+ input = new BufferedReader(new FileReader(file));
+ String line;
+ while (!gotValidFile() && (line = input.readLine()) != null) {
+ lineNum++;
+ checkLine(line);
+ }
+ } catch (IOException e) {
+ System.err.println("reading line " + lineNum + " of " + file);
+ e.printStackTrace(System.err);
+ } finally {
+ if (null != input) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ } // ignore
+ }
+ }
+ return gotValidFile();
+ }
+
+ @Override
+ public String toString() {
+ return tag;
+ }
+
+ private void checkLine(String line) {
+ if ((null == line) || (0 == line.length())) {
+ return;
+ }
+ if (!gotLicense && (null != license) && (-1 != line.indexOf(license))) {
+ gotLicense = true;
+ }
+ if (!gotCopyright && (null != copyright)) {
+ int loc;
+ for (int j = 0; !gotCopyright && (j < YEARS.length); j++) {
+ if (-1 != (loc = line.indexOf(YEARS[j]))) {
+ loc += YEARS[j].length();
+ String afterLoc = line.substring(loc).trim();
+ for (int i = 0; !gotCopyright && (i < copyright.length); i++) {
+ if (0 == afterLoc.indexOf(copyright[i])) {
+ gotCopyright = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void clear() {
+ if (gotLicense) {
+ gotLicense = false;
+ }
+ if (gotCopyright) {
+ gotCopyright = false;
+ }
+ }
+ } // class License
+}
+
+class HeaderInfo {
+ /** File for which this is the info */
+ public final File file;
+
+ /** unmodifiable List of String years */
+ public final List years;
+
+ /** last line of license */
+ public final int lastLine;
+
+ /** last line of license */
+ public final boolean hasLicense;
+
+ public HeaderInfo(File file, int lastLine, List<String> years, boolean hasLicense) {
+ this.lastLine = lastLine;
+ this.file = file;
+ this.hasLicense = hasLicense;
+ List<String> newYears = new ArrayList<String>();
+ newYears.addAll(years);
+ Collections.sort(newYears);
+ this.years = Collections.unmodifiableList(newYears);
+ if ((null == file) || !file.canWrite()) {
+ throw new IllegalArgumentException("bad file: " + this);
+ }
+ if (!hasLicense) {
+ if ((0 > lastLine) || (65 < lastLine)) {
+ throw new IllegalArgumentException("bad last line: " + this);
+ }
+ } else {
+ if ((null == years) || (1 > years.size())) {
+ throw new IllegalArgumentException("no years: " + this);
+ }
+ if ((20 > lastLine) || (65 < lastLine)) {
+ throw new IllegalArgumentException("bad last line: " + this);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return file.getPath() + ":" + lastLine + " " + years;
+ }
+
+ public void writeHeader(PrintWriter writer) {
+ if (!hasLicense) {
+ writer.println(TOP);
+ writer.println(PARC_ONLY);
+ writeRest(writer);
+ } else {
+ final int size = years.size();
+ if (1 > size) {
+ throw new Error("no years found in " + toString());
+ }
+ String first = (String) years.get(0);
+ String last = (String) years.get(size - 1);
+ boolean lastIs2002 = "2002".equals(last);
+ String xlast = last;
+ if (lastIs2002) { // 2002 was PARC
+ xlast = (String) (size > 1 ? years.get(size - 2) : null);
+ // 1999-2002 Xerox implies 1999-2001 Xerox
+ if (first.equals(xlast) && !"2001".equals(xlast)) {
+ xlast = "2001";
+ }
+ }
+ String xyears = first + "-" + xlast;
+ if (first.equals(last)) {
+ xyears = first;
+ }
+
+ writer.println(TOP);
+ if (!lastIs2002) { // Xerox only
+ writer.println(XEROX_PREFIX + xyears + XEROX_SUFFIX + ". ");
+ } else if (size == 1) { // PARC only
+ writer.println(PARC_ONLY);
+ } else { // XEROX plus PARC
+ writer.println(XEROX_PREFIX + xyears + XEROX_SUFFIX + ", ");
+ writer.println(PARC);
+ }
+ writeRest(writer);
+ }
+ }
+
+ void writeRest(PrintWriter writer) {
+ writer.println(" * All rights reserved. ");
+ writer.println(" * This program and the accompanying materials are made available ");
+ writer.println(" * under the terms of the Eclipse Public License v1.0 ");
+ writer.println(" * which accompanies this distribution and is available at ");
+ writer.println(" * http://www.eclipse.org/legal/epl-v10.html ");
+ writer.println(" * ");
+ writer.println(" * Contributors: ");
+ writer.println(" * Xerox/PARC initial implementation ");
+ writer.println(" * ******************************************************************/");
+ writer.println("");
+ }
+
+ public static final String TOP = "/* *******************************************************************";
+ public static final String PARC = " * 2002 Palo Alto Research Center, Incorporated (PARC).";
+ public static final String PARC_ONLY = " * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).";
+ public static final String XEROX_PREFIX = " * Copyright (c) ";
+ public static final String XEROX_SUFFIX = " Xerox Corporation";
+ /*
+ * /* ******************************************************************* Copyright (c) 1998-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 v1.0 which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Xerox/PARC initial implementation ******************************************************************
+ */
+}
+
+/**
+ * header search/replace using hokey string matching
+ */
+class Header {
+
+ /** replace the header in file */
+ public static boolean replaceHeader(File file, HeaderInfo info) {
+ // ArrayList years = new ArrayList();
+ // int endLine = 0;
+ BufferedReader input = null;
+ PrintWriter output = null;
+ FileWriter outWriter = null;
+ int lineNum = 0;
+ boolean result = false;
+ final File inFile = new File(file.getPath() + ".tmp");
+ try {
+ File outFile = new File(file.getPath());
+ if (!file.renameTo(inFile) || !inFile.canRead()) {
+ throw new Error("unable to rename " + file + " to " + inFile);
+ }
+ outWriter = new FileWriter(outFile);
+ input = new BufferedReader(new FileReader(inFile));
+ output = new PrintWriter(outWriter, true);
+ info.writeHeader(output);
+ String line;
+ while (null != (line = input.readLine())) {
+ lineNum++;
+ if (lineNum > info.lastLine) {
+ output.println(line);
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("writing line " + lineNum + " of " + file);
+ e.printStackTrace(System.err);
+ result = false;
+ } finally {
+ if (null != input) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ result = false;
+ }
+ }
+ if (null != outWriter) {
+ try {
+ outWriter.close();
+ } catch (IOException e) {
+ result = false;
+ }
+ }
+ result = inFile.delete();
+ }
+ return result;
+ }
+
+ public static HeaderInfo checkFile(final File file) {
+ ArrayList<String> years = new ArrayList<String>();
+ int endLine = 0;
+ BufferedReader input = null;
+ int lineNum = 0;
+ try {
+ input = new BufferedReader(new FileReader(file));
+ String line;
+ while (null != (line = input.readLine())) {
+ lineNum++;
+ String ll = line.trim();
+ if (ll.startsWith("package ") || ll.startsWith("import ")) {
+ break; // ignore default package w/o imports
+ }
+ if (checkLine(line, years)) {
+ endLine = lineNum;
+ break;
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("reading line " + lineNum + " of " + file);
+ e.printStackTrace(System.err);
+ } finally {
+ if (null != input) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ } // ignore
+ }
+ }
+ return new HeaderInfo(file, endLine, years, endLine > 0);
+ }
+
+ /**
+ * Add any years found (as String) to years, and return true at the first end-of-comment
+ *
+ * @return true if this line has end-of-comment
+ */
+ private static boolean checkLine(String line, ArrayList<String> years) {
+ if ((null == line) || (0 == line.length())) {
+ return false;
+ }
+ int loc;
+ int start = 0;
+
+ while ((-1 != (loc = line.indexOf("199", start)) || (-1 != (loc = line.indexOf("200", start))))) {
+ char c = line.charAt(loc + 3);
+ if ((c <= '9') && (c >= '0')) {
+ years.add(line.substring(loc, loc + 4));
+ }
+ start = loc + 4;
+ }
+
+ return (-1 != line.indexOf("*/"));
+ }
+
+} // class Header
+
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public abstract class ConditionalTask extends Task {
+
+ public final static String TRUE = "true";
+
+ private List<If> ifs;
+ protected List<If> ifs() {
+ return ifs != null ? ifs : (ifs = new Vector<If>());
+ }
+
+ public If createIf() {
+ If i = new If();
+ ifs().add(i);
+ return i;
+ }
+
+ public If createIf(String name, String equals, boolean strict) {
+ If i = createIf();
+ i.setName(name);
+ i.setEquals(equals);
+ i.setStrict(strict);
+ return i;
+ }
+
+ public If createIf(String name, String equals) {
+ return createIf(name, equals, false);
+ }
+
+ public If createIf(String name) {
+ return createIf(name, TRUE, false);
+ }
+
+ public If createIf(String name, boolean strict) {
+ return createIf(name, TRUE, strict);
+ }
+
+ public void setIfs(String ifs) {
+ StringTokenizer tok = new StringTokenizer(ifs, ",;: ", false);
+ while (tok.hasMoreTokens()) {
+ String next = tok.nextToken();
+ int iequals = next.lastIndexOf("=");
+ String equals;
+ String name;
+ boolean strict;
+ If i = createIf();
+ if (iequals != -1) {
+ name = next.substring(0, iequals);
+ equals = next.substring(iequals + 1);
+ strict = true;
+ } else {
+ name = next.substring(0);
+ equals = TRUE;
+ strict = false;
+ }
+ i.setName(name);
+ i.setEquals(equals);
+ i.setStrict(strict);
+ }
+ }
+
+ public void setIf(String ifStr) {
+ setIfs(ifStr);
+ }
+
+ public class If {
+ public If() {
+ this(null, null);
+ }
+ public If(String name) {
+ this(name, TRUE);
+ }
+ public If(String name, String equals) {
+ setName(name);
+ setEquals(equals);
+ }
+ private String name;
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ return name;
+ }
+ private String equals;
+ public void setEquals(String equals) {
+ this.equals = equals;
+ }
+ public String getEquals() {
+ return equals;
+ }
+ private boolean strict = false;
+ public void setStrict(boolean strict) {
+ this.strict = strict;
+ }
+ public boolean isStrict() {
+ return strict;
+ }
+ public boolean isOk(String prop) {
+ return isOk(prop, isStrict());
+ }
+ //XXX Need a better boolean parser
+ public boolean isOk(String prop, boolean isStrict) {
+ if (isStrict) {
+ return prop != null && prop.equals(getEquals());
+ } else {
+ if (isOk(prop, true)) {
+ return true;
+ }
+ if (prop == null || isFalse(getEquals())) {
+ return true;
+ }
+ if ( (isTrue(getEquals()) && isTrue(prop)) ||
+ (isFalse(getEquals()) && isFalse(prop)) ) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private boolean isFalse(String prop) {
+ return isOneOf(prop, falses) || isOneOf(prop, complement(trues));
+ }
+ private boolean isTrue(String prop) {
+ return isOneOf(prop, trues) || isOneOf(prop, complement(falses));
+ }
+ private boolean isOneOf(String prop, String[] strings) {
+ for (int i = 0; i < strings.length; i++) {
+ if (strings[i].equals(prop)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ private String[] complement(String[] strings) {
+ for (int i = 0; i < strings.length; i++) {
+ strings[i] = "!" + strings[i];
+ }
+ return strings;
+ }
+ }
+
+ final static String[] falses = { "false", "no" };
+ final static String[] trues = { "true", "yes" };
+
+ protected boolean checkIfs() {
+ return getFalses().size() == 0;
+ }
+
+ protected List<String> getFalses() {
+ Iterator<If> iter = ifs().iterator();
+ List<String> result = new Vector<String>();
+ while (iter.hasNext()) {
+ If next = (If) iter.next();
+ String name = next.getName();
+ String prop = project.getProperty(name);
+ if (prop == null) {
+ prop = project.getUserProperty(name);
+ }
+ if (!next.isOk(prop)) {
+ result.add(name);
+ }
+ }
+ return result;
+ }
+
+ public abstract void execute() throws BuildException;
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Mkdir;
+
+public class CopyAndInlineStylesheet extends Task {
+
+ private File file;
+ public void setFile(String file) {
+ this.file = project.resolveFile(file);
+ }
+
+ private File todir;
+ public void setTodir(String todir) {
+ this.todir = project.resolveFile(todir);
+ }
+
+
+ public void execute() throws BuildException {
+ try {
+ if (todir == null) {
+ throw new BuildException("must set 'todir' attribute");
+ }
+ if (file == null) {
+ throw new BuildException("must set 'file' attribute");
+ }
+ log("copying html from" + file + " to " + todir.getAbsolutePath());
+
+ File toFile = new File(todir, file.getName());
+
+ Mkdir mkdir = (Mkdir) project.createTask("mkdir");
+ mkdir.setDir(todir);
+ mkdir.execute();
+
+ BufferedReader in = new BufferedReader(new FileReader(file));
+ PrintStream out = new PrintStream(new FileOutputStream(toFile));
+
+ outer:
+ while (true) {
+ String line = in.readLine();
+ if (line == null) break;
+ if (isStyleSheet(line)) {
+ doStyleSheet(line, out, file);
+ while (true) {
+ String line2 = in.readLine();
+ if (line2 == null) break outer;
+ out.println(line2);
+ }
+ } else {
+ out.println(line);
+ }
+ }
+
+ in.close();
+ out.close();
+ } catch (IOException e) {
+ throw new BuildException(e.getMessage());
+ }
+ }
+
+ private static void doStyleSheet(String line, PrintStream out, File file) throws IOException {
+ int srcIndex = line.indexOf("href");
+ int startQuotIndex = line.indexOf('"', srcIndex);
+ int endQuotIndex = line.indexOf('"', startQuotIndex + 1);
+
+ String stylesheetLocation = line.substring(startQuotIndex + 1, endQuotIndex);
+
+ File styleSheetFile = new File(file.getParent(), stylesheetLocation);
+
+ out.println("<style type=\"text/css\">");
+ out.println("<!--");
+
+ BufferedReader inStyle = new BufferedReader(new FileReader(styleSheetFile));
+
+ while (true) {
+ String line2 = inStyle.readLine();
+ if (line2 == null) break;
+ out.println(line2);
+ }
+ inStyle.close();
+
+ out.println("-->");
+ out.println("</style>");
+ }
+
+
+ private static boolean isStyleSheet(String line) throws IOException {
+ line = line.toLowerCase();
+ int len = line.length();
+ int i = 0;
+
+ while (true) {
+ if (i == len) return false;
+ if (! Character.isWhitespace(line.charAt(i))) break;
+ }
+
+ return line.startsWith("<link", i);
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+
+/**
+ * Task to convert html source files into files with only body content.
+ *
+ * <p> This task can take the following arguments:</p>
+ *
+ * <ul>
+ * <li>srcdir</li>
+ * <li>destdir</li>
+ * <li>include</li>
+ * <li>exclude</li>
+ * </ul>
+ *
+ * <p>Of these arguments, only <b>sourcedir</b> is required.</p>
+ *
+ * <p> When this task executes, it will scan the srcdir based on the
+ * include and exclude properties.</p>
+ */
+
+public class StripNonBodyHtml extends MatchingTask {
+
+ private File srcDir;
+ private File destDir = null;
+
+ public void setSrcdir(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+ public void setDestdir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ public void execute() throws BuildException {
+ if (srcDir == null) {
+ throw new BuildException("srcdir attribute must be set!");
+ }
+ if (!srcDir.exists()) {
+ throw new BuildException("srcdir does not exist!");
+ }
+ if (!srcDir.isDirectory()) {
+ throw new BuildException("srcdir is not a directory!");
+ }
+ if (destDir != null) {
+ if (!destDir.exists()) {
+ throw new BuildException("destdir does not exist!");
+ }
+ if (!destDir.isDirectory()) {
+ throw new BuildException("destdir is not a directory!");
+ }
+ }
+
+ DirectoryScanner ds = super.getDirectoryScanner(srcDir);
+ String[] files = ds.getIncludedFiles();
+
+ log("stripping " + files.length + " files");
+ int stripped = 0;
+ for (int i = 0, len = files.length; i < len; i++) {
+ if (processFile(files[i])) {
+ stripped++;
+ } else {
+ log(files[i] + " not stripped");
+ }
+ }
+ log(stripped + " files successfully stripped");
+ }
+
+ boolean processFile(String filename) throws BuildException {
+ File srcFile = new File(srcDir, filename);
+ File destFile;
+ if (destDir == null) {
+ destFile = srcFile;
+ } else {
+ destFile = new File(destDir, filename);
+ destFile.getParentFile().mkdirs();
+ }
+ try {
+ return strip(srcFile, destFile);
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private boolean strip(File f, File g) throws IOException {
+ BufferedInputStream in =
+ new BufferedInputStream(new FileInputStream(f));
+ String s = readToString(in);
+ in.close();
+ return writeBodyTo(s, g);
+ }
+
+ private ByteArrayOutputStream temp = new ByteArrayOutputStream();
+ private byte[] buf = new byte[2048];
+
+ private String readToString(InputStream in) throws IOException {
+ ByteArrayOutputStream temp = this.temp;
+ byte[] buf = this.buf;
+ String s = "";
+ try {
+ while (true) {
+ int i = in.read(buf, 0, 2048);
+ if (i == -1) break;
+ temp.write(buf, 0, i);
+
+ }
+ s = temp.toString();
+ } finally {
+ temp.reset();
+ }
+ return s;
+ }
+
+ private boolean writeBodyTo(String s, File f) throws IOException {
+ int start;//, end;
+ try {
+ start = findStart(s);
+ findEnd(s, start);
+ } catch (ParseException e) {
+ return false; // if we get confused, just don't write the file.
+ }
+ s = processBody(s,f);
+ BufferedOutputStream out =
+ new BufferedOutputStream(new FileOutputStream(f));
+
+ out.write(s.getBytes());
+ out.close();
+ return true;
+ }
+
+ /**
+ * Process body. This implemenation strips text
+ * between <!-- start strip -->
+ * and <!-- end strip -->
+ * inclusive.
+ */
+ private String processBody(String body, File file) {
+ if (null == body) return body;
+ final String START = "<!-- start strip -->";
+ final String END = "<!-- end strip -->";
+ return stripTags(body, file.toString(), START, END);
+ }
+
+ /**
+ * Strip 0..n substrings in input: "s/${START}.*${END}//g"
+ * @param input the String to strip
+ * @param source the name of the source for logging purposes
+ * @param start the starting tag (case sensitive)
+ * @param end the ending tag (case sensitive)
+ */
+ String stripTags(String input, final String SOURCE,
+ final String START, final String END) {
+ if (null == input) return input;
+ StringBuffer buffer = new StringBuffer(input.length());
+ String result = input;
+ int curLoc = 0;
+ while (true) {
+ int startLoc = input.indexOf(START, curLoc);
+ if (-1 == startLoc) {
+ buffer.append(input.substring(curLoc));
+ result = buffer.toString();
+ break; // <------------ valid exit
+ } else {
+ int endLoc = input.indexOf(END, startLoc);
+ if (-1 == endLoc) {
+ log(SOURCE + " stripTags - no end tag - startLoc=" + startLoc);
+ break; // <------------ invalid exit
+ } else if (endLoc < startLoc) {
+ log(SOURCE + " stripTags - impossible: startLoc="
+ + startLoc + " > endLoc=" + endLoc);
+ break; // <------------ invalid exit
+ } else {
+ buffer.append(input.substring(curLoc, startLoc));
+ curLoc = endLoc + END.length();
+ }
+ }
+ }
+ return result;
+ }
+
+ private int findStart(String s) throws ParseException {
+ int len = s.length();
+ int start = 0;
+ while (true) {
+ start = s.indexOf("<body", start);
+ if (start == -1) {
+ start = s.indexOf("<BODY", start);
+ if (start == -1) throw barf();
+ }
+ start = start + 5;
+ if (start >= len) throw barf();
+ char ch = s.charAt(start);
+ if (ch == '>') return start + 1;
+ if (Character.isWhitespace(ch)) {
+ start = s.indexOf('>', start);
+ if (start == -1) return -1;
+ return start + 1;
+ }
+ }
+ }
+
+ private int findEnd(String s, int start) throws ParseException {
+ int end;
+ end = s.indexOf("</body>", start);
+ if (end == -1) {
+ end = s.indexOf("</BODY>", start);
+ if (end == -1) throw barf();
+ }
+ return end;
+ }
+
+ private static class ParseException extends Exception {
+ private static final long serialVersionUID = -1l;
+ }
+
+ private static ParseException barf() {
+ return new ParseException();
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Arrays;
+
+import org.apache.tools.ant.Project;
+import org.aspectj.internal.tools.build.BuildSpec;
+import org.aspectj.internal.tools.build.Builder;
+import org.aspectj.internal.tools.build.Util;
+
+public class TestBuildModule {
+// private static boolean REBUILD = false;
+ private static final String SYNTAX = "java {classname} <[product|module]dir>";
+ public static void main(String[] args) {
+
+ if ((null == args) || (1 > args.length)
+ || !Util.canReadDir(new File(args[0]))) {
+ System.err.println(SYNTAX);
+ return;
+ }
+ File dir = new File(args[0]);
+ // create a module
+ if (Util.canReadDir(new File(dir, "dist"))) {
+ createProduct(args);
+ } else if (Util.canReadFile(new File(dir, ".classpath"))) {
+ createModule(args);
+ } else {
+ System.err.println(SYNTAX);
+ }
+ }
+
+ static void createModule(String[] args) {
+ File moduleDir = new File(args[0]);
+ File baseDir = moduleDir.getParentFile();
+ if (null == baseDir) {
+ baseDir = new File(".");
+ }
+ File jarDir = new File(baseDir, "aj-build-jars");
+ if (!(Util.canReadDir(jarDir) || jarDir.mkdirs())) {
+ System.err.println("createModule unable to create " + jarDir);
+ return;
+ }
+
+ // set module dir or basedir plus module name
+ BuildSpec buildSpec = new BuildSpec();
+ buildSpec.moduleDir = moduleDir;
+ buildSpec.jarDir = jarDir;
+ buildSpec.verbose = true;
+ buildSpec.failonerror = true;
+ buildSpec.trimTesting = true;
+ buildSpec.rebuild = true;
+
+ File tempDir = null;
+ Project project = new Project();
+ project.setProperty("verbose", "true");
+ project.setName("TestBuildModule.createModule" + Arrays.asList(args));
+ Builder builder = AntBuilder.getBuilder("", project, tempDir);
+ builder.build(buildSpec);
+ }
+
+ static void createProduct(String[] args) {
+ throw new Error("unimplemented");
+ }
+}
+
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Check if version source file has the specified build version,
+ * and ensure a tag file reflects whether it does or not.
+ */
+public class VersionUptodate extends Task {
+ public VersionUptodate() {}
+
+ private String buildVersion;
+ private File versionSource;
+ private File versionTagFile;
+
+ /**
+ * @param buildVersion String expected as Version.text - required
+ */
+ public void setVersion(String buildVersion) {
+ this.buildVersion = buildVersion;
+ }
+
+ /**
+ * @param versionSource the File Version.java containing text constant
+ * - required
+ */
+ public void setVersionSourceFile(File versionSource) {
+ this.versionSource = versionSource;
+ }
+
+ /**
+ * @param versionTagFile the File whose existence signals that the version
+ * is uptodate after this task executes - required.
+ */
+ public void setVersionTagFile(File versionTagFile) {
+ this.versionTagFile = versionTagFile;
+ }
+
+ /**
+ * If the Version.java source file contains the correct
+ * build version, then create the output tag file,
+ * else delete it if it exists.
+ * @throws BuildException if tagFile not creatable and version is incorrect
+ * or if version is correct and tagFile cannot be deleted.
+ */
+ public void execute() throws BuildException {
+ if (null == buildVersion) {
+ throw new BuildException("require buildVersion");
+ }
+ if ((null == versionSource) || !versionSource.canRead()){
+ throw new BuildException("require versionSource");
+ }
+ if (null == versionTagFile){
+ throw new BuildException("require versionTagFile");
+ }
+ if (sameVersion(versionSource, buildVersion)) {
+ if (!versionTagFile.exists()) {
+ createFile(versionTagFile, buildVersion);
+ }
+ } else if (null == versionTagFile) {
+ throw new BuildException("no tag file, and version out of date");
+ } else if (versionTagFile.exists()) {
+ if (!versionTagFile.delete()) {
+ throw new BuildException("version out of date, but cannot delete " + versionTagFile);
+ }
+ }
+ }
+
+ /**
+ * Detect whether version is correct in Java sources.
+ * @param versionSource
+ * @param buildVersion
+ * @return boolean
+ */
+ private boolean sameVersion(File versionSource, String buildVersion) {
+ // XXX build and load instead of scanning?
+ FileReader fileReader = null;
+ try {
+ fileReader = new FileReader(versionSource);
+ BufferedReader reader = new BufferedReader(fileReader);
+ String line;
+ while (null != (line = reader.readLine())) {
+ int loc = line.indexOf("static final String text = ");
+ if (-1 != loc) {
+ return (-1 != line.indexOf(buildVersion , loc));
+ }
+ }
+ return false;
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (null != fileReader) {
+ try {
+ fileReader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Create file with contents
+ */
+ private void createFile(File versionTagFile, String contents) {
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(versionTagFile);
+ char[] buf = new char[contents.length()];
+ contents.getChars(0, buf.length, buf, 0);
+ writer.write(contents);
+ } catch (IOException e) {
+ throw new BuildException("writing " + versionTagFile, e);
+ } finally {
+ if (null != writer) {
+ try {
+ writer.close();
+ } catch (IOException e){
+ // ignore
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null
+ajinstaller=org.aspectj.internal.tools.ant.taskdefs.AJInstaller
+ajpush=org.aspectj.internal.tools.ant.taskdefs.AJPush
+ajbuild=org.aspectj.internal.tools.ant.taskdefs.BuildModule
+versionuptodate=org.aspectj.internal.tools.ant.taskdefs.VersionUptodate
+checklics=org.aspectj.internal.tools.ant.taskdefs.Checklics
+stripnonbodyhtml=org.aspectj.internal.tools.ant.taskdefs.StripNonBodyHtml
+
+# ajclean=org.aspectj.internal.tools.ant.taskdefs.AJclean
+# ajcvs=org.aspectj.internal.tools.ant.taskdefs.Ajcvs
+# ajikes=org.aspectj.internal.tools.ant.taskdefs.AJikes
+# ajinit=org.aspectj.internal.tools.ant.taskdefs.AjInit
+# checkrelease=org.aspectj.internal.tools.ant.taskdefs.Checkrelease
+# clear=org.aspectj.internal.tools.ant.taskdefs.Clear
+# inlinestylesheetaj=org.aspectj.internal.tools.ant.taskdefs.CopyAndInlineStyleshee
+# ensure=org.aspectj.internal.tools.ant.taskdefs.Ensure
+# ensureproperties=org.aspectj.internal.tools.ant.taskdefs.EnsureProperties
+# newdir=org.aspectj.internal.tools.ant.taskdefs.Newdir
+# overwrite=org.aspectj.internal.tools.ant.taskdefs.Overwrite
+# props2filters=org.aspectj.internal.tools.ant.taskdefs.Props2Filters
+# tgz=org.aspectj.internal.tools.ant.taskdefs.Tgz
+# vmcheck=org.aspectj.internal.tools.ant.taskdefs.VMCheck
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC),
+ * 2005 Contributors.
+ * 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:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.build;
+
+
+import java.io.File;
+
+/**
+ * Open struct for specifying builds for both modules and products.
+ * Separated from bulder to permit this to build many modules
+ * concurrently.
+ */
+public class BuildSpec {
+ public static final String DEFAULT_VERSION = "DEVELOPMENT";
+ // shared
+ public File baseDir;
+ public File moduleDir;
+ public File jarDir;
+ public File tempDir;
+ public File stagingDir;
+ public String buildConfig;
+ public String version;
+ public boolean rebuild;
+ public boolean trimTesting;
+ public boolean assembleAll;
+ public boolean failonerror;
+ public boolean verbose;
+
+ // building products
+ public File productDir;
+ public boolean createInstaller;
+ public File distDir;
+
+ // building modules
+ public String module;
+ public BuildSpec() {
+ version = DEFAULT_VERSION;
+ }
+
+ public boolean isProduct() {
+ return (Util.canReadDir(productDir));
+ }
+
+ public boolean isModule() {
+ return (!isProduct() && Util.canReadDir(moduleDir));
+ }
+
+ public boolean isValid() {
+ return (isProduct() || isModule());
+ }
+
+ public String toString() {
+ if (null != productDir) {
+ return "product " + productDir.getName();
+ } else if (null != moduleDir) {
+ return "module " + moduleDir.getName();
+ } else {
+ return "<bad BuildSpec - "
+ + " baseDir=" + baseDir
+ + " jarDir=" + jarDir
+ + " buildConfig=" + buildConfig
+ + " module=" + module
+ + ">";
+ }
+ }
+}
+
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC),
+ * 2003 Contributors.
+ * 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:
+ * PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.build;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.aspectj.internal.tools.build.Result.Kind;
+
+/**
+ * Template class to build (eclipse) modules (and, weakly, products), including
+ * any required modules. When building modules, this assumes:
+ * <ul>
+ * <li>the name of the module is the base name of the module directory</li>
+ * <li>all module directories are in the same base (workspace) directory</li>
+ * <li>the name of the target module jar is {moduleName}.jar</li>
+ * <li>a module directory contains a <code>.classpath</code> file with
+ * (currently line-parseable) entries per Eclipse (XML) conventions</li>
+ * <li><code>Builder.RESOURCE_PATTERN</code> identifies all resources to copy
+ * to output.</li>
+ * <li>This can safely trim test-related code:
+ * <ul>
+ * <li>source directories named "testsrc"</li>
+ * <li>libraries named "junit.jar"</li>
+ * <li>required modules whose names start with "testing"</li>
+ * </ul>
+ * <li>A file <code>{moduleDir}/{moduleName}.properties</code> is a property
+ * file possibly containing entries defining requirements to be merged with the
+ * output jar (deprecated mechanism - use assembleAll or products)</li>
+ * </ul>
+ * This currently provides no control over the compile or assembly process, but
+ * clients can harvest <code>{moduleDir}/bin</code> directories to re-use the
+ * results of eclipse compiles.
+ * <p>
+ * When building products, this assumes:
+ * <ul>
+ * <li>the installer-resources directory is a peer of the products directory,
+ * itself the parent of the particular product directory.</li>
+ * <li>the dist, jar, product, and base (module) directory are set</li>
+ * <li>the product distribution consists of all (and only) the files in the
+ * dist sub-directory of the product directory</li>
+ * <li>files in the dist sub-directory that are empty and end with .jar
+ * represent modules to build, either as named or through aliases known here.</li>
+ * <li>When assembling the distribution, all non-binary files are to be
+ * filtered.
+ * <li>
+ * <li>the name of the product installer is
+ * aspectj-{productName}-{version}.jar, where {productName} is the base name of
+ * the product directory</li>
+ * </ul>
+ * <p>
+ * When run using main(String[]), all relevant Ant libraries and properties must
+ * be defined.
+ * <p>
+ * Written to compile standalone. Refactor if using utils, bridge, etc.
+ */
+public abstract class Builder {
+
+ /**
+ * This has only weak forms for build instructions needed: - resource
+ * pattern - compiler selection and control
+ *
+ * Both assumed and generated paths are scattered; see XXXNameLiteral and
+ * XXXFileLiteral.
+ *
+ * Builder is supposed to be thread-safe, but currently caches build
+ * properties to tunnel for filters. hmm.
+ */
+
+ public static final String RESOURCE_PATTERN;
+
+ public static final String BINARY_SOURCE_PATTERN;
+
+ public static final String ALL_PATTERN;
+
+ /** enable copy filter semantics */
+ protected static final boolean FILTER_ON = true;
+
+ /** disable copy filter semantics */
+ protected static final boolean FILTER_OFF = false;
+
+ /** define libraries to skip as comma-delimited values for this key */
+ private static final String SKIP_LIBRARIES_KEY = "skip.libraries";
+
+ /** List (String) names of libraries to skip during assembly */
+ private static final List<String> SKIP_LIBRARIES;
+
+ private static final String ERROR_KEY = "error loading properties";
+
+ private static final Properties PROPS;
+ static {
+ PROPS = new Properties();
+ List<String> skips = Collections.emptyList();
+ String resourcePattern = "**/*.txt,**/*.rsc,**/*.gif,**/*.properties";
+ String allPattern = "**/*";
+ String binarySourcePattern = "**/*.rsc,**/*.gif,**/*.jar,**/*.zip";
+ String name = Builder.class.getName().replace('.', '/') + ".properties";
+ try {
+ InputStream in = Builder.class.getClassLoader()
+ .getResourceAsStream(name);
+ PROPS.load(in);
+ allPattern = PROPS.getProperty("all.pattern");
+ resourcePattern = PROPS.getProperty("resource.pattern");
+ binarySourcePattern = PROPS.getProperty("binarySource.pattern");
+ skips = commaStrings(PROPS.getProperty(SKIP_LIBRARIES_KEY));
+ } catch (Throwable t) {
+ if (t instanceof ThreadDeath) {
+ throw (ThreadDeath) t;
+ }
+ String m = "error loading " + name + ": " + t.getClass() + " " + t;
+ PROPS.setProperty(ERROR_KEY, m);
+ }
+ SKIP_LIBRARIES = skips;
+ ALL_PATTERN = allPattern;
+ BINARY_SOURCE_PATTERN = binarySourcePattern;
+ RESOURCE_PATTERN = resourcePattern;
+ }
+
+ /**
+ * Splits strings into an unmodifable <code>List</code> of String using
+ * comma as the delimiter and trimming whitespace from the result.
+ *
+ * @param text
+ * <code>String</code> to split.
+ * @return unmodifiable List (String) of String delimited by comma in text
+ */
+ public static List commaStrings(String text) {
+ if ((null == text) || (0 == text.length())) {
+ return Collections.EMPTY_LIST;
+ }
+ List<String> strings = new ArrayList<String>();
+ StringTokenizer tok = new StringTokenizer(text, ",");
+ while (tok.hasMoreTokens()) {
+ String token = tok.nextToken().trim();
+ if (0 < token.length()) {
+ strings.add(token);
+ }
+ }
+ return Collections.unmodifiableList(strings);
+ }
+
+ /**
+ * Map delivered-jar name to created-module name
+ *
+ * @param jarName
+ * the String (lowercased) of the jar/zip to map
+ */
+ private String moduleAliasFor(String jarName) {
+ String result = PROPS.getProperty("alias." + jarName, jarName);
+ if (verbose && result.equals(jarName)) {
+ String m = "expected alias for " + jarName;
+ handler.error(m + PROPS.getProperty(ERROR_KEY, ""));
+ }
+ return result;
+ }
+
+ protected final Messager handler;
+
+ protected boolean buildingEnabled;
+
+ private final File tempDir;
+
+ private final ArrayList tempFiles;
+
+ private final boolean useEclipseCompiles;
+
+ protected boolean verbose;
+
+ protected Builder(File tempDir, boolean useEclipseCompiles, Messager handler) {
+ Util.iaxIfNull(handler, "handler");
+ this.useEclipseCompiles = useEclipseCompiles;
+ this.handler = handler;
+ this.tempFiles = new ArrayList();
+ if ((null == tempDir) || !tempDir.canWrite() || !tempDir.isDirectory()) {
+ this.tempDir = Util.makeTempDir("Builder");
+ } else {
+ this.tempDir = tempDir;
+ }
+ buildingEnabled = true;
+ }
+
+ /** tell builder to stop or that it's ok to run */
+ public void setBuildingEnabled(boolean enabled) {
+ buildingEnabled = enabled;
+ }
+
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ private void verifyBuildSpec(BuildSpec buildSpec) {
+ if (null == buildSpec.productDir) { // ensure module properties
+ // derive moduleDir from baseDir + module
+ if (null == buildSpec.moduleDir) {
+ if (null == buildSpec.baseDir) {
+ throw new BuildException("require baseDir or moduleDir");
+ } else if (null == buildSpec.module) {
+ throw new BuildException("require module with baseDir");
+ } else {
+ if (null == buildSpec.baseDir) {
+ buildSpec.baseDir = new File("."); // user.home?
+ }
+ buildSpec.moduleDir = new File(buildSpec.baseDir,
+ buildSpec.module);
+ }
+ } else if (null == buildSpec.baseDir) {
+ // derive baseDir from moduleDir parent
+ buildSpec.baseDir = buildSpec.moduleDir.getParentFile();
+ // rule: base is parent
+ if (null == buildSpec.baseDir) {
+ buildSpec.baseDir = new File("."); // user.home?
+ }
+ handler.log("Builder using derived baseDir: "
+ + buildSpec.baseDir);
+ }
+ Util.iaxIfNotCanReadDir(buildSpec.moduleDir, "moduleDir");
+ if (null == buildSpec.module) {
+ // derive module name from directory
+ buildSpec.module = buildSpec.moduleDir.getName();
+ if (null == buildSpec.module) {
+ throw new BuildException("no name, even from "
+ + buildSpec.moduleDir);
+ }
+ }
+ }
+ }
+
+ /**
+ * Find the Result (and hence Module and Modules) for this BuildSpec.
+ */
+ protected Result specifyResultFor(BuildSpec buildSpec) {
+ if (buildSpec.trimTesting
+ && (-1 != buildSpec.module.indexOf("testing"))) { // XXXNameLiteral
+ String warning = "Warning - cannot trimTesting for testing modules: ";
+ handler.log(warning + buildSpec.module);
+ }
+ Messager handler = new Messager();
+ Modules modules = new Modules(buildSpec.baseDir, buildSpec.jarDir,
+ handler);
+
+ final Module moduleToBuild = modules.getModule(buildSpec.module);
+ Kind kind = Result.kind(buildSpec.trimTesting,
+ buildSpec.assembleAll);
+ return moduleToBuild.getResult(kind);
+ }
+
+ public final boolean build(BuildSpec buildSpec) {
+ if (!buildingEnabled) {
+ return false;
+ }
+ verifyBuildSpec(buildSpec);
+
+ if (null != buildSpec.productDir) {
+ return buildProduct(buildSpec);
+ }
+ Result result = specifyResultFor(buildSpec);
+ ArrayList<String> errors = new ArrayList<String>();
+ try {
+ return buildAll(result, errors);
+ } finally {
+ if (0 < errors.size()) {
+ String label = "error building " + buildSpec + ": ";
+ for (Iterator<String> iter = errors.iterator(); iter.hasNext();) {
+ String m = label + iter.next();
+ handler.error(m);
+ }
+ }
+ }
+ }
+
+ /**
+ * Clean up any temporary files, etc. after build completes
+ */
+ public boolean cleanup() {
+ boolean noErr = true;
+ for (ListIterator iter = tempFiles.listIterator(); iter.hasNext();) {
+ File file = (File) iter.next();
+ if (!Util.deleteContents(file) || !file.delete()) {
+ if (noErr) {
+ noErr = false;
+ }
+ handler.log("unable to clean up " + file);
+ }
+ }
+ return noErr;
+ }
+
+ protected final boolean isLogging() {
+ return (verbose && (null != this.handler));
+ }
+
+ protected Result[] skipUptodate(Result[] results) {
+ if (null == results) {
+ return new Result[0];
+ }
+ Result[] done = new Result[results.length];
+ int to = 0;
+ for (int i = 0; i < done.length; i++) {
+ if ((null != results[i]) && results[i].outOfDate()) {
+ done[to++] = results[i];
+ }
+ }
+ if (to < results.length) {
+ Result[] newdone = new Result[to];
+ System.arraycopy(done, 0, newdone, 0, newdone.length);
+ done = newdone;
+ }
+ return done;
+ }
+
+ /**
+ * Build a result with all antecedants.
+ *
+ * @param result
+ * the Result to build
+ * @param errors
+ * the List sink for errors, if any
+ * @return false after successful build, when module jar should exist
+ */
+ protected final boolean buildAll(Result result, List errors) {
+ Result[] buildList = skipUptodate(getAntecedantResults(result));
+ ArrayList<String> doneList = new ArrayList<String>();
+ if ((null != buildList) && (0 < buildList.length)) {
+ if (isLogging()) {
+ handler.log("modules to build: " + Arrays.asList(buildList));
+ }
+ for (int i = 0; i < buildList.length; i++) {
+ Result required = buildList[i];
+ if (!buildingEnabled) {
+ return false;
+ }
+ String requiredName = required.getName();
+ if (!doneList.contains(requiredName)) {
+ doneList.add(requiredName);
+ if (!buildOnly(required, errors)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Build a module but no antecedants.
+ *
+ * @param module
+ * the Module to build
+ * @param errors
+ * the List sink for errors, if any
+ * @return false after successful build, when module jar should exist
+ */
+ protected final boolean buildOnly(Result result, List<String> errors) {
+ if (!result.outOfDate()) {
+ return true;
+ }
+ if (isLogging()) {
+ handler.log("building " + result);
+ }
+ if (!buildingEnabled) {
+ return false;
+ }
+ if (result.getKind().assemble) {
+ return assembleAll(result, handler);
+ }
+ Module module = result.getModule();
+ final File classesDir;
+ if (useEclipseCompiles) {
+ classesDir = new File(module.moduleDir, "bin"); // FileLiteral
+ } else {
+ String name = "classes-" + System.currentTimeMillis();
+ classesDir = new File(tempDir, name);
+ }
+ if (verbose) {
+ handler.log("buildOnly " + module);
+ }
+ try {
+ return (compile(result, classesDir,useEclipseCompiles, errors))
+ && assemble(result, classesDir, errors);
+ } finally {
+ if (!useEclipseCompiles && !Util.delete(classesDir)) {
+ errors.add("buildOnly unable to delete " + classesDir);
+ }
+ }
+ }
+
+ /**
+ * Register temporary file or directory to be deleted when the build is
+ * complete, even if an Exception is thrown.
+ */
+ protected void addTempFile(File tempFile) {
+ if (null != tempFile) {
+ tempFiles.add(tempFile);
+ }
+ }
+
+ /**
+ * Build product by discovering any modules to build, building those,
+ * assembling the product distribution, and optionally creating an installer
+ * for it.
+ *
+ * @return true on success
+ */
+ protected final boolean buildProduct(BuildSpec buildSpec)
+ throws BuildException {
+ Util.iaxIfNull(buildSpec, "buildSpec");
+
+ if (!buildSpec.trimTesting) {
+ buildSpec.trimTesting = true;
+ handler.log("testing trimmed for " + buildSpec);
+ }
+ Util.iaxIfNotCanReadDir(buildSpec.productDir, "productDir");
+ Util.iaxIfNotCanReadDir(buildSpec.baseDir, "baseDir");
+ Util.iaxIfNotCanWriteDir(buildSpec.distDir, "distDir");
+
+ // ---- discover modules to build, and build them
+ Modules modules = new Modules(buildSpec.baseDir, buildSpec.jarDir,
+ handler);
+ ProductModule[] productModules = discoverModules(buildSpec.productDir,
+ modules);
+ for (int i = 0; i < productModules.length; i++) {
+ if (buildSpec.verbose) {
+ handler.log("building product module " + productModules[i]);
+ }
+ if (!buildProductModule(productModules[i])) {
+ return false;
+ }
+ }
+ if (buildSpec.verbose) {
+ handler.log("assembling product module for " + buildSpec);
+ }
+
+ // ---- assemble product distribution
+ final String productName = buildSpec.productDir.getName();
+ final File targDir = new File(buildSpec.distDir, productName);
+ final String targDirPath = targDir.getPath();
+ if (targDir.canWrite()) {
+ Util.deleteContents(targDir);
+ }
+
+ if (!targDir.canWrite() && !targDir.mkdirs()) {
+ if (buildSpec.verbose) {
+ handler.log("buildProduct unable to create " + targDir);
+ }
+ return false;
+ }
+
+ // copy non-binaries (with filter)
+ File distDir = new File(buildSpec.productDir, "dist");
+ if (!copyNonBinaries(buildSpec, distDir, targDir)) {
+ return false;
+ }
+
+ // copy binaries (but not module flag files)
+ String excludes = null;
+ {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < productModules.length; i++) {
+ if (0 < buf.length()) {
+ buf.append(",");
+ }
+ buf.append(productModules[i].relativePath);
+ }
+ if (0 < buf.length()) {
+ excludes = buf.toString();
+ }
+ }
+
+ if (!copyBinaries(buildSpec, distDir, targDir, excludes)) {
+ return false;
+ }
+
+ // copy binaries associated with module flag files
+ for (int i = 0; i < productModules.length; i++) {
+ final ProductModule product = productModules[i];
+ final Kind kind = Result.kind(Result.NORMAL, product.assembleAll);
+ Result result = product.module.getResult(kind);
+ String targPath = Util.path(targDirPath, product.relativePath);
+ File jarFile = result.getOutputFile();
+ copyFile(jarFile, new File(targPath), FILTER_OFF);
+ }
+ handler.log("created product in " + targDir);
+
+ // ---- create installer
+ if (buildSpec.createInstaller) {
+ return buildInstaller(buildSpec, targDirPath);
+ } else {
+ return true;
+ }
+ }
+
+ protected boolean copyBinaries(BuildSpec buildSpec, File distDir,
+ File targDir, String excludes) {
+ String includes = Builder.BINARY_SOURCE_PATTERN;
+ return copyFiles(distDir, targDir, includes, excludes, FILTER_OFF);
+ }
+
+ /**
+ * filter-copy everything but the binaries
+ */
+ protected boolean copyNonBinaries(BuildSpec buildSpec, File distDir,
+ File targDir) {
+ String excludes = Builder.BINARY_SOURCE_PATTERN;
+ String includes = Builder.ALL_PATTERN;
+ return copyFiles(distDir, targDir, includes, excludes, FILTER_ON);
+ }
+
+ protected final boolean buildProductModule(ProductModule module) {
+ ArrayList errors = new ArrayList();
+ try {
+ Kind productKind = Result.kind(Result.NORMAL, Result.ASSEMBLE);
+ Result result = module.module.getResult(productKind);
+ return buildAll(result, errors);
+ } finally {
+ for (Iterator iter = errors.iterator(); iter.hasNext();) {
+ handler.error("error building " + module + ": " + iter.next());
+ }
+ }
+ }
+
+ /**
+ * Discover any modules that might need to be built in order to assemble the
+ * product distribution. This interprets empty .jar files as module
+ * deliverables.
+ */
+ protected ProductModule[] discoverModules(File productDir, Modules modules) {
+ final ArrayList<File> found = new ArrayList<File>();
+ FileFilter filter = new FileFilter() {// empty jar files
+ public boolean accept(File file) {
+ if ((null != file) && file.canRead()
+ && file.getPath().endsWith(".jar") // XXXFileLiteral
+ && (0l == file.length())) {
+ found.add(file);
+ }
+ return true;
+ }
+ };
+ Util.visitFiles(productDir, filter);
+ ArrayList<ProductModule> results = new ArrayList<ProductModule>();
+ for (File file: found) {
+ String jarName = moduleAliasFor(file.getName().toLowerCase());
+ if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) { // XXXFileLiteral
+ jarName = jarName.substring(0, jarName.length() - 4);
+ } else {
+ handler.log("can only replace .[jar|zip]: " + file);
+ // XXX error?
+ }
+ boolean assembleAll = jarName.endsWith("-all");
+ // XXXFileLiteral
+ String name = (!assembleAll ? jarName : jarName.substring(0,
+ jarName.length() - 4));
+ Module module = modules.getModule(name);
+ if (null == module) {
+ handler.log("unable to find module for " + file);
+ } else {
+ results.add(new ProductModule(productDir, file, module,
+ assembleAll));
+ }
+ }
+ return (ProductModule[]) results.toArray(new ProductModule[0]);
+ }
+
+ /**
+ * Subclasses should query whether to include library files in the assembly.
+ *
+ * @param module
+ * the Module being built
+ * @param libraries
+ * the List of File path to the jar to consider assembling
+ * @return true if the jar should be included, false otherwise.
+ */
+ protected void removeLibraryFilesToSkip(Module module, List libraries) {
+ for (ListIterator liter = libraries.listIterator(); liter.hasNext();) {
+ File library = (File) liter.next();
+ final String fname = library.getName();
+ if (null != fname) {
+ for (Iterator iter = SKIP_LIBRARIES.iterator(); iter.hasNext();) {
+ String name = (String) iter.next();
+ if (fname.equals(name)) {
+ liter.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @return String[] names of results to build for this module
+ */
+ abstract protected Result[] getAntecedantResults(Result toBuild);
+
+ /**
+ * Compile module classes to classesDir, saving String errors.
+ *
+ * @param module
+ * the Module to compile
+ * @param classesDir
+ * the File directory to compile to
+ * @param useExistingClasses
+ * if true, don't recompile and ensure classes are available
+ * @param errors
+ * the List to add error messages to
+ */
+ abstract protected boolean compile(Result result, File classesDir,
+ boolean useExistingClasses, List<String> errors);
+
+ /**
+ * Assemble the module distribution from the classesDir, saving String
+ * errors.
+ *
+ * @see #removeLibraryFilesToSkip(Module, File)
+ */
+ abstract protected boolean assemble(Result result, File classesDir,
+ List<String> errors);
+
+ /**
+ * Assemble the module distribution from the classesDir and all
+ * antecendants, saving String errors.
+ *
+ * @see #removeLibraryFilesToSkip(Module, File)
+ */
+ abstract protected boolean assembleAll(Result result, Messager handler);
+
+ /**
+ * Generate the installer for this product to targDirPath
+ */
+ abstract protected boolean buildInstaller(BuildSpec buildSpec,
+ String targDirPath);
+
+ /**
+ * Copy fromFile to toFile, optionally filtering contents
+ */
+ abstract protected boolean copyFile(File fromFile, File toFile,
+ boolean filter);
+
+ /**
+ * Copy toDir any fromDir included files without any exluded files,
+ * optionally filtering contents.
+ *
+ * @param fromDir
+ * File dir to read from - error if not readable
+ * @param toDir
+ * File dir to write to - error if not writable
+ * @param included
+ * String Ant pattern of included files (if null, include all)
+ * @param excluded
+ * String Ant pattern of excluded files (if null, exclude none)
+ * @param filter
+ * if FILTER_ON, then filter file contents using global
+ * token/value pairs
+ */
+ abstract protected boolean copyFiles(File fromDir, File toDir,
+ String included, String excluded, boolean filter);
+}
--- /dev/null
+# documented in build/readme-build-module.html
+
+# alias product/dist/lib/{name} to project jar
+# used by Builder.moduleAliasFor(String)
+alias.aspectjtools.jar=ajbrowser-all.jar
+alias.aspectjrt.jar=aspectj5rt-all.jar
+alias.aspectjweaver.jar=loadtime5-all.jar
+# alias.aspectjlib.jar=org.aspectj.lib.jar
+alias.org.aspectj.matcher.jar=org.aspectj.matcher-all.jar
+
+# libraries to avoid bundling (IBM JRE different, etc.)
+# see build/readme-build-module.html, Builder.SKIP_LIBRARIES
+skip.libraries=asm-3.1.jar,core.jar,graphics.jar,ant.jar,tools.jar,bcel-verifier.jar,asm-3.1.jar,junit.jar,xml-apis.jar,xercesImpl.jar,commons.jar,jrockit.jar
+
+# Ant patterns to gather and omit resources
+# files copied during module jar assembly
+resource.pattern=**/*.txt,**/*.rsc,**/*.gif,**/*.properties,**/*.xml,**/*.dtd
+# files not filtered when copied during product assembly
+binarySource.pattern=**/*.rsc,**/*.gif,**/*.jar,**/*.zip
+all.pattern=**/*
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.build;
+
+/** logging stub XXX replace */
+public class Messager {
+ public Messager() {
+ }
+ public boolean log(String s) {
+ System.out.println(s);
+ return true;
+ }
+
+ public boolean error(String s) {
+ System.out.println(s);
+ return true;
+ }
+
+ public boolean logException(String context, Throwable thrown) {
+ System.err.println(context);
+ thrown.printStackTrace(System.err);
+ return true;
+ }
+}
+
+
+
+
+
+
+
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.build;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.aspectj.internal.tools.build.Result.Kind;
+import org.aspectj.internal.tools.build.Util.OSGIBundle;
+import org.aspectj.internal.tools.build.Util.OSGIBundle.RequiredBundle;
+
+
+/**
+ * This represents an (eclipse) build module/unit used by a Builder to compile
+ * classes and/or assemble zip file of classes, optionally with all antecedants.
+ * This implementation infers attributes from two files in the module directory:
+ * <ul>
+ * <li>an Eclipse project <code>.classpath</code> file containing required
+ * libraries and modules (collectively, "antecedants") </li>
+ * <li>a file <code>{moduleName}.mf.txt</code> is taken as the manifest of
+ * any .jar file produced, after filtering. </li>
+ * </ul>
+ *
+ * @see Builder
+ * @see Modules#getModule(String)
+ */
+public class Module {
+ private static final String[] ATTS = new String[] { "exported", "kind",
+ "path", "sourcepath" };
+
+// private static final int getATTSIndex(String key) {
+// for (int i = 0; i < ATTS.length; i++) {
+// if (ATTS[i].equals(key))
+// return i;
+// }
+// return -1;
+// }
+
+ /**
+ * @return true if file is null or cannot be read or was last modified after
+ * time
+ */
+ private static boolean outOfDate(long time, File file) {
+ return ((null == file) || !file.canRead() || (file.lastModified() > time));
+ }
+
+ /** @return all source files under srcDir */
+ private static Iterator<File> sourceFiles(File srcDir) {
+ ArrayList<File> result = new ArrayList<File>();
+ sourceFiles(srcDir, result);
+ return result.iterator();
+ }
+
+ private static void sourceFiles(File srcDir, List<File> result) {
+ if ((null == srcDir) || !srcDir.canRead() || !srcDir.isDirectory()) {
+ return;
+ }
+ File[] files = srcDir.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ sourceFiles(files[i], result);
+ } else if (isSourceFile(files[i])) {
+ result.add(files[i]);
+ }
+ }
+ }
+
+ private static void addIfNew(List<File> source, List<File> sink) {
+ for (File item: source) {
+ if (!sink.contains(item)) {
+ sink.add(item);
+ }
+ }
+ }
+
+ /**
+ * Recursively find antecedant jars.
+ *
+ * @see findKnownJarAntecedants()
+ */
+ static void doFindJarRequirements(Result result, List<File> known) {
+ Util.iaxIfNull(result, "result");
+ Util.iaxIfNull(known, "known");
+ addIfNew(result.getLibJars(), known);
+ addIfNew(result.getExportedLibJars(), known);
+ Result[] reqs = result.getRequired();
+ for (int i = 0; i < reqs.length; i++) {
+ Result requiredResult = reqs[i];
+ File requiredJar = requiredResult.getOutputFile();
+ if (!known.contains(requiredJar)) {
+ known.add(requiredJar);
+ doFindJarRequirements(requiredResult, known);
+ }
+ }
+ }
+
+ /** @return true if this is a source file */
+ private static boolean isSourceFile(File file) {
+ String path = file.getPath();
+ return (path.endsWith(".java") || path.endsWith(".aj")); // XXXFileLiteral
+ }
+
+// /** @return List of File of any module or library jar ending with suffix */
+// private static ArrayList findJarsBySuffix(String suffix, Kind kind,
+// List libJars, List required) {
+// ArrayList result = new ArrayList();
+// if (null != suffix) {
+// // library jars
+// for (Iterator iter = libJars.iterator(); iter.hasNext();) {
+// File file = (File) iter.next();
+// if (file.getPath().endsWith(suffix)) {
+// result.add(file);
+// }
+// }
+// // module jars
+// for (Iterator iter = required.iterator(); iter.hasNext();) {
+// Module module = (Module) iter.next();
+// Result moduleResult = module.getResult(kind);
+// File file = moduleResult.getOutputFile();
+// if (file.getPath().endsWith(suffix)) {
+// result.add(file);
+// }
+// }
+// }
+// return result;
+// }
+
+ public final boolean valid;
+
+ public final File moduleDir;
+
+ public final String name;
+
+ /** reference back to collection for creating required modules */
+ private final Modules modules;
+
+ private final Result release;
+
+ private final Result test;
+
+ private final Result testAll;
+
+ private final Result releaseAll;
+
+ /** path to output jar - may not exist */
+ private final File moduleJar;
+
+ /** File list of library jars */
+ private final List<File> libJars;
+
+ /** List of classpath variables */
+ private final List<String> classpathVariables;
+
+ /**
+ * List of library jars exported to clients (duplicates some libJars
+ * entries)
+ */
+ private final List<File> exportedLibJars;
+
+ /** File list of source directories */
+ private final List<File> srcDirs;
+
+ /** properties from the modules {name}.properties file */
+ private final Properties properties;
+
+ /** List of required modules */
+ private final List<Module> requiredModules;
+
+ /** logger */
+ private final Messager messager;
+
+ Module(File moduleDir, File jarDir, String name, Modules modules,
+ Messager messager) {
+ Util.iaxIfNotCanReadDir(moduleDir, "moduleDir");
+ Util.iaxIfNotCanReadDir(jarDir, "jarDir");
+ Util.iaxIfNull(name, "name");
+ Util.iaxIfNull(modules, "modules");
+ this.moduleDir = moduleDir;
+ this.libJars = new ArrayList<File>();
+ this.exportedLibJars = new ArrayList<File>();
+ this.requiredModules = new ArrayList<Module>();
+ this.srcDirs = new ArrayList<File>();
+ this.classpathVariables = new ArrayList<String>();
+ this.properties = new Properties();
+ this.name = name;
+ this.modules = modules;
+ this.messager = messager;
+ this.moduleJar = new File(jarDir, name + ".jar");
+ this.release = new Result(Result.RELEASE, this, jarDir);
+ this.releaseAll = new Result(Result.RELEASE_ALL, this, jarDir);
+ this.test = new Result(Result.TEST, this, jarDir);
+ this.testAll = new Result(Result.TEST_ALL, this, jarDir);
+ valid = init();
+ }
+
+
+ /** @return Modules registry of known modules, including this one */
+ public Modules getModules() {
+ return modules;
+ }
+
+ /**
+ * @param kind
+ * the Kind of the result to recalculate
+ * @param recalculate
+ * if true, then force recalculation
+ * @return true if the target jar for this module is older than any source
+ * files in a source directory or any required modules or any
+ * libraries or if any libraries or required modules are missing
+ */
+ public static boolean outOfDate(Result result) {
+ File outputFile = result.getOutputFile();
+ if (!(outputFile.exists() && outputFile.canRead())) {
+ return true;
+ }
+ final long time = outputFile.lastModified();
+ File file;
+ for (Iterator<File> iter = result.getSrcDirs().iterator(); iter.hasNext();) {
+ File srcDir = iter.next();
+ for (Iterator<File> srcFiles = sourceFiles(srcDir); srcFiles.hasNext();) {
+ file = srcFiles.next();
+ if (outOfDate(time, file)) {
+ return true;
+ }
+ }
+ }
+ // required modules
+ Result[] reqs = result.getRequired();
+ for (int i = 0; i < reqs.length; i++) {
+ Result requiredResult = reqs[i];
+ file = requiredResult.getOutputFile();
+ if (outOfDate(time, file)) {
+ return true;
+ }
+ }
+ // libraries
+ for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
+ file = (File) iter.next();
+ if (outOfDate(time, file)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+ public String toString() {
+ return name;
+ }
+
+ public String toLongString() {
+ return "Module [name=" + name + ", srcDirs=" + srcDirs + ", required="
+ + requiredModules + ", moduleJar=" + moduleJar + ", libJars="
+ + libJars + "]";
+ }
+
+ public Result getResult(Kind kind) {
+ return kind.assemble ? (kind.normal ? releaseAll : testAll)
+ : (kind.normal ? release : test);
+ }
+
+ List<File> srcDirs(Result result) {
+ myResult(result);
+ return srcDirs;
+ }
+
+ List<File> libJars(Result result) {
+ myResult(result);
+ return libJars;
+ }
+
+ List<String> classpathVariables(Result result) {
+ myResult(result);
+ return classpathVariables;
+ }
+
+ List<File> exportedLibJars(Result result) {
+ myResult(result);
+ return exportedLibJars;
+ }
+
+ List<Module> requiredModules(Result result) {
+ myResult(result);
+ return requiredModules;
+ }
+
+ private void myResult(Result result) {
+ if ((null == result) || this != result.getModule()) {
+ throw new IllegalArgumentException("not my result: " + result + ": " + this);
+ }
+ }
+
+ private boolean init() {
+ boolean cp = initClasspath();
+ boolean mf = initManifest();
+ if (!cp && !mf) {
+ return false;
+ }
+ return initProperties() && reviewInit() && initResults();
+ }
+
+ /** read OSGI manifest.mf file XXX hacked */
+ private boolean initManifest() {
+ File metaInf = new File(moduleDir, "META-INF");
+ if (!metaInf.canRead() || !metaInf.isDirectory()) {
+ return false;
+ }
+ File file = new File(metaInf, "MANIFEST.MF"); // XXXFileLiteral
+ if (!file.exists()) {
+ return false; // ok, not OSGI
+ }
+ InputStream fin = null;
+ OSGIBundle bundle = null;
+ try {
+ fin = new FileInputStream(file);
+ bundle = new OSGIBundle(fin);
+ } catch (IOException e) {
+ messager.logException("IOException reading " + file, e);
+ return false;
+ } finally {
+ Util.closeSilently(fin);
+ }
+ RequiredBundle[] bundles = bundle.getRequiredBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ RequiredBundle required = bundles[i];
+ update("src", "/" + required.name, required.text, false);
+ }
+ String[] libs = bundle.getClasspath();
+ for (int i = 0; i < libs.length; i++) {
+ update("lib", libs[i], libs[i], false);
+ }
+
+ return true;
+ }
+
+ /** read eclipse .classpath file XXX line-oriented hack */
+ private boolean initClasspath() {
+ // meaning testsrc directory, junit library, etc.
+ File file = new File(moduleDir, ".classpath"); // XXXFileLiteral
+ if (!file.exists()) {
+ return false; // OSGI???
+ }
+ FileReader fin = null;
+ try {
+ fin = new FileReader(file);
+ BufferedReader reader = new BufferedReader(fin);
+ String line;
+ XMLItem item = new XMLItem("classpathentry", new ICB());
+ while (null != (line = reader.readLine())) {
+ line = line.trim();
+ // dumb - only handle comment-only lines
+ if (!line.startsWith("<?xml") && !line.startsWith("<!--")) {
+ item.acceptLine(line);
+ }
+ }
+ return (0 < (srcDirs.size() + libJars.size()));
+ } catch (IOException e) {
+ messager.logException("IOException reading " + file, e);
+ } finally {
+ if (null != fin) {
+ try {
+ fin.close();
+ } catch (IOException e) {
+ } // ignore
+ }
+ }
+ return false;
+ }
+
+// private boolean update(String toString, String[] attributes) {
+// String kind = attributes[getATTSIndex("kind")];
+// String path = attributes[getATTSIndex("path")];
+// String exp = attributes[getATTSIndex("exported")];
+// boolean exported = ("true".equals(exp));
+// return update(kind, path, toString, exported);
+// }
+
+ private boolean update(String kind, String path, String toString,
+ boolean exported) {
+ String libPath = null;
+ if ("src".equals(kind)) {
+ if (path.startsWith("/")) { // module
+ String moduleName = path.substring(1);
+ Module req = modules.getModule(moduleName);
+ if (null != req) {
+ requiredModules.add(req);
+ return true;
+ } else {
+ messager.error("update unable to create required module: "
+ + moduleName);
+ }
+ } else { // src dir
+ String fullPath = getFullPath(path);
+ File srcDir = new File(fullPath);
+ if (srcDir.canRead() && srcDir.isDirectory()) {
+ srcDirs.add(srcDir);
+ return true;
+ } else {
+ messager.error("not a src dir: " + srcDir);
+ }
+ }
+ } else if ("lib".equals(kind)) {
+ libPath = path;
+ } else if ("var".equals(kind)) {
+ final String JAVA_HOME = "JAVA_HOME/";
+ if (path.startsWith(JAVA_HOME)) {
+ path = path.substring(JAVA_HOME.length());
+ String home = System.getProperty("java.home");
+ if (null != home) {
+ libPath = Util.path(home, path);
+ File f = new File(libPath);
+ if (!f.exists() && home.endsWith("jre")) {
+ f = new File(home).getParentFile();
+ libPath = Util.path(f.getPath(), path);
+ }
+ }
+ }
+ if (null == libPath) {
+ warnVariable(path, toString);
+ classpathVariables.add(path);
+ }
+ } else if ("con".equals(kind)) {
+ // 'special' for container pointing at AspectJ runtime...
+ if (path.equals("org.eclipse.ajdt.core.ASPECTJRT_CONTAINER")) {
+ classpathVariables.add("ASPECTJRT_LIB");
+ } else {
+ if (-1 == path.indexOf("JRE")) { // warn non-JRE containers
+ messager.log("cannot handle con yet: " + toString);
+ }
+ }
+ } else if ("out".equals(kind) || "output".equals(kind)) {
+ // ignore output entries
+ } else {
+ messager.log("unrecognized kind " + kind + " in " + toString);
+ }
+ if (null != libPath) {
+ File libJar = new File(libPath);
+ if (!libJar.exists()) {
+ libJar = new File(getFullPath(libPath));
+ }
+ if (libJar.canRead() && libJar.isFile()) {
+ libJars.add(libJar);
+ if (exported) {
+ exportedLibJars.add(libJar);
+ }
+ return true;
+ } else {
+ messager.error("no such library jar " + libJar + " from "
+ + toString);
+ }
+ }
+ return false;
+ }
+
+ private void warnVariable(String path, String toString) {
+ String[] known = { "JRE_LIB", "ASPECTJRT_LIB", "JRE15_LIB" };
+ for (int i = 0; i < known.length; i++) {
+ if (known[i].equals(path)) {
+ return;
+ }
+ }
+ messager.log("Module cannot handle var yet: " + toString);
+ }
+
+ /** @return true if any properties were read correctly */
+ private boolean initProperties() {
+ File file = new File(moduleDir, name + ".properties"); // XXXFileLiteral
+ if (!Util.canReadFile(file)) {
+ return true; // no properties to read
+ }
+ FileInputStream fin = null;
+ try {
+ fin = new FileInputStream(file);
+ properties.load(fin);
+ return true;
+ } catch (IOException e) {
+ messager.logException("IOException reading " + file, e);
+ return false;
+ } finally {
+ if (null != fin) {
+ try {
+ fin.close();
+ } catch (IOException e) {
+ } // ignore
+ }
+ }
+ }
+
+ /**
+ * Post-process initialization. This implementation trims java5 source dirs
+ * if not running in a Java 5 VM.
+ * @return true if initialization post-processing worked
+ */
+ protected boolean reviewInit() {
+ try {
+ for (ListIterator iter = srcDirs.listIterator(); iter.hasNext();) {
+ File srcDir = (File) iter.next();
+ String lcname = srcDir.getName().toLowerCase();
+ if (!Util.JAVA5_VM
+ && (Util.Constants.JAVA5_SRC.equals(lcname) || Util.Constants.JAVA5_TESTSRC
+ .equals(lcname))) {
+ // assume optional for pre-1.5 builds
+ iter.remove();
+ }
+ }
+ } catch (UnsupportedOperationException e) {
+ return false; // failed XXX log also if verbose
+ }
+ return true;
+ }
+
+ /**
+ * After reviewInit, setup four kinds of results.
+ */
+ protected boolean initResults() {
+ return true; // results initialized lazily
+ }
+
+ /** resolve path absolutely, assuming / means base of modules dir */
+ public String getFullPath(String path) {
+ String fullPath;
+ if (path.startsWith("/")) {
+ fullPath = modules.baseDir.getAbsolutePath() + path;
+ } else {
+ fullPath = moduleDir.getAbsolutePath() + "/" + path;
+ }
+ // check for absolute paths (untested - none in our modules so far)
+ File testFile = new File(fullPath);
+ // System.out.println("Module.getFullPath: " + fullPath + " - " +
+ // testFile.getAbsolutePath());
+ if (!testFile.exists()) {
+ testFile = new File(path);
+ if (testFile.exists() && testFile.isAbsolute()) {
+ fullPath = path;
+ }
+ }
+ return fullPath;
+ }
+
+ class ICB implements XMLItem.ICallback {
+ public void end(Properties attributes) {
+ String kind = attributes.getProperty("kind");
+ String path = attributes.getProperty("path");
+ String exp = attributes.getProperty("exported");
+ boolean exported = ("true".equals(exp));
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ attributes.list(new PrintStream(bout));
+ update(kind, path, bout.toString(), exported);
+ }
+ }
+
+ public static class XMLItem {
+ public interface ICallback {
+ void end(Properties attributes);
+ }
+
+ static final String START_NAME = "classpathentry";
+
+ static final String ATT_STARTED = "STARTED";
+
+ final ICallback callback;
+
+ final StringBuffer input = new StringBuffer();
+
+ final String[] attributes = new String[ATTS.length];
+
+ final String targetEntity;
+
+ String entityName;
+
+ String attributeName;
+
+ XMLItem(String targetEntity, ICallback callback) {
+ this.callback = callback;
+ this.targetEntity = targetEntity;
+ reset();
+
+ }
+
+ private void reset() {
+ input.setLength(0);
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i] = null;
+ }
+ entityName = null;
+ attributeName = null;
+ }
+
+ String[] tokenize(String line) {
+ final String DELIM = " \n\t\\<>\"=";
+ StringTokenizer st = new StringTokenizer(line, DELIM, true);
+ ArrayList<String> result = new ArrayList<String>();
+ StringBuffer quote = new StringBuffer();
+ boolean inQuote = false;
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ if ((1 == s.length()) && (-1 != DELIM.indexOf(s))) {
+ if ("\"".equals(s)) { // end quote (or escaped)
+ if (inQuote) {
+ inQuote = false;
+ quote.append("\"");
+ result.add(quote.toString());
+ quote.setLength(0);
+ } else {
+ quote.append("\"");
+ inQuote = true;
+ }
+ } else {
+ result.add(s);
+ }
+ } else { // not a delimiter
+ if (inQuote) {
+ quote.append(s);
+ } else {
+ result.add(s);
+ }
+ }
+ }
+ return (String[]) result.toArray(new String[0]);
+ }
+
+ public void acceptLine(String line) {
+ String[] tokens = tokenize(line);
+ for (int i = 0; i < tokens.length; i++) {
+ next(tokens[i]);
+ }
+ }
+
+ private Properties attributesToProperties() {
+ Properties result = new Properties();
+ for (int i = 0; i < attributes.length; i++) {
+ String a = attributes[i];
+ if (null != a) {
+ result.setProperty(ATTS[i], a);
+ }
+ }
+ return result;
+ }
+
+ void errorIfNotNull(String name, String value) {
+ if (null != value) {
+ error("Did not expect " + name + ": " + value);
+ }
+ }
+
+ void errorIfNull(String name, String value) {
+ if (null == value) {
+ error("expected value for " + name);
+ }
+ }
+
+ boolean activeEntity() {
+ return targetEntity.equals(entityName);
+ }
+
+ /**
+ * Assumes that comments and "<?xml"-style lines are removed.
+ */
+ public void next(String s) {
+ if ((null == s) || (0 == s.length())) {
+ return;
+ }
+ input.append(s);
+ s = s.trim();
+ if (0 == s.length()) {
+ return;
+ }
+ if ("<".equals(s)) {
+ errorIfNotNull("entityName", entityName);
+ errorIfNotNull("attributeName", attributeName);
+ } else if (">".equals(s)) {
+ errorIfNull("entityName", entityName);
+ if ("/".equals(attributeName)) {
+ attributeName = null;
+ } else {
+ errorIfNotNull("attributeName", attributeName);
+ }
+ if (activeEntity()) {
+ callback.end(attributesToProperties());
+ }
+ entityName = null;
+ } else if ("=".equals(s)) {
+ errorIfNull("entityName", entityName);
+ errorIfNull("attributeName", attributeName);
+ } else if (s.startsWith("\"")) {
+ errorIfNull("entityName", entityName);
+ errorIfNull("attributeName", attributeName);
+ writeAttribute(attributeName, s);
+ attributeName = null;
+ } else {
+ if (null == entityName) {
+ reset();
+ entityName = s;
+ } else if (null == attributeName) {
+ attributeName = s;
+ } else {
+ System.out
+ .println("unknown state - not value, attribute, or entity: "
+ + s);
+ }
+ }
+ }
+
+ void readAttribute(String s) {
+ for (int i = 0; i < ATTS.length; i++) {
+ if (s.equals(ATTS[i])) {
+ attributes[i] = ATT_STARTED;
+ break;
+ }
+ }
+ }
+
+ void writeAttribute(String name, String value) {
+ for (int i = 0; i < ATTS.length; i++) {
+ if (name.equals(ATTS[i])) {
+ if (!value.startsWith("\"") || !value.endsWith("\"")) {
+ error("bad attribute value: " + value);
+ }
+ value = value.substring(1, value.length() - 1);
+ attributes[i] = value;
+ return;
+ }
+ }
+ }
+
+ void error(String s) {
+ throw new Error(s + " at input " + input);
+ }
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.build;
+
+import java.io.File;
+import java.util.Hashtable;
+
+/**
+ * Registration and factory for modules
+ * @see Module
+ * @see Builder
+ */
+public class Modules {
+
+ private final Hashtable<String,Module> modules = new Hashtable<String,Module>();
+ public final File baseDir;
+ public final File jarDir;
+ private final Messager handler;
+
+ public Modules(File baseDir, File jarDir, Messager handler) {
+ this.baseDir = baseDir;
+ this.jarDir = jarDir;
+ this.handler = handler;
+ Util.iaxIfNotCanReadDir(baseDir, "baseDir");
+ Util.iaxIfNotCanReadDir(jarDir, "jarDir");
+ Util.iaxIfNull(handler, "handler");
+ }
+
+
+ /**
+ * Get module associated with name.
+ * @return fail if unable to find or create module {name}.
+ */
+ public Module getModule(String name) {
+ if (null == name) {
+ return null;
+ }
+ Module result = (Module) modules.get(name);
+ if (null == result) {
+ File moduleDir = new File(baseDir, name);
+ if (!Util.canReadDir(moduleDir)) {
+ handler.error("not a module: " + name);
+ } else {
+ result = new Module(moduleDir, jarDir, name, this, handler);
+ if (result.valid) {
+ modules.put(name, result);
+ } else {
+ handler.error("invalid module: " + result.toLongString());
+ }
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+package org.aspectj.internal.tools.build;
+
+import java.io.File;
+
+/**
+ * Struct associating module with target product distribution jar
+ * and assembly instructions.
+ * When building product distributions, a zero-length jar file
+ * in the dist directory may signify a module to be built,
+ * renamed, and included in the distribution.
+ */
+public class ProductModule {
+ /** name of distribution directory in product directory */
+ private static final String DIST = "dist";
+
+ /** top-level product directory being produced */
+ public final File productDir;
+
+ /** path to file in distribution template dir for this module jar */
+ public final File replaceFile;
+
+ /** relative path within distribution of this product module jar */
+ public final String relativePath;
+
+ /** the module jar is the file to replace */
+ public final Module module;
+
+ /** if true, assemble all when building module */
+ public final boolean assembleAll;
+
+ public ProductModule(File productDir, File replaceFile, Module module, boolean assembleAll) {
+ this.replaceFile = replaceFile;
+ this.module = module;
+ this.productDir = productDir;
+ this.assembleAll = assembleAll;
+ Util.iaxIfNull(module, "module");
+ Util.iaxIfNotCanReadDir(productDir, "productDir");
+ Util.iaxIfNotCanReadFile(replaceFile, "replaceFile");
+ String productDirPath = productDir.getAbsolutePath();
+ String replaceFilePath = replaceFile.getAbsolutePath();
+ if (!replaceFilePath.startsWith(productDirPath)) {
+ String m = "\"" + replaceFilePath
+ + "\" does not start with \""
+ + productDirPath
+ + "\"";
+ throw new IllegalArgumentException(m);
+ }
+ replaceFilePath = replaceFilePath.substring(1+productDirPath.length());
+ if (!replaceFilePath.startsWith(DIST)) {
+ String m = "\"" + replaceFilePath
+ + "\" does not start with \"" + DIST + "\"";
+ throw new IllegalArgumentException(m);
+ }
+ relativePath = replaceFilePath.substring(1 + DIST.length());
+ }
+ public String toString() {
+ return "" + module + " for " + productDir;
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.internal.tools.build;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Represents a prospective build result and any requirements for it. Used for
+ * [testing|normal][jar|assembled-jar|classesDir?].
+ */
+public class Result {
+ public static final boolean NORMAL = true;
+
+ public static final boolean ASSEMBLE = true;
+
+ static final Kind RELEASE = new Kind("RELEASE", NORMAL, !ASSEMBLE);
+
+ static final Kind RELEASE_ALL = new Kind("RELEASE_ALL", NORMAL, ASSEMBLE);
+
+ static final Kind TEST = new Kind("TEST", !NORMAL, !ASSEMBLE);
+
+ static final Kind TEST_ALL = new Kind("TEST_ALL", !NORMAL, ASSEMBLE);
+
+ private static final Kind[] KINDS = { RELEASE, TEST, RELEASE_ALL, TEST_ALL };
+
+ private static final HashMap<String,Result> nameToResult = new HashMap<String, Result>();
+
+ public static boolean isTestingJar(String name) {
+ name = name.toLowerCase();
+ return "junit.jar".equals(name);
+ }
+
+ public static boolean isTestingDir(String name) {
+ name = name.toLowerCase();
+ return (Util.Constants.TESTSRC.equals(name) || Util.Constants.JAVA5_TESTSRC
+ .equals(name));
+ }
+
+ public static boolean isTestingModule(Module module) {
+ String name = module.name.toLowerCase();
+ return name.startsWith("testing") || "tests".equals(name);
+ }
+
+ public static synchronized Result getResult(String name) {
+ if (null == name) {
+ throw new IllegalArgumentException("null name");
+ }
+ return (Result) nameToResult.get(name);
+ }
+
+ public static Result[] getResults(String[] names) {
+ if (null == names) {
+ return new Result[0];
+ }
+ Result[] results = new Result[names.length];
+
+ for (int i = 0; i < results.length; i++) {
+ String name = names[i];
+ if (null == name) {
+ String m = "no name at " + i + ": " + Arrays.asList(names);
+ throw new IllegalArgumentException(m);
+ }
+ Result r = Result.getResult(name);
+ if (null == r) {
+ String m = "no result [" + i + "]: " + name + ": "
+ + Arrays.asList(names);
+ throw new IllegalArgumentException(m);
+ }
+ results[i] = r;
+ }
+ return results;
+
+ }
+
+ public static Kind[] KINDS() {
+ Kind[] result = new Kind[KINDS.length];
+ System.arraycopy(KINDS, 0, result, 0, result.length);
+ return result;
+ }
+
+ public static void iaxUnlessNormal(Result result) {
+ if ((null == result) || !result.getKind().normal) {
+ throw new IllegalArgumentException("not normal: " + result);
+ }
+ }
+
+ public static void iaxUnlessAssembly(Result result) {
+ if ((null == result) || !result.getKind().assemble) {
+ throw new IllegalArgumentException("not assembly: " + result);
+ }
+ }
+
+ public static Kind kind(boolean normal, boolean assemble) {
+ return (normal == NORMAL ? (assemble == ASSEMBLE ? RELEASE_ALL
+ : RELEASE) : (assemble == ASSEMBLE ? TEST_ALL : TEST));
+ }
+
+ public static class Kind {
+ final String name;
+
+ final boolean normal;
+
+ final boolean assemble;
+
+ private Kind(String name, boolean normal, boolean assemble) {
+ this.name = name;
+ this.normal = normal;
+ this.assemble = assemble;
+ }
+
+ public final boolean isAssembly() {
+ return assemble;
+ }
+
+ public final boolean isNormal() {
+ return normal;
+ }
+
+ public final String toString() {
+ return name;
+ }
+ }
+
+ /** path to output jar - may not exist */
+ private final File outputFile;
+
+ /** List of required Result */
+ private final List<Result> requiredResults;
+
+ /** List of library jars */
+ private final List<File> libJars;
+
+ /** List of classpath variables */
+ private final List<String> classpathVariables;
+
+ transient String toLongString;
+
+ /**
+ * List of library jars exported to clients (duplicates some libJars
+ * entries)
+ */
+ private final List<File> exportedLibJars;
+
+ /** List of source directories */
+ private final List<File> srcDirs;
+
+ /** true if this has calculated List fields. */
+ private boolean requiredDone;
+
+ /** true if this has been found to be out of date */
+ private boolean outOfDate;
+
+ /** true if we have calculated whether this is out of date */
+ private boolean outOfDateSet;
+
+ private final Kind kind;
+
+ private final Module module;
+
+ private final String name;
+
+ Result(Kind kind, Module module, File jarDir) {
+ this.kind = kind;
+ this.module = module;
+ this.libJars = new ArrayList<File>();
+ this.exportedLibJars = new ArrayList<File>();
+ this.srcDirs = new ArrayList<File>();
+ this.classpathVariables = new ArrayList<String>();
+ this.requiredResults = new ArrayList<Result>();
+ String name = module.name;
+ if (!kind.normal) {
+ name += "-test";
+ }
+ if (kind.assemble) {
+ name += "-all";
+ }
+ this.name = name;
+ this.outputFile = new File(jarDir, name + ".jar");
+ nameToResult.put(name, this);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public File getOutputFile() {
+ return outputFile;
+ }
+
+ public void clearOutOfDate() {
+ outOfDateSet = false;
+ outOfDate = false;
+ }
+
+ public boolean outOfDate() {
+ if (!outOfDateSet) {
+ outOfDate = Module.outOfDate(this);
+ outOfDateSet = true;
+ }
+ return outOfDate;
+ }
+
+ /** @return List (File) of jar's required */
+ public List<File> findJarRequirements() {
+ ArrayList<File> result = new ArrayList<File>();
+ Module.doFindJarRequirements(this, result);
+ return result;
+ }
+
+ /** @return unmodifiable List of String classpath variables */
+ public List<String> getClasspathVariables() {
+ return safeList(classpathVariables);
+ }
+
+ //
+ /** @return unmodifiable List of required modules String names */
+ public Result[] getRequired() {
+ return safeResults(requiredResults);
+ }
+
+ /**
+ * @return unmodifiable list of exported library files, guaranteed readable
+ */
+ public List<File> getExportedLibJars() {
+ return safeList(exportedLibJars);
+ }
+
+ /**
+ * @return unmodifiable list of required library files, guaranteed readable
+ */
+ public List<File> getLibJars() {
+ requiredDone();
+ return safeList(libJars);
+ }
+
+ /**
+ * @return unmodifiable list of required library files, guaranteed readable
+ */
+ // public List getMerges() {
+ // requiredDone();
+ // return safeList(merges);
+ // }
+ /** @return unmodifiable list of source directories, guaranteed readable */
+ public List<File> getSrcDirs() {
+ return safeList(srcDirs);
+ }
+
+ public Module getModule() {
+ return module;
+ }
+
+ public Kind getKind() {
+ return kind;
+ }
+
+ public String toLongString() {
+ if (null == toLongString) {
+ toLongString = name + "[outputFile=" + outputFile
+ + ", requiredResults=" + requiredResults + ", srcDirs="
+ + srcDirs + ", libJars=" + libJars + "]";
+ }
+ return toLongString;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ private <T> List<T> safeList(List<T> l) {
+ requiredDone();
+ return Collections.unmodifiableList(l);
+ }
+
+ private Result[] safeResults(List<Result> list) {
+ requiredDone();
+ if (null == list) {
+ return new Result[0];
+ }
+ return (Result[]) list.toArray(new Result[0]);
+ }
+
+ private void initSrcDirs() {
+ srcDirs.addAll(getModule().srcDirs(this));
+ if (getKind().normal) {
+ // trim testing source directories
+ for (ListIterator<File> iter = srcDirs.listIterator(); iter.hasNext();) {
+ File srcDir = iter.next();
+ if (isTestingDir(srcDir.getName())) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ private void initLibJars() {
+ libJars.addAll(getModule().libJars(this));
+ if (getKind().normal && !isTestingModule(getModule())) {
+ // trim testing libraries
+ for (ListIterator<File> iter = libJars.listIterator(); iter.hasNext();) {
+ File libJar = iter.next();
+ if (isTestingJar(libJar.getName())) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ private void assertKind(Kind kind) {
+ if (kind != getKind()) {
+ throw new IllegalArgumentException("expected " + getKind()
+ + " got " + kind);
+ }
+ }
+
+ private void initRequiredResults() {
+ final Module module = getModule();
+ final Kind kind = getKind();
+ if (kind.assemble) {
+ if (kind.normal) {
+ assertKind(RELEASE_ALL);
+ requiredResults.add(module.getResult(RELEASE));
+ } else {
+ assertKind(TEST_ALL);
+ requiredResults.add(module.getResult(TEST));
+ requiredResults.add(module.getResult(RELEASE));
+ }
+ } else if (!kind.normal) {
+ assertKind(TEST);
+ requiredResults.add(module.getResult(RELEASE));
+ } else {
+ assertKind(RELEASE);
+ }
+ // externally-required:
+ List<Module> modules = module.requiredModules(this);
+ final boolean adoptTests = !kind.normal || isTestingModule(module);
+ for (Module required: modules) {
+ if (adoptTests) {
+ // testing builds can rely on other release and test results
+ requiredResults.add(required.getResult(TEST));
+ requiredResults.add(required.getResult(RELEASE));
+ } else if (!isTestingModule(required)){
+ // release builds can only rely on non-testing results
+ // from non-testing modules
+ requiredResults.add(required.getResult(RELEASE));
+ } // else skip release dependencies on testing-* (testing-util)
+ }
+ }
+
+ private void initClasspathVariables() {
+ // no difference
+ classpathVariables.addAll(getModule().classpathVariables(this));
+ }
+
+ private void initExportedLibJars() {
+ // no difference
+ exportedLibJars.addAll(getModule().exportedLibJars(this));
+ }
+
+ private synchronized void requiredDone() {
+ if (!requiredDone) {
+ initSrcDirs();
+ initLibJars();
+ initRequiredResults();
+ initClasspathVariables();
+ initExportedLibJars();
+ requiredDone = true;
+ }
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors.
+ * 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:
+ * Wes Isberg initial implementation
+ * ******************************************************************/
+
+/*
+ * A quickie hack to extract sample code from testable sources.
+ * This could reuse a lot of code from elsewhere,
+ * but currently doesn't,
+ * to keep it in the build module which avoids dependencies.
+ * (Too bad we can't use scripting languages...)
+ */
+package org.aspectj.internal.tools.build;
+
+import java.io.*;
+import java.text.DateFormat;
+import java.util.*;
+
+/**
+ * This gathers sample code delimited with [START..END]-SAMPLE
+ * from source files under a base directory,
+ * along with any <code>@author</code> info.
+ * <pre>// START-SAMPLE {anchorName} {anchorText}
+ * ... sample code ...
+ * // END-SAMPLE {anchorName}
+ * </pre>
+ * where {anchorName} need not be unique and might be
+ * hierarchical wrt "-", e.g., "genus-species-individual".
+ */
+public class SampleGatherer {
+
+ /** EOL String for gathered lines */
+ public static final String EOL = "\n"; // XXX
+
+ static final String START = "START-SAMPLE";
+ static final String END = "END-SAMPLE";
+ static final String AUTHOR = "@author";
+ static final String FLAG = "XXX";
+
+// private static void test(String[] args){
+// String[] from = new String[] { "<pre>", "</pre>" };
+// String[] to = new String[] { "<pre>", "</pre>" };
+// String source = "in this <pre> day and </pre> age of <pre and /pre>";
+// System.err.println("from " + source);
+// System.err.println(" to " + SampleUtil.replace(source, from, to));
+// source = "<pre> day and </pre>";
+// System.err.println("from " + source);
+// System.err.println(" to " + SampleUtil.replace(source, from, to));
+// source = "<pre day and </pre";
+// System.err.println("from " + source);
+// System.err.println(" to " + SampleUtil.replace(source, from, to));
+// source = "<pre> day and </pre> age";
+// System.err.println("from " + source);
+// System.err.println(" to " + SampleUtil.replace(source, from, to));
+// source = "in this <pre> day and </pre> age";
+// System.err.println("from " + source);
+// System.err.println(" to " + SampleUtil.replace(source, from, to));
+//
+// }
+ /**
+ * Emit samples gathered from any input args.
+ * @param args the String[] of paths to files or directories to search
+ * @throws IOException if unable to read a source file
+ */
+ public static void main(String[] args) throws IOException {
+ if ((null == args) || (0 == args.length)) {
+ String cname = SampleGatherer.class.getName();
+ System.err.println("java " + cname + " [dir|file]");
+ return;
+ }
+ Samples result = new Samples();
+ for (int i = 0; i < args.length; i++) {
+ result = gather(new File(args[i]), result);
+ }
+
+ StringBuffer sb = HTMLSamplesRenderer.ME.render(result, null);
+
+ File out = new File("../docs/dist/doc/sample-code.html");
+ FileOutputStream fos = new FileOutputStream(out);
+ fos.write(sb.toString().getBytes());
+ fos.close();
+ System.out.println("see file:///" + out);
+ }
+
+ /**
+ * Gather samples from a source file or directory
+ * @param source the File file or directory to start with
+ * @param sink the Samples collection to add to
+ * @return sink or a new Samples collection with any samples found
+ * @throws IOException if unable to read a source file
+ */
+ public static Samples gather(File source, Samples sink)
+ throws IOException {
+ if (null == sink) {
+ sink = new Samples();
+ }
+ if (null == source) {
+ source = new File(".");
+ }
+ doGather(source, sink);
+ return sink;
+ }
+ private static String trimCommentEnd(String line, int start) {
+ if (null == line) {
+ return "";
+ }
+ if ((start > 0) && (start < line.length())) {
+ line = line.substring(start);
+ }
+ line = line.trim();
+ if (line.endsWith("*/")) {
+ line = line.substring(0, line.length()-2).trim();
+ } else if (line.endsWith("-->")) {
+ line = line.substring(0, line.length()-3).trim();
+ }
+ return line;
+ }
+
+ private static void doGather(File source, Samples sink)
+ throws IOException {
+ if (source.isFile()) {
+ if (isSource(source)) {
+ gatherFromFile(source, sink);
+ }
+ } else if (source.isDirectory() && source.canRead()) {
+ File[] files = source.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ doGather(files[i], sink);
+ }
+ }
+ }
+
+ private static boolean isSource(File file) {
+ if ((null == file) || !file.isFile() || !file.canRead()) {
+ return false;
+ }
+ String path = file.getName().toLowerCase();
+ String[] suffixes = Sample.Kind.SOURCE_SUFFIXES;
+ for (int i = 0; i < suffixes.length; i++) {
+ if (path.endsWith(suffixes[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void gatherFromFile(final File source, final Samples sink)
+ throws IOException {
+ Reader reader = null;
+ try {
+ String author = null;
+ StringBuffer sampleCode = new StringBuffer();
+ String anchorName = null;
+ String anchorTitle = null;
+ ArrayList flags = new ArrayList();
+ int startLine = -1; // seeking
+ int endLine = Integer.MAX_VALUE; // not seeking
+ reader = new FileReader(source);
+ LineNumberReader lineReader = new LineNumberReader(reader);
+ String line;
+
+ while (null != (line = lineReader.readLine())) { // XXX naive
+ // found start?
+ int loc = line.indexOf(START);
+ if (-1 != loc) {
+ int lineNumber = lineReader.getLineNumber();
+ if (-1 != startLine) {
+ abort("unexpected " + START, source, line, lineNumber);
+ }
+ startLine = lineNumber;
+ endLine = -1;
+ anchorName = trimCommentEnd(line, loc + START.length());
+ loc = anchorName.indexOf(" ");
+ if (-1 == loc) {
+ anchorTitle = null;
+ } else {
+ anchorTitle = anchorName.substring(1+loc).trim();
+ anchorName = anchorName.substring(0, loc);
+ }
+ continue;
+ }
+
+ // found end?
+ loc = line.indexOf(END);
+ if (-1 != loc) {
+ int lineNumber = lineReader.getLineNumber();
+ if (Integer.MAX_VALUE == endLine) {
+ abort("unexpected " + END, source, line, lineNumber);
+ }
+ String newtag = trimCommentEnd(line, loc + END.length());
+ if ((newtag.length() > 0) && !newtag.equals(anchorName)) {
+ String m = "expected " + anchorName
+ + " got " + newtag;
+ abort(m, source, line, lineNumber);
+ }
+ endLine = lineNumber;
+ Sample sample = new Sample(anchorName,
+ anchorTitle,
+ author,
+ sampleCode.toString(),
+ source,
+ startLine,
+ endLine,
+ (String[]) flags.toArray(new String[flags.size()]));
+ sink.addSample(sample);
+
+ // back to seeking start
+ sampleCode.setLength(0);
+ startLine = -1;
+ endLine = Integer.MAX_VALUE;
+ continue;
+ }
+
+ // found author?
+ loc = line.indexOf(AUTHOR);
+ if (-1 != loc) {
+ author = trimCommentEnd(line, loc + AUTHOR.length());
+ }
+ // found flag comment?
+ loc = line.indexOf(FLAG);
+ if (-1 != loc) {
+ flags.add(trimCommentEnd(line, loc + FLAG.length()));
+ }
+
+ // reading?
+ if ((-1 != startLine) && (-1 == endLine)) {
+ sampleCode.append(line);
+ sampleCode.append(EOL);
+ }
+ }
+ if (-1 == endLine) {
+ abort("incomplete sample", source, "", lineReader.getLineNumber());
+ }
+ } finally {
+ if (null != reader) {
+ reader.close();
+ }
+ }
+ }
+ private static void abort(String why, File file, String line, int lineNumber)
+ throws Abort {
+ throw new Abort(why + " at " + file + ":" + lineNumber + ": " + line);
+ }
+// private static void delay(Object toDelay) {
+// synchronized (toDelay) { // XXX sleep instead?
+// toDelay.notifyAll();
+// }
+// }
+ static class Abort extends IOException {
+ private static final long serialVersionUID = -1l;
+ Abort(String s) {
+ super(s);
+ }
+ }
+}
+
+/**
+ * Data associated with sample code - struct class.
+ */
+class Sample {
+ public static final String ASPECTJ_TEAM = "The AspectJ Team";
+
+ /** sort by anchorName, file path, and start/end location */
+ static Comparator<Sample> NAME_SOURCE_COMPARER = new Comparator<Sample>() {
+ public int compare(Sample left, Sample right) {
+ if (null == left) {
+ return (null == right ? 0 : -1);
+ }
+ if (null == right) {
+ return 1;
+ }
+ int result = left.anchorName.compareTo(right.anchorName);
+ if (0 != result) {
+ return result;
+ }
+ result = left.sourcePath.compareTo(right.sourcePath);
+ if (0 != result) {
+ return result;
+ }
+ result = right.startLine - left.startLine;
+ if (0 != result) {
+ return result;
+ }
+ return right.endLine - left.endLine;
+ }
+ };
+
+ /** sort by author, then NAME_SOURCE_COMPARER */
+ static Comparator<Sample> AUTHOR_NAME_SOURCE_COMPARER = new Comparator<Sample>() {
+ public int compare(Sample left, Sample right) {
+ if (null == left) {
+ return (null == right ? 0 : -1);
+ }
+ if (null == right) {
+ return 1;
+ }
+ int result = left.author.compareTo(right.author);
+ if (0 != result) {
+ return result;
+ }
+ return NAME_SOURCE_COMPARER.compare(left,right);
+ }
+ };
+
+ final String anchorName;
+ final String anchorTitle;
+ final String author;
+ final String sampleCode;
+ final File sourcePath;
+ final int startLine;
+ final int endLine;
+ final Kind kind;
+ /** List of String flags found in the sample */
+ final List flags;
+ public Sample(
+ String anchorName,
+ String anchorTitle,
+ String author,
+ String sampleCode,
+ File sourcePath,
+ int startLine,
+ int endLine,
+ String[] flags) {
+ this.anchorName = anchorName;
+ this.anchorTitle = anchorTitle;
+ this.author = (null != author ? author : ASPECTJ_TEAM);
+ this.sampleCode = sampleCode;
+ this.sourcePath = sourcePath;
+ this.startLine = startLine;
+ this.endLine = endLine;
+ this.kind = Kind.getKind(sourcePath);
+// List theFlags;
+ if ((null == flags) || (0 == flags.length)) {
+ this.flags = Collections.EMPTY_LIST;
+ } else {
+ this.flags = Collections.unmodifiableList(Arrays.asList(flags));
+ }
+ }
+
+ public String toString() {
+ return sampleCode;
+ }
+
+ public static class Kind {
+
+ /** lowercase source suffixes identify files to gather samples from */
+ public static final String[] SOURCE_SUFFIXES = new String[]
+ { ".java", ".aj", ".sh", ".ksh",
+ ".txt", ".text", ".html", ".htm", ".xml" };
+ static final Kind XML = new Kind();
+ static final Kind HTML = new Kind();
+ static final Kind PROGRAM = new Kind();
+ static final Kind SCRIPT = new Kind();
+ static final Kind TEXT = new Kind();
+ static final Kind OTHER = new Kind();
+ public static Kind getKind(File file) {
+ if (null == file) {
+ return OTHER;
+ }
+ String name = file.getName().toLowerCase();
+ if ((name.endsWith(".java") || name.endsWith(".aj"))) {
+ return PROGRAM;
+ }
+ if ((name.endsWith(".html") || name.endsWith(".htm"))) {
+ return HTML;
+ }
+ if ((name.endsWith(".sh") || name.endsWith(".ksh"))) {
+ return SCRIPT;
+ }
+ if ((name.endsWith(".txt") || name.endsWith(".text"))) {
+ return TEXT;
+ }
+ if (name.endsWith(".xml")) {
+ return XML;
+ }
+ return OTHER;
+ }
+ private Kind() {
+ }
+ }
+}
+
+/**
+ * type-safe Collection of samples.
+ */
+class Samples {
+ private ArrayList<Sample> samples = new ArrayList<Sample>();
+ int size() {
+ return samples.size();
+ }
+ void addSample(Sample sample) {
+ samples.add(sample);
+ }
+ /**
+ * @return List copy, sorted by Sample.NAME_SOURCE_COMPARER
+ */
+ List<Sample> getSortedSamples() {
+ return getSortedSamples(Sample.NAME_SOURCE_COMPARER);
+ }
+
+ List<Sample> getSortedSamples(Comparator<Sample> comparer) {
+ ArrayList<Sample> result = new ArrayList<Sample>();
+ result.addAll(samples);
+ Collections.sort(result, comparer);
+ return result;
+ }
+}
+
+
+/**
+ * Render samples by using method visitors.
+ */
+class SamplesRenderer {
+ public static SamplesRenderer ME = new SamplesRenderer();
+ protected SamplesRenderer() {
+ }
+ public static final String EOL = "\n"; // XXX
+ public static final String INFO =
+ "<p>This contains contributions from the AspectJ community of "
+ + "<ul><li>sample code for AspectJ programs,</li>"
+ + "<li>sample code for extensions to AspectJ tools using the public API's,</li>"
+ + "<li>sample scripts for invoking AspectJ tools, and </li> "
+ + "<li>documentation trails showing how to do given tasks"
+ + " using AspectJ, AJDT, or various IDE or deployment"
+ + " environments.</li></ul></p>"
+ + "<p>Find complete source files in the AspectJ CVS repository at "
+ + "<code>org.aspectj/modules/docs/sandbox</code>. "
+ + "For instructions on downloading code from the CVS repository, "
+ + "see the <a href=\"doc/faq.html#q:buildingsource\">FAQ entry "
+ + "\"buildingsource\"</a>.</p>";
+
+ public static final String COPYRIGHT =
+ "<p><small>Copyright 2003 Contributors. All Rights Reserved. "
+ + "This sample code is made available under the Common Public "\r + "License version 1.0 available at "
+ + "<a href=\"http://www.eclipse.org/legal/epl-v10.html\">"
+ + "http://www.eclipse.org/legal/epl-v10.html</a>."
+ + "Contributors are listed in this document as authors. "
+ + "Permission to republish portions of this sample code "
+ + "is hereby granted if the publication acknowledges "
+ + "the author by name and "
+ + "the source by reference to the AspectJ project home page "
+ + " at http://eclipse.org/aspectj.</small></p>"
+ + EOL;
+
+ /** template algorithm to render */
+ public final StringBuffer render(Samples samples, StringBuffer sink) {
+ if (null == sink) {
+ sink = new StringBuffer();
+ }
+ if ((null == samples) || (0 == samples.size())) {
+ return sink;
+ }
+ startList(samples, sink);
+ List list = samples.getSortedSamples();
+ String anchorName = null;
+ for (ListIterator iter = list.listIterator();
+ iter.hasNext();) {
+ Sample sample = (Sample) iter.next();
+ String newAnchorName = sample.anchorName;
+ if ((null == anchorName)
+ || (!anchorName.equals(newAnchorName))) {
+ endAnchorName(anchorName, sink);
+ startAnchorName(newAnchorName, sample.anchorTitle, sink);
+ anchorName = newAnchorName;
+ }
+ render(sample, sink);
+ }
+ endAnchorName(anchorName, sink);
+ endList(samples, sink);
+ return sink;
+ }
+ protected void startList(Samples samples, StringBuffer sink) {
+ sink.append("Printing " + samples.size() + " samples");
+ sink.append(EOL);
+ }
+
+ protected void startAnchorName(String name, String title, StringBuffer sink) {
+ sink.append("anchor " + name);
+ sink.append(EOL);
+ }
+
+ protected void render(Sample sample, StringBuffer sink) {
+ SampleUtil.render(sample, "=", ", ",sink);
+ sink.setLength(sink.length()-2);
+ sink.append(EOL);
+ }
+
+ /**
+ * @param name the String name being ended - ignore if null
+ * @param sink
+ */
+ protected void endAnchorName(String name, StringBuffer sink) {
+ if (null == name) {
+ return;
+ }
+ }
+
+ protected void endList(Samples samples, StringBuffer sink) {
+ sink.append("Printed " + samples.size() + " samples");
+ sink.append(EOL);
+ }
+
+}
+
+// XXX need DocBookSamplesRenderer
+
+/**
+ * Output the samples as a single HTML file, with a table of contents
+ * and sorting the samples by their anchor tags.
+ */
+class HTMLSamplesRenderer extends SamplesRenderer {
+ public static SamplesRenderer ME = new HTMLSamplesRenderer();
+ // XXX move these
+ public static boolean doHierarchical = true;
+ public static boolean doFlags = false;
+
+
+ final StringBuffer tableOfContents;
+ final StringBuffer sampleSection;
+ String[] lastAnchor = new String[0];
+ String currentAnchor;
+ String currentAuthor;
+
+ protected HTMLSamplesRenderer() {
+ sampleSection = new StringBuffer();
+ tableOfContents = new StringBuffer();
+ }
+
+ protected void startAnchorName(String name, String title, StringBuffer sink) {
+ if (doHierarchical) {
+ doContentTree(name);
+ }
+ // ---- now do anchor
+ tableOfContents.append(" <li><a href=\"#" + name);
+ if ((null == title) || (0 == title.length())) {
+ title = name;
+ }
+ tableOfContents.append("\">" + title + "</a></li>");
+ tableOfContents.append(EOL);
+ currentAnchor = name;
+ }
+
+ protected void startList(Samples samples, StringBuffer sink) {
+ }
+
+ protected void render(Sample sample, StringBuffer sink) {
+ if (null != currentAnchor) {
+ if (!currentAnchor.equals(sample.anchorName)) {
+ String m = "expected " + currentAnchor
+ + " got " + sample.anchorName;
+ throw new Error(m);
+ }
+ currentAnchor = null;
+ }
+
+ // do heading then code
+ renderHeading(sample.anchorName, sample.anchorTitle, sampleSection);
+ if (sample.kind == Sample.Kind.HTML) {
+ renderHTML(sample);
+ } else if (sample.kind == Sample.Kind.XML) {
+ renderXML(sample);
+ } else {
+ renderPre(sample);
+ }
+ }
+
+ protected boolean doRenderAuthor(Sample sample) {
+ return (null != sample.author);
+ // && !sample.author.equals(currentAuthor)
+ }
+
+ protected void renderStandardHeader(Sample sample) {
+ // XXX starting same as pre
+ if (doRenderAuthor(sample)) {
+ currentAuthor = sample.author;
+ sampleSection.append(" <p>| " + currentAuthor);
+ sampleSection.append(EOL);
+ }
+ sampleSection.append(" | ");
+ sampleSection.append(SampleUtil.renderCodePath(sample.sourcePath));
+ sampleSection.append(":" + sample.startLine);
+ sampleSection.append(" |");
+ sampleSection.append(EOL);
+ sampleSection.append("<p>");
+ sampleSection.append(EOL);
+ if (doFlags) {
+ boolean flagHeaderDone = false;
+ for (Iterator iter = sample.flags.iterator(); iter.hasNext();) {
+ String flag = (String) iter.next();
+ if (!flagHeaderDone) {
+ sampleSection.append("<p>Comments flagged:<ul>");
+ sampleSection.append(EOL);
+ flagHeaderDone = true;
+ }
+ sampleSection.append("<li>");
+ sampleSection.append(flag);
+ sampleSection.append("</li>");
+ }
+ if (flagHeaderDone) {
+ sampleSection.append("</ul>");
+ sampleSection.append(EOL);
+ }
+ }
+ }
+
+ protected void renderXML(Sample sample) {
+ renderStandardHeader(sample);
+ sampleSection.append(" <pre>");
+ sampleSection.append(EOL);
+ sampleSection.append(prepareXMLSample(sample.sampleCode));
+ sampleSection.append(EOL);
+ sampleSection.append(" </pre>");
+ sampleSection.append(EOL);
+ }
+
+ protected void renderHTML(Sample sample) {
+ renderStandardHeader(sample);
+ sampleSection.append(EOL);
+ sampleSection.append(prepareHTMLSample(sample.sampleCode));
+ sampleSection.append(EOL);
+ }
+
+ protected void renderPre(Sample sample) {
+ renderStandardHeader(sample);
+ sampleSection.append(" <pre>");
+ sampleSection.append(EOL);
+ sampleSection.append(prepareCodeSample(sample.sampleCode));
+ sampleSection.append(" </pre>");
+ sampleSection.append(EOL);
+ }
+
+ protected void endAnchorName(String name, StringBuffer sink) {
+ if (null == name) {
+ return;
+ }
+ currentAnchor = null;
+ currentAuthor = null; // authors don't span anchors
+ }
+
+ protected void endList(Samples samples, StringBuffer sink) {
+ sink.append("<html>");
+ sink.append(EOL);
+ sink.append("<title>AspectJ sample code</title>");
+ sink.append(EOL);
+ sink.append("<body>");
+ sink.append(EOL);
+ sink.append(" <a name=\"top\"></a>");
+ sink.append(EOL);
+ sink.append(" <h1>AspectJ sample code</h1>");
+ sink.append(INFO);
+ sink.append(EOL);
+ sink.append(COPYRIGHT);
+ sink.append(EOL);
+ sink.append("<p><small>Generated on ");
+ sink.append(DateFormat.getDateInstance().format(new Date()));
+ sink.append(" by SamplesGatherer</small>");
+ sink.append(EOL);
+ sink.append(" <h2>Contents</h2>");
+ sink.append(EOL);
+ sink.append(" <ul>");
+ sink.append(EOL);
+ sink.append(tableOfContents.toString());
+ // unwind to common prefix, if necessary
+ for (int i = 0; i < lastAnchor.length ; i++) {
+ sink.append(" </ul>");
+ }
+
+ sink.append(" <li><a href=\"#authorIndex\">Author Index</a></li>");
+ sink.append(" </ul>");
+ sink.append(" <h2>Listings</h2>");
+ sink.append(EOL);
+ sink.append(sampleSection.toString());
+ renderAuthorIndex(samples, sink);
+ sink.append("</body></html>");
+ sink.append(EOL);
+ }
+
+ protected String prepareXMLSample(String sampleCode) {
+ String[] from = new String[] {"\t", "<"};
+ String[] to = new String[] {" ", "<"};
+ return (SampleUtil.replace(sampleCode, from, to));
+ }
+
+ protected String prepareHTMLSample(String sampleCode) {
+ String[] from = new String[20];
+ String[] to = new String[20];
+ for (int i = 0; i < to.length; i++) {
+ String h = "h" + i + ">";
+ from[i] = "<" + h;
+ to[i] = "<p><b>";
+ from[++i] = "</" + h;
+ to[i] = "</b></p><p>";
+ }
+ return (SampleUtil.replace(sampleCode, from, to));
+ }
+
+ protected String prepareCodeSample(String sampleCode) {
+ String[] from = new String[] { "<pre>", "</pre>" };
+ String[] to = new String[] { "<pre>", "</pre>" };
+ return (SampleUtil.replace(sampleCode, from, to));
+ }
+
+ protected void renderHeading(String anchor, String title, StringBuffer sink) {
+ sink.append(" <a name=\"" + anchor + "\"></a>");
+ sink.append(EOL);
+ if ((null == title) || (0 == title.length())) {
+ title = anchor;
+ }
+ sink.append(" <h3>" + title + "</h3>");
+ sink.append(EOL);
+ sink.append("<a href=\"#top\">back to top</a>");
+ sink.append(EOL);
+ }
+
+ /**
+ * Manage headings in both table of contents and listings.
+ * @param name the String anchor
+ */
+ protected void doContentTree(String name) {
+ if (name.equals(lastAnchor)) {
+ return;
+ }
+ // ---- handle trees
+ String[] parts = SampleUtil.splitAnchorName(name);
+ //String[] lastAnchor = (String[]) lastAnchors.peek();
+ int firstDiff = SampleUtil.commonPrefix(parts, lastAnchor);
+ // unwind to common prefix, if necessary
+ if (firstDiff+1 < lastAnchor.length) {
+ for (int i = 1; i < lastAnchor.length-firstDiff ; i++) {
+ tableOfContents.append(" </ul>");
+ tableOfContents.append(EOL);
+ }
+ }
+ // build up prefix
+ StringBuffer branchAnchor = new StringBuffer();
+ for (int i = 0; i < firstDiff;) {
+ branchAnchor.append(parts[i]);
+ i++;
+ branchAnchor.append("-");
+ }
+ // emit leading headers, but not anchor itself
+ for (int i = firstDiff; i < (parts.length-1); i++) {
+ branchAnchor.append(parts[i]);
+ String prefixName = branchAnchor.toString();
+ branchAnchor.append("-");
+ tableOfContents.append(" <li><a href=\"#");
+ tableOfContents.append(prefixName);
+ tableOfContents.append("\">" + prefixName + "</a></li>");
+ tableOfContents.append(EOL);
+ tableOfContents.append(" <ul>");
+ tableOfContents.append(EOL);
+
+ renderHeading(prefixName, prefixName, sampleSection);
+ }
+ lastAnchor = parts;
+ }
+
+ protected void renderAuthorIndex(Samples samples, StringBuffer sink) {
+ sink.append("<h2><a name=\"authorIndex\"></a>Author Index</h2>");
+ List list = samples.getSortedSamples(Sample.AUTHOR_NAME_SOURCE_COMPARER);
+ String lastAuthor = null;
+ for (ListIterator iter = list.listIterator(); iter.hasNext();) {
+ Sample sample = (Sample)iter.next();
+ String author = sample.author;
+ if (!author.equals(lastAuthor)) {
+ if (null != lastAuthor) {
+ sink.append("</li></ul>");
+ }
+ sink.append("<li>");
+ sink.append(author);
+ sink.append(EOL);
+ sink.append("<ul>");
+ sink.append(EOL);
+ lastAuthor = author;
+ }
+ sink.append(" <li><a href=\"#");
+ sink.append(sample.anchorName);
+ sink.append("\">");
+ if (null == sample.anchorTitle) {
+ sink.append(sample.anchorName);
+ } else {
+ sink.append(sample.anchorTitle);
+ }
+ sink.append("</a></li>");
+ }
+ }
+}
+
+class SampleUtil {
+ public static final String SAMPLE_BASE_DIR_NAME = "sandbox";
+
+ public static void simpleRender(Samples result, StringBuffer sink) {
+ List sortedSamples = result.getSortedSamples();
+ int i = 0;
+ for (ListIterator iter = sortedSamples.listIterator();
+ iter.hasNext();) {
+ Sample sample = (Sample) iter.next();
+ sink.append(i++ + ": " + sample);
+ }
+ }
+
+ /** result struct for getPackagePath */
+ static class JavaFile {
+ /** input File possibly signifying a java file */
+ final File path;
+
+ /** String java path suffix in form "com/company/Bar.java"
+ * null if this is not a java file
+ */
+ final String javaPath;
+
+ /** any prefix before java path suffix in the original path */
+ final String prefix;
+
+ /** error handling */
+ final Throwable thrown;
+ JavaFile(File path, String javaPath, String prefix, Throwable thrown) {
+ this.path = path;
+ this.javaPath = javaPath;
+ this.prefix = prefix;
+ this.thrown = thrown;
+ }
+ }
+
+ /**
+ * Read any package statement in the file to determine
+ * the package path of the file
+ * @param path the File to seek the package in
+ * @return the JavaFile with the components of the path
+ */
+ public static JavaFile getJavaFile(File path) {
+ if (null == path) {
+ throw new IllegalArgumentException("null path");
+ }
+ String result = path.getPath().replace('\\', '/');
+ String packag = "";
+ String javaPath = null;
+ String prefix = null;
+ Throwable thrown = null;
+ if (result.endsWith(".java") || result.endsWith(".aj")) {
+ FileReader reader = null;
+ try {
+ reader = new FileReader(path);
+ BufferedReader br = new BufferedReader(reader);
+ String line;
+ while (null != (line = br.readLine())) {
+ int loc = line.indexOf("package");
+ if (-1 != loc) {
+ int end = line.indexOf(";");
+ if (-1 == loc) {
+ String m = "unterminated package statement \"";
+ throw new Error(m + line + "\" in " + path);
+ }
+ packag = (line.substring(loc + 7, end) + ".")
+ .trim()
+ .replace('.', '/');
+ break;
+ }
+ loc = line.indexOf("import");
+ if (-1 != loc) {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ thrown = e;
+ } finally {
+ if (null != reader) {
+ try {
+ reader.close();
+ } catch (IOException e1) {
+ // ignore
+ }
+ }
+ }
+ if (null == thrown) {
+ javaPath = packag + path.getName();
+ int loc = result.indexOf(javaPath);
+ if (-1 == loc) {
+ String m = "expected suffix " + javaPath + " in ";
+ throw new Error(m + result);
+ }
+ prefix = result.substring(0, loc);
+ }
+ }
+ return new JavaFile(path, javaPath, prefix, thrown);
+ }
+
+ /**
+ * Extract file path relative to base of package directory
+ * and directory in SAMPLE_BASE_DIR_NAME for this file.
+ * @param path the File to render from SAMPLE_BASE_DIR_NAME
+ * @return String "baseDir {path}"
+ */
+ public static String renderCodePath(File path) {
+ JavaFile javaFile = getJavaFile(path);
+ if (javaFile.thrown != null) {
+ throw new Error(javaFile.thrown.getClass()
+ + ": " + javaFile.thrown.getMessage());
+ }
+
+ String file = javaFile.javaPath; // can be null...
+ String prefix = javaFile.prefix;
+ if (prefix == null) {
+ prefix = path.getPath().replace('\\', '/');
+ }
+ int loc = prefix.lastIndexOf(SAMPLE_BASE_DIR_NAME);
+ if (-1 == loc) {
+ String m = "not after " + SAMPLE_BASE_DIR_NAME;
+ throw new IllegalArgumentException(m + "?: " + path);
+ }
+ prefix = prefix.substring(loc + 1 + SAMPLE_BASE_DIR_NAME.length());
+
+ if (file == null) {
+ int slash = prefix.lastIndexOf('/');
+ if (-1 == slash) {
+ file = prefix;
+ prefix = "";
+ } else {
+ file = prefix.substring(slash+1);
+ prefix = prefix.substring(0, slash);
+ }
+ }
+ if (prefix.endsWith("/")) {
+ prefix = prefix.substring(0, prefix.length()-1);
+ }
+ return (prefix + " " + file).trim();
+ }
+
+ public static int commonPrefix(String[] lhs, String[] rhs) {
+ final int max = smallerSize(lhs, rhs);
+ int firstDiff = 0;
+ while (firstDiff < max) {
+ if (!lhs[firstDiff].equals(rhs[firstDiff])) {
+ break;
+ }
+ firstDiff++;
+ }
+ return firstDiff;
+ }
+
+ private static int smallerSize(Object[] one, Object[] two) {
+ if ((null == one) || (null == two)) {
+ return 0;
+ }
+ return (one.length > two.length ? two.length : one.length);
+ }
+
+ public static String[] splitAnchorName(Sample sample) {
+ return splitAnchorName(sample.anchorName);
+ }
+
+ public static String[] splitAnchorName(String anchorName) {
+ ArrayList<String> result = new ArrayList<String>();
+ int start = 0;
+ int loc = anchorName.indexOf("-", start);
+ String next;
+ while (loc != -1) {
+ next = anchorName.substring(start, loc);
+ result.add(next);
+ start = loc+1;
+ loc = anchorName.indexOf("-", start);
+ }
+ next = anchorName.substring(start);
+ result.add(next);
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+ /**
+ * Replace literals with literals in source string
+ * @param source the String to modify
+ * @param from the String[] of literals to replace
+ * @param to the String[] of literals to use when replacing
+ * @return the String source as modified by the replaces
+ */
+ public static String replace(String source, String[] from, String[] to) {
+ if ((null == source) || (0 == source.length())) {
+ return source;
+ }
+ if (from.length != to.length) {
+ throw new IllegalArgumentException("unmatched from/to");
+ }
+ StringBuffer result = new StringBuffer();
+ int LEN = source.length();
+ int start = 0;
+ for (int i = 0; i < LEN; i++) {
+ String suffix = source.substring(i);
+ for (int j = 0; j < from.length; j++) {
+ if (suffix.startsWith(from[j])) {
+ result.append(source.substring(start, i));
+ result.append(to[j]);
+ start = i + from[j].length();
+ i = start-1;
+ break;
+ }
+ }
+ }
+ if (start < source.length()) {
+ result.append(source.substring(start));
+ }
+ return result.toString();
+ }
+
+ public static void render(
+ Sample sample,
+ String fieldDelim,
+ String valueDelim,
+ StringBuffer sink) {
+ if ((null == sink) || (null == sample)) {
+ return;
+ }
+ if (null == fieldDelim) {
+ fieldDelim = "";
+ }
+ if (null == valueDelim) {
+ valueDelim = "";
+ }
+ sink.append("anchorName");
+ sink.append(valueDelim);
+ sink.append(sample.anchorName);
+ sink.append(fieldDelim);
+ sink.append("author");
+ sink.append(valueDelim);
+ sink.append(sample.author);
+ sink.append(fieldDelim);
+ sink.append("sourcePath");
+ sink.append(valueDelim);
+ sink.append(sample.sourcePath.toString());
+ sink.append(fieldDelim);
+ sink.append("startLine");
+ sink.append(valueDelim);
+ sink.append(sample.startLine);
+ sink.append(fieldDelim);
+ sink.append("endLine");
+ sink.append(valueDelim);
+ sink.append(sample.endLine);
+ sink.append(fieldDelim);
+ sink.append("sampleCode");
+ sink.append(valueDelim);
+ sink.append(sample.sampleCode.toString());
+ sink.append(fieldDelim);
+ }
+ private SampleUtil(){}
+}
--- /dev/null
+/* *******************************************************************
+ * 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 v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.internal.tools.build;
+
+import java.io.*;
+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.Manifest;
+import java.util.jar.Attributes.Name;
+
+/**
+ * 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) {
+ StringBuffer sb = new StringBuffer();
+ 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 (int i = 0; i < files.length; i++) {
+ if (!deleteContents(files[i]) || !files[i].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 (int i = 0; i < actual.length; i++) {
+ if (null != actual[i]) {
+ sb.append(prefix);
+ prefix = ", ";
+ sb.append("\"");
+ sb.append(actual[i]);
+ sb.append("\"");
+ }
+ }
+ sb.append("] missing [");
+ prefix = "";
+ for (int i = 0; i < expected.length; i++) {
+ if (null != expected[i]) {
+ sb.append(prefix);
+ prefix = ", ";
+ sb.append("\"");
+ sb.append(expected[i]);
+ 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 NAMES;
+ static {
+ ArrayList 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);
+ }
+ }
+ }
+}
+
--- /dev/null
+<html>
+<!-- todo
+- backed off on doing product installer builds directly;
+ the one installer is now built using Ant.
+
+-
+-->
+<body>
+The build taskdef relies on the classes in this package for
+behavior independent of Ant.
+</body>
+</html>
}
final static List<String> SOURCE_NAMES = Collections.unmodifiableList(
- Arrays.asList(new String[]{"src", "testsrc", "java5-src", "java5-testsrc", "aspectj-src"}));
+ Arrays.asList(new String[]{"src/main/java", "src/test/java" }));
/**
* @param moduleDir
public void testLicense_util() {
checkLicense("util");
}
+
public void testLicense_weaver() {
String module = "weaver";
// skip (testdata) packages fluffy, reflect
- checkSourceDirectory(new File(Util.path(new String[] {"..", module, "src"})), module);
- checkSourceDirectory(new File(Util.path(new String[] {"..", module, "testsrc", "org"})), module);
+ checkSourceDirectory(new File(Util.path(new String[] {"..", module, "src","main","java"})), module);
+ checkSourceDirectory(new File(Util.path(new String[] {"..", module, "src","test","java", "org"})), module);
}
public void testLicense_ajdoc() {
File moduleDir = new File(Util.path("..", module));
File[] srcDirs = findSourceRoots(moduleDir);
for (int i = 0; i < srcDirs.length; i++) {
+ System.out.println(srcDirs[i]);
checkSourceDirectory(srcDirs[i], module);
}
}
}
// separate check to verify all file types (suffixes) are known
- if (!"testsrc".equals(srcDir.getName())) {
+ if (!isTestFolder(srcDir)) {
ArrayList<File> unknownFiles = new ArrayList<File>();
UnknownFileCheck.SINGLETON.unknownFiles(srcDir, unknownFiles);
+ System.out.println(unknownFiles);
if (!unknownFiles.isEmpty()) {
String s = "unknown files (see readme-build-module.html to "
+ "update Builder.properties resource patterns): ";
}
}
}
+
+ private boolean isTestFolder(File dir) {
+ return dir.toString().contains("src/test/java");
+ }
+
/**
* Check tree for files not managed by the build system
* (either source files or managed as resources).
// System.out.println("results: " + Arrays.asList(results));
// deleteTempFiles();
// }
- public void testNoDuplicates() {
+
+ public void xtestNoDuplicates() {
File weaverAllJar = null;
try {
weaverAllJar = doTask("weaver",true, true, true);
* Xerox/PARC initial implementation
* Wes Isberg build tests
* ******************************************************************/
-
package org.aspectj.internal.build;
import java.io.File;
import org.aspectj.internal.tools.build.Result;
import org.aspectj.internal.tools.build.Util;
import org.aspectj.internal.tools.build.Result.Kind;
-/**
- *
- */
+
public class ModulesTest extends TestCase {
+
public static final List<String> MODULE_NAMES;
+
private static final File BASE_DIR = new File("..");
+
static {
String[] names = {
- "ajbrowser", "ajde", "ajdoc", "asm", "aspectj5rt",
- "bridge", "loadtime", "loadtime5", "org.aspectj.ajdt.core",
+ "ajbrowser", "ajde", "ajdoc", "asm",
+ "bridge", "loadtime", "org.aspectj.ajdt.core",
"runtime", "taskdefs", "testing-client", "testing-util",
"tests", "util", "weaver"};
List<String> list = Arrays.asList(names);
}
}
}
+
Modules getModules(Messager handler) {
File jarDir = new File("../aj-build-test-jars");
if (!jarDir.exists()) {
}
}
- public void testClasspathCreation() {
+ public void xtestClasspathCreation() {
Modules modules = getModules(null);
+
Module ajdt = modules.getModule("org.aspectj.ajdt.core");
assertTrue(ajdt.valid);