================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/weaving/StaticWeave.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:10 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/weaving/StaticWeave.java Mon Nov 27 11:25:10 2006 *************** *** 0 **** --- 1,225 ---- + package oracle.toplink.essentials.weaving; + + import java.io.File; + import java.io.FileWriter; + import java.io.PrintStream; + import java.io.Writer; + import java.net.MalformedURLException; + import java.net.URL; + import java.net.URLClassLoader; + + import oracle.toplink.essentials.exceptions.StaticWeaveException; + import oracle.toplink.essentials.internal.localization.ExceptionLocalization; + import oracle.toplink.essentials.internal.localization.ToStringLocalization; + import oracle.toplink.essentials.logging.AbstractSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + + /** + *

+ * Description: This is the static weave command line processing class that verifies command options and invokes + * StaticWeaveProcessor to statically weave the classes. + *

+ * Usage:
+ *  StaticWeave [options] source target
+ * Options:
+ *  -classpath
+ *    Set the user class path, use ";" as the delimiter in Window system and ":" in Unix system.
+ *  -log
+ *    the path of log file, the standard output will be the default.
+ *  -loglevel
+ *  nbsp; specify a literal value for toplink log level(OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST). The default value is OFF.
+ *  -persistenceinfo
+ *    The path contains META-INF/persistence.xml. This is ONLY required when the source does not include it. + * The classpath must contain all the classes necessary in oder to perform weaving.
+ * The weaving will be performed in place if source and target point to the same location. Weaving in place is ONLY applicable for directory-based sources.
+ *Example:
+ * To weave all entites contained in c:\foo-source.jar with its persistence.xml contained within c:\foo-containing-persistence-xml.jar, and output to c:\\foo-target.jar,
+ *StaticWeave -persistenceinfo c:\foo-containing-persistencexml.jar -classpath c:\classpath1;c:\classpath2 c:\foo-source.jar -o c:\foo-target.jar\r\r"} + * + **/ + + public class StaticWeave { + + // command line arguments + private String[] argv; + + // The location path of the source, null if none was given + private String source; + + // The location path containing persistence.xml, null if none was given + private String persistenceinfopath; + + // The location path of the target, null if none was given + private String target; + + private int loglevel=SessionLog.OFF; + + private Writer logWriter; + + private PrintStream vout = System.out; + + private String[] classpaths; + + public static void main(String[] argv) { + + StaticWeave staticweaver = new StaticWeave(argv); + + try { + // Verify the command line arguments + staticweaver.processCommandLine(); + staticweaver.start(); + } catch (Exception e) { + throw StaticWeaveException.exceptionPerformWeaving(e); + } + } + + + public StaticWeave(String[] argv) { + this.argv = argv; + } + + /** + * Invoke StaticWeaveProcessor to perform weaving. + */ + public void start() throws Exception { + + //perform weaving + StaticWeaveProcessor staticWeaverProcessor= new StaticWeaveProcessor(this.source,this.target); + if(persistenceinfopath!=null){ + staticWeaverProcessor.setPersistenceInfo(this.persistenceinfopath); + } + if(classpaths!=null){ + staticWeaverProcessor.setClassLoader(getClassLoader()); + } + if(logWriter!=null){ + staticWeaverProcessor.setLog(logWriter); + } + staticWeaverProcessor.setLogLevel(loglevel); + staticWeaverProcessor.performWeaving(); + } + + + /* + * Verify command line option. + */ + void processCommandLine() throws Exception + { + if (argv.length < 2 || argv.length>10) { + printUsage(); + System.exit(1); + } + for (int i=0;i= argv.length ){ + printUsage(); + System.exit(1); + } + classpaths=argv[i+1].split(File.pathSeparator); + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-persistenceinfo")) { + if ((i + 1) >= argv.length ){ + printUsage(); + System.exit(1); + } + persistenceinfopath=argv[i+1]; + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-log")) { + if ((i + 1) >= argv.length ){ + printUsage(); + System.exit(1); + } + logWriter=new FileWriter(argv[i+1]); + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-loglevel")) { + if ((i + 1) >= argv.length ) { + printUsage(); + System.exit(1); + } + + if ( argv[i+1].equalsIgnoreCase("OFF") || + argv[i+1].equalsIgnoreCase("SEVERE") || + argv[i+1].equalsIgnoreCase("WARNING") || + argv[i+1].equalsIgnoreCase("INFO") || + argv[i+1].equalsIgnoreCase("CONFIG") || + argv[i+1].equalsIgnoreCase("FINE") || + argv[i+1].equalsIgnoreCase("FINER") || + argv[i+1].equalsIgnoreCase("FINEST") || + argv[i+1].equalsIgnoreCase("ALL")) { + loglevel=AbstractSessionLog.translateStringToLoggingLevel(argv[i+1].toUpperCase()); + } else{ + printUsage(); + System.exit(1); + } + i++; + continue; + } + + if(source!=null){ + printUsage(); + System.exit(1); + } + + if(target!=null){ + printUsage(); + System.exit(1); + } + + source=argv[i]; + if((i+1)>=argv.length){ + printUsage(); + System.exit(1); + } + i++; + if(i>=argv.length){ + printUsage(); + System.exit(1); + } + target=argv[i]; + i++; + } + + + //Ensure source and target have been specified + if(source==null){ + printUsage(); + throw StaticWeaveException.missingSource(); + } + if(target==null){ + printUsage(); + throw StaticWeaveException.missingTarget(); + } + } + + /* + * print command help message + */ + private void printUsage() { + PrintStream o = vout; + o.println(ToStringLocalization.buildMessage("staticweave_commandline_help_message", new Object[]{null})); + } + + /* + * Convert the specified classpath arrary to URL array where new classloader will build on. + */ + private ClassLoader getClassLoader() throws MalformedURLException{ + if (classpaths!=null){ + URL[] urls= new URL[classpaths.length]; + for(int i=0;i + * Description: This is the static weave ant task definition class that verifies the value of specified attributes and invokes + * StaticWeaveProcessor to weave classes. + *

+ * Usage: + *

+ *Example: + * + *<target name="define.task" description="New task definition for toplink static weaving"/>
+ *  <taskdef name="weave" classname="oracle.toplink.essentials.weaving.StaticWeaverAntTask"/>
+ *</target>
+ *<target name="weaving" description="perform weaving." depends="define.task">
+ *  <weave source= "c:\foo.jar" target = "c:\wovenfoo.jar" persistenceinfo="c:\foo-containing-persistenceinfo.jar">
+ *    <classpath>
+ *      <pathelement path="c:\foo-dependent.jar"/>
+ *    </classpath>
+ *  </weave>
+ *</target> + *
+ */ + + + public class StaticWeaveAntTask extends Task{ + + private String source; + private String persistenceinfo; + private String target; + private Vector classPaths = new Vector(); + private int logLevel=SessionLog.OFF; + private Writer logWriter; + + + /** + * Set the input archive to be used to weave. + * @param inputJarFile + */ + public void setSource(String source) { + this.source = source; + } + + /** + * Set output archive to be used to weave to + * @param outputJarFile + */ + public void setTarget(String target) { + this.target = target; + } + + /** + * Set the archive containing persistence.xml while input archive does not contain it. + * @param inputMainJarFile + */ + public void setLog(String logFile) throws IOException { + try{ + this.logWriter = new FileWriter(logFile); + }catch(Exception e){ + throw StaticWeaveException.openLoggingFileException(logFile,e); + } + } + + public void setLogLevel(String logLevel) { + if (logLevel.equalsIgnoreCase("OFF") || + logLevel.equalsIgnoreCase("SEVERE") || + logLevel.equalsIgnoreCase("WARNING") || + logLevel.equalsIgnoreCase("INFO") || + logLevel.equalsIgnoreCase("CONFIG") || + logLevel.equalsIgnoreCase("FINE") || + logLevel.equalsIgnoreCase("FINER") || + logLevel.equalsIgnoreCase("FINEST") || + logLevel.equalsIgnoreCase("ALL")) { + this.logLevel=AbstractSessionLog.translateStringToLoggingLevel(logLevel.toUpperCase()); + } else{ + throw StaticWeaveException.illegalLoggingLevel(logLevel); + } + } + + public void setPersistenceinfo(String persistenceinfo) { + this.persistenceinfo = persistenceinfo; + } + + /** + * Add the dependent classpath in order to load classes from the specified input jar. + * @param path + */ + public void addClasspath(Path path) { + classPaths.add(path); + } + + /* + * Parse the class path element and store them into vector. + */ + private Vector getPathElement(){ + Vector pathElements = new Vector(); + for(int i=0;i + * Description: The StaticWeaveProcessor controls the static weaving process. It is invoked by both the command line + * StaticWeave class and the StaticWeaveAntTask. + *

+ * Responsibilities:Process the source classes, performs weaving as necessary out outputs to the target + **/ + public class StaticWeaveProcessor { + private URL source; + private URL target; + private URL persistenceInfo; + private Writer logWriter; + private ClassLoader classLoader; + private int logLevel = SessionLog.OFF; + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the name of the location to be weaved + * @param target the name of the location to be weaved to + * @throws MalformedURLException + */ + public StaticWeaveProcessor(String source,String target)throws MalformedURLException{ + if (source!=null){ + this.source=new File(source).toURL(); + } + if (target!=null){ + this.target=new File(target).toURL(); + } + } + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the File object of the source to be weaved + * @param target the File object of the target to be weaved to + * @throws MalformedURLException + */ + public StaticWeaveProcessor(File source, File target)throws MalformedURLException{ + this.source=source.toURL(); + this.target=target.toURL(); + } + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the URL of the source to be weaved + * @param target the URL of the target to be weaved to + */ + public StaticWeaveProcessor(URL source, URL target){ + this.source=source; + this.target=target; + } + + /** + * The method allows user to specify the ouput for the log message. + * @param log writer - the lcation where the log message writes to. the default value is standardout + */ + public void setLog(Writer logWriter){ + this.logWriter= logWriter; + } + + /** + * The method allows user to define nine levels toplink logging. + * @param level - the integer value of log level. default is OFF. + */ + public void setLogLevel(int level){ + this.logLevel=level; + } + + /** + * Set the user classloader. + * @param classLoader + */ + public void setClassLoader(ClassLoader classLoader){ + this.classLoader=classLoader; + } + + /** + * Set an explicitly identified URL of the location containing persistence.xml. + * @param persistenceInfo the URL of the location containing persistence.xml, the URL + * must point to the root of META-INF/persistence.xml + */ + public void setPersistenceInfo (URL persistenceInfo){ + this.persistenceInfo = persistenceInfo; + } + + /** + * Set an explicitly identified the location containing persistence.xml. + * @param persistenceinfo the path of the location containing persistence.xml, the path + * must point to the root of META-INF/persistence.xml + */ + public void setPersistenceInfo(String persistenceInfoPath) throws MalformedURLException{ + if (persistenceInfoPath!=null){ + this.persistenceInfo=new File(persistenceInfoPath).toURL(); + } + } + + + /** + * Set an explicitly identified the location containing persistence.xml. + * @param persistenceinfo the file containing persistence.xml, the file + * should contain META-INF/persistence.xml + */ + public void setPersistenceInfo(File persistenceInfoFile) throws MalformedURLException{ + if (persistenceInfoFile!=null){ + this.persistenceInfo=persistenceInfoFile.toURL(); + } + } + + + /** + * This method performs weaving function on the class individually from the specified source. + * @throws Exception. + */ + public void performWeaving() throws URISyntaxException,MalformedURLException,IOException{ + preProcess(); + process(); + } + + /* + * INTERNAL: + * This method perform all necessary steps(verification, pre-build the target directory) + * prior to the invokation of the weaving function. + */ + private void preProcess() throws URISyntaxException,MalformedURLException{ + //Instantiate default session log + AbstractSessionLog.getLog().setLevel(this.logLevel); + if(logWriter!=null){ + ((DefaultSessionLog)AbstractSessionLog.getLog()).setWriter(logWriter); + } + + //Make sure the source is existing + if(!(new File(source.toURI())).exists()){ + throw StaticWeaveException.missingSource(); + } + + //Verification target and source, two use cases create warning or exception. + //1. If source is directory and target is jar - + // This will lead unkown outcome, user attempt to use this tool to pack outcome into a Jar. + // Warning message will be logged, this is can be workarounded by other utilities. + //2. Both source and target are specified as a same jar - + // User was tryint to perform waving in same Jar which is not support, Exception will be thrown. + if(isDirectory(source) && target.toURI().toString().endsWith(".jar")){ + AbstractSessionLog.getLog().log(SessionLog.WARNING, ToStringLocalization.buildMessage("staticweave_processor_unknown_outcome", new Object[]{null})); + } + + if(!isDirectory(source) && target.toString().equals(source.toString())){ + throw StaticWeaveException.weaveInplaceForJar(source.toString()); + } + + //pre-create target if it is directory and dose not exsit. + //Using the method File.isDirectory() is not enough to determine what the type(dir or jar) + //of the target(specified by URL)that user want to create. File.isDirectory() will return false in + //two possibilities, the location either is not directory or the location dose not exist. + //Therefore pre-build of the directory target is required. Pre-build for the file(JAR) target + //is not required since it gets built automically by opening outputstream. + if(!(new File(target.toURI())).exists()){ + if(!target.toURI().toString().endsWith(".jar")){ + (new File(target.toURI())).mkdirs(); + //if directory fails to build, which may leads to unknown outcome since it will + //be treated as single file in the class StaticWeaveHandler and automicatlly gets built + //by outputstream. + + //re-assign URL. + target = (new File(target.toURI())).toURL(); + } + } + } + + /* + * INTERNAL: + * The method performs weaving function + */ + private void process() throws IOException,URISyntaxException{ + //Instantiate output handler + AbstractStaticWeaveOutputHandler swoh; + if(isDirectory(this.target)){ + swoh= new StaticWeaveDirectoryOutputHandler(this.source,this.target); + }else{ + swoh= new StaticWeaveJAROutputHandler(new JarOutputStream(new FileOutputStream(new File(this.target.toURI())))); + } + + //Instantiate classloader + this.classLoader = (this.classLoader == null)? Thread.currentThread().getContextClassLoader():this.classLoader; + this.classLoader = new URLClassLoader(getURLs(), this.classLoader); + + //Instantiate the classtransformer, we check if the persistenceinfo URL has been specified. + StaticWeaveClassTransformer classTransformer=null; + if(persistenceInfo!=null){ + classTransformer = new StaticWeaveClassTransformer(persistenceInfo, this.classLoader,this.logWriter,this.logLevel); + } else{ + classTransformer = new StaticWeaveClassTransformer(source, this.classLoader,this.logWriter,this.logLevel); + } + + //Starting process... + Archive sourceArchive =(new ArchiveFactoryImpl()).createArchive(source); + Iterator entries = sourceArchive.getEntries(); + while (entries.hasNext()){ + String entryName = (String)entries.next(); + InputStream entryInputStream = sourceArchive.getEntry(entryName); + String className = PersistenceUnitProcessor.buildClassNameFromEntryString(entryName) ; + + //Add a directory entry + swoh.addDirEntry(getDirectoryFromEntryName(entryName)); + + //Add a regular entry + JarEntry newEntry = new JarEntry(entryName); + + byte[] originalClassBytes=null; + byte[] transferredClassBytes=null; + try { + Class thisClass = this.classLoader.loadClass(className); + //if the class is not in the classpath, we simply copy the entry + //to the target(no weaving). + if (thisClass == null){ + swoh.addEntry(entryInputStream, newEntry); + continue; + } + + //Try to read the loaded class bytes, the class bytes is required for + //classtransformer to perform transfer. Simply copy entry to the target(no weaving) + //if the class bytes can't be read. + InputStream is = this.classLoader.getResourceAsStream(entryName); + if (is!=null){ + originalClassBytes = new byte[is.available()]; + is.read(originalClassBytes); + }else{ + swoh.addEntry(entryInputStream, newEntry); + continue; + } + + //If everything is OK so far, we perform the weaving. we need three paramteres in order to + //class to perform weaving for that class, the class name,the class object and class bytes. + transferredClassBytes = classTransformer.transform(className.replace('.', '/'), thisClass, originalClassBytes); + + //if transferredClassBytes is null means the class dose not get woven. + if(transferredClassBytes!=null){ + swoh.addEntry(newEntry, transferredClassBytes); + } else{ + swoh.addEntry(entryInputStream, newEntry); + } + } catch (IllegalClassFormatException e) { + //Anything went wrong, we need log a warning message, copy the entry to the target and + //process next entry. + swoh.addEntry(entryInputStream, newEntry); + continue; + } catch (ClassNotFoundException e){ + swoh.addEntry(entryInputStream, newEntry); + continue; + }finally{ + //need close the inputstream for current entry before processing next one. + entryInputStream.close(); + } + } + swoh.closeOutputStream(); + } + + + //Extract directory from entry name. + public static String getDirectoryFromEntryName(String entryName){ + String result=""; + if (entryName==null ) { + return result; + } + if(entryName.lastIndexOf("/")>=0){ + result=entryName.substring(0, entryName.lastIndexOf("/"))+File.separator; + } + return result; + } + + /* + * Determine whether or not the URL is pointing to directory. + */ + private boolean isDirectory(URL url) throws URISyntaxException{ + File file = new File(url.toURI()); + if (file.isDirectory()) { + return true; + }else{ + return false; + } + } + + /* + * Generate URL array for specified source and persistenceinfo + */ + private URL[] getURLs(){ + if((this.source!=null) && (this.persistenceInfo!=null)){ + return new URL[]{this.persistenceInfo,this.source}; + } else if(this.source!=null){ + return new URL[]{this.source}; + } else if (this.persistenceInfo!=null){ + return new URL[]{this.persistenceInfo}; + } + return new URL[]{}; + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/StaticWeaveExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:21 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/StaticWeaveExceptionResource.java Mon Nov 27 11:25:21 2006 *************** *** 0 **** --- 1,43 ---- + /* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the "License"). You may not use this file except + * in compliance with the License. + * + * You can obtain a copy of the license at + * glassfish/bootstrap/legal/CDDLv1.0.txt or + * https://glassfish.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * HEADER in each file and include the License file at + * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, + * add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your + * own identifying information: Portions Copyright [yyyy] + * [name of copyright owner] + */ + // Copyright (c) 1998, 2006, Oracle. All rights reserved. + package oracle.toplink.essentials.exceptions.i18n; + + import java.util.ListResourceBundle; + + public class StaticWeaveExceptionResource extends ListResourceBundle { + static final Object[][] contents = { + { "40001", "An exception was thrown while trying to open an archive from URL: {0}"}, + { "40002", "No source was specified for weaving"}, + { "40003", "No target was specified for weaving"}, + { "40004", "Performing weaving in place for JAR file is not allowed"}, + { "40005", "An exception was thrown while trying to open a logging file: {0}"}, + { "40006", "Logging level was specified in wrong value, must be one of (OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST)"}, + { "40007", "An exception was thrown while weaving: {0}"} + }; + + /** + * Return the lookup table. + */ + protected Object[][] getContents() { + return contents; + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/StaticWeaveException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000009/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000009/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:25 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/StaticWeaveException.java Mon Nov 27 11:25:24 2006 *************** *** 0 **** --- 1,163 ---- + /* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the "License"). You may not use this file except + * in compliance with the License. + * + * You can obtain a copy of the license at + * glassfish/bootstrap/legal/CDDLv1.0.txt or + * https://glassfish.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * HEADER in each file and include the License file at + * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, + * add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your + * own identifying information: Portions Copyright [yyyy] + * [name of copyright owner] + */ + // Copyright (c) 1998, 2006, Oracle. All rights reserved. + package oracle.toplink.essentials.exceptions; + + import java.io.File; + import java.net.URL; + + import oracle.toplink.essentials.exceptions.i18n.*; + + public class StaticWeaveException extends TopLinkException { + + private String resourceName = null; + + public static final int EXCEPTION_OPENNING_ARCHIVE = 40001; + public static final int EXCEPTION_NO_SOURCE_SPECIFIED = 40002; + public static final int EXCEPTION_NO_TARGET_SPECIFIED = 40003; + public static final int EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR = 40004; + public static final int EXCEPTION_OPEN_LOGGING_FILE = 40005; + public static final int EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL = 40006; + public static final int EXCEPTION_WEAVING = 40007; + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public StaticWeaveException() { + super(); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + protected StaticWeaveException(String message) { + super(message); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + protected StaticWeaveException(String message, Throwable internalException) { + super(message); + setInternalException(internalException); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException exceptionOpeningArchive(URL archive, Exception cause) { + Object[] args = { archive }; + + StaticWeaveException openArchiveException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_OPENNING_ARCHIVE, args),cause); + openArchiveException.setResourceName(archive.toString()); + openArchiveException.setErrorCode(EXCEPTION_OPENNING_ARCHIVE); + return openArchiveException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException weaveInplaceForJar(String filePath) { + Object[] args = { filePath }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR, args)); + loadingException.setResourceName(filePath); + loadingException.setErrorCode(EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR); + return loadingException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException missingSource() { + Object[] args = { null }; + + StaticWeaveException missingSourceException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_SOURCE_SPECIFIED, args)); + missingSourceException.setResourceName(null); + missingSourceException.setErrorCode(EXCEPTION_NO_SOURCE_SPECIFIED); + return missingSourceException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException missingTarget() { + Object[] args = { null }; + + StaticWeaveException missingTargetException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_TARGET_SPECIFIED, args)); + missingTargetException.setResourceName(null); + missingTargetException.setErrorCode(EXCEPTION_NO_TARGET_SPECIFIED); + return missingTargetException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException openLoggingFileException(String LoggingFile,Exception cause) { + Object[] args = { LoggingFile }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_OPEN_LOGGING_FILE, args), cause); + loadingException.setResourceName(LoggingFile); + loadingException.setErrorCode(EXCEPTION_OPEN_LOGGING_FILE); + return loadingException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException illegalLoggingLevel(String loggingLevel) { + Object[] args = { loggingLevel }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL, args)); + loadingException.setResourceName(loggingLevel); + loadingException.setErrorCode(EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL); + return loadingException; + } + + + public static StaticWeaveException exceptionPerformWeaving(Exception cause) { + Object[] args = { }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_WEAVING, args), cause); + loadingException.setResourceName(null); + loadingException.setErrorCode(EXCEPTION_WEAVING); + return loadingException; + } + + + public String getResourceName(){ + return resourceName; + } + + public void setResourceName(String resourceName){ + this.resourceName = resourceName; + } + + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/AbstractStaticWeaveOutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000011/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000011/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:28 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/AbstractStaticWeaveOutputHandler.java Mon Nov 27 11:25:28 2006 *************** *** 0 **** --- 1,71 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; + import java.net.URISyntaxException; + import java.util.jar.JarEntry; + import java.util.jar.JarOutputStream; + + /** + * The abstract class provides a set of methods to out outputs into the sepcified archive file. + */ + public abstract class AbstractStaticWeaveOutputHandler{ + protected JarOutputStream outputStreamHolder=null; + + /** + * create directory into target directory, or insert directory entry into outputstream. + * @param dirPath + * @throws IOException + */ + abstract public void addDirEntry(String dirPath)throws IOException; + + /** + * Write entry bytes into target, this is usually called if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + abstract public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException; + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + abstract public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException; + + + /** + * Close the output stream. + * @throws IOException + */ + public void closeOutputStream() throws IOException { + if(outputStreamHolder!=null){ + outputStreamHolder.close(); + } + } + + /** + * Get the ouput stream instance. + * @return + */ + public JarOutputStream getOutputStream(){ + return this.outputStreamHolder; + } + + + // This is part of the ugly workaround for a design flaw + // in the JDK zip API, the entry will not write into the target zip file + // properly if this method not being gone through. + protected void readwriteStreams(InputStream in, OutputStream out) throws IOException + { + int numRead; + byte[] buffer = new byte[8*1024]; + + while ((numRead = in.read(buffer,0,buffer.length)) != -1) { + out.write(buffer,0,numRead); + } + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveClassTransformer.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000012/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000012/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:32 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveClassTransformer.java Mon Nov 27 11:25:31 2006 *************** *** 0 **** --- 1,170 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.Writer; + import java.lang.instrument.IllegalClassFormatException; + import java.net.URISyntaxException; + import java.net.URL; + import java.util.ArrayList; + import java.util.Collection; + import java.util.HashMap; + import java.util.Iterator; + import java.util.List; + import java.util.zip.ZipException; + + import javax.persistence.spi.ClassTransformer; + import javax.persistence.spi.PersistenceUnitInfo; + + import oracle.toplink.essentials.ejb.cmp3.persistence.Archive; + import oracle.toplink.essentials.ejb.cmp3.persistence.ArchiveFactoryImpl; + import oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcessor; + import oracle.toplink.essentials.ejb.cmp3.persistence.SEPersistenceUnitInfo; + import oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException; + import oracle.toplink.essentials.exceptions.StaticWeaveException; + import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor; + import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; + import oracle.toplink.essentials.logging.DefaultSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + import oracle.toplink.essentials.sessions.DatabaseLogin; + import oracle.toplink.essentials.sessions.Project; + import oracle.toplink.essentials.threetier.ServerSession; + + /** + *

+ * Description: This class provides the implementation of class transformer by leveraging on the following existing APIs, + *

+ *

+ * Responsibilities: + *

+ * + **/ + + public class StaticWeaveClassTransformer { + private ArrayList classTransformers; + private Writer logWriter; + private int logLevel = SessionLog.OFF; + private ClassLoader aClassLoader; + + /** + * Constructs an instance of StaticWeaveClassTransformer + * @param inputArchiveURL + * @param aclassloader + * @throws Exception + */ + public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader) throws Exception { + this(inputArchiveURL,aclassloader,null,SessionLog.OFF); + } + + /** + * Constructs an instance of StaticWeaveClassTransformer + * @param inputArchiveURL + * @param aclassloader + * @param log + * @param loglevel + * @throws Exception + */ + public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader, Writer logWriter, int loglevel) throws URISyntaxException,IOException { + this.aClassLoader = aclassloader; + this.logWriter=logWriter; + this.logLevel=loglevel; + buildClassTransformers(inputArchiveURL,aclassloader); + } + + + /** + * INTERNAL: + * The method performs weaving function on the given class. + * @param originalClassName + * @param originalClass + * @param originalClassBytes + * @return the converted(woven) class + * @throws Exception + */ + public byte[] transform(String originalClassName, Class originalClass, byte[] originalClassBytes)throws IllegalClassFormatException{ + byte[] newClassBytes = null; + for(ClassTransformer transformer : classTransformers){ + newClassBytes=transformer.transform(aClassLoader, originalClassName,originalClass, null, originalClassBytes); + if(newClassBytes!=null) { + break; + }; + } + return newClassBytes; + } + + /** + * INTERNAL: + * The method creates classtransformer list corresponding to each persistence unit. + * @param inputArchiveURL + * @param aclassloader + * @throws Exception + */ + private void buildClassTransformers(URL inputArchiveURL,ClassLoader aclassloader) throws URISyntaxException,IOException{ + if(classTransformers!=null) { + return ; + } else{ + classTransformers = new ArrayList(); + } + Archive archive =null; + try{ + archive = (new ArchiveFactoryImpl()).createArchive(inputArchiveURL); + }catch(ZipException e){ + throw StaticWeaveException.exceptionOpeningArchive(inputArchiveURL,e); + } + + List persistenceUnitsList = + PersistenceUnitProcessor.processPersistenceArchive(archive, aclassloader); + if(persistenceUnitsList==null){ + throw PersistenceUnitLoadingException.couldNotGetUnitInfoFromUrl(inputArchiveURL); + } + Iterator persistenceUnitsIterator = persistenceUnitsList.iterator(); + while (persistenceUnitsIterator.hasNext()){ + SEPersistenceUnitInfo unitInfo = (SEPersistenceUnitInfo)persistenceUnitsIterator.next(); + unitInfo.setNewTempClassLoader(aclassloader); + //build class transformer. + ClassTransformer transformer = buildTransformer(unitInfo,this.logWriter,this.logLevel); + classTransformers.add(transformer); + } + } + + /** + * INTERNAL: + * This method builds the classtransformer for the specified perisistence unit. + * @param unitInfo + * @param logWriter + * @param logLevel + * @return a ClassTransformer + */ + + private ClassTransformer buildTransformer(PersistenceUnitInfo unitInfo, Writer logWriter, int logLevel) { + //persistenceUnitInfo = unitInfo; + ClassLoader privateClassLoader = unitInfo.getNewTempClassLoader(); + + // create server session (it should be done before initializing ServerPlatform) + ServerSession session = new ServerSession(new Project(new DatabaseLogin())); + session.setLogLevel(logLevel); + if(logWriter!=null){ + ((DefaultSessionLog)session.getSessionLog()).setWriter(logWriter); + } + + session.getPlatform().setConversionManager(new EJB30ConversionManager()); + + // Create an instance of MetadataProcessor for specified persistence unit info + MetadataProcessor processor = new MetadataProcessor(unitInfo, session, privateClassLoader, true); + // Process the Object/relational metadata from XML and annotations. + PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session, false); + + //Collection entities = buildEntityList(persistenceUnitInfo, privateClassLoader); + Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); + + // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only + // be returned if we we are mean to process these mappings + return TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveDirectoryOutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000013/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000013/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:36 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveDirectoryOutputHandler.java Mon Nov 27 11:25:35 2006 *************** *** 0 **** --- 1,77 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.File; + import java.io.FileInputStream; + import java.io.FileOutputStream; + import java.io.IOException; + import java.io.InputStream; + import java.net.URISyntaxException; + import java.net.URL; + import java.util.jar.JarEntry; + + /** + * The class provides a set of methods to pack passed-in entries into the sepcified archive file. + * the class handle directory output. + */ + public class StaticWeaveDirectoryOutputHandler extends AbstractStaticWeaveOutputHandler{ + private URL source=null; + private URL target=null; + + + /** + * Construct an instance of StaticWeaveDirectoryOutputHandler. + * @param source + * @param target + */ + public StaticWeaveDirectoryOutputHandler(URL source,URL target){ + this.source=source; + this.target=target; + } + /** + * create directory into target directory. + * @param dirPath + * @throws IOException + */ + public void addDirEntry(String dirPath)throws IOException { + File file = new File(this.target.getPath()+File.separator+dirPath).getAbsoluteFile(); + if (!file.exists()){ + file.mkdirs(); + } + } + + /** + * Write entry bytes into target, this method is usually invoked if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException{ + File target = new File(this.target.getPath()+targetEntry.getName()).getAbsoluteFile(); + if(!target.exists()) { + target.createNewFile(); + } + (new FileOutputStream(target)).write(entryBytes); + } + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException { + File target = new File(this.target.getPath()+entry.getName()).getAbsoluteFile(); + if(!target.exists()) { + target.createNewFile(); + } + if((new File(this.source.toURI())).isDirectory()){ + File sourceEntry = new File(this.source.getPath()+entry.getName()); + FileInputStream fis = new FileInputStream(sourceEntry); + byte[] classBytes = new byte[fis.available()]; + fis.read(classBytes); + (new FileOutputStream(target)).write(classBytes); + }else{ + readwriteStreams(jis,(new FileOutputStream(target))); + } + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveJAROutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000014/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000014/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:39 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveJAROutputHandler.java Mon Nov 27 11:25:39 2006 *************** *** 0 **** --- 1,66 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.InputStream; + import java.net.URISyntaxException; + import java.util.jar.JarEntry; + import java.util.jar.JarOutputStream; + import java.util.zip.ZipException; + + /** + * The class provides a set of methods to pack passing in entries into the sepcified archive file. + * the class JAR output. + */ + public class StaticWeaveJAROutputHandler extends AbstractStaticWeaveOutputHandler{ + + /** + * Construct an instance of StaticWeaveJAROutputHandler + * @param outputStreamHolder + */ + public StaticWeaveJAROutputHandler(JarOutputStream outputStreamHolder){ + super.outputStreamHolder=outputStreamHolder; + } + + /** + * Add directory entry into outputstream. + * @param dirPath + * @throws IOException + */ + public void addDirEntry(String dirPath)throws IOException { + try{ + JarEntry newEntry = new JarEntry(dirPath); + newEntry.setSize(0); + addEntry(newEntry, null); + }catch(ZipException e){ + //ignore duplicate directory entry exceptions. + } + } + + /** + * Write entry bytes into target, this method is usually called if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException{ + outputStreamHolder.putNextEntry(targetEntry); + if(entryBytes!=null){ + outputStreamHolder.write(entryBytes); + } + outputStreamHolder.closeEntry(); + } + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException { + outputStreamHolder.putNextEntry(entry); + if(!entry.isDirectory()){ + readwriteStreams(jis,outputStreamHolder); + } + outputStreamHolder.closeEntry(); + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/PersistenceUnitLoadingExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000015/AB0952363AC40CBFE034080020E8C54E.9 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000015/AB0952363AC40CBFE034080020E8C54E.9 Fri Nov 24 14:32:49 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/PersistenceUnitLoadingExceptionResource.java Mon Nov 27 11:26:27 2006 *************** *** 36,42 **** { "30008", "File path returned was empty or null"}, { "30009", "An exception was thrown while trying to load persistence unit at url: {0}"}, { "30010", "An exception was thrown while loading ORM XML file: {0}"}, ! { "30011", "TopLink could not get classes from the URL: {0}. TopLink attempted to read this URL as a jarFile and as a Directory and was unable to process it."} }; /** --- 36,43 ---- { "30008", "File path returned was empty or null"}, { "30009", "An exception was thrown while trying to load persistence unit at url: {0}"}, { "30010", "An exception was thrown while loading ORM XML file: {0}"}, ! { "30011", "TopLink could not get classes from the URL: {0}. TopLink attempted to read this URL as a jarFile and as a Directory and was unable to process it."}, ! { "30012", "TopLink could not get persistence unit info from the URL:{0}"} }; /** ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/persistence/PersistenceUnitProcessor.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000016/AB0952363AC40CBFE034080020E8C54E.32 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000016/AB0952363AC40CBFE034080020E8C54E.32 Fri Nov 24 14:33:40 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/persistence/PersistenceUnitProcessor.java Mon Nov 27 11:26:27 2006 *************** *** 28,37 **** --- 28,40 ---- import java.io.File; import java.io.IOException; import java.io.InputStream; + import java.util.ArrayList; + import java.util.Collection; import java.util.List; import java.util.Iterator; import java.util.Set; import java.util.HashSet; + import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; *************** *** 47,53 **** --- 50,59 ---- import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.PersistenceContentHandler; import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLException; import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLExceptionHandler; + import oracle.toplink.essentials.internal.sessions.AbstractSession; import oracle.toplink.essentials.logging.AbstractSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + import oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider; /** * INTERNAL: *************** *** 71,77 **** /** * Go through the jar file for this PeristeneUnitProcessor and process any XML provided in it */ ! private static List processPersistenceArchive(Archive archive, ClassLoader loader){ URL puRootURL = archive.getRootURL(); try { InputStream pxmlStream = archive.getEntry("META-INF/persistence.xml"); // NOI18N --- 77,83 ---- /** * Go through the jar file for this PeristeneUnitProcessor and process any XML provided in it */ ! public static List processPersistenceArchive(Archive archive, ClassLoader loader){ URL puRootURL = archive.getRootURL(); try { InputStream pxmlStream = archive.getEntry("META-INF/persistence.xml"); // NOI18N *************** *** 154,160 **** * @param classEntryString * @return */ ! private static String buildClassNameFromEntryString(String classEntryString){ String classNameForLoader = classEntryString; if (classEntryString.endsWith(".class")){ // NOI18N classNameForLoader = classNameForLoader.substring(0, classNameForLoader.length() - 6);; --- 160,166 ---- * @param classEntryString * @return */ ! public static String buildClassNameFromEntryString(String classEntryString){ String classNameForLoader = classEntryString; if (classEntryString.endsWith(".class")){ // NOI18N classNameForLoader = classNameForLoader.substring(0, classNameForLoader.length() - 6);; *************** *** 316,319 **** --- 322,380 ---- return false; } + /** + * Process the Object/relational metadata from XML and annotations + * @param processor + * @param privateClassLoader + * @param session + * @param throwExceptionOnFail + */ + public static void processORMetadata( + MetadataProcessor processor, + ClassLoader privateClassLoader, + AbstractSession session, + boolean throwExceptionOnFail){ + // DO NOT CHANGE the order of invocation of various methods. + + // build the list of mapping files and read them. Need to do this before + // we start processing entities as the list of entity classes + // depend on metadata read from mapping files. + processor.readMappingFiles(throwExceptionOnFail); + + processor.buildEntityList(); + + // process persistence unit metadata/defaults defined in + // ORM XML instance documents in the persistence unit + processor.processPersistenceUnitMetadata(); + + processor.processMappingFiles(); + + processor.processAnnotations(); + + } + + /** + * Create a list of the entities that will be deployed. This list is build from the information + * provided in the PersistenceUnitInfo argument. + * The list contains Classes specified in the PersistenceUnitInfo's class list and also + * files that are annotated with @Entity, @Embeddable and @MappedSuperclass in + * the jar files provided in the persistence info. + * This list of classes will used by TopLink to build a deployment project and to + * decide what classes to weave. + * @param loader + * @return + */ + public static Collection buildEntityList(MetadataProcessor processor,ClassLoader loader) { + ArrayList entityList = new ArrayList(); + for (String className : processor.getProject().getEntityNames()) { + try { + Class entityClass = loader.loadClass(className); + entityList.add(entityClass); + } catch (ClassNotFoundException exc) { + AbstractSessionLog.getLog().log(SessionLog.CONFIG, + "exception_loading_entity_class", className, exc); + } + } + return entityList; + } } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/PersistenceUnitLoadingException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000017/AB0952363AC40CBFE034080020E8C54E.12 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000017/AB0952363AC40CBFE034080020E8C54E.12 Fri Nov 24 14:34:59 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/PersistenceUnitLoadingException.java Mon Nov 27 11:26:27 2006 *************** *** 41,46 **** --- 41,47 ---- public static final int EXCEPTION_LOADING_FROM_URL = 30009; public static final int EXCEPTION_OPENING_ORM_XML = 30010; public static final int COULD_NOT_GET_CLASS_NAMES_FROM_URL = 30011; + public static final int COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL = 30012; /** * INTERNAL: *************** *** 164,169 **** --- 165,178 ---- return loadingException; } + public static PersistenceUnitLoadingException couldNotGetUnitInfoFromUrl(URL url) { + Object[] args = { url }; + + PersistenceUnitLoadingException loadingException = new PersistenceUnitLoadingException(ExceptionMessageGenerator.buildMessage(PersistenceUnitLoadingException.class, COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL, args)); + loadingException.setResourceName(url.toString()); + loadingException.setErrorCode(COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL); + return loadingException; + } public String getResourceName(){ return resourceName; } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000018/AB0952363AC40CBFE034080020E8C54E.81 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000018/AB0952363AC40CBFE034080020E8C54E.81 Fri Nov 24 14:35:10 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java Mon Nov 27 11:26:27 2006 *************** *** 56,61 **** --- 56,62 ---- import oracle.toplink.essentials.exceptions.*; import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; import javax.persistence.spi.PersistenceUnitTransactionType; + import oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcessor; import oracle.toplink.essentials.internal.ejb.cmp3.jdbc.base.DataSourceImpl; import oracle.toplink.essentials.tools.sessionconfiguration.DescriptorCustomizer; *************** *** 110,139 **** } } - /** - * Create a list of the entities that will be deployed. This list is build from the information - * provided in the PersistenceUnitInfo argument. - * The list contains Classes specified in the PersistenceUnitInfo's class list and also - * files that are annotated with @Entity, @Embeddable and @MappedSuperclass in - * the jar files provided in the persistence info. - * This list of classes will used by TopLink to build a deployment project and to - * decide what classes to weave. - * @param loader - * @return - */ - private Collection buildEntityList(ClassLoader loader) { - ArrayList entityList = new ArrayList(); - for (String className : processor.getProject().getEntityNames()) { - try { - Class entityClass = loader.loadClass(className); - entityList.add(entityClass); - } catch (ClassNotFoundException exc) { - AbstractSessionLog.getLog().log(SessionLog.WARNING, - "exception_loading_entity_class", className, exc); - } - } - return entityList; - } /** * Deploy a persistence session and return an EntityManagerFactory. --- 111,116 ---- *************** *** 526,535 **** enableLazyForOneToOne = false; } } // Process the Object/relational metadata from XML and annotations. ! processORMetadata(privateClassLoader, session, enableLazyForOneToOne); // The connector will be reconstructed when the session is actually deployed session.getProject().getLogin().setConnector(new DefaultConnector()); --- 503,519 ---- enableLazyForOneToOne = false; } } + + boolean throwExceptionOnFail = "true".equalsIgnoreCase( + EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); + // Create an instance of MetadataProcessor for specified persistence unit info + processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); + // Process the Object/relational metadata from XML and annotations. ! PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); + // The connector will be reconstructed when the session is actually deployed session.getProject().getLogin().setConnector(new DefaultConnector()); *************** *** 542,548 **** ClassTransformer transformer = null; if (enableLazyForOneToOne){ // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = buildEntityList(privateClassLoader); transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } --- 526,532 ---- ClassTransformer transformer = null; if (enableLazyForOneToOne){ // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } *************** *** 952,981 **** } } - private void processORMetadata( - ClassLoader privateClassLoader, AbstractSession session, - boolean enableLazyForOneToOne){ - processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); - - // DO NOT CHANGE the order of invocation of various methods. - - // build the list of mapping files and read them. Need to do this before - // we start processing entities as the list of entity classes - // depend on metadata read from mapping files. - boolean throwExceptionOnFail = "true".equalsIgnoreCase( - getConfigPropertyAsString(TOPLINK_ORM_THROW_EXCEPTIONS, "true")); - processor.readMappingFiles(throwExceptionOnFail); - - processor.buildEntityList(); - - // process persistence unit metadata/defaults defined in - // ORM XML instance documents in the persistence unit - processor.processPersistenceUnitMetadata(); - - processor.processMappingFiles(); - - processor.processAnnotations(); - } public boolean isPredeployed() { return state == STATE_PREDEPLOYED; --- 936,941 ---- ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/ToStringLocalizationResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000019/AB0952363AC40CBFE034080020E8C54E.4 Report generated at Mon Nov 27 11:26:27 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000019/AB0952363AC40CBFE034080020E8C54E.4 Fri Nov 24 14:35:42 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/ToStringLocalizationResource.java Mon Nov 27 11:26:27 2006 *************** *** 18,24 **** * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */ ! // Copyright (c) 1998, 2005, Oracle. All rights reserved. package oracle.toplink.essentials.internal.localization.i18n; import java.util.ListResourceBundle; --- 18,24 ---- * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */ ! // Copyright (c) 1998, 2006, Oracle. All rights reserved. package oracle.toplink.essentials.internal.localization.i18n; import java.util.ListResourceBundle; *************** *** 74,80 **** { "no_files", "no file(s)" }, { "mulitple_files", "mulitple files" }, { "unknown", "unknown" }, ! { "connector", "connector" } }; /** --- 74,98 ---- { "no_files", "no file(s)" }, { "mulitple_files", "mulitple files" }, { "unknown", "unknown" }, ! { "connector", "connector" }, ! { "staticweave_processor_unknown_outcome", "Weaving classes stored in a directory and outputing to a JAR often leads to unexpected results." }, ! { "staticweave_commandline_help_message", ! " Usage: StaticWeave [options] source target\r\r"+ ! " Options:\r"+ ! " -classpath classpath\r" + ! " Set the user class path. use \";\" as delimiter in windows and \":\" in unix.\r"+ ! " -persistenceinfo \r" + ! " Explicitly identify where META-INF/persistence.xml is stored. It must be the root of META-INF/persistence.xml.\r"+ ! " -log \r" + ! " Specify logging file.\r"+ ! " -loglevel \r" + ! " Specify a literal value of the toplink logging level(OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST).\r"+ ! " The classpath must contain all the classes necessary to load the classes in the source.\r"+ ! " The weaving will be performed in place if source and target point to the same location. Weaving in place is ONLY applicable for directory-based sources.\r"+ ! " Example:\r" + ! " To weave all entites contained in c:\\foo-source.jar with its persistence.xml contained within the c:\\foo-containing-persistence-xml.jar,\r"+ ! " and output to c:\\foo-target.jar,\r"+ ! " StaticWeave -persistenceinfo c:\\foo-containing-persistence-xml.jar -classpath c:\\classpath1;c:\\classpath2 c:\\foo-source.jar c:\\foo-target.jar\r\r"} }; /** ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/weaving/StaticWeave.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:10 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/weaving/StaticWeave.java Mon Nov 27 11:25:10 2006 *************** *** 0 **** --- 1,225 ---- + package oracle.toplink.essentials.weaving; + + import java.io.File; + import java.io.FileWriter; + import java.io.PrintStream; + import java.io.Writer; + import java.net.MalformedURLException; + import java.net.URL; + import java.net.URLClassLoader; + + import oracle.toplink.essentials.exceptions.StaticWeaveException; + import oracle.toplink.essentials.internal.localization.ExceptionLocalization; + import oracle.toplink.essentials.internal.localization.ToStringLocalization; + import oracle.toplink.essentials.logging.AbstractSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + + /** + *

+ * Description: This is the static weave command line processing class that verifies command options and invokes + * StaticWeaveProcessor to statically weave the classes. + *

+ * Usage:
+ *  StaticWeave [options] source target
+ * Options:
+ *  -classpath
+ *    Set the user class path, use ";" as the delimiter in Window system and ":" in Unix system.
+ *  -log
+ *    the path of log file, the standard output will be the default.
+ *  -loglevel
+ *  nbsp; specify a literal value for toplink log level(OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST). The default value is OFF.
+ *  -persistenceinfo
+ *    The path contains META-INF/persistence.xml. This is ONLY required when the source does not include it. + * The classpath must contain all the classes necessary in oder to perform weaving.
+ * The weaving will be performed in place if source and target point to the same location. Weaving in place is ONLY applicable for directory-based sources.
+ *Example:
+ * To weave all entites contained in c:\foo-source.jar with its persistence.xml contained within c:\foo-containing-persistence-xml.jar, and output to c:\\foo-target.jar,
+ *StaticWeave -persistenceinfo c:\foo-containing-persistencexml.jar -classpath c:\classpath1;c:\classpath2 c:\foo-source.jar -o c:\foo-target.jar\r\r"} + * + **/ + + public class StaticWeave { + + // command line arguments + private String[] argv; + + // The location path of the source, null if none was given + private String source; + + // The location path containing persistence.xml, null if none was given + private String persistenceinfopath; + + // The location path of the target, null if none was given + private String target; + + private int loglevel=SessionLog.OFF; + + private Writer logWriter; + + private PrintStream vout = System.out; + + private String[] classpaths; + + public static void main(String[] argv) { + + StaticWeave staticweaver = new StaticWeave(argv); + + try { + // Verify the command line arguments + staticweaver.processCommandLine(); + staticweaver.start(); + } catch (Exception e) { + throw StaticWeaveException.exceptionPerformWeaving(e); + } + } + + + public StaticWeave(String[] argv) { + this.argv = argv; + } + + /** + * Invoke StaticWeaveProcessor to perform weaving. + */ + public void start() throws Exception { + + //perform weaving + StaticWeaveProcessor staticWeaverProcessor= new StaticWeaveProcessor(this.source,this.target); + if(persistenceinfopath!=null){ + staticWeaverProcessor.setPersistenceInfo(this.persistenceinfopath); + } + if(classpaths!=null){ + staticWeaverProcessor.setClassLoader(getClassLoader()); + } + if(logWriter!=null){ + staticWeaverProcessor.setLog(logWriter); + } + staticWeaverProcessor.setLogLevel(loglevel); + staticWeaverProcessor.performWeaving(); + } + + + /* + * Verify command line option. + */ + void processCommandLine() throws Exception + { + if (argv.length < 2 || argv.length>10) { + printUsage(); + System.exit(1); + } + for (int i=0;i= argv.length ){ + printUsage(); + System.exit(1); + } + classpaths=argv[i+1].split(File.pathSeparator); + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-persistenceinfo")) { + if ((i + 1) >= argv.length ){ + printUsage(); + System.exit(1); + } + persistenceinfopath=argv[i+1]; + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-log")) { + if ((i + 1) >= argv.length ){ + printUsage(); + System.exit(1); + } + logWriter=new FileWriter(argv[i+1]); + i++; + continue; + } + + if (argv[i].equalsIgnoreCase("-loglevel")) { + if ((i + 1) >= argv.length ) { + printUsage(); + System.exit(1); + } + + if ( argv[i+1].equalsIgnoreCase("OFF") || + argv[i+1].equalsIgnoreCase("SEVERE") || + argv[i+1].equalsIgnoreCase("WARNING") || + argv[i+1].equalsIgnoreCase("INFO") || + argv[i+1].equalsIgnoreCase("CONFIG") || + argv[i+1].equalsIgnoreCase("FINE") || + argv[i+1].equalsIgnoreCase("FINER") || + argv[i+1].equalsIgnoreCase("FINEST") || + argv[i+1].equalsIgnoreCase("ALL")) { + loglevel=AbstractSessionLog.translateStringToLoggingLevel(argv[i+1].toUpperCase()); + } else{ + printUsage(); + System.exit(1); + } + i++; + continue; + } + + if(source!=null){ + printUsage(); + System.exit(1); + } + + if(target!=null){ + printUsage(); + System.exit(1); + } + + source=argv[i]; + if((i+1)>=argv.length){ + printUsage(); + System.exit(1); + } + i++; + if(i>=argv.length){ + printUsage(); + System.exit(1); + } + target=argv[i]; + i++; + } + + + //Ensure source and target have been specified + if(source==null){ + printUsage(); + throw StaticWeaveException.missingSource(); + } + if(target==null){ + printUsage(); + throw StaticWeaveException.missingTarget(); + } + } + + /* + * print command help message + */ + private void printUsage() { + PrintStream o = vout; + o.println(ToStringLocalization.buildMessage("staticweave_commandline_help_message", new Object[]{null})); + } + + /* + * Convert the specified classpath arrary to URL array where new classloader will build on. + */ + private ClassLoader getClassLoader() throws MalformedURLException{ + if (classpaths!=null){ + URL[] urls= new URL[classpaths.length]; + for(int i=0;i + * Description: This is the static weave ant task definition class that verifies the value of specified attributes and invokes + * StaticWeaveProcessor to weave classes. + *

+ * Usage: + *

    + *
  • Ensure the classpath contains all the classes necessary to load the classes in the source. + *
  • The lib containing this weaving Ant task must be added into the classpath by using the -lib option on Ant command line instead of using the classpath attribute of the taskdef Ant task. + *
  • Define weaving Ant task and Ant target by using following attributes: + * source - specify source location. In the default configuration StaticWeaveAntTask assumes the source contains the persistence.xml,if this is not the case, the location containing the persistence.xml must be explicitly identified by the attribute 'persistenceinfo'. + * target - specify the output location (either a directory or a jar). + * persistenceinfo - specify the location containing the persistence.xml. This is optional and should only be specified if the source does not contain the persistence.xml. + * log - specify a logging file. This is optional + * loglevel - specify a literal value of toplink logging level(OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST) The default value is OFF(8). This is optional. + *
  • The weaving will be performed in place if source and target point to the same location. Weaving in place is ONLY applicable for directory-based sources. + *
+ *Example: + * + *<target name="define.task" description="New task definition for toplink static weaving"/>
+ *  <taskdef name="weave" classname="oracle.toplink.essentials.weaving.StaticWeaverAntTask"/>
+ *</target>
+ *<target name="weaving" description="perform weaving." depends="define.task">
+ *  <weave source= "c:\foo.jar" target = "c:\wovenfoo.jar" persistenceinfo="c:\foo-containing-persistenceinfo.jar">
+ *    <classpath>
+ *      <pathelement path="c:\foo-dependent.jar"/>
+ *    </classpath>
+ *  </weave>
+ *</target> + *
+ */ + + + public class StaticWeaveAntTask extends Task{ + + private String source; + private String persistenceinfo; + private String target; + private Vector classPaths = new Vector(); + private int logLevel=SessionLog.OFF; + private Writer logWriter; + + + /** + * Set the input archive to be used to weave. + * @param inputJarFile + */ + public void setSource(String source) { + this.source = source; + } + + /** + * Set output archive to be used to weave to + * @param outputJarFile + */ + public void setTarget(String target) { + this.target = target; + } + + /** + * Set the archive containing persistence.xml while input archive does not contain it. + * @param inputMainJarFile + */ + public void setLog(String logFile) throws IOException { + try{ + this.logWriter = new FileWriter(logFile); + }catch(Exception e){ + throw StaticWeaveException.openLoggingFileException(logFile,e); + } + } + + public void setLogLevel(String logLevel) { + if (logLevel.equalsIgnoreCase("OFF") || + logLevel.equalsIgnoreCase("SEVERE") || + logLevel.equalsIgnoreCase("WARNING") || + logLevel.equalsIgnoreCase("INFO") || + logLevel.equalsIgnoreCase("CONFIG") || + logLevel.equalsIgnoreCase("FINE") || + logLevel.equalsIgnoreCase("FINER") || + logLevel.equalsIgnoreCase("FINEST") || + logLevel.equalsIgnoreCase("ALL")) { + this.logLevel=AbstractSessionLog.translateStringToLoggingLevel(logLevel.toUpperCase()); + } else{ + throw StaticWeaveException.illegalLoggingLevel(logLevel); + } + } + + public void setPersistenceinfo(String persistenceinfo) { + this.persistenceinfo = persistenceinfo; + } + + /** + * Add the dependent classpath in order to load classes from the specified input jar. + * @param path + */ + public void addClasspath(Path path) { + classPaths.add(path); + } + + /* + * Parse the class path element and store them into vector. + */ + private Vector getPathElement(){ + Vector pathElements = new Vector(); + for(int i=0;i + * Description: The StaticWeaveProcessor controls the static weaving process. It is invoked by both the command line + * StaticWeave class and the StaticWeaveAntTask. + *

+ * Responsibilities:Process the source classes, performs weaving as necessary out outputs to the target + **/ + public class StaticWeaveProcessor { + private URL source; + private URL target; + private URL persistenceInfo; + private Writer logWriter; + private ClassLoader classLoader; + private int logLevel = SessionLog.OFF; + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the name of the location to be weaved + * @param target the name of the location to be weaved to + * @throws MalformedURLException + */ + public StaticWeaveProcessor(String source,String target)throws MalformedURLException{ + if (source!=null){ + this.source=new File(source).toURL(); + } + if (target!=null){ + this.target=new File(target).toURL(); + } + } + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the File object of the source to be weaved + * @param target the File object of the target to be weaved to + * @throws MalformedURLException + */ + public StaticWeaveProcessor(File source, File target)throws MalformedURLException{ + this.source=source.toURL(); + this.target=target.toURL(); + } + + /** + * Constructs an instance of StaticWeaveProcessor + * @param source the URL of the source to be weaved + * @param target the URL of the target to be weaved to + */ + public StaticWeaveProcessor(URL source, URL target){ + this.source=source; + this.target=target; + } + + /** + * The method allows user to specify the ouput for the log message. + * @param log writer - the lcation where the log message writes to. the default value is standardout + */ + public void setLog(Writer logWriter){ + this.logWriter= logWriter; + } + + /** + * The method allows user to define nine levels toplink logging. + * @param level - the integer value of log level. default is OFF. + */ + public void setLogLevel(int level){ + this.logLevel=level; + } + + /** + * Set the user classloader. + * @param classLoader + */ + public void setClassLoader(ClassLoader classLoader){ + this.classLoader=classLoader; + } + + /** + * Set an explicitly identified URL of the location containing persistence.xml. + * @param persistenceInfo the URL of the location containing persistence.xml, the URL + * must point to the root of META-INF/persistence.xml + */ + public void setPersistenceInfo (URL persistenceInfo){ + this.persistenceInfo = persistenceInfo; + } + + /** + * Set an explicitly identified the location containing persistence.xml. + * @param persistenceinfo the path of the location containing persistence.xml, the path + * must point to the root of META-INF/persistence.xml + */ + public void setPersistenceInfo(String persistenceInfoPath) throws MalformedURLException{ + if (persistenceInfoPath!=null){ + this.persistenceInfo=new File(persistenceInfoPath).toURL(); + } + } + + + /** + * Set an explicitly identified the location containing persistence.xml. + * @param persistenceinfo the file containing persistence.xml, the file + * should contain META-INF/persistence.xml + */ + public void setPersistenceInfo(File persistenceInfoFile) throws MalformedURLException{ + if (persistenceInfoFile!=null){ + this.persistenceInfo=persistenceInfoFile.toURL(); + } + } + + + /** + * This method performs weaving function on the class individually from the specified source. + * @throws Exception. + */ + public void performWeaving() throws URISyntaxException,MalformedURLException,IOException{ + preProcess(); + process(); + } + + /* + * INTERNAL: + * This method perform all necessary steps(verification, pre-build the target directory) + * prior to the invokation of the weaving function. + */ + private void preProcess() throws URISyntaxException,MalformedURLException{ + //Instantiate default session log + AbstractSessionLog.getLog().setLevel(this.logLevel); + if(logWriter!=null){ + ((DefaultSessionLog)AbstractSessionLog.getLog()).setWriter(logWriter); + } + + //Make sure the source is existing + if(!(new File(source.toURI())).exists()){ + throw StaticWeaveException.missingSource(); + } + + //Verification target and source, two use cases create warning or exception. + //1. If source is directory and target is jar - + // This will lead unkown outcome, user attempt to use this tool to pack outcome into a Jar. + // Warning message will be logged, this is can be workarounded by other utilities. + //2. Both source and target are specified as a same jar - + // User was tryint to perform waving in same Jar which is not support, Exception will be thrown. + if(isDirectory(source) && target.toURI().toString().endsWith(".jar")){ + AbstractSessionLog.getLog().log(SessionLog.WARNING, ToStringLocalization.buildMessage("staticweave_processor_unknown_outcome", new Object[]{null})); + } + + if(!isDirectory(source) && target.toString().equals(source.toString())){ + throw StaticWeaveException.weaveInplaceForJar(source.toString()); + } + + //pre-create target if it is directory and dose not exsit. + //Using the method File.isDirectory() is not enough to determine what the type(dir or jar) + //of the target(specified by URL)that user want to create. File.isDirectory() will return false in + //two possibilities, the location either is not directory or the location dose not exist. + //Therefore pre-build of the directory target is required. Pre-build for the file(JAR) target + //is not required since it gets built automically by opening outputstream. + if(!(new File(target.toURI())).exists()){ + if(!target.toURI().toString().endsWith(".jar")){ + (new File(target.toURI())).mkdirs(); + //if directory fails to build, which may leads to unknown outcome since it will + //be treated as single file in the class StaticWeaveHandler and automicatlly gets built + //by outputstream. + + //re-assign URL. + target = (new File(target.toURI())).toURL(); + } + } + } + + /* + * INTERNAL: + * The method performs weaving function + */ + private void process() throws IOException,URISyntaxException{ + //Instantiate output handler + AbstractStaticWeaveOutputHandler swoh; + if(isDirectory(this.target)){ + swoh= new StaticWeaveDirectoryOutputHandler(this.source,this.target); + }else{ + swoh= new StaticWeaveJAROutputHandler(new JarOutputStream(new FileOutputStream(new File(this.target.toURI())))); + } + + //Instantiate classloader + this.classLoader = (this.classLoader == null)? Thread.currentThread().getContextClassLoader():this.classLoader; + this.classLoader = new URLClassLoader(getURLs(), this.classLoader); + + //Instantiate the classtransformer, we check if the persistenceinfo URL has been specified. + StaticWeaveClassTransformer classTransformer=null; + if(persistenceInfo!=null){ + classTransformer = new StaticWeaveClassTransformer(persistenceInfo, this.classLoader,this.logWriter,this.logLevel); + } else{ + classTransformer = new StaticWeaveClassTransformer(source, this.classLoader,this.logWriter,this.logLevel); + } + + //Starting process... + Archive sourceArchive =(new ArchiveFactoryImpl()).createArchive(source); + Iterator entries = sourceArchive.getEntries(); + while (entries.hasNext()){ + String entryName = (String)entries.next(); + InputStream entryInputStream = sourceArchive.getEntry(entryName); + String className = PersistenceUnitProcessor.buildClassNameFromEntryString(entryName) ; + + //Add a directory entry + swoh.addDirEntry(getDirectoryFromEntryName(entryName)); + + //Add a regular entry + JarEntry newEntry = new JarEntry(entryName); + + byte[] originalClassBytes=null; + byte[] transferredClassBytes=null; + try { + Class thisClass = this.classLoader.loadClass(className); + //if the class is not in the classpath, we simply copy the entry + //to the target(no weaving). + if (thisClass == null){ + swoh.addEntry(entryInputStream, newEntry); + continue; + } + + //Try to read the loaded class bytes, the class bytes is required for + //classtransformer to perform transfer. Simply copy entry to the target(no weaving) + //if the class bytes can't be read. + InputStream is = this.classLoader.getResourceAsStream(entryName); + if (is!=null){ + originalClassBytes = new byte[is.available()]; + is.read(originalClassBytes); + }else{ + swoh.addEntry(entryInputStream, newEntry); + continue; + } + + //If everything is OK so far, we perform the weaving. we need three paramteres in order to + //class to perform weaving for that class, the class name,the class object and class bytes. + transferredClassBytes = classTransformer.transform(className.replace('.', '/'), thisClass, originalClassBytes); + + //if transferredClassBytes is null means the class dose not get woven. + if(transferredClassBytes!=null){ + swoh.addEntry(newEntry, transferredClassBytes); + } else{ + swoh.addEntry(entryInputStream, newEntry); + } + } catch (IllegalClassFormatException e) { + //Anything went wrong, we need log a warning message, copy the entry to the target and + //process next entry. + swoh.addEntry(entryInputStream, newEntry); + continue; + } catch (ClassNotFoundException e){ + swoh.addEntry(entryInputStream, newEntry); + continue; + }finally{ + //need close the inputstream for current entry before processing next one. + entryInputStream.close(); + } + } + swoh.closeOutputStream(); + } + + + //Extract directory from entry name. + public static String getDirectoryFromEntryName(String entryName){ + String result=""; + if (entryName==null ) { + return result; + } + if(entryName.lastIndexOf("/")>=0){ + result=entryName.substring(0, entryName.lastIndexOf("/"))+File.separator; + } + return result; + } + + /* + * Determine whether or not the URL is pointing to directory. + */ + private boolean isDirectory(URL url) throws URISyntaxException{ + File file = new File(url.toURI()); + if (file.isDirectory()) { + return true; + }else{ + return false; + } + } + + /* + * Generate URL array for specified source and persistenceinfo + */ + private URL[] getURLs(){ + if((this.source!=null) && (this.persistenceInfo!=null)){ + return new URL[]{this.persistenceInfo,this.source}; + } else if(this.source!=null){ + return new URL[]{this.source}; + } else if (this.persistenceInfo!=null){ + return new URL[]{this.persistenceInfo}; + } + return new URL[]{}; + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/StaticWeaveExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:21 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/StaticWeaveExceptionResource.java Mon Nov 27 11:25:21 2006 *************** *** 0 **** --- 1,43 ---- + /* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the "License"). You may not use this file except + * in compliance with the License. + * + * You can obtain a copy of the license at + * glassfish/bootstrap/legal/CDDLv1.0.txt or + * https://glassfish.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * HEADER in each file and include the License file at + * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, + * add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your + * own identifying information: Portions Copyright [yyyy] + * [name of copyright owner] + */ + // Copyright (c) 1998, 2006, Oracle. All rights reserved. + package oracle.toplink.essentials.exceptions.i18n; + + import java.util.ListResourceBundle; + + public class StaticWeaveExceptionResource extends ListResourceBundle { + static final Object[][] contents = { + { "40001", "An exception was thrown while trying to open an archive from URL: {0}"}, + { "40002", "No source was specified for weaving"}, + { "40003", "No target was specified for weaving"}, + { "40004", "Performing weaving in place for JAR file is not allowed"}, + { "40005", "An exception was thrown while trying to open a logging file: {0}"}, + { "40006", "Logging level was specified in wrong value, must be one of (OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST)"}, + { "40007", "An exception was thrown while weaving: {0}"} + }; + + /** + * Return the lookup table. + */ + protected Object[][] getContents() { + return contents; + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/StaticWeaveException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000009/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000009/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:25 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/StaticWeaveException.java Mon Nov 27 11:25:24 2006 *************** *** 0 **** --- 1,163 ---- + /* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the "License"). You may not use this file except + * in compliance with the License. + * + * You can obtain a copy of the license at + * glassfish/bootstrap/legal/CDDLv1.0.txt or + * https://glassfish.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * HEADER in each file and include the License file at + * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable, + * add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your + * own identifying information: Portions Copyright [yyyy] + * [name of copyright owner] + */ + // Copyright (c) 1998, 2006, Oracle. All rights reserved. + package oracle.toplink.essentials.exceptions; + + import java.io.File; + import java.net.URL; + + import oracle.toplink.essentials.exceptions.i18n.*; + + public class StaticWeaveException extends TopLinkException { + + private String resourceName = null; + + public static final int EXCEPTION_OPENNING_ARCHIVE = 40001; + public static final int EXCEPTION_NO_SOURCE_SPECIFIED = 40002; + public static final int EXCEPTION_NO_TARGET_SPECIFIED = 40003; + public static final int EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR = 40004; + public static final int EXCEPTION_OPEN_LOGGING_FILE = 40005; + public static final int EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL = 40006; + public static final int EXCEPTION_WEAVING = 40007; + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public StaticWeaveException() { + super(); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + protected StaticWeaveException(String message) { + super(message); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + protected StaticWeaveException(String message, Throwable internalException) { + super(message); + setInternalException(internalException); + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException exceptionOpeningArchive(URL archive, Exception cause) { + Object[] args = { archive }; + + StaticWeaveException openArchiveException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_OPENNING_ARCHIVE, args),cause); + openArchiveException.setResourceName(archive.toString()); + openArchiveException.setErrorCode(EXCEPTION_OPENNING_ARCHIVE); + return openArchiveException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException weaveInplaceForJar(String filePath) { + Object[] args = { filePath }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR, args)); + loadingException.setResourceName(filePath); + loadingException.setErrorCode(EXCEPTION_NO_SUPPORT_WEAVING_INPLACE_FOR_JAR); + return loadingException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException missingSource() { + Object[] args = { null }; + + StaticWeaveException missingSourceException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_SOURCE_SPECIFIED, args)); + missingSourceException.setResourceName(null); + missingSourceException.setErrorCode(EXCEPTION_NO_SOURCE_SPECIFIED); + return missingSourceException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException missingTarget() { + Object[] args = { null }; + + StaticWeaveException missingTargetException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_NO_TARGET_SPECIFIED, args)); + missingTargetException.setResourceName(null); + missingTargetException.setErrorCode(EXCEPTION_NO_TARGET_SPECIFIED); + return missingTargetException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException openLoggingFileException(String LoggingFile,Exception cause) { + Object[] args = { LoggingFile }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_OPEN_LOGGING_FILE, args), cause); + loadingException.setResourceName(LoggingFile); + loadingException.setErrorCode(EXCEPTION_OPEN_LOGGING_FILE); + return loadingException; + } + + /** + * INTERNAL: + * TopLink exceptions should only be thrown by TopLink. + */ + public static StaticWeaveException illegalLoggingLevel(String loggingLevel) { + Object[] args = { loggingLevel }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL, args)); + loadingException.setResourceName(loggingLevel); + loadingException.setErrorCode(EXCEPTION_FOR_ILLEGALE_LOGGING_LEVEL); + return loadingException; + } + + + public static StaticWeaveException exceptionPerformWeaving(Exception cause) { + Object[] args = { }; + + StaticWeaveException loadingException = new StaticWeaveException(ExceptionMessageGenerator.buildMessage(StaticWeaveException.class, EXCEPTION_WEAVING, args), cause); + loadingException.setResourceName(null); + loadingException.setErrorCode(EXCEPTION_WEAVING); + return loadingException; + } + + + public String getResourceName(){ + return resourceName; + } + + public void setResourceName(String resourceName){ + this.resourceName = resourceName; + } + + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/AbstractStaticWeaveOutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000011/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000011/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:28 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/AbstractStaticWeaveOutputHandler.java Mon Nov 27 11:25:28 2006 *************** *** 0 **** --- 1,71 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; + import java.net.URISyntaxException; + import java.util.jar.JarEntry; + import java.util.jar.JarOutputStream; + + /** + * The abstract class provides a set of methods to out outputs into the sepcified archive file. + */ + public abstract class AbstractStaticWeaveOutputHandler{ + protected JarOutputStream outputStreamHolder=null; + + /** + * create directory into target directory, or insert directory entry into outputstream. + * @param dirPath + * @throws IOException + */ + abstract public void addDirEntry(String dirPath)throws IOException; + + /** + * Write entry bytes into target, this is usually called if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + abstract public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException; + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + abstract public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException; + + + /** + * Close the output stream. + * @throws IOException + */ + public void closeOutputStream() throws IOException { + if(outputStreamHolder!=null){ + outputStreamHolder.close(); + } + } + + /** + * Get the ouput stream instance. + * @return + */ + public JarOutputStream getOutputStream(){ + return this.outputStreamHolder; + } + + + // This is part of the ugly workaround for a design flaw + // in the JDK zip API, the entry will not write into the target zip file + // properly if this method not being gone through. + protected void readwriteStreams(InputStream in, OutputStream out) throws IOException + { + int numRead; + byte[] buffer = new byte[8*1024]; + + while ((numRead = in.read(buffer,0,buffer.length)) != -1) { + out.write(buffer,0,numRead); + } + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveClassTransformer.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000012/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000012/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:32 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveClassTransformer.java Mon Nov 27 11:25:31 2006 *************** *** 0 **** --- 1,170 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.Writer; + import java.lang.instrument.IllegalClassFormatException; + import java.net.URISyntaxException; + import java.net.URL; + import java.util.ArrayList; + import java.util.Collection; + import java.util.HashMap; + import java.util.Iterator; + import java.util.List; + import java.util.zip.ZipException; + + import javax.persistence.spi.ClassTransformer; + import javax.persistence.spi.PersistenceUnitInfo; + + import oracle.toplink.essentials.ejb.cmp3.persistence.Archive; + import oracle.toplink.essentials.ejb.cmp3.persistence.ArchiveFactoryImpl; + import oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcessor; + import oracle.toplink.essentials.ejb.cmp3.persistence.SEPersistenceUnitInfo; + import oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException; + import oracle.toplink.essentials.exceptions.StaticWeaveException; + import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor; + import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; + import oracle.toplink.essentials.logging.DefaultSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + import oracle.toplink.essentials.sessions.DatabaseLogin; + import oracle.toplink.essentials.sessions.Project; + import oracle.toplink.essentials.threetier.ServerSession; + + /** + *

+ * Description: This class provides the implementation of class transformer by leveraging on the following existing APIs, + *

    + *
  • PersistenceUnitProcessor.processORMetadata() - get class descriptor. + *
  • PersistenceUnitProcessor.buildEntityList() - get entity classes lsit. + *
  • TransformerFactory.createTransformerAndModifyProject - get class transformer. + *
+ *

+ * Responsibilities: + *

    + *
  • Create the classtransformer for each persistence unit individually and store them into the list. + *
  • Provide class transfom method to perform weaving function. + *
+ * + **/ + + public class StaticWeaveClassTransformer { + private ArrayList classTransformers; + private Writer logWriter; + private int logLevel = SessionLog.OFF; + private ClassLoader aClassLoader; + + /** + * Constructs an instance of StaticWeaveClassTransformer + * @param inputArchiveURL + * @param aclassloader + * @throws Exception + */ + public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader) throws Exception { + this(inputArchiveURL,aclassloader,null,SessionLog.OFF); + } + + /** + * Constructs an instance of StaticWeaveClassTransformer + * @param inputArchiveURL + * @param aclassloader + * @param log + * @param loglevel + * @throws Exception + */ + public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader, Writer logWriter, int loglevel) throws URISyntaxException,IOException { + this.aClassLoader = aclassloader; + this.logWriter=logWriter; + this.logLevel=loglevel; + buildClassTransformers(inputArchiveURL,aclassloader); + } + + + /** + * INTERNAL: + * The method performs weaving function on the given class. + * @param originalClassName + * @param originalClass + * @param originalClassBytes + * @return the converted(woven) class + * @throws Exception + */ + public byte[] transform(String originalClassName, Class originalClass, byte[] originalClassBytes)throws IllegalClassFormatException{ + byte[] newClassBytes = null; + for(ClassTransformer transformer : classTransformers){ + newClassBytes=transformer.transform(aClassLoader, originalClassName,originalClass, null, originalClassBytes); + if(newClassBytes!=null) { + break; + }; + } + return newClassBytes; + } + + /** + * INTERNAL: + * The method creates classtransformer list corresponding to each persistence unit. + * @param inputArchiveURL + * @param aclassloader + * @throws Exception + */ + private void buildClassTransformers(URL inputArchiveURL,ClassLoader aclassloader) throws URISyntaxException,IOException{ + if(classTransformers!=null) { + return ; + } else{ + classTransformers = new ArrayList(); + } + Archive archive =null; + try{ + archive = (new ArchiveFactoryImpl()).createArchive(inputArchiveURL); + }catch(ZipException e){ + throw StaticWeaveException.exceptionOpeningArchive(inputArchiveURL,e); + } + + List persistenceUnitsList = + PersistenceUnitProcessor.processPersistenceArchive(archive, aclassloader); + if(persistenceUnitsList==null){ + throw PersistenceUnitLoadingException.couldNotGetUnitInfoFromUrl(inputArchiveURL); + } + Iterator persistenceUnitsIterator = persistenceUnitsList.iterator(); + while (persistenceUnitsIterator.hasNext()){ + SEPersistenceUnitInfo unitInfo = (SEPersistenceUnitInfo)persistenceUnitsIterator.next(); + unitInfo.setNewTempClassLoader(aclassloader); + //build class transformer. + ClassTransformer transformer = buildTransformer(unitInfo,this.logWriter,this.logLevel); + classTransformers.add(transformer); + } + } + + /** + * INTERNAL: + * This method builds the classtransformer for the specified perisistence unit. + * @param unitInfo + * @param logWriter + * @param logLevel + * @return a ClassTransformer + */ + + private ClassTransformer buildTransformer(PersistenceUnitInfo unitInfo, Writer logWriter, int logLevel) { + //persistenceUnitInfo = unitInfo; + ClassLoader privateClassLoader = unitInfo.getNewTempClassLoader(); + + // create server session (it should be done before initializing ServerPlatform) + ServerSession session = new ServerSession(new Project(new DatabaseLogin())); + session.setLogLevel(logLevel); + if(logWriter!=null){ + ((DefaultSessionLog)session.getSessionLog()).setWriter(logWriter); + } + + session.getPlatform().setConversionManager(new EJB30ConversionManager()); + + // Create an instance of MetadataProcessor for specified persistence unit info + MetadataProcessor processor = new MetadataProcessor(unitInfo, session, privateClassLoader, true); + // Process the Object/relational metadata from XML and annotations. + PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session, false); + + //Collection entities = buildEntityList(persistenceUnitInfo, privateClassLoader); + Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); + + // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only + // be returned if we we are mean to process these mappings + return TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveDirectoryOutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000013/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000013/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:36 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveDirectoryOutputHandler.java Mon Nov 27 11:25:35 2006 *************** *** 0 **** --- 1,77 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.File; + import java.io.FileInputStream; + import java.io.FileOutputStream; + import java.io.IOException; + import java.io.InputStream; + import java.net.URISyntaxException; + import java.net.URL; + import java.util.jar.JarEntry; + + /** + * The class provides a set of methods to pack passed-in entries into the sepcified archive file. + * the class handle directory output. + */ + public class StaticWeaveDirectoryOutputHandler extends AbstractStaticWeaveOutputHandler{ + private URL source=null; + private URL target=null; + + + /** + * Construct an instance of StaticWeaveDirectoryOutputHandler. + * @param source + * @param target + */ + public StaticWeaveDirectoryOutputHandler(URL source,URL target){ + this.source=source; + this.target=target; + } + /** + * create directory into target directory. + * @param dirPath + * @throws IOException + */ + public void addDirEntry(String dirPath)throws IOException { + File file = new File(this.target.getPath()+File.separator+dirPath).getAbsoluteFile(); + if (!file.exists()){ + file.mkdirs(); + } + } + + /** + * Write entry bytes into target, this method is usually invoked if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException{ + File target = new File(this.target.getPath()+targetEntry.getName()).getAbsoluteFile(); + if(!target.exists()) { + target.createNewFile(); + } + (new FileOutputStream(target)).write(entryBytes); + } + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException { + File target = new File(this.target.getPath()+entry.getName()).getAbsoluteFile(); + if(!target.exists()) { + target.createNewFile(); + } + if((new File(this.source.toURI())).isDirectory()){ + File sourceEntry = new File(this.source.getPath()+entry.getName()); + FileInputStream fis = new FileInputStream(sourceEntry); + byte[] classBytes = new byte[fis.available()]; + fis.read(classBytes); + (new FileOutputStream(target)).write(classBytes); + }else{ + readwriteStreams(jis,(new FileOutputStream(target))); + } + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveJAROutputHandler.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000014/AB0952363AC40CBFE034080020E8C54E.0 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000014/AB0952363AC40CBFE034080020E8C54E.0 Mon Nov 27 11:25:39 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/weaving/StaticWeaveJAROutputHandler.java Mon Nov 27 11:25:39 2006 *************** *** 0 **** --- 1,66 ---- + package oracle.toplink.essentials.internal.weaving; + + import java.io.IOException; + import java.io.InputStream; + import java.net.URISyntaxException; + import java.util.jar.JarEntry; + import java.util.jar.JarOutputStream; + import java.util.zip.ZipException; + + /** + * The class provides a set of methods to pack passing in entries into the sepcified archive file. + * the class JAR output. + */ + public class StaticWeaveJAROutputHandler extends AbstractStaticWeaveOutputHandler{ + + /** + * Construct an instance of StaticWeaveJAROutputHandler + * @param outputStreamHolder + */ + public StaticWeaveJAROutputHandler(JarOutputStream outputStreamHolder){ + super.outputStreamHolder=outputStreamHolder; + } + + /** + * Add directory entry into outputstream. + * @param dirPath + * @throws IOException + */ + public void addDirEntry(String dirPath)throws IOException { + try{ + JarEntry newEntry = new JarEntry(dirPath); + newEntry.setSize(0); + addEntry(newEntry, null); + }catch(ZipException e){ + //ignore duplicate directory entry exceptions. + } + } + + /** + * Write entry bytes into target, this method is usually called if class has been tranformed + * @param targetEntry + * @param entryBytes + * @throws IOException + */ + public void addEntry(JarEntry targetEntry,byte[] entryBytes)throws IOException{ + outputStreamHolder.putNextEntry(targetEntry); + if(entryBytes!=null){ + outputStreamHolder.write(entryBytes); + } + outputStreamHolder.closeEntry(); + } + + /** + * Write entry into target, this method usually copy original class into target. + * @param jis + * @param entry + * @throws IOException + */ + public void addEntry(InputStream jis,JarEntry entry) throws IOException,URISyntaxException { + outputStreamHolder.putNextEntry(entry); + if(!entry.isDirectory()){ + readwriteStreams(jis,outputStreamHolder); + } + outputStreamHolder.closeEntry(); + } + } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/PersistenceUnitLoadingExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000015/AB0952363AC40CBFE034080020E8C54E.9 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000015/AB0952363AC40CBFE034080020E8C54E.9 Fri Nov 24 14:32:49 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/PersistenceUnitLoadingExceptionResource.java Mon Nov 27 11:26:27 2006 *************** *** 36,42 **** { "30008", "File path returned was empty or null"}, { "30009", "An exception was thrown while trying to load persistence unit at url: {0}"}, { "30010", "An exception was thrown while loading ORM XML file: {0}"}, ! { "30011", "TopLink could not get classes from the URL: {0}. TopLink attempted to read this URL as a jarFile and as a Directory and was unable to process it."} }; /** --- 36,43 ---- { "30008", "File path returned was empty or null"}, { "30009", "An exception was thrown while trying to load persistence unit at url: {0}"}, { "30010", "An exception was thrown while loading ORM XML file: {0}"}, ! { "30011", "TopLink could not get classes from the URL: {0}. TopLink attempted to read this URL as a jarFile and as a Directory and was unable to process it."}, ! { "30012", "TopLink could not get persistence unit info from the URL:{0}"} }; /** ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/persistence/PersistenceUnitProcessor.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000016/AB0952363AC40CBFE034080020E8C54E.32 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000016/AB0952363AC40CBFE034080020E8C54E.32 Fri Nov 24 14:33:40 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/persistence/PersistenceUnitProcessor.java Mon Nov 27 11:26:27 2006 *************** *** 28,37 **** --- 28,40 ---- import java.io.File; import java.io.IOException; import java.io.InputStream; + import java.util.ArrayList; + import java.util.Collection; import java.util.List; import java.util.Iterator; import java.util.Set; import java.util.HashSet; + import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; *************** *** 47,53 **** --- 50,59 ---- import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.PersistenceContentHandler; import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLException; import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLExceptionHandler; + import oracle.toplink.essentials.internal.sessions.AbstractSession; import oracle.toplink.essentials.logging.AbstractSessionLog; + import oracle.toplink.essentials.logging.SessionLog; + import oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider; /** * INTERNAL: *************** *** 71,77 **** /** * Go through the jar file for this PeristeneUnitProcessor and process any XML provided in it */ ! private static List processPersistenceArchive(Archive archive, ClassLoader loader){ URL puRootURL = archive.getRootURL(); try { InputStream pxmlStream = archive.getEntry("META-INF/persistence.xml"); // NOI18N --- 77,83 ---- /** * Go through the jar file for this PeristeneUnitProcessor and process any XML provided in it */ ! public static List processPersistenceArchive(Archive archive, ClassLoader loader){ URL puRootURL = archive.getRootURL(); try { InputStream pxmlStream = archive.getEntry("META-INF/persistence.xml"); // NOI18N *************** *** 154,160 **** * @param classEntryString * @return */ ! private static String buildClassNameFromEntryString(String classEntryString){ String classNameForLoader = classEntryString; if (classEntryString.endsWith(".class")){ // NOI18N classNameForLoader = classNameForLoader.substring(0, classNameForLoader.length() - 6);; --- 160,166 ---- * @param classEntryString * @return */ ! public static String buildClassNameFromEntryString(String classEntryString){ String classNameForLoader = classEntryString; if (classEntryString.endsWith(".class")){ // NOI18N classNameForLoader = classNameForLoader.substring(0, classNameForLoader.length() - 6);; *************** *** 316,319 **** --- 322,380 ---- return false; } + /** + * Process the Object/relational metadata from XML and annotations + * @param processor + * @param privateClassLoader + * @param session + * @param throwExceptionOnFail + */ + public static void processORMetadata( + MetadataProcessor processor, + ClassLoader privateClassLoader, + AbstractSession session, + boolean throwExceptionOnFail){ + // DO NOT CHANGE the order of invocation of various methods. + + // build the list of mapping files and read them. Need to do this before + // we start processing entities as the list of entity classes + // depend on metadata read from mapping files. + processor.readMappingFiles(throwExceptionOnFail); + + processor.buildEntityList(); + + // process persistence unit metadata/defaults defined in + // ORM XML instance documents in the persistence unit + processor.processPersistenceUnitMetadata(); + + processor.processMappingFiles(); + + processor.processAnnotations(); + + } + + /** + * Create a list of the entities that will be deployed. This list is build from the information + * provided in the PersistenceUnitInfo argument. + * The list contains Classes specified in the PersistenceUnitInfo's class list and also + * files that are annotated with @Entity, @Embeddable and @MappedSuperclass in + * the jar files provided in the persistence info. + * This list of classes will used by TopLink to build a deployment project and to + * decide what classes to weave. + * @param loader + * @return + */ + public static Collection buildEntityList(MetadataProcessor processor,ClassLoader loader) { + ArrayList entityList = new ArrayList(); + for (String className : processor.getProject().getEntityNames()) { + try { + Class entityClass = loader.loadClass(className); + entityList.add(entityClass); + } catch (ClassNotFoundException exc) { + AbstractSessionLog.getLog().log(SessionLog.CONFIG, + "exception_loading_entity_class", className, exc); + } + } + return entityList; + } } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/PersistenceUnitLoadingException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000017/AB0952363AC40CBFE034080020E8C54E.12 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000017/AB0952363AC40CBFE034080020E8C54E.12 Fri Nov 24 14:34:59 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/exceptions/PersistenceUnitLoadingException.java Mon Nov 27 11:26:27 2006 *************** *** 41,46 **** --- 41,47 ---- public static final int EXCEPTION_LOADING_FROM_URL = 30009; public static final int EXCEPTION_OPENING_ORM_XML = 30010; public static final int COULD_NOT_GET_CLASS_NAMES_FROM_URL = 30011; + public static final int COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL = 30012; /** * INTERNAL: *************** *** 164,169 **** --- 165,178 ---- return loadingException; } + public static PersistenceUnitLoadingException couldNotGetUnitInfoFromUrl(URL url) { + Object[] args = { url }; + + PersistenceUnitLoadingException loadingException = new PersistenceUnitLoadingException(ExceptionMessageGenerator.buildMessage(PersistenceUnitLoadingException.class, COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL, args)); + loadingException.setResourceName(url.toString()); + loadingException.setErrorCode(COULD_NOT_GET_PERSISTENCE_UNIT_INFO_FROM_URL); + return loadingException; + } public String getResourceName(){ return resourceName; } ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000018/AB0952363AC40CBFE034080020E8C54E.81 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000018/AB0952363AC40CBFE034080020E8C54E.81 Fri Nov 24 14:35:10 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java Mon Nov 27 11:26:27 2006 *************** *** 56,61 **** --- 56,62 ---- import oracle.toplink.essentials.exceptions.*; import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; import javax.persistence.spi.PersistenceUnitTransactionType; + import oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcessor; import oracle.toplink.essentials.internal.ejb.cmp3.jdbc.base.DataSourceImpl; import oracle.toplink.essentials.tools.sessionconfiguration.DescriptorCustomizer; *************** *** 110,139 **** } } - /** - * Create a list of the entities that will be deployed. This list is build from the information - * provided in the PersistenceUnitInfo argument. - * The list contains Classes specified in the PersistenceUnitInfo's class list and also - * files that are annotated with @Entity, @Embeddable and @MappedSuperclass in - * the jar files provided in the persistence info. - * This list of classes will used by TopLink to build a deployment project and to - * decide what classes to weave. - * @param loader - * @return - */ - private Collection buildEntityList(ClassLoader loader) { - ArrayList entityList = new ArrayList(); - for (String className : processor.getProject().getEntityNames()) { - try { - Class entityClass = loader.loadClass(className); - entityList.add(entityClass); - } catch (ClassNotFoundException exc) { - AbstractSessionLog.getLog().log(SessionLog.WARNING, - "exception_loading_entity_class", className, exc); - } - } - return entityList; - } /** * Deploy a persistence session and return an EntityManagerFactory. --- 111,116 ---- *************** *** 526,535 **** enableLazyForOneToOne = false; } } // Process the Object/relational metadata from XML and annotations. ! processORMetadata(privateClassLoader, session, enableLazyForOneToOne); // The connector will be reconstructed when the session is actually deployed session.getProject().getLogin().setConnector(new DefaultConnector()); --- 503,519 ---- enableLazyForOneToOne = false; } } + + boolean throwExceptionOnFail = "true".equalsIgnoreCase( + EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); + // Create an instance of MetadataProcessor for specified persistence unit info + processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); + // Process the Object/relational metadata from XML and annotations. ! PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); + // The connector will be reconstructed when the session is actually deployed session.getProject().getLogin().setConnector(new DefaultConnector()); *************** *** 542,548 **** ClassTransformer transformer = null; if (enableLazyForOneToOne){ // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = buildEntityList(privateClassLoader); transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } --- 526,532 ---- ClassTransformer transformer = null; if (enableLazyForOneToOne){ // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } *************** *** 952,981 **** } } - private void processORMetadata( - ClassLoader privateClassLoader, AbstractSession session, - boolean enableLazyForOneToOne){ - processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); - - // DO NOT CHANGE the order of invocation of various methods. - - // build the list of mapping files and read them. Need to do this before - // we start processing entities as the list of entity classes - // depend on metadata read from mapping files. - boolean throwExceptionOnFail = "true".equalsIgnoreCase( - getConfigPropertyAsString(TOPLINK_ORM_THROW_EXCEPTIONS, "true")); - processor.readMappingFiles(throwExceptionOnFail); - - processor.buildEntityList(); - - // process persistence unit metadata/defaults defined in - // ORM XML instance documents in the persistence unit - processor.processPersistenceUnitMetadata(); - - processor.processMappingFiles(); - - processor.processAnnotations(); - } public boolean isPredeployed() { return state == STATE_PREDEPLOYED; --- 936,941 ---- ================================================================================ Merge Diffs: /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/ToStringLocalizationResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000019/AB0952363AC40CBFE034080020E8C54E.4 Report generated at Mon Nov 27 11:28:07 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/xiaosche/xiaosche_main_staticweave_061124/ade_storage/000019/AB0952363AC40CBFE034080020E8C54E.4 Fri Nov 24 14:35:42 2006 --- /ade/xiaosche_tl_main_test/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/ToStringLocalizationResource.java Mon Nov 27 11:26:27 2006 *************** *** 18,24 **** * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */ ! // Copyright (c) 1998, 2005, Oracle. All rights reserved. package oracle.toplink.essentials.internal.localization.i18n; import java.util.ListResourceBundle; --- 18,24 ---- * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] */ ! // Copyright (c) 1998, 2006, Oracle. All rights reserved. package oracle.toplink.essentials.internal.localization.i18n; import java.util.ListResourceBundle; *************** *** 74,80 **** { "no_files", "no file(s)" }, { "mulitple_files", "mulitple files" }, { "unknown", "unknown" }, ! { "connector", "connector" } }; /** --- 74,98 ---- { "no_files", "no file(s)" }, { "mulitple_files", "mulitple files" }, { "unknown", "unknown" }, ! { "connector", "connector" }, ! { "staticweave_processor_unknown_outcome", "Weaving classes stored in a directory and outputing to a JAR often leads to unexpected results." }, ! { "staticweave_commandline_help_message", ! " Usage: StaticWeave [options] source target\r\r"+ ! " Options:\r"+ ! " -classpath classpath\r" + ! " Set the user class path. use \";\" as delimiter in windows and \":\" in unix.\r"+ ! " -persistenceinfo \r" + ! " Explicitly identify where META-INF/persistence.xml is stored. It must be the root of META-INF/persistence.xml.\r"+ ! " -log \r" + ! " Specify logging file.\r"+ ! " -loglevel \r" + ! " Specify a literal value of the toplink logging level(OFF,SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST).\r"+ ! " The classpath must contain all the classes necessary to load the classes in the source.\r"+ ! " The weaving will be performed in place if source and target point to the same location. Weaving in place is ONLY applicable for directory-based sources.\r"+ ! " Example:\r" + ! " To weave all entites contained in c:\\foo-source.jar with its persistence.xml contained within the c:\\foo-containing-persistence-xml.jar,\r"+ ! " and output to c:\\foo-target.jar,\r"+ ! " StaticWeave -persistenceinfo c:\\foo-containing-persistence-xml.jar -classpath c:\\classpath1;c:\\classpath2 c:\\foo-source.jar c:\\foo-target.jar\r\r"} }; /**