diff options
Diffstat (limited to 'build/src/main/java./aspectj/internal/tools/ant/taskdefs/AJInstaller.java')
-rw-r--r-- | build/src/main/java./aspectj/internal/tools/ant/taskdefs/AJInstaller.java | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/build/src/main/java./aspectj/internal/tools/ant/taskdefs/AJInstaller.java b/build/src/main/java./aspectj/internal/tools/ant/taskdefs/AJInstaller.java new file mode 100644 index 000000000..6bc2fc09b --- /dev/null +++ b/build/src/main/java./aspectj/internal/tools/ant/taskdefs/AJInstaller.java @@ -0,0 +1,364 @@ +/* ******************************************************************* + * 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); + } + } + +} |