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

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