From 17f57d3764cf1f12cbbd013d9c659994ed94617a Mon Sep 17 00:00:00 2001 From: acolyer Date: Tue, 16 Mar 2004 22:11:51 +0000 Subject: [PATCH] fix for Bugzilla Bug 54622 Incremental support ignores resources --- .../internal/core/builder/AjBuildManager.java | 134 +++++++++++++++-- .../ajdt/internal/core/builder/AjState.java | 64 +++++++++ .../org/aspectj/weaver/bcel/BcelWeaver.java | 136 +++++++++--------- 3 files changed, 254 insertions(+), 80 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index 94ed3a627..0ee4c1a6d 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -17,6 +17,7 @@ import java.io.*; import java.util.*; import java.util.jar.*; import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.aspectj.ajdt.internal.compiler.AjCompilerAdapter; @@ -214,6 +215,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda private void closeOutputStream() { try { if (zos != null) zos.close(); + zos = null; } catch (IOException ex) { IMessage message = new Message("Unable to write outjar " @@ -228,13 +230,116 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda private void copyResourcesToDestination() throws IOException { - if (buildConfig.getOutputJar() != null) { - bcelWeaver.dumpResourcesToOutJar(zos); - } else { - bcelWeaver.dumpResourcesToOutPath(); - } + // resources that we need to copy are contained in the injars and inpath only + for (Iterator i = buildConfig.getInJars().iterator(); i.hasNext(); ) { + File inJar = (File)i.next(); + copyResourcesFromJarFile(inJar); + } + + for (Iterator i = buildConfig.getInpath().iterator(); i.hasNext(); ) { + File inPathElement = (File)i.next(); + if (inPathElement.isDirectory()) { + copyResourcesFromDirectory(inPathElement); + } else { + copyResourcesFromJarFile(inPathElement); + } + } + + if (buildConfig.getSourcePathResources() != null) { + for (Iterator i = buildConfig.getSourcePathResources().keySet().iterator(); i.hasNext(); ) { + String resource = (String)i.next(); + copyResourcesFromFile((File)buildConfig.getSourcePathResources().get(resource), + resource); + } + } } - + + private void copyResourcesFromJarFile(File jarFile) throws IOException { + ZipInputStream inStream = null; + try { + inStream = new ZipInputStream(new FileInputStream(jarFile)); + while (true) { + ZipEntry entry = inStream.getNextEntry(); + if (entry == null) break; + + String filename = entry.getName(); + + if (!entry.isDirectory() && acceptResource(filename)) { + byte[] bytes = FileUtil.readAsByteArray(inStream); + writeResource(filename,bytes); + } + + inStream.closeEntry(); + } + } finally { + if (inStream != null) inStream.close(); + } + } + + private void copyResourcesFromDirectory(File dir) throws IOException { + // Get a list of all files (i.e. everything that isnt a directory) + File[] files = FileUtil.listFiles(dir,new FileFilter() { + public boolean accept(File f) { + boolean accept = !(f.isDirectory() || f.getName().endsWith(".class")) ; + return accept; + } + }); + + // For each file, add it either as a real .class file or as a resource + for (int i = 0; i < files.length; i++) { + // ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath() + // or we are in trouble... + String filename = files[i].getAbsolutePath().substring( + dir.getAbsolutePath().length()+1); + copyResourcesFromFile(files[i],filename); + } + } + + private void copyResourcesFromFile(File f,String filename) throws IOException { + if (!acceptResource(filename)) return; + FileInputStream fis = null; + try { + fis = new FileInputStream(f); + byte[] bytes = FileUtil.readAsByteArray(fis); + // String relativePath = files[i].getPath(); + + writeResource(filename,bytes); + } finally { + if (fis != null) fis.close(); + } + } + + private void writeResource(String filename, byte[] content) throws IOException { + if (state.resources.contains(filename)) return; + if (zos != null) { + ZipEntry newEntry = new ZipEntry(filename); //??? get compression scheme right + + zos.putNextEntry(newEntry); + zos.write(content); + zos.closeEntry(); + } else { + OutputStream fos = + FileUtil.makeOutputStream(new File(buildConfig.getOutputDir(),filename)); + fos.write(content); + fos.close(); + } + state.resources.add(filename); + } + + private boolean acceptResource(String resourceName) { + if ( + (resourceName.startsWith("CVS/")) || + (resourceName.indexOf("/CVS/") != -1) || + (resourceName.endsWith("/CVS")) || + (resourceName.endsWith(".class")) + ) + { + return false; + } else { + return true; + } + } + /** * Responsible for managing the ASM model between builds. Contains the policy for * maintaining the persistance of elements in the model. @@ -298,14 +403,15 @@ public class AjBuildManager implements IOutputClassFileNameProvider,ICompilerAda state.binarySourceFiles.put(inPathElement.getPath(),unwovenClasses); // good enough for ajc to lump these together } - if (buildConfig.getSourcePathResources() != null) { - for (Iterator i = buildConfig.getSourcePathResources().keySet().iterator(); i.hasNext(); ) { - // File resource = (File)i.next(); - String resource = (String)i.next(); - bcelWeaver.addResource(resource, (File)buildConfig.getSourcePathResources().get(resource), buildConfig.getOutputDir()); - // bcelWeaver.addResource(resource, buildConfig.getOutputDir()); - } - } +// if (buildConfig.getSourcePathResources() != null) { +// // XXX buildConfig.getSourcePathResources always returns null (CompileCommand.java) +// for (Iterator i = buildConfig.getSourcePathResources().keySet().iterator(); i.hasNext(); ) { +// // File resource = (File)i.next(); +// String resource = (String)i.next(); +// bcelWeaver.addResource(resource, (File)buildConfig.getSourcePathResources().get(resource), buildConfig.getOutputDir()); +// // bcelWeaver.addResource(resource, buildConfig.getOutputDir()); +// } +// } bcelWeaver.setReweavableMode(buildConfig.isXreweavable(),buildConfig.getXreweavableCompressClasses()); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java index 3a4fd4cd4..f37763901 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java @@ -14,6 +14,7 @@ package org.aspectj.ajdt.internal.core.builder; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -25,6 +26,7 @@ import java.util.Map; import java.util.Set; import org.aspectj.ajdt.internal.compiler.InterimCompilationResult; +import org.aspectj.util.FileUtil; import org.aspectj.weaver.bcel.UnwovenClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; @@ -50,6 +52,7 @@ public class AjState { Map/*File, List*/ binarySourceFiles = new HashMap(); Map/**/ classesFromName = new HashMap(); List/*File*/ compiledSourceFiles = new ArrayList(); + List/*String*/ resources = new ArrayList(); ArrayList/**/ qualifiedStrings; ArrayList/**/ simpleStrings; @@ -135,6 +138,7 @@ public class AjState { thisTime.addAll(addedFiles); deleteClassFiles(); + deleteResources(); addAffectedSourceFiles(thisTime,thisTime); } else { @@ -159,6 +163,66 @@ public class AjState { } } } + + private void deleteResources() { + List oldResources = new ArrayList(); + oldResources.addAll(resources); + + // note - this deliberately ignores resources in jars as we don't yet handle jar changes + // with incremental compilation + for (Iterator i = buildConfig.getInpath().iterator(); i.hasNext(); ) { + File inPathElement = (File)i.next(); + if (inPathElement.isDirectory()) { + deleteResourcesFromDirectory(inPathElement,oldResources); + } + } + + if (buildConfig.getSourcePathResources() != null) { + for (Iterator i = buildConfig.getSourcePathResources().keySet().iterator(); i.hasNext(); ) { + String resource = (String)i.next(); + maybeDeleteResource(resource, oldResources); + } + } + + // oldResources need to be deleted... + for (Iterator iter = oldResources.iterator(); iter.hasNext();) { + String victim = (String) iter.next(); + File f = new File(buildConfig.getOutputDir(),victim); + if (f.exists()) { + f.delete(); + } + resources.remove(victim); + } + } + + private void maybeDeleteResource(String resName, List oldResources) { + if (resources.contains(resName)) { + oldResources.remove(resName); + File source = new File(buildConfig.getOutputDir(),resName); + if ((source != null) && (source.exists()) && + (source.lastModified() >= lastSuccessfulBuildTime)) { + resources.remove(resName); // will ensure it is re-copied + } + } + } + + private void deleteResourcesFromDirectory(File dir, List oldResources) { + File[] files = FileUtil.listFiles(dir,new FileFilter() { + public boolean accept(File f) { + boolean accept = !(f.isDirectory() || f.getName().endsWith(".class")) ; + return accept; + } + }); + + // For each file, add it either as a real .class file or as a resource + for (int i = 0; i < files.length; i++) { + // ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath() + // or we are in trouble... + String filename = files[i].getAbsolutePath().substring( + dir.getAbsolutePath().length()+1); + maybeDeleteResource(filename, oldResources); + } + } private void deleteClassFile(UnwovenClassFile classFile) { classesFromName.remove(classFile.getClassName()); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 222295e95..7cc91555b 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -80,7 +80,7 @@ public class BcelWeaver implements IWeaver { // private Map sourceJavaClasses = new HashMap(); /* String -> UnwovenClassFile */ private List addedClasses = new ArrayList(); /* List */ private List deletedTypenames = new ArrayList(); /* List */ - private Map resources = new HashMap(); /* String -> UnwovenClassFile */ +// private Map resources = new HashMap(); /* String -> UnwovenClassFile */ private boolean needToReweaveWorld = false; private List shadowMungerList = null; // setup by prepareForWeave @@ -178,11 +178,11 @@ public class BcelWeaver implements IWeaver { // System.err.println("BCELWeaver: processing class from input directory "+classFile); this.addClassFile(classFile); addedClassFiles.add(classFile); - } else { - if (CopyResourcesFromInpathDirectoriesToOutput) { - // System.err.println("BCELWeaver: processing resource from input directory "+filename); - addResource(filename,classFile); - } +// } else { +// if (CopyResourcesFromInpathDirectoriesToOutput) { +// // System.err.println("BCELWeaver: processing resource from input directory "+filename); +// addResource(filename,classFile); +// } } fis.close(); } @@ -219,11 +219,11 @@ public class BcelWeaver implements IWeaver { this.addClassFile(classFile); addedClassFiles.add(classFile); } - else if (!entry.isDirectory()) { - - /* bug-44190 Copy meta-data */ - addResource(filename,classFile); - } +// else if (!entry.isDirectory()) { +// +// /* bug-44190 Copy meta-data */ +// addResource(filename,classFile); +// } inStream.closeEntry(); } @@ -257,20 +257,20 @@ public class BcelWeaver implements IWeaver { return addedClassFiles; } - public void addResource(String name, File inPath, File outDir) throws IOException { - - /* Eliminate CVS files. Relative paths use "/" */ - if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) { -// System.err.println("? addResource('" + name + "')"); -// BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inPath)); -// byte[] bytes = new byte[(int)inPath.length()]; -// inStream.read(bytes); -// inStream.close(); - byte[] bytes = FileUtil.readAsByteArray(inPath); - UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, name).getAbsolutePath(), bytes); - addResource(name,resourceFile); - } - } +// public void addResource(String name, File inPath, File outDir) throws IOException { +// +// /* Eliminate CVS files. Relative paths use "/" */ +// if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) { +//// System.err.println("? addResource('" + name + "')"); +//// BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inPath)); +//// byte[] bytes = new byte[(int)inPath.length()]; +//// inStream.read(bytes); +//// inStream.close(); +// byte[] bytes = FileUtil.readAsByteArray(inPath); +// UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, name).getAbsolutePath(), bytes); +// addResource(name,resourceFile); +// } +// } public boolean needToReweaveWorld() { return needToReweaveWorld; @@ -293,16 +293,16 @@ public class BcelWeaver implements IWeaver { world.deleteSourceObjectType(TypeX.forName(typename)); } - public void addResource (String name, UnwovenClassFile resourceFile) { - /* bug-44190 Change error to warning and copy first resource */ - if (!resources.containsKey(name)) { - resources.put(name, resourceFile); - } - else { - world.showMessage(IMessage.WARNING, "duplicate resource: '" + name + "'", - null, null); - } - } +// public void addResource (String name, UnwovenClassFile resourceFile) { +// /* bug-44190 Change error to warning and copy first resource */ +// if (!resources.containsKey(name)) { +// resources.put(name, resourceFile); +// } +// else { +// world.showMessage(IMessage.WARNING, "duplicate resource: '" + name + "'", +// null, null); +// } +// } // ---- weave preparation @@ -358,38 +358,38 @@ public class BcelWeaver implements IWeaver { // } // } - public void dumpResourcesToOutPath() throws IOException { -// System.err.println("? dumpResourcesToOutPath() resources=" + resources.keySet()); - Iterator i = resources.keySet().iterator(); - while (i.hasNext()) { - UnwovenClassFile res = (UnwovenClassFile)resources.get(i.next()); - dumpUnchanged(res); - } - //resources = new HashMap(); - } - +// public void dumpResourcesToOutPath() throws IOException { +//// System.err.println("? dumpResourcesToOutPath() resources=" + resources.keySet()); +// Iterator i = resources.keySet().iterator(); +// while (i.hasNext()) { +// UnwovenClassFile res = (UnwovenClassFile)resources.get(i.next()); +// dumpUnchanged(res); +// } +// //resources = new HashMap(); +// } +// /* BUG #40943 */ - public void dumpResourcesToOutJar() throws IOException { -// System.err.println("? dumpResourcesToOutJar() resources=" + resources.keySet()); - Iterator i = resources.keySet().iterator(); - while (i.hasNext()) { - String name = (String)i.next(); - UnwovenClassFile res = (UnwovenClassFile)resources.get(name); - writeZipEntry(name,res.getBytes()); - } - //resources = new HashMap(); - } - - // halfway house for when the jar is managed outside of the weaver, but the resources - // to be copied are known in the weaver. - public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException { - this.zipOutputStream = zos; - dumpResourcesToOutJar(); - } +// public void dumpResourcesToOutJar() throws IOException { +//// System.err.println("? dumpResourcesToOutJar() resources=" + resources.keySet()); +// Iterator i = resources.keySet().iterator(); +// while (i.hasNext()) { +// String name = (String)i.next(); +// UnwovenClassFile res = (UnwovenClassFile)resources.get(name); +// writeZipEntry(name,res.getBytes()); +// } +// resources = new HashMap(); +// } +// +// // halfway house for when the jar is managed outside of the weaver, but the resources +// // to be copied are known in the weaver. +// public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException { +// this.zipOutputStream = zos; +// dumpResourcesToOutJar(); +// } // ---- weaving - // Used by some test cases... + // Used by some test cases only... public Collection weave(File file) throws IOException { OutputStream os = FileUtil.makeOutputStream(file); this.zipOutputStream = new ZipOutputStream(os); @@ -402,7 +402,11 @@ public class BcelWeaver implements IWeaver { public IWeaveRequestor getRequestor() { return new IWeaveRequestor() { - public void acceptResult(UnwovenClassFile result) {} + public void acceptResult(UnwovenClassFile result) { + try { + writeZipEntry(result.filename, result.bytes); + } catch(IOException ex) {} + } public void processingReweavableState() {} public void addingTypeMungers() {} public void weavingAspects() {} @@ -411,8 +415,8 @@ public class BcelWeaver implements IWeaver { }; } }); - /* BUG 40943*/ - dumpResourcesToOutJar(); +// /* BUG 40943*/ +// dumpResourcesToOutJar(); zipOutputStream.close(); //this flushes and closes the acutal file return c; } -- 2.39.5