You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AJInstaller.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. //XXX INCLUDES CODE FROM ANT -- UNDER APACHE LICENSE
  14. package org.aspectj.internal.tools.ant.taskdefs;
  15. import java.io.ByteArrayInputStream;
  16. import java.io.ByteArrayOutputStream;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.FileOutputStream;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.io.StringBufferInputStream;
  23. import java.util.ArrayList;
  24. import java.util.Iterator;
  25. import java.util.List;
  26. import java.util.zip.CRC32;
  27. import java.util.zip.ZipEntry;
  28. import java.util.zip.ZipOutputStream;
  29. import org.apache.tools.ant.BuildException;
  30. import org.apache.tools.ant.DirectoryScanner;
  31. import org.apache.tools.ant.Project;
  32. import org.apache.tools.ant.taskdefs.Copy;
  33. import org.apache.tools.ant.taskdefs.Delete;
  34. import org.apache.tools.ant.taskdefs.Expand;
  35. import org.apache.tools.ant.taskdefs.MatchingTask;
  36. import org.apache.tools.ant.types.FileSet;
  37. import org.apache.tools.ant.types.PatternSet;
  38. @SuppressWarnings("deprecation")
  39. public class AJInstaller extends MatchingTask {
  40. static final String INCLUDE_CLASSES = "$installer$/org/aspectj/*.class";
  41. static final String MAIN_CLASS = "$installer$.org.aspectj.Main";
  42. static final String CONTENTS_FILE = "$installer$/org/aspectj/resources/contents.txt";
  43. private String htmlSrc;
  44. public void setHtmlSrc(String v) { htmlSrc = v; }
  45. private String resourcesSrc;
  46. public void setResourcesSrc(String v) { resourcesSrc = v; }
  47. private String mainclass;
  48. public void setMainclass(String v) { mainclass = v; }
  49. private File installerClassJar;
  50. public void setInstallerclassjar(String v) {
  51. installerClassJar = project.resolveFile(v);
  52. }
  53. protected List<String> contentsNames = new ArrayList<>();
  54. protected long contentsBytes = 0;
  55. protected void addToContents(File file, String vPath) {
  56. contentsNames.add(vPath);
  57. contentsBytes += file.length();
  58. }
  59. String[] getFiles(File baseDir) {
  60. DirectoryScanner ds = new DirectoryScanner();
  61. setBasedir(baseDir.getAbsolutePath());
  62. ds.setBasedir(baseDir);
  63. //ds.setIncludes(new String [] {pattern});
  64. ds.scan();
  65. return ds.getIncludedFiles();
  66. }
  67. protected Copy getCopyTask() {
  68. Copy cd = (Copy)project.createTask("copy");
  69. if (null == cd) {
  70. log("project.createTask(\"copy\") failed - direct", Project.MSG_VERBOSE);
  71. cd = new Copy();
  72. cd.setProject(getProject());
  73. }
  74. return cd;
  75. }
  76. protected void finishZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException {
  77. writeContents(zOut);
  78. writeManifest(zOut);
  79. File tempDir = setupTempDir();
  80. String tmp = tempDir.getAbsolutePath();
  81. // installer class files
  82. Expand expand = new Expand();
  83. expand.setProject(getProject());
  84. expand.setSrc(installerClassJar);
  85. expand.setDest(new File(tmp));
  86. PatternSet patterns = new PatternSet();
  87. patterns.setIncludes(INCLUDE_CLASSES);
  88. expand.addPatternset(patterns);
  89. expand.execute();
  90. // move the correct resource files into the jar
  91. Copy cd = getCopyTask();
  92. fileset = new FileSet();
  93. fileset.setDir(new File(resourcesSrc));
  94. fileset.setIncludes("*");
  95. fileset.setExcludes("contents.txt,properties.txt");
  96. cd.addFileset(fileset);
  97. cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
  98. cd.execute();
  99. project.getGlobalFilterSet().addFilter("installer.main.class", this.mainclass);
  100. Copy cf = getCopyTask();
  101. fileset = new FileSet();
  102. fileset.setDir(new File(resourcesSrc));
  103. fileset.setIncludes("properties.txt");
  104. cf.setFiltering(true);
  105. cf.addFileset(fileset);
  106. cf.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
  107. cf.execute();
  108. // move the correct resource files into the jar
  109. cd = getCopyTask();
  110. fileset = new FileSet();
  111. fileset.setDir(new File(htmlSrc));
  112. fileset.setIncludes("*");
  113. cd.addFileset(fileset);
  114. cd.setTodir(new File(tmp+"/$installer$/org/aspectj/resources"));
  115. cd.execute();
  116. // now move these files into the jar
  117. setBasedir(tmp);
  118. writeFiles(zOut, getFiles(tempDir));
  119. // and delete the tmp dir
  120. Delete dt = (Delete)project.createTask("delete");
  121. if (null == dt) {
  122. dt = new Delete();
  123. dt.setProject(getProject());
  124. }
  125. dt.setDir(tempDir);
  126. dt.execute();
  127. tempDir = null;
  128. }
  129. static final char NEWLINE = '\n';
  130. protected void writeContents(ZipOutputStream zOut) throws IOException {
  131. // write to a StringBuffer
  132. StringBuffer buf = new StringBuffer();
  133. buf.append(contentsBytes);
  134. buf.append(NEWLINE);
  135. for (String name : contentsNames) {
  136. buf.append(name);
  137. buf.append(NEWLINE);
  138. }
  139. zipFile(new StringBufferInputStream(buf.toString()), zOut, CONTENTS_FILE, System.currentTimeMillis());
  140. }
  141. protected void writeManifest(ZipOutputStream zOut) throws IOException {
  142. // write to a StringBuffer
  143. StringBuffer buf = new StringBuffer();
  144. buf.append("Manifest-Version: 1.0");
  145. buf.append(NEWLINE);
  146. buf.append("Main-Class: " + MAIN_CLASS);
  147. buf.append(NEWLINE);
  148. zipFile(new StringBufferInputStream(buf.toString()), zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis());
  149. }
  150. //XXX cut-and-paste from Zip super-class (under apache license)
  151. private File zipFile;
  152. private File baseDir;
  153. private boolean doCompress = true;
  154. protected String archiveType = "zip";
  155. /**
  156. * This is the name/location of where to
  157. * create the .zip file.
  158. */
  159. public void setZipfile(String zipFilename) {
  160. zipFile = project.resolveFile(zipFilename);
  161. }
  162. /**
  163. * This is the base directory to look in for
  164. * things to zip.
  165. */
  166. public void setBasedir(String baseDirname) {
  167. baseDir = project.resolveFile(baseDirname);
  168. }
  169. /**
  170. * Sets whether we want to compress the files or only store them.
  171. */
  172. public void setCompress(String compress) {
  173. doCompress = Project.toBoolean(compress);
  174. }
  175. protected void initZipOutputStream(ZipOutputStream zOut)
  176. throws IOException, BuildException
  177. {
  178. }
  179. protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
  180. throws IOException
  181. {
  182. }
  183. protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
  184. long lastModified)
  185. throws IOException
  186. {
  187. ZipEntry ze = new ZipEntry(vPath);
  188. ze.setTime(lastModified);
  189. /*
  190. * XXX ZipOutputStream.putEntry expects the ZipEntry to know its
  191. * size and the CRC sum before you start writing the data when using
  192. * STORED mode.
  193. *
  194. * This forces us to process the data twice.
  195. *
  196. * I couldn't find any documentation on this, just found out by try
  197. * and error.
  198. */
  199. if (!doCompress) {
  200. long size = 0;
  201. CRC32 cal = new CRC32();
  202. if (!in.markSupported()) {
  203. // Store data into a byte[]
  204. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  205. byte[] buffer = new byte[8 * 1024];
  206. int count = 0;
  207. do {
  208. size += count;
  209. cal.update(buffer, 0, count);
  210. bos.write(buffer, 0, count);
  211. count = in.read(buffer, 0, buffer.length);
  212. } while (count != -1);
  213. in = new ByteArrayInputStream(bos.toByteArray());
  214. } else {
  215. in.mark(Integer.MAX_VALUE);
  216. byte[] buffer = new byte[8 * 1024];
  217. int count = 0;
  218. do {
  219. size += count;
  220. cal.update(buffer, 0, count);
  221. count = in.read(buffer, 0, buffer.length);
  222. } while (count != -1);
  223. in.reset();
  224. }
  225. ze.setSize(size);
  226. ze.setCrc(cal.getValue());
  227. }
  228. zOut.putNextEntry(ze);
  229. byte[] buffer = new byte[8 * 1024];
  230. int count = 0;
  231. do {
  232. zOut.write(buffer, 0, count);
  233. count = in.read(buffer, 0, buffer.length);
  234. } while (count != -1);
  235. }
  236. protected void zipFile(File file, ZipOutputStream zOut, String vPath)
  237. throws IOException
  238. {
  239. if ( !vPath.startsWith("$installer$") ) {
  240. addToContents(file, vPath);
  241. }
  242. FileInputStream fIn = new FileInputStream(file);
  243. try {
  244. zipFile(fIn, zOut, vPath, file.lastModified());
  245. } finally {
  246. fIn.close();
  247. }
  248. }
  249. private File setupTempDir() throws BuildException {
  250. File tmpDirF = null;
  251. File tmpDir = null;
  252. try {
  253. tmpDirF = File.createTempFile("tgz", ".di");
  254. tmpDir = new File(tmpDirF.getParentFile(), "AJInstaller");
  255. tmpDirF.delete();
  256. } catch (IOException e) {
  257. // retrying below
  258. }
  259. if (null == tmpDir || !tmpDir.mkdirs()) {
  260. tmpDir = new File("AJInstaller.finishZipOutputStream.tmp");
  261. if (!tmpDir.mkdirs()) {
  262. throw new BuildException("unable to make temp dir");
  263. }
  264. }
  265. return tmpDir;
  266. }
  267. public void execute() throws BuildException {
  268. if (installerClassJar == null) {
  269. throw new BuildException("installerClassJar attribute must be set!");
  270. }
  271. if (!installerClassJar.canRead()
  272. || !installerClassJar.getPath().endsWith(".jar")) {
  273. throw new BuildException("not readable jar:" + installerClassJar);
  274. }
  275. // if (installerClassDir == null) {
  276. // throw new BuildException("installerClassDir attribute must be set!");
  277. // }
  278. // if (!installerClassDir.exists()) {
  279. // throw new BuildException("no such directory: installerClassDir=" + installerClassDir);
  280. // }
  281. if (baseDir == null) {
  282. throw new BuildException("basedir attribute must be set!");
  283. }
  284. if (!baseDir.exists()) {
  285. throw new BuildException("basedir does not exist!");
  286. }
  287. DirectoryScanner ds = super.getDirectoryScanner(baseDir);
  288. String[] files = ds.getIncludedFiles();
  289. String[] dirs = ds.getIncludedDirectories();
  290. log("Building installer: "+ zipFile.getAbsolutePath());
  291. ZipOutputStream zOut = null;
  292. try {
  293. zOut = new ZipOutputStream(new FileOutputStream(zipFile));
  294. if (doCompress) {
  295. zOut.setMethod(ZipOutputStream.DEFLATED);
  296. } else {
  297. zOut.setMethod(ZipOutputStream.STORED);
  298. }
  299. initZipOutputStream(zOut);
  300. writeDirs(zOut, dirs);
  301. writeFiles(zOut, files);
  302. finishZipOutputStream(zOut); // deletes temp dir
  303. } catch (IOException ioe) {
  304. String msg = "Problem creating " + archiveType + " " + ioe.getMessage();
  305. throw new BuildException(msg, ioe, location);
  306. } finally {
  307. if (zOut != null) {
  308. try {
  309. // close up
  310. zOut.close();
  311. }
  312. catch (IOException e) {}
  313. }
  314. }
  315. }
  316. protected void writeDirs(ZipOutputStream zOut, String[] dirs) throws IOException {
  317. for (String dir : dirs) {
  318. File f = new File(baseDir, dir);
  319. String name = dir.replace(File.separatorChar, '/') + "/";
  320. zipDir(f, zOut, name);
  321. }
  322. }
  323. protected void writeFiles(ZipOutputStream zOut, String[] files) throws IOException {
  324. for (String file : files) {
  325. File f = new File(baseDir, file);
  326. String name = file.replace(File.separatorChar, '/');
  327. zipFile(f, zOut, name);
  328. }
  329. }
  330. }