Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 28494 Details for
Bug 113191
Contribution: Command Line Weaver that Can be Packaged with aspectjweaver.jar
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
the command line weaver implementation
CmdLineWeaver.java (text/plain), 17.08 KB, created by
Ron Bodkin
on 2005-10-20 01:05:48 EDT
(
hide
)
Description:
the command line weaver implementation
Filename:
MIME Type:
Creator:
Ron Bodkin
Created:
2005-10-20 01:05:48 EDT
Size:
17.08 KB
patch
obsolete
>package org.aspectj.weaver.tools; > >import java.io.BufferedOutputStream; >import java.io.File; >import java.io.FileInputStream; >import java.io.IOException; >import java.io.OutputStream; >import java.io.PrintWriter; >import java.util.ArrayList; >import java.util.Collection; >import java.util.HashSet; >import java.util.Iterator; >import java.util.List; >import java.util.Set; >import java.util.StringTokenizer; >import java.util.jar.JarInputStream; >import java.util.jar.JarOutputStream; >import java.util.zip.ZipEntry; > >import org.aspectj.bridge.AbortException; >import org.aspectj.bridge.IMessage; >import org.aspectj.bridge.IMessageHandler; >import org.aspectj.bridge.Message; >import org.aspectj.bridge.MessageWriter; >import org.aspectj.bridge.SourceLocation; >import org.aspectj.bridge.IMessage.Kind; >import org.aspectj.util.FileUtil; >import org.aspectj.weaver.IClassFileProvider; >import org.aspectj.weaver.IWeaveRequestor; >import org.aspectj.weaver.bcel.BcelWeaver; >import org.aspectj.weaver.bcel.BcelWorld; >import org.aspectj.weaver.bcel.UnwovenClassFile; > >/** > * Simple command-line weaver that depends only on aspectjweaver.jar, not any part of the compiler. > * Supports all reasonable options > */ > >public class CmdLineWeaver { > protected JarOutputStream zos; > protected List/*String*/ resources = new ArrayList(); > protected static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; > protected BcelWorld world; > protected BcelWeaver weaver; > protected List unwovenClasses = new ArrayList(); > protected IClassFileProvider classFileProvider = new WeavingClassFileProvider(); > protected IMessageHandler messageHandler = new JarWeaverMessageHandler(new PrintWriter(System.err)); > > public static String CONFIG_MSG = "weave config error: "; > > protected class State { > public List inpath = new ArrayList(); > public List aspectpath = new ArrayList(); > //TODO: test pulling in bootstrap classes, not conflicting system classpath classes when specifying -classpath > public String classpathStr = null; > public String bootClasspathStr = null; > public String extdirs = null; > public File outjar; > public boolean verbose = false; > public boolean showWeaveInfo = false; > public File xlintFile = null; > > public boolean xLazyTjp = true; > public boolean reweavable = true; > public boolean xNoInline = false; > > public boolean hasErrors = false; > private boolean nowarn; > public File outputDir = null; > public File baseDir = new File(System.getProperty("user.dir")); //$NON-NLS-1$ > public void addError(String message) { > System.err.println(CONFIG_MSG + message); > hasErrors = true; > } > public boolean hasErrors() { > return hasErrors; > } > /** > * > * @param args > * @return true if no errors > */ > public boolean parse(String args[]) { > boolean showUsage = false; >// currentDir = new File("."); //TODO make fully portable > for (int i=0; i<args.length; i++) { > String arg = args[i]; > if (arg.equals("-inpath")) { > parsePath(inpath, args, ++i, "in"); > } else if (arg.equals("-cp") || arg.equals("-classpath")) { > if (args.length > ++i) { > classpathStr = args[i]; > } else { > addError("missing classpath argument"); > } > } else if (arg.equals("-bootclasspath")) { > if (args.length > ++i) { > bootClasspathStr = args[i]; > } else { > addError("missing bootclasspath argument"); > } > } else if (arg.equals("-extdirs")) { > if (args.length > ++i) { > extdirs = args[i]; > } else { > addError("missing extdirs argument"); > } > } else if (arg.equals("-aspectpath")) {; > aspectpath = new ArrayList(); > parsePath(aspectpath, args, ++i, "aspect"); > } else if (arg.equals("-outjar")) { > ++i; > if (args.length > i) { > outjar = makeFile(args[i], baseDir); > if (FileUtil.hasZipSuffix(outjar)) { > try { > if (!outjar.exists()) { > outjar.createNewFile(); > } > } catch (IOException ioe) { > addError("unable to create outjar file: " + outjar); > } > } else { > addError("invalid -outjar file: " + outjar); > } > } else { > addError("-outjar requires jar path argument"); > } > } else if (arg.equals("-verbose")) { > verbose = true; > } else if (arg.equals("-showWeaveInfo")) { > showWeaveInfo = true; > } else if (arg.equals("-Xlintfile")) { > if (args.length > ++i) { > xlintFile = makeFile(args[i], baseDir); > if (!xlintFile.canRead()) { > addError("can't read Xlintfile "+args[i]); > } > if (!xlintFile.getName().endsWith(".properties")) { > addError("-Xlintfile requires .properties file argument"); > } > } else { > addError("-Xlintfile requires file argument"); > } > } else if (arg.equals("-XlazyTjp")) { > showWarning("-XlazyTjp is true by default in CmdLineWeaver"); > xLazyTjp = true; > } else if (arg.equals("-XnotLazyTjp")) { > xLazyTjp = false; > } else if (arg.startsWith("-Xreweavable")) { > showWarning("-Xreweavable is on by default"); > if (arg.endsWith(":compress")) { > showWarning("-Xreweavable:compress is no longer available - reweavable is now default"); > } > } else if (arg.startsWith("-XnotReweavable")) { > reweavable = false; > } else if (arg.equals("-XnoInline")) { > xNoInline = true; > } else if (arg.equals("-nowarn")) { > nowarn = true; > } else if (arg.equals("-help")) { > showUsage = true; > } else if (arg.equals("-d")) { > if (args.length > ++i) { > outputDir = new File(args[i]); > } else { > addError("-d requires directory argument"); > } > } else { > addError("unknown argument: "+arg); > showUsage = true; > } > } > if (outjar == null) { > if (outputDir == null) { > outputDir = baseDir; > } > if (outputDir.exists()) { > if (!outputDir.isDirectory()) { > addError("Output directory isn't a directory: "+outputDir.getPath()); > } > } else { > if (!outputDir.mkdirs()) { > addError("Can't create output directory: "+outputDir.getPath()); > } > } > } > if (showUsage) { > usage(); > } > return !hasErrors || showUsage; > } > > private void parsePath(List path, String args[], int pos, String pathType) { > if (args.length > pos) { > String pathStr = args[pos]; > StringTokenizer st = new StringTokenizer(pathStr, File.pathSeparator); > while (st.hasMoreTokens()) { > String filename = st.nextToken(); > File jarFile = makeFile(filename, baseDir); > if (jarFile.exists() && (FileUtil.hasZipSuffix(filename) || jarFile.isDirectory())) { > path.add(jarFile); > } else if (jarFile.isDirectory()) { > path.add(jarFile); > } else { > addError("bad "+pathType+"path entry: " + filename); > } > } > } else { > addError("missing "+pathType+"path argument"); > } > } > > public List getClasspath() { > List ret = new ArrayList(); > > if (extdirs == null) { > extdirs = System.getProperty("java.ext.dirs", ""); > } > addExtDirs(extdirs, ret); > > if (classpathStr == null) { > addClasspath(System.getProperty("java.class.path", ""), ret); > List fixedList = new ArrayList(); > for (Iterator it = ret.iterator(); it.hasNext(); ) { > String entry = (String)it.next(); > if (!entry.endsWith("aspectjweaver.jar")) { > fixedList.add(entry); > } > } > ret = fixedList; > } else { > addClasspath(classpathStr, ret); > } > //??? eclipse seems to put outdir on the classpath > //??? we're brave and believe we don't need it > return ret; > } > > private void addExtDirs(String extdirs, List classpathCollector) { > StringTokenizer tokenizer = new StringTokenizer(extdirs, File.pathSeparator); > while (tokenizer.hasMoreTokens()) { >// classpathCollector.add(tokenizer.nextToken()); > File dirFile = new File((String)tokenizer.nextToken()); > if (dirFile.canRead() && dirFile.isDirectory()) { > File[] files = dirFile.listFiles(FileUtil.ZIP_FILTER); > for (int i = 0; i < files.length; i++) { > classpathCollector.add(files[i].getAbsolutePath()); > } > } else { > showWarning("invalid -extdirs entry: "+dirFile.getPath()); > } > } > } > > > private void addClasspath(String classpath, List classpathCollector) { > StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator); > while (tokenizer.hasMoreTokens()) { > classpathCollector.add(tokenizer.nextToken()); > } > } > > public List getBootclasspath() { > List ret = new ArrayList(); > > if (bootClasspathStr == null) { > addClasspath(System.getProperty("sun.boot.class.path", ""), ret); > } else { > addClasspath(bootClasspathStr, ret); > } > return ret; > } > > }; > protected State state = new State(); >// File currentDir; > > public static void main(String args[]) throws IOException { > CmdLineWeaver jarWeaver = new CmdLineWeaver(); > jarWeaver.run(args); > } > > > public void showWarning(String string) { > messageHandler.handleMessage(new Message(string, null, false, null)); > } > > > public void usage() { > System.err.println("jarWeaver [-inpath path] -outjar jar [-classpath|-cp path] [-verbose] [-showWeaveInfo] [-Xlintfile file] "+ > "[-XnotLazyTjp to change default] [-XnotReweavable] [-XnoInline] [-extdirs] [-noWarn] [-d directory]"); > } > > public void run(String args[]) throws IOException { > if (state.parse(args)) { > try { > prepare(); > > Collection result = weaver.weave(classFileProvider); > > if (state.verbose) { > System.out.println(); > } > > world.showMessage(IMessage.INFO, > "Processed: "+result.size()+" entries ", > null, null); > } finally { > if (zos != null) { > zos.close(); > } > } > > } > } > > /** method to support testing: could be exposed through a command line arg */ > public void setBaseDir(File baseDir) { > state.baseDir = baseDir; > } > > /** method to support testing */ > public void setMessageHander(IMessageHandler handler) { > this.messageHandler = handler; > } > > protected void prepare() throws IOException { > if (state.verbose) { > messageHandler.dontIgnore(IMessage.INFO); > } > if (state.showWeaveInfo) { > messageHandler.dontIgnore(IMessage.WEAVEINFO); > } > if (state.nowarn) { > //XXX ignore should be added to the MessageHandler interface too, see also Alex's use of dontIgnore > // to convey "ignore" for this case. Blech! > ((JarWeaverMessageHandler)messageHandler).ignore(IMessage.WARNING); > } > List classpath = state.getBootclasspath(); > classpath.addAll(state.getClasspath()); > > world = new BcelWorld(classpath,messageHandler,null); > world.setXnoInline(state.xNoInline); > world.setXlazyTjp(state.xLazyTjp); > > if (state.xlintFile != null) { > world.getLint().setFromProperties(state.xlintFile); > } else { > world.getLint().loadDefaultProperties(); > } > > weaver = new BcelWeaver(world); > weaver.setReweavableMode(!state.reweavable); > > for (Iterator it=state.aspectpath.iterator(); it.hasNext();) { > File aspectPathEntry = (File)(it.next()); > weaver.addLibraryJarFile(aspectPathEntry); > } > > //Map binarySourceFiles = new HashMap(); > for (Iterator it=state.inpath.iterator(); it.hasNext();) { > File inPathEntry = (File)(it.next()); > if (inPathEntry.isDirectory()) { > unwovenClasses.addAll(weaver.addDirectoryContents(inPathEntry, state.outputDir)); > } else { > unwovenClasses.addAll(weaver.addJarFile(inPathEntry, state.outputDir, true)); > } > } > > if (state.outjar != null) { > OutputStream os = FileUtil.makeOutputStream(state.outjar); > zos = new JarOutputStream(os,weaver.getManifest(true)); > } > > for (Iterator it=state.inpath.iterator(); it.hasNext();) { > File inPathEntry = (File)(it.next()); > if (!inPathEntry.isDirectory()) { > copyResourcesFromJarFile(inPathEntry); > } > } > > weaver.prepareForWeave(); > } > > private class WeavingClassFileProvider implements IClassFileProvider { > > public Iterator getClassFileIterator() { > return unwovenClasses.iterator(); > } > > public IWeaveRequestor getRequestor() { > return new IWeaveRequestor() { > > public void acceptResult(UnwovenClassFile result) { > try { > String filename = result.getClassName().replace('.', '/') + ".class"; > > if (zos != null) { > writeZipEntry(filename, result.getBytes()); > } else { > writeDirectoryEntry(filename, result.getBytes()); > } > } catch (IOException e) { > throw new RuntimeException("losing! ", e); > } > } > > public void processingReweavableState() { } > > public void addingTypeMungers() {} > > public void weavingAspects() {} > > public void weavingClasses() {} > > public void weaveCompleted() {} > }; > } > } > > private void writeDirectoryEntry(String filename, byte[] bytes) throws IOException { > File outFile = new File(state.outputDir, filename); > BufferedOutputStream os = > FileUtil.makeOutputStream(outFile); > try { > os.write(bytes); > } finally { > os.close(); > } > } > > private void writeZipEntry(String filename, byte[] bytes) throws IOException { > ZipEntry newEntry = new ZipEntry(filename); //??? get compression scheme right > > zos.putNextEntry(newEntry); > zos.write(bytes); > zos.closeEntry(); > } > > // should be refactored, not copied into here > private void copyResourcesFromJarFile(File jarFile) throws IOException { > JarInputStream inStream = null; > try { > inStream = new JarInputStream(new FileInputStream(jarFile)); > while (true) { > ZipEntry entry = inStream.getNextEntry(); > if (entry == null) break; > > String filename = entry.getName(); >// System.out.println("? copyResourcesFromJarFile() filename='" + filename +"'"); > > if (!entry.isDirectory() && acceptResource(filename)) { > byte[] bytes = FileUtil.readAsByteArray(inStream); > writeResource(filename,bytes,jarFile); > } > > inStream.closeEntry(); > } > } finally { > if (inStream != null) inStream.close(); > } > } > private void writeResource(String filename, byte[] content, File srcLocation) throws IOException { > if (resources.contains(filename)) { > IMessage msg = new Message("duplicate resource: '" + filename + "'", > IMessage.WARNING, > null, > new SourceLocation(srcLocation,0)); > messageHandler.handleMessage(msg); > return; > } > if (zos != null) { > // XXX test this - add a property to the test jar > ZipEntry newEntry = new ZipEntry(filename); //??? get compression scheme right > > zos.putNextEntry(newEntry); > zos.write(content); > zos.closeEntry(); > } > resources.add(filename); > } > > private boolean acceptResource(String resourceName) { > if ( > (resourceName.startsWith("CVS/")) || > (resourceName.indexOf("/CVS/") != -1) || > (resourceName.endsWith("/CVS")) || > (resourceName.endsWith(".class")) || > (resourceName.toUpperCase().equals(MANIFEST_NAME)) > ) > { > return false; > } else { > return true; > } > } > > protected static File makeFile(String name, File dir) { > name = name.replace('/', File.separatorChar); > File ret = new File(name); > if (dir != null && !ret.isAbsolute()) { > ret = new File(dir, name); > } > try { > ret = ret.getCanonicalFile(); > } catch (IOException ioEx) { > // proceed without canonicalization > // so nothing to do here > } > return ret; > } > > // copy/paste from BcelWorld private > protected static List getPathEntries(String s) { > List ret = new ArrayList(); > StringTokenizer tok = new StringTokenizer(s, File.pathSeparator); > > while(tok.hasMoreTokens()) ret.add(tok.nextToken()); > > return ret; > } > > protected class JarWeaverMessageHandler extends MessageWriter { > > private Set ignoring = new HashSet(); > private IMessage.Kind failKind; > > public JarWeaverMessageHandler(PrintWriter writer) { > super(writer,true); > > ignore(IMessage.WEAVEINFO); > ignore(IMessage.INFO); > this.failKind = IMessage.ERROR; > > } > > public boolean handleMessage(IMessage message) throws AbortException { > boolean result = super.handleMessage(message); > if (0 <= message.getKind().compareTo(failKind)) { > throw new AbortException(message); > } > return true; > } > > public boolean isIgnoring (Kind kind) { > return ((null != kind) && (ignoring.contains(kind))); > } > > /** > * Set a message kind to be ignored from now on > */ > public void ignore (IMessage.Kind kind) { > if ((null != kind) && (!ignoring.contains(kind))) { > ignoring.add(kind); > } > } > > /** > * Remove a message kind from the list of those ignored from now on. > */ > public void dontIgnore (IMessage.Kind kind) { > if (null != kind) { > ignoring.remove(kind); > } > } > } > >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 113191
: 28494 |
28495
|
28496