db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From c..@apache.org
Subject svn commit: r818642 - in /db/jdo/trunk/api2: ./ src/java/javax/jdo/ test/java/javax/jdo/ test/resources/ test/resources/META-INF/ test/resources/META-INF/services/
Date Thu, 24 Sep 2009 22:26:28 GMT
Author: clr
Date: Thu Sep 24 22:26:27 2009
New Revision: 818642

URL: http://svn.apache.org/viewvc?rev=818642&view=rev
Log:
JDO-621 Add javax.jdo.Enhancer to API

Added:
    db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java   (with props)
    db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java   (with props)
    db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java   (with props)
    db/jdo/trunk/api2/test/resources/
    db/jdo/trunk/api2/test/resources/META-INF/
    db/jdo/trunk/api2/test/resources/META-INF/services/
    db/jdo/trunk/api2/test/resources/META-INF/services/javax.jdo.JDOEnhancer
Modified:
    db/jdo/trunk/api2/pom.xml
    db/jdo/trunk/api2/project.xml
    db/jdo/trunk/api2/src/java/javax/jdo/Bundle.properties
    db/jdo/trunk/api2/src/java/javax/jdo/Constants.java
    db/jdo/trunk/api2/src/java/javax/jdo/JDOHelper.java

Modified: db/jdo/trunk/api2/pom.xml
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/pom.xml?rev=818642&r1=818641&r2=818642&view=diff
==============================================================================
--- db/jdo/trunk/api2/pom.xml (original)
+++ db/jdo/trunk/api2/pom.xml Thu Sep 24 22:26:27 2009
@@ -50,6 +50,9 @@
     </resources>
     <testResources>
       <testResource>
+        <directory>${basedir}/test/resources</directory>
+      </testResource>
+      <testResource>
         <directory>${basedir}/test/schema</directory>
         <includes>
           <include>**/*.jdo</include>

Modified: db/jdo/trunk/api2/project.xml
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/project.xml?rev=818642&r1=818641&r2=818642&view=diff
==============================================================================
--- db/jdo/trunk/api2/project.xml (original)
+++ db/jdo/trunk/api2/project.xml Thu Sep 24 22:26:27 2009
@@ -85,12 +85,18 @@
                 <resource>
                 <directory>${basedir}/test/schema</directory>
                 <includes>
-                    <include>**/*.jdo</include>
-                    <include>**/*.jdoquery</include>
-                    <include>**/*.orm</include>
-                    <include>**/jdoconfig.xml</include>
+                  <include>**/*.jdo</include>
+                  <include>**/*.jdoquery</include>
+                  <include>**/*.orm</include>
+                  <include>**/jdoconfig.xml</include>
                 </includes>
                 </resource>
+                <resource>
+                  <directory>${basedir}/test/resources</directory>
+                  <includes>
+                    <include>**/*</include>
+                  </includes>
+                </resource>
             </resources>
         </unitTest>
         <defaultGoal>jar:install</defaultGoal>

Modified: db/jdo/trunk/api2/src/java/javax/jdo/Bundle.properties
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/src/java/javax/jdo/Bundle.properties?rev=818642&r1=818641&r2=818642&view=diff
==============================================================================
--- db/jdo/trunk/api2/src/java/javax/jdo/Bundle.properties (original)
+++ db/jdo/trunk/api2/src/java/javax/jdo/Bundle.properties Thu Sep 24 22:26:27 2009
@@ -122,5 +122,35 @@
 or the given persistence unit name "{0}" was not found.
 
 EXC_GetEnhancerNoValidEnhancerAvailable=\
-There were no valid JDOEnhancer implementations identified in the CLASSPATH. \
+There are {0} services entries for the JDOEnhancer; \
+there were no valid JDOEnhancer implementations found in the CLASSPATH. \
 The file META-INF/services/javax.jdo.JDOEnhancer should name the implementation class.
+MSG_EnhancerUsage=\
+Usage: java -cp <class path> javax.jdo.Enhancer <options> <files>\n\
+options:\n\
+    \t? (print this message and exit)\n\
+    \t-h (print this message and exit)\n\
+    \t-help (print this message and exit)\n\
+    \t-cp <class path> (use the class path with its own class loader)\n\
+    \t-pu <persistence unit> (look for the persistence unit in META-INF/persistence.xml)\n\
+    \t-d <output directory> (write enhanced classes with package structure into this directory)\n\
+    \t-checkonly (do not enhance; just check)\n\
+    \t-verbose (output detail information)\n\
+    \t-v (output detail information)\n\
+    \t-r (recursively descend into parameter directories)\n\
+files:\n\
+    \tfiles and directories to be enhanced, including .class and .jdo files
+ERR_EnhancerRequiredArgumentMissing=Required Argument Missing.
+ERR_EnhancerUnrecognizedOption=Enhancer unrecognized option {0}.
+MSG_EnhancerProcessing=Enhancer Processing {0}.
+MSG_EnhancerValidatedClasses=Enhancer validated {0} classes.
+MSG_EnhancerEnhancedClasses=Enhancer enhanced {0} classes.
+MSG_EnhancerClass=Enhancer found JDOEnhancer of class {0}.
+MSG_EnhancerJarFileName=Enhancer adding jar file {0}.
+MSG_EnhancerJDOFileName=Enhancer adding jdo file {0}.
+MSG_EnhancerClassFileName=Enhancer adding class file {0}.
+MSG_EnhancerPersistenceUnitName=Enhancer adding Persistence Unit {0}.
+MSG_EnhancerClassPath=Enhancer processing classpath {0}.
+MSG_EnhancerOutputDirectory=Enhancer processing output directory {0}.
+ERR_EnhancerBadClassPath=Enhancer cannot construct URL from path {0}.
+MSG_EnhancerProperty:Enhancer property key:{0} value:{1}.

Modified: db/jdo/trunk/api2/src/java/javax/jdo/Constants.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/src/java/javax/jdo/Constants.java?rev=818642&r1=818641&r2=818642&view=diff
==============================================================================
--- db/jdo/trunk/api2/src/java/javax/jdo/Constants.java (original)
+++ db/jdo/trunk/api2/src/java/javax/jdo/Constants.java Thu Sep 24 22:26:27 2009
@@ -565,6 +565,39 @@
         = "javax.jdo.PersistenceManagerFactoryClass";
 
     /**
+     * "VendorName"
+     *
+     * @see JDOEnhancer#getProperties()
+     * @since 2.3
+     */
+    static String PROPERTY_ENHANCER_VENDOR_NAME
+        = "VendorName";
+
+    /**
+     * "VersionNumber"
+     *
+     * @see JDOEnhancer#getProperties()
+     * @since 2.3
+     */
+    static String PROPERTY_ENHANCER_VERSION_NUMBER
+        = "VersionNumber";
+
+    /** Exit value for no enhancer found 
+     * @since 2.3
+     * */
+    public static int ENHANCER_NO_JDO_ENHANCER_FOUND = 2;
+
+    /** Exit value for usage error 
+     * @since 2.3
+     * */
+    public static int ENHANCER_USAGE_ERROR = 3;
+
+    /** Exit value for an exception from the JDOEnhancer 
+     * @since 2.3
+     * */
+    public static int ENHANCER_EXCEPTION = 1;
+
+    /**
      * "javax.jdo.option.Optimistic"
      *
      * @see PersistenceManagerFactory#getOptimistic()

Added: db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java?rev=818642&view=auto
==============================================================================
--- db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java (added)
+++ db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java Thu Sep 24 22:26:27 2009
@@ -0,0 +1,451 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javax.jdo;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import static javax.jdo.Constants.ENHANCER_EXCEPTION;
+import static javax.jdo.Constants.ENHANCER_NO_JDO_ENHANCER_FOUND;
+import static javax.jdo.Constants.ENHANCER_USAGE_ERROR;
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VENDOR_NAME;
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VERSION_NUMBER;
+
+import javax.jdo.spi.I18NHelper;
+
+/**
+ * Main class to invoke a JDO Enhancer.
+ * The enhancer is invoked with the following command line:
+ * <xmp>
+ * java -cp <classpath> javax.jdo.Enhancer <options> <directory, file, or resource names>
+ * </xmp>
+ * &lt;classpath&gt; must contain the jdo specification jar, the implementation jar and any 
+ * implementation dependencies, the statically-compiled classes, and the jdo 
+ * metadata files loadable as resources.
+ * 
+ * <p/>&lt;options&gt; include: 
+ * <ul><li>? : print usage to stderr and exit
+ * </li><li>-h : print usage to stderr and exit
+ * </li><li>-help : print usage to stderr and exit
+ * </li><li>-pu &lt;persistence-unit-name&gt; : the name of a persistence unit 
+ * </li><li>-d &lt;target directory&gt; : write the enhanced classes to the specified directory 
+ * </li><li>-checkonly : just check the classes for enhancement status 
+ * </li><li>-v : verbose output
+ * </li><li>-r : recurse through directories to find all classes and metadata files to enhance 
+ * </li><li>-cp &lt;enhancer class loader path&gt; : if not already included in the java class loader, 
+ * this parameter must contain the statically-compiled classes, and the jdo metadata 
+ * files loadable as resources 
+ * </li></ul>&lt;directory, file, or resource names&gt;
+ * <ul><li>Directory names must not end in ".jdo", ".jar", or ".class"
+ * </li><li>Directories will be searched for files with suffixes ".jdo", ".jar", and ".class"
+ * </li><li>Directories will be searched recursively if the -r option is set
+ * </li></ul>
+ * 
+ * @since 2.3
+ */
+public class Enhancer {
+
+    /** The Internationalization message helper. */
+    private final static I18NHelper msg = 
+        I18NHelper.getInstance ("javax.jdo.Bundle"); //NOI18N
+
+    /** New Line */
+    private char NL = '\n'; //NOI18N
+    /** Jar file suffix */
+    private String JAR_FILE_SUFFIX = ".jar"; //NOI18N
+    /** JDO Metadata file suffix */
+    private String JDO_FILE_SUFFIX = ".jdo"; //NOI18N
+    /** Class file suffix */
+    private String CLASS_FILE_SUFFIX = ".class"; //NOI18N
+
+    /** Error indicator */
+    private boolean error = false;
+    /** If set, process parameters, print usage, and exit. */
+    private boolean printAndExit = false;
+
+    /** Persistence Units */
+    private List<String> persistenceUnitNames = new ArrayList<String>();
+    /** Target Directory Parameter */
+    private String directoryName = null;
+    /** ClassLoader for JDOEnhancer */
+    private ClassLoader loader = null;
+    /** Classpath (-cp) parameter */
+    private String classPath = null;
+    /** Check Only flag */
+    private boolean checkOnly = false;
+    /** Verbose flag */
+    private boolean verbose = false;
+    /** Recurse flag */
+    private boolean recurse = false;
+    /** Error messages should be empty unless there is an error */
+    private StringBuilder errorBuffer = new StringBuilder();
+    /** Verbose messages are always collected but only output if verbose flag is set */
+    private StringBuilder verboseBuffer = new StringBuilder();
+    /** File Names */
+    private List<String> fileNames = new ArrayList<String>();
+    /** Class File Names */
+    private List<String> classFileNames = new ArrayList<String>();
+    /** JDO File Names */
+    private List<String> jdoFileNames = new ArrayList<String>();
+    /** Jar File Names */
+    private List<String> jarFileNames = new ArrayList<String>();
+    /** The number of classes validated by the JDOEnhancer */
+    private int numberOfValidatedClasses = 0;
+    /** The number of classes enhanced by the JDOEnhancer */
+    private int numberOfEnhancedClasses = 0;
+
+    /** The properties from the JDOEnhancer */
+    private Properties properties;
+
+    /** Run the enhancer from the command line.
+     * 
+     * @param args command line arguments
+     */
+    public static void main (String[] args) {
+        Enhancer enhancerMain = new Enhancer();
+        enhancerMain.run(args);
+    }
+
+    /** Execute the enhancer.
+     * 
+     * @param args the command line arguments
+     */
+    private void run(String[] args) {
+        // processArgs will exit if errors or help
+        processArgs(args);
+        JDOEnhancer enhancer = null;
+        try {
+            enhancer = JDOHelper.getEnhancer();
+        } catch (JDOException jdoex) {
+            jdoex.printStackTrace(); // outputs to stderr
+            exit(ENHANCER_NO_JDO_ENHANCER_FOUND);
+        }
+
+        try {
+            // provide verbose property settings of the JDOEnhancer we just loaded
+            properties = enhancer.getProperties();
+            addVerboseMessage("MSG_EnhancerClass", enhancer.getClass().getName()); //NOI18N
+            addVerboseMessage("MSG_EnhancerProperty", PROPERTY_ENHANCER_VENDOR_NAME, //NOI18N
+                    properties.getProperty(PROPERTY_ENHANCER_VENDOR_NAME));
+            addVerboseMessage("MSG_EnhancerProperty", PROPERTY_ENHANCER_VERSION_NUMBER, //NOI18N
+                    properties.getProperty(PROPERTY_ENHANCER_VERSION_NUMBER));
+            Set<Entry<Object, Object>> props = properties.entrySet();
+            Iterator<Entry<Object, Object>> entries = props.iterator();
+            while (entries.hasNext()) {
+                Entry<Object, Object> entry = entries.next();
+                if (!(PROPERTY_ENHANCER_VENDOR_NAME.equals(entry.getKey()) ||
+                        PROPERTY_ENHANCER_VERSION_NUMBER.equals(entry.getKey()))) {
+                    addVerboseMessage("MSG_EnhancerProperty", (String)entry.getKey(), //NOI18N
+                            (String)entry.getValue());                    
+                }
+            }
+            enhancer.setVerbose(verbose);
+            if (loader != null) {
+                enhancer.setClassLoader(loader);
+            }
+
+            int numberOfClasses = classFileNames.size();
+            if (numberOfClasses != 0) {
+                enhancer.addClasses(classFileNames.toArray(new String[numberOfClasses]));
+            }
+            int numberOfFiles = jdoFileNames.size();
+            if (numberOfFiles != 0) {
+                enhancer.addFiles(jdoFileNames.toArray(new String[numberOfFiles]));
+            }
+            if (0 < jarFileNames.size()) {
+                for (String jarFileName : jarFileNames) {
+                    enhancer.addJar(jarFileName);
+                }
+            }
+            if (persistenceUnitNames != null) {
+                for (String persistenceUnitName: persistenceUnitNames) {
+                    enhancer.addPersistenceUnit(persistenceUnitName);
+                }
+            }
+            if (directoryName != null) {
+                enhancer.setOutputDirectory(directoryName);
+            }
+            if (checkOnly) {
+                numberOfValidatedClasses = enhancer.validate();
+                addVerboseMessage("MSG_EnhancerValidatedClasses", numberOfValidatedClasses); //NOI18N
+            } else {
+                numberOfEnhancedClasses = enhancer.enhance();
+                addVerboseMessage("MSG_EnhancerEnhancedClasses", numberOfEnhancedClasses); //NOI18N
+            }
+            exit(0); // good exit
+        } catch (Exception ex) {
+            ex.printStackTrace(); // outputs to stderr
+            exit(ENHANCER_EXCEPTION); // error exit
+        }
+    }
+
+    /** Process the command line arguments and exit if there is a usage request or an error.
+     * 
+     * @param args the command line arguments
+     */
+    private void processArgs(String[] args) {
+        parseArgs(args);
+        parseFiles(fileNames.toArray(new String[fileNames.size()]), true, recurse);
+        loader = prepareClassLoader(classPath);
+        if (error) {
+            addErrorMessage(msg.msg("MSG_EnhancerUsage")); //NOI18N
+            exit(ENHANCER_USAGE_ERROR); // error exit
+        }
+        if (printAndExit) {
+            addVerboseMessage("MSG_EnhancerUsage"); //NOI18N
+            exit(0); // good exit
+        }
+    }
+
+    /** Parse the command line arguments. Put the results into fields.
+     * 
+     * @param args the command line arguments
+     */
+    private void parseArgs(String[] args) {
+        boolean doneWithOptions = false;
+        fileNames = new ArrayList<String>();
+        for (int i = 0; i < args.length; ++i) {
+            String arg = args[i];
+            // if first argument is ? then simply print usage and return.
+            if ("?".equals(arg)) {
+                printAndExit = true;
+                return;
+            }
+            if (!doneWithOptions) {
+                if (arg.startsWith("-")) { //NOI18N
+                    String option = arg.substring(1);
+                    if ("help".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-help"); //NOI18N
+                        setPrintAndExit();
+                    } else if ("h".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-h"); //NOI18N
+                        setPrintAndExit();
+                    } else if ("v".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-v"); //NOI18N
+                        verbose = true;
+                    } else if ("verbose".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-verbose"); //NOI18N
+                        verbose = true;
+                    } else if ("pu".equals(option)) { //NOI18N
+                        if (hasNextArgument("MSG_EnhancerProcessing", "-pu", i, args.length)) { //NOI18N
+                            String puName = args[++i];
+                            addVerboseMessage("MSG_EnhancerPersistenceUnitName", puName); //NOI18N
+                            persistenceUnitNames.add(puName);
+                        } else {
+                            setError();
+                        }
+                    } else if ("cp".equals(option)) { //NOI18N
+                        if (hasNextArgument("MSG_EnhancerProcessing", "-cp", i, args.length)) { //NOI18N
+                            classPath = args[++i];
+                            addVerboseMessage("MSG_EnhancerClassPath", classPath); //NOI18N
+                         } else {
+                             setError();
+                       }
+                    } else if ("d".equals(option)) { //NOI18N
+                        if (hasNextArgument("MSG_EnhancerProcessing", "-d", i, args.length)) { //NOI18N
+                            directoryName = args[++i];
+                            addVerboseMessage("MSG_EnhancerOutputDirectory", directoryName); //NOI18N
+                        } else {
+                            setError();
+                        }
+                    } else if ("checkonly".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-checkonly"); //NOI18N
+                        checkOnly = true;
+                    } else if ("r".equals(option)) { //NOI18N
+                        addVerboseMessage("MSG_EnhancerProcessing", "-r"); //NOI18N
+                        recurse = true;
+                    } else {
+                        setError();
+                        addErrorMessage(msg.msg("ERR_EnhancerUnrecognizedOption", option)); //NOI18N
+                    }
+                } else {
+                    doneWithOptions = true;
+                    fileNames.add(arg);
+                }
+            } else {
+                fileNames.add(arg);
+            }
+        }
+    }
+
+    /** Check whether there is another parameter (the argument for an option
+     * that requires an argument).
+     * @param msgId the message id for an error message
+     * @param where the parameter for the message
+     * @param i the index into the parameter array
+     * @param length the length of the parameter array
+     * @return
+     */
+    private boolean hasNextArgument(String msgId, String where, int i, int length) {
+        if (i + 1 >= length) {
+            setError();
+            addErrorMessage(msg.msg(msgId, where));
+            addErrorMessage(msg.msg("ERR_EnhancerRequiredArgumentMissing")); //NOI18N
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Files can be one of four types:
+     * <ol><li>directory: the directory is examined for files of the following types
+     * </li><li>.class: this is a java class file
+     * </li><li>.jdo: this is a jdo metadata file
+     * </li><li>.jar: this is a jar file
+     * </li></ol>
+     * If the recursion flag is set, directories contained in directories are examined,
+     * recursively.
+     */
+    private void parseFiles(String[] fileNames, boolean search, boolean recurse) {
+        for (String fileName: fileNames) {
+            if (fileName.endsWith(JAR_FILE_SUFFIX)) {
+                // add to jar file names
+                jarFileNames.add(fileName);
+                addVerboseMessage("MSG_EnhancerJarFileName", fileName); //NOI18N
+            } else if (fileName.endsWith(JDO_FILE_SUFFIX)) {
+                // add to jdo file names
+                jdoFileNames.add(fileName);
+                addVerboseMessage("MSG_EnhancerJDOFileName", fileName); //NOI18N
+            } else if (fileName.endsWith(CLASS_FILE_SUFFIX)) {
+                // add to class file names
+                classFileNames.add(fileName);
+                addVerboseMessage("MSG_EnhancerClassFileName", fileName); //NOI18N
+            } else {
+                // assume a directory if no suffix
+                File directory = new File(fileName);
+                if (directory.isDirectory() && search) {
+                    String[] files = directory.list();
+                    if (files != null) {
+                        parseFiles(files, recurse, recurse);
+                    }
+                }
+            }
+        }
+    }
+
+    /** Prepare the class loader from the classPath specified
+     * 
+     * @param classPath the classPath string from the "-cp classPath" option
+     * @return the class loader
+     */
+    private ClassLoader prepareClassLoader(String classPath) {
+        if (classPath == null)
+            return null;
+        ClassLoader result = null;
+        // separate classPath using system class path separator
+        String separator = System.getProperty("path.separator");
+        String[] paths = classPath.split(separator);
+        List<URL> urls = new ArrayList<URL>();
+        for (String path: paths) {
+            // for each path construct a URL from the File
+            File file = new File(path);
+            URI uri = file.toURI();
+            try {
+                URL url = uri.toURL();
+                addVerboseMessage("MSG_EnhancerClassPath", url.toString());
+                urls.add(url);
+            } catch (MalformedURLException e) {
+                setError();
+                addErrorMessage(msg.msg("ERR_EnhancerBadClassPath", file));
+            }
+        }
+        result = new URLClassLoader(urls.toArray(new URL[urls.size()]), null);
+        return result;
+    }
+
+    /** Add a message to stderr.
+     * 
+     * @param message the internationalized message to add
+     */
+    private void addErrorMessage(String message) {
+        errorBuffer.append(message);
+        errorBuffer.append(NL);
+    }
+
+    /** Set the error flag.
+     * 
+     */
+    private void setError() {
+        error = true;
+    }
+
+    /** Set the print-and-exit flag.
+     * 
+     */
+    private void setPrintAndExit() {
+        printAndExit = true;
+    }
+
+    /** Exit this process.
+     * 
+     * @param exitValue the process exit value
+     */
+    private void exit(int exitValue) {
+        System.out.print(verboseBuffer.toString());
+        System.err.print(errorBuffer.toString());
+        System.exit(exitValue);
+    }
+
+    /** Add a message to the verbose message buffer.
+     * 
+     * @param msgId the message id
+     * @param where the parameter
+     */
+    private void addVerboseMessage(String msgId, String... where) {
+        verboseBuffer.append(msg.msg(msgId, where));
+        verboseBuffer.append(NL);
+    }
+
+    /** Add a message to the verbose message buffer.
+     * 
+     * @param msgId the message id
+     * @param where the parameter
+     */
+    private void addVerboseMessage(String msgId, String where) {
+        verboseBuffer.append(msg.msg(msgId, where));
+        verboseBuffer.append(NL);
+    }
+
+    /** Add a message to the verbose message buffer.
+     * 
+     * @param msgId the message id
+     */
+    private void addVerboseMessage(String msgId) {
+        verboseBuffer.append(msg.msg(msgId));
+        verboseBuffer.append(NL);
+    }
+
+    /** Add a message to the verbose message buffer.
+     * 
+     * @param msgId the message id
+     * @param where the parameter
+     */
+    private void addVerboseMessage(String msgId, int where) {
+        addVerboseMessage(msgId, String.valueOf(where));
+    }
+
+}
\ No newline at end of file

Propchange: db/jdo/trunk/api2/src/java/javax/jdo/Enhancer.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: db/jdo/trunk/api2/src/java/javax/jdo/JDOHelper.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/src/java/javax/jdo/JDOHelper.java?rev=818642&r1=818641&r2=818642&view=diff
==============================================================================
--- db/jdo/trunk/api2/src/java/javax/jdo/JDOHelper.java (original)
+++ db/jdo/trunk/api2/src/java/javax/jdo/JDOHelper.java Thu Sep 24 22:26:27 2009
@@ -89,7 +89,7 @@
     /**
      * A mapping from jdoconfig.xsd element attributes to PMF properties.
      */
-    static final Map ATTRIBUTE_PROPERTY_XREF
+    static final Map<String, String> ATTRIBUTE_PROPERTY_XREF
         = createAttributePropertyXref();
 
     /** The Internationalization message helper.
@@ -102,8 +102,8 @@
      * @return An unmodifiable Map of jdoconfig.xsd element attributes to PMF
      * properties.
      */
-    static Map createAttributePropertyXref() {
-        Map<String,String> xref = new HashMap<String,String>();
+    static Map<String, String> createAttributePropertyXref() {
+        Map<String, String> xref = new HashMap<String,String>();
 
         xref.put(
             PMF_ATTRIBUTE_CLASS,
@@ -396,7 +396,7 @@
      */
     public static Collection<Object> getObjectIds(Collection<Object> pcs) {
         ArrayList<Object> result = new ArrayList<Object>();
-        for (Iterator it = pcs.iterator(); it.hasNext();) {
+        for (Iterator<?> it = pcs.iterator(); it.hasNext();) {
             result.add(getObjectId(it.next()));
         }
         return result;
@@ -694,7 +694,7 @@
      * @see #getPersistenceManagerFactory(java.util.Map,ClassLoader)
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-            (Map props) {
+            (Map<?, ?> props) {
         return getPersistenceManagerFactory(
                 null, props, getContextClassLoader());
     }
@@ -714,7 +714,7 @@
      * @since 1.0
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-            (Map props, ClassLoader pmfClassLoader) {
+            (Map<?, ?> props, ClassLoader pmfClassLoader) {
         return getPersistenceManagerFactory(
                 null, props, pmfClassLoader);
     }
@@ -788,20 +788,20 @@
      * @since 2.1
      */
     protected static PersistenceManagerFactory getPersistenceManagerFactory
-            (Map overrides, Map props, ClassLoader pmfClassLoader) {
+            (Map<?, ?> overrides, Map<?, ?> props, ClassLoader pmfClassLoader) {
         List<Throwable> exceptions = new ArrayList<Throwable>();
         if (pmfClassLoader == null)
             throw new JDOFatalUserException (msg.msg (
                 "EXC_GetPMFNullLoader")); //NOI18N
 
-	    // first try to get the class name from the properties object.
+        // first try to get the class name from the properties object.
         String pmfClassName = (String) props.get (
                 PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS);
 
         if (!isNullOrBlank(pmfClassName)) {
-	    // a valid name was returned from the properties.
+            // a valid name was returned from the properties.
             return invokeGetPersistenceManagerFactoryOnImplementation(
-                        pmfClassName, overrides, props, pmfClassLoader);
+                    pmfClassName, overrides, props, pmfClassLoader);
 
         } else {
             /*
@@ -820,7 +820,7 @@
              * Otherwise add the exception thrown to 
              * an exception list.
              */
-            Enumeration urls = null;
+            Enumeration<URL> urls = null;
             try {
                 urls = getResources(pmfClassLoader,
                         SERVICE_LOOKUP_PMF_RESOURCE_NAME);
@@ -949,7 +949,7 @@
      * @see #getPersistenceManagerFactory(Map,String,ClassLoader,ClassLoader)
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-            (Map overrides, String name) {
+            (Map<?, ?> overrides, String name) {
 
         ClassLoader cl = getContextClassLoader();
         return getPersistenceManagerFactory(overrides, name, cl, cl);
@@ -963,7 +963,7 @@
      * @see #getPersistenceManagerFactory(Map,String,ClassLoader,ClassLoader)
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-            (Map overrides, String name, ClassLoader resourceLoader) {
+            (Map<?, ?> overrides, String name, ClassLoader resourceLoader) {
 
         return getPersistenceManagerFactory(
                 overrides, name, resourceLoader, resourceLoader);
@@ -1048,7 +1048,7 @@
      * @see Constants#ANONYMOUS_PERSISTENCE_MANAGER_FACTORY_NAME
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory(
-            Map overrides,
+            Map<?, ?> overrides,
             String name,
             ClassLoader resourceLoader,
             ClassLoader pmfLoader) {
@@ -1110,11 +1110,11 @@
      */
     protected static PersistenceManagerFactory
         invokeGetPersistenceManagerFactoryOnImplementation(
-            String pmfClassName, Map overrides, Map properties, ClassLoader cl) {
+            String pmfClassName, Map<?, ?> overrides, Map<?, ?> properties, ClassLoader cl) {
         if (overrides != null) {
             // overrides is not null; use getPersistenceManagerFactory(Map overrides, Map props)
             try {
-                Class implClass = forName(pmfClassName, true, cl);
+                Class<?> implClass = forName(pmfClassName, true, cl);
                 Method m = getMethod(implClass,
                         "getPersistenceManagerFactory", //NOI18N
                         new Class[]{Map.class, Map.class});
@@ -1152,7 +1152,7 @@
         } else {
             // overrides is null; use getPersistenceManagerFactory(Map props)
             try {
-                Class implClass = forName(pmfClassName, true, cl);
+                Class<?> implClass = forName(pmfClassName, true, cl);
                 Method m = getMethod(implClass,
                         "getPersistenceManagerFactory", //NOI18N
                         new Class[]{Map.class});
@@ -1460,7 +1460,7 @@
 
                 // check for duplicate properties among atts & elems
                 if (requestedPMFName.equals(pmfName)) {
-                    Iterator it =
+                    Iterator<?> it =
                         pmfPropertiesFromAttributes.keySet().iterator();
                     while (it.hasNext()) {
                         String property = (String) it.next();
@@ -1833,7 +1833,7 @@
      * @since 2.3
      */
     public static JDOEnhancer getEnhancer() {
-    	return getEnhancer(getContextClassLoader());
+        return getEnhancer(getContextClassLoader());
     }
 
     /**
@@ -1845,43 +1845,45 @@
      * @since 2.3
      */
     public static JDOEnhancer getEnhancer(ClassLoader loader) {
-    	ClassLoader ctrLoader = loader;
-    	if (ctrLoader == null) {
-    		ctrLoader = Thread.currentThread().getContextClassLoader();
-    	}
-
-    	/*
-    	 * If you have a jar file that provides the jdo enhancer implementation,
-    	 * a file naming the implementation goes into the file 
-    	 * packaged into the jar file, called "META-INF/services/javax.jdo.JDOEnhancer".
-    	 * The contents of the file is a string that is the enhancer class name.
-    	 * For each file in the class loader named "META-INF/services/javax.jdo.JDOEnhancer",
-    	 * this method will invoke the default constructor of the implementation class.
-    	 * Return the enhancer if a valid class name is extracted from resources and
-    	 * the invocation returns an instance.
-    	 * Otherwise add the exception thrown to an exception list.
-    	 */
-    	ArrayList<Throwable> exceptions = new ArrayList<Throwable>();
-    	try {
-    		Enumeration urls = getResources(loader, SERVICE_LOOKUP_ENHANCER_RESOURCE_NAME);
-        	if (urls != null) {
-        		while (urls.hasMoreElements()) {
-        			try {
+            ClassLoader ctrLoader = loader;
+        if (ctrLoader == null) {
+            ctrLoader = Thread.currentThread().getContextClassLoader();
+        }
+
+    /*
+     * If you have a jar file that provides the jdo enhancer implementation,
+     * a file naming the implementation goes into the file 
+     * packaged into the jar file, called "META-INF/services/javax.jdo.JDOEnhancer".
+     * The contents of the file is a string that is the enhancer class name.
+     * For each file in the class loader named "META-INF/services/javax.jdo.JDOEnhancer",
+     * this method will invoke the default constructor of the implementation class.
+     * Return the enhancer if a valid class name is extracted from resources and
+     * the invocation returns an instance.
+     * Otherwise add the exception thrown to an exception list.
+     */
+        ArrayList<Throwable> exceptions = new ArrayList<Throwable>();
+        int numberOfJDOEnhancers = 0;
+        try {
+            Enumeration<URL> urls = getResources(loader, SERVICE_LOOKUP_ENHANCER_RESOURCE_NAME);
+            if (urls != null) {
+                while (urls.hasMoreElements()) {
+                    numberOfJDOEnhancers++;
+                    try {
                         String enhancerClassName = getClassNameFromURL((URL)urls.nextElement());
-                        Class enhancerClass = forName(enhancerClassName, true, ctrLoader);
+                        Class<?> enhancerClass = forName(enhancerClassName, true, ctrLoader);
                         JDOEnhancer enhancer = (JDOEnhancer)enhancerClass.newInstance();
                         return enhancer;
-        			} catch (Throwable ex) {
-        				// remember exceptions from failed enhancer invocations
-        				exceptions.add(ex);
-        			}
-        		}
-        	}
-    	} catch (Throwable ex) {
-    		exceptions.add(ex);
-    	}
+                    } catch (Throwable ex) {
+                        // remember exceptions from failed enhancer invocations
+                        exceptions.add(ex);
+                    }
+                }
+            }
+        } catch (Throwable ex) {
+            exceptions.add(ex);
+        }
 
-        throw new JDOFatalUserException(msg.msg("EXC_GetEnhancerNoValidEnhancerAvailable"),
+        throw new JDOFatalUserException(msg.msg("EXC_GetEnhancerNoValidEnhancerAvailable", numberOfJDOEnhancers),
                 (Throwable[])exceptions.toArray(new Throwable[exceptions.size()]));
     }
 
@@ -1924,9 +1926,9 @@
      * @return the Method instance
      */
     private static Method getMethod(
-            final Class implClass, 
+            final Class<?> implClass, 
             final String methodName, 
-            final Class[] parameterTypes) 
+            final Class<?>[] parameterTypes) 
                 throws NoSuchMethodException {
         try {
             return AccessController.doPrivileged(
@@ -1997,15 +1999,15 @@
      * @param loader which class loader to use
      * @return the class
      */
-    private static Class forName(
+    private static Class<?> forName(
             final String name, 
             final boolean init, 
             final ClassLoader loader) 
                 throws ClassNotFoundException {
         try {
             return AccessController.doPrivileged(
-                new PrivilegedExceptionAction<Class>() {
-                    public Class run() throws ClassNotFoundException {
+                new PrivilegedExceptionAction<Class<?>>() {
+                    public Class<?> run() throws ClassNotFoundException {
                         return Class.forName(name, init, loader);
                     }
                 }

Added: db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java?rev=818642&view=auto
==============================================================================
--- db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java (added)
+++ db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java Thu Sep 24 22:26:27 2009
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package javax.jdo;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.CharBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import static javax.jdo.Constants.ENHANCER_USAGE_ERROR;
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VENDOR_NAME;
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VERSION_NUMBER;
+
+import javax.jdo.util.AbstractTest;
+import javax.jdo.util.BatchTestRunner;
+
+
+/**
+ * Tests class javax.jdo.Enhancer (Enhancer main class).
+ * <p>
+ */
+public class EnhancerTest extends AbstractTest {
+
+    /** The path delimiter for constructing classpaths. */
+    private static String pathDelimiter = System.getProperty("path.separator");
+
+    /** The maven basedir identifying the directory of the execution environment. */
+    private static String basedir = System.getProperty("basedir");
+
+    /** */
+    public static void main(String args[]) {
+        BatchTestRunner.run(EnhancerTest.class);
+    }
+
+    public void testUsageOption() {
+        // invoke enhancer with a usage option
+        InvocationResult result = invokeEnhancer("?");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected Usage message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("javax.jdo.Enhancer"));
+    }
+
+    public void testHelpOption() {
+        // invoke enhancer with a usage option
+        InvocationResult result = invokeEnhancer("-help");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected Usage message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("javax.jdo.Enhancer"));
+    }
+
+    public void testHOption() {
+        // invoke enhancer with a usage option
+        InvocationResult result = invokeEnhancer("-h");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected Usage message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("javax.jdo.Enhancer"));
+    }
+
+    public void testInvalidOption() {
+        // invoke enhancer with an invalid option
+        InvocationResult result = invokeEnhancer("-poo");
+        assertEquals("Wrong return value ", ENHANCER_USAGE_ERROR, result.getExitValue());
+        String errorString = result.getErrorString();
+        assertTrue("Expected Usage message from err:\n" + errorString, errorString.contains("javax.jdo.Enhancer"));
+    }
+
+    public void testProperties() {
+        // invoke enhancer with verbose option
+        InvocationResult result = invokeEnhancer("-v");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected MockEnhancer vendor message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains(PROPERTY_ENHANCER_VENDOR_NAME));
+        assertTrue("Expected MockEnhancer version message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains(PROPERTY_ENHANCER_VERSION_NUMBER));
+        assertTrue("Expected MockEnhancer vendor message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("Mock Enhancer"));
+        assertTrue("Expected MockEnhancer vendor message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("2.3.0"));
+        assertTrue("Expected MockEnhancer properties message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("MockKey"));
+    }
+
+    public void testVOption() {
+        // invoke enhancer with verbose option
+        InvocationResult result = invokeEnhancer("-v");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected Enhancer class message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("javax.jdo.MockEnhancer"));
+    }
+
+    public void testVerboseOption() {
+        // invoke enhancer with verbose option
+        InvocationResult result = invokeEnhancer("-verbose");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected Enhancer class message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("javax.jdo.MockEnhancer"));
+    }
+
+    public void testVerboseClasses() {
+        // invoke enhancer with .class parameter
+        InvocationResult result = invokeEnhancer("-v some.class");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected class message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.class"));
+        assertTrue("Expected number of classes from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("1"));
+    }
+
+    public void testVerboseJars() {
+        // invoke enhancer with a .jar parameter
+        InvocationResult result = invokeEnhancer("-v some.jar");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected jar message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jar"));
+        assertTrue("Expected number of jars from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("1"));
+    }
+
+    public void testVerboseJDOs() {
+        // invoke enhancer with a .jdo parameter
+        InvocationResult result = invokeEnhancer("-v some.jdo");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected jdo message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jdo"));
+        assertTrue("Expected number of jdos from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("1"));
+    }
+
+    public void testVerboseAll() {
+        // invoke enhancer with multiple parameters
+        InvocationResult result = invokeEnhancer("-v some.class some.jar some.jdo");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected jdo message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jdo"));
+        assertTrue("Expected jar message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jar"));
+        assertTrue("Expected class message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.class"));
+        assertTrue("Expected number of elements from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("3"));
+    }
+
+    public void testVerboseCheckonlyAll() {
+        // invoke enhancer with a checkonly option
+        InvocationResult result = invokeEnhancer("-v -checkonly some.class some.jar some.jdo");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected jdo message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jdo"));
+        assertTrue("Expected jar message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.jar"));
+        assertTrue("Expected class message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some.class"));
+        assertTrue("Expected number of elements from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("3"));
+    }
+
+    public void testMissingPU() {
+        // invoke enhancer with missing parameter
+        InvocationResult result = invokeEnhancer("-v -pu");
+        assertEquals("Wrong return value ", 3, result.getExitValue());
+    }
+
+    public void testVerbosePU() {
+        // invoke enhancer with a pu parameter
+        InvocationResult result = invokeEnhancer("-v -pu myPU -pu yourPU");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected pu message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("myPU"));
+        assertTrue("Expected pu message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("yourPU"));
+        assertTrue("Expected number of elements from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("2"));
+    }
+
+    public void testClasspath() {
+        // invoke enhancer with a classpath parameter
+        // JDOHelper must be loadable from this path
+        // the File.toURI should append "/" to the path, so only "target/classes" is needed
+        InvocationResult result = invokeEnhancer("-v -cp " + basedir + "/target/classes");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected classpath message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("target/classes"));
+    }
+
+    public void testBadClasspath() {
+        // invoke enhancer with a bad classpath parameter
+        // JDOHelper is not loadable from this path
+        InvocationResult result = invokeEnhancer("-v -cp target");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 1, result.getExitValue());
+        assertTrue("Expected classpath error message from out:\n" + outputString + " with err:\n" + errorString, errorString.contains("JDOHelper"));
+    }
+
+    public void testClasspathJar() throws IOException, InterruptedException {
+        // invoke enhancer with a classpath parameter
+        // JDOHelper must be loadable from this path
+        // create the jar file from the target/classes directory
+        Process create = Runtime.getRuntime().exec("jar -cf " + basedir + "/target/enhancer-test.jar -C " + basedir + "/target/classes .");
+        int returnCode = create.waitFor();
+        assertEquals("jar command returned wrong return code.", 0, returnCode);
+        // find the jdo.jar in target
+        InvocationResult result = invokeEnhancer("-v -cp " + basedir + "/target/enhancer-test.jar");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected classpath message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("target/enhancer-test.jar"));
+        // remove the jar file if successful
+        Runtime.getRuntime().exec("rm target/enhancer-test.jar").waitFor();
+    }
+
+    public void testOutputDirectory() {
+        // invoke enhancer with an output directory parameter
+        InvocationResult result = invokeEnhancer("-v -d some/output/directory");
+        String outputString = result.getOutputString();
+        String errorString = result.getErrorString();
+        assertEquals("Wrong exit code from Enhancer with stderr:\n" + errorString, 0, result.getExitValue());
+        assertTrue("Expected directory message from out:\n" + outputString + " with err:\n" + errorString, outputString.contains("some/output/directory"));
+    }
+
+    public void testMissingOutputDirectory() {
+        // invoke enhancer with missing parameter
+        InvocationResult result = invokeEnhancer("-v -d");
+        assertEquals("Wrong return value ", 3, result.getExitValue());
+    }
+
+    private InvocationResult invokeEnhancer(String string) {
+        InvocationResult result = new InvocationResult();
+        try {
+            // create the java command to invoke the Enhancer
+            List<String> commands = new ArrayList<String>();
+            // find the java command in the user's path
+            commands.add("java");
+            commands.add("-cp");
+            commands.add("" + basedir + "/target/classes" + pathDelimiter + "" + basedir + "/target/test-classes");
+            commands.add("javax.jdo.Enhancer");
+            // add the test options (from the method parameter) to the java command
+            String[] optionArray = string.split(" ");
+            for (String option: optionArray) {
+                commands.add(option);
+            }
+            String[] cmdarray = commands.toArray(new String[commands.size()]);
+            ProcessBuilder builder = new ProcessBuilder(cmdarray);
+            Process proc = builder.start();
+            InputStream stdout = proc.getInputStream();
+            InputStream stderr = proc.getErrorStream();
+            CharBuffer outBuffer = CharBuffer.allocate(1000000);
+            CharBuffer errBuffer = CharBuffer.allocate(1000000);
+            Thread outputThread = createReaderThread(stdout, outBuffer);
+            Thread errorThread = createReaderThread(stderr, errBuffer);
+            int exitValue = proc.waitFor();
+            result.setExitValue(exitValue);
+            errorThread.join(10000); // wait ten seconds to get stderr after process terminates
+            outputThread.join(10000); // wait ten seconds to get stdout after process terminates
+            result.setErrorString(errBuffer.toString());
+            result.setOutputString(outBuffer.toString());
+            // wait until the Enhancer command finishes
+        } catch (InterruptedException ex) {
+            throw new RuntimeException("InterruptedException", ex);
+        } catch (IOException ex) {
+            throw new RuntimeException("IOException", ex);
+        } catch (JDOException jdoex) {
+            jdoex.printStackTrace();
+            Throwable[] throwables = jdoex.getNestedExceptions();
+            System.out.println("Exception throwables of size: " + throwables.length);
+            for (Throwable throwable: throwables) {
+                throwable.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+    private Thread createReaderThread(final InputStream input, final CharBuffer output) {
+        final Reader reader = new InputStreamReader(input);
+        Thread thread = new Thread(
+                new Runnable() {
+                    public void run() {
+                        int count = 0;
+                        int outputBytesRead = 0;
+                        try {
+                            while (-1 != (outputBytesRead = reader.read(output))) {
+                                count += outputBytesRead;
+                            }
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        } finally {
+                            output.flip();
+                        }
+                    }
+                });
+        thread.start();
+        return thread;
+    }
+
+    class InvocationResult {
+        private int exitValue;
+        private String errorString;
+        private String outputString;
+
+        int getExitValue() {
+            return exitValue;
+        }
+
+        private void setExitValue(int exitValue) {
+            this.exitValue = exitValue;
+        }
+
+        private void setErrorString(String errorString) {
+            this.errorString = errorString;
+        }
+
+        String getErrorString() {
+            return errorString;
+        }
+
+        private void setOutputString(String outputString) {
+            this.outputString = outputString;
+        }
+
+        String getOutputString() {
+            return outputString;
+        }
+
+    }
+
+}

Propchange: db/jdo/trunk/api2/test/java/javax/jdo/EnhancerTest.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java?rev=818642&view=auto
==============================================================================
--- db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java (added)
+++ db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java Thu Sep 24 22:26:27 2009
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package javax.jdo;
+
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VENDOR_NAME;
+import static javax.jdo.Constants.PROPERTY_ENHANCER_VERSION_NUMBER;
+
+import javax.jdo.metadata.JDOMetadata;
+
+
+/**
+ * Tests class javax.jdo.Enhancer (main class).
+ * <p>
+ */
+public class MockEnhancer implements JDOEnhancer {
+
+    static Properties props = new Properties();
+    static {
+        props.put(PROPERTY_ENHANCER_VENDOR_NAME, "Mock Enhancer");
+        props.put(PROPERTY_ENHANCER_VERSION_NUMBER, "2.3.0");
+        props.put("MockKey", "MockValue");
+    }
+    @SuppressWarnings("unused")
+    private boolean verbose;
+    private int numberOfElements;
+    private List<String> classNames = new ArrayList<String>();
+    private List<String> jarNames = new ArrayList<String>();
+    private List<String> jdoNames = new ArrayList<String>();
+    private List<String> puNames = new ArrayList<String>();
+    @SuppressWarnings("unused")
+    private String outputDirectory = null;
+
+    public MockEnhancer(){
+    }
+
+    public Properties getProperties() {
+        return props;
+    }
+
+    public JDOEnhancer setVerbose(boolean flag) {
+        this.verbose = flag;
+        return this;
+    }
+
+    public JDOEnhancer setOutputDirectory(String dirName) {
+        outputDirectory = dirName;
+        return this;
+    }
+
+    public JDOEnhancer setClassLoader(ClassLoader loader) {
+        // check to see if JDOHelper is loadable from the loader
+        try {
+        loader.loadClass("javax.jdo.JDOHelper");
+        } catch (ClassNotFoundException ex) {
+            // bad
+            throw new JDOFatalInternalException("Should be able to load JDOHelper from the class loader");
+        }
+        return this;
+    }
+
+    public JDOEnhancer addPersistenceUnit(String persistenceUnit) {
+        numberOfElements++;
+        this.puNames.add(persistenceUnit);
+        return this;
+    }
+
+    public JDOEnhancer addClass(String className, byte[] bytes) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public JDOEnhancer addClasses(String... classNames) {
+        numberOfElements += classNames.length;
+        this.classNames.addAll(Arrays.asList(classNames));
+        return this;
+    }
+
+    public JDOEnhancer addFiles(String... metadataFiles) {
+        numberOfElements += metadataFiles.length;
+        this.jdoNames.addAll(Arrays.asList(metadataFiles));
+        return this;
+    }
+
+    public JDOEnhancer addJar(String jarFileName) {
+        numberOfElements++;
+        this.jarNames.add(jarFileName);
+        return this;
+    }
+
+    public int enhance() {
+        return numberOfElements;
+    }
+
+    public int validate() {
+        return numberOfElements;
+    }
+
+    public byte[] getEnhancedBytes(String className) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void registerMetadata(JDOMetadata metadata) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public JDOMetadata newMetadata() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
+

Propchange: db/jdo/trunk/api2/test/java/javax/jdo/MockEnhancer.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: db/jdo/trunk/api2/test/resources/META-INF/services/javax.jdo.JDOEnhancer
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api2/test/resources/META-INF/services/javax.jdo.JDOEnhancer?rev=818642&view=auto
==============================================================================
--- db/jdo/trunk/api2/test/resources/META-INF/services/javax.jdo.JDOEnhancer (added)
+++ db/jdo/trunk/api2/test/resources/META-INF/services/javax.jdo.JDOEnhancer Thu Sep 24 22:26:27 2009
@@ -0,0 +1 @@
+javax.jdo.MockEnhancer



Mime
View raw message