You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2005/05/22 19:55:54 UTC
svn commit: r171351 [3/16] - in /incubator/jdo/trunk/enhancer20: ./ src/
src/conf/ src/java/ src/java/org/ src/java/org/apache/
src/java/org/apache/jdo/ src/java/org/apache/jdo/enhancer/
src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/
src/java/org/apache/jdo/impl/enhancer/classfile/
src/java/org/apache/jdo/impl/enhancer/core/
src/java/org/apache/jdo/impl/enhancer/generator/
src/java/org/apache/jdo/impl/enhancer/meta/
src/java/org/apache/jdo/impl/enhancer/meta/model/
src/java/org/apache/jdo/impl/enhancer/meta/prop/
src/java/org/apache/jdo/impl/enhancer/meta/util/
src/java/org/apache/jdo/impl/enhancer/util/ test/ test/sempdept/
test/sempdept/src/ test/sempdept/src/empdept/
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OptionSet.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OptionSet.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OptionSet.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OptionSet.java Sun May 22 10:55:51 2005
@@ -0,0 +1,715 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer;
+
+import java.io.PrintWriter;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Properties;
+
+
+/**
+ * Represents a set of options a program may support.
+ *
+ * @author Martin Zaun
+ */
+public class OptionSet
+ extends LogSupport
+{
+ // return values of parse/check methods
+ static public final int OK = 0;
+ static public final int USAGE_ERROR = -1;
+
+ // command-line option prefixes
+ static public final String prefix = "-";
+ static public final String lprefix = "--";
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * The base class of all option types.
+ */
+ static public abstract class Option
+ {
+ /**
+ * The set the option is registered with.
+ */
+ protected OptionSet set;
+
+ /**
+ * The long form name of this option.
+ */
+ public final String name;
+
+ /**
+ * The short form name of this option.
+ */
+ public final String abbrev;
+
+ /**
+ * A description of this option.
+ */
+ public final String descr;
+
+ /**
+ * Creates an instance.
+ */
+ public Option(String name,
+ String abbrev,
+ String descr)
+ {
+ affirm(name != null);
+ this.name = name;
+ this.abbrev = abbrev;
+ this.descr = descr;
+ }
+
+ /**
+ * Parse this option for arguments it may require.
+ */
+ abstract public int parse(Iterator i);
+
+ /**
+ * Returns a <code>String</code> representation of this option's
+ * value for printing.
+ */
+ abstract public String asNameValue();
+
+ /**
+ * Returns a usage description of this option.
+ */
+ public String asUsageHelp()
+ {
+ String abbr = (abbrev == null ? " " : prefix + abbrev + "|");
+ return (abbr + lprefix + name + " " + descr);
+ }
+ }
+
+ /**
+ * An option that always causes a USAGE_ERROR when parsed (used for
+ * '-h|--help' kind of options).
+ */
+ static public class HelpOption extends Option
+ {
+ /**
+ * Creates an instance.
+ */
+ public HelpOption(String name,
+ String abbrev,
+ String descr)
+ {
+ super(name, abbrev, descr);
+ }
+
+ public int parse(Iterator i)
+ {
+ return USAGE_ERROR;
+ }
+
+ public String asNameValue()
+ {
+ return ("help = false");
+ }
+ }
+
+ /**
+ * An option representing a boolean flag.
+ */
+ static public class FlagOption extends Option
+ {
+ /**
+ * The default value for this option.
+ */
+ public final boolean deflt;
+
+ /**
+ * The value of this option.
+ */
+ public boolean value;
+
+ /**
+ * Creates an instance.
+ */
+ public FlagOption(String name,
+ String abbrev,
+ String descr)
+ {
+ this(name, abbrev, descr, false);
+ }
+
+ /**
+ * Creates an instance.
+ */
+ public FlagOption(String name,
+ String abbrev,
+ String descr,
+ boolean deflt)
+ {
+ super(name, abbrev, descr);
+ this.deflt = deflt;
+ this.value = deflt;
+ }
+
+ public int parse(Iterator i)
+ {
+ if (value != deflt) {
+ set.printUsageError("Repeated option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ value = true;
+ return OK;
+ }
+
+ public String asNameValue()
+ {
+ return (name + " = " + String.valueOf(value));
+ }
+ }
+
+ /**
+ * An option representing a <code>int</code> value.
+ */
+ static public class IntOption extends Option
+ {
+ /**
+ * The default value for this option.
+ */
+ public final int deflt;
+
+ /**
+ * The value of this option.
+ */
+ public int value;
+
+ /**
+ * Creates an instance.
+ */
+ public IntOption(String name,
+ String abbrev,
+ String descr)
+ {
+ this(name, abbrev, descr, 0);
+ }
+
+ /**
+ * Creates an instance.
+ */
+ public IntOption(String name,
+ String abbrev,
+ String descr,
+ int deflt)
+ {
+ super(name, abbrev, descr);
+ this.deflt = deflt;
+ this.value = deflt;
+ }
+
+ public int parse(Iterator i)
+ {
+ if (value != deflt) {
+ set.printUsageError("Repeated option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ if (!i.hasNext()) {
+ set.printUsageError("Missing argument to option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ try {
+ value = Integer.valueOf((String)i.next()).intValue();
+ } catch (NumberFormatException ex) {
+ set.printUsageError("Illegal argument to option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ return OK;
+ }
+
+ public String asNameValue()
+ {
+ return (name + " = " + String.valueOf(value));
+ }
+ }
+
+ /**
+ * An option representing a <code>String</code> value.
+ */
+ static public class StringOption extends Option
+ {
+ /**
+ * The default value for this option.
+ */
+ public final String deflt;
+
+ /**
+ * The value of this option.
+ */
+ public String value;
+
+ /**
+ * Creates an instance.
+ */
+ public StringOption(String name,
+ String abbrev,
+ String descr)
+ {
+ this(name, abbrev, descr, null);
+ }
+
+ /**
+ * Creates an instance.
+ */
+ public StringOption(String name,
+ String abbrev,
+ String descr,
+ String deflt)
+ {
+ super(name, abbrev, descr);
+ this.deflt = deflt;
+ this.value = deflt;
+ }
+
+ public int parse(Iterator i)
+ {
+ if (value != deflt) {
+ set.printUsageError("Repeated option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ if (!i.hasNext()) {
+ set.printUsageError("Missing argument to option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ value = (String)i.next();
+ if (value.startsWith(prefix)) {
+ set.printUsageError("Missing argument to option: "
+ + prefix + abbrev + "/" + lprefix + name);
+ return USAGE_ERROR;
+ }
+ return OK;
+ }
+
+ public String asNameValue()
+ {
+ return (name + " = " + String.valueOf(value));
+ }
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * The list of registered options.
+ */
+ protected final List options = new ArrayList();
+
+ /**
+ * Maps the option's long form against option instances.
+ */
+ protected final Map names = new HashMap();
+
+ /**
+ * Maps the option's short form against option instances.
+ */
+ protected final Map abbrevs = new HashMap();
+
+ /**
+ * The collected arguments.
+ */
+ protected final List arguments = new ArrayList();
+
+ /**
+ * Usage printout.
+ */
+ public String usageHeader
+ = "Usage: <options>.. <arguments>..";
+
+ /**
+ * Usage printout.
+ */
+ public String optionsHeader
+ = "Options:";
+
+ /**
+ * Usage printout.
+ */
+ public String argumentsHeader
+ = "Arguments:";
+
+ /**
+ * Usage printout.
+ */
+ public String returnHeader
+ = "Returns: A non-zero value in case of errors.";
+
+ /**
+ * Usage printout.
+ */
+ public String indent
+ = " ";
+
+ /**
+ * Creates an instance.
+ */
+ public OptionSet(PrintWriter out,
+ PrintWriter err)
+ {
+ super(out, err);
+ }
+
+ /**
+ * Creates an instance.
+ */
+ public OptionSet(PrintWriter out,
+ PrintWriter err,
+ String usageHeader,
+ String optionsHeader,
+ String argumentsHeader,
+ String returnHeader,
+ String indent)
+ {
+ this(out, err);
+ this.usageHeader = usageHeader;
+ this.optionsHeader = optionsHeader;
+ this.argumentsHeader = argumentsHeader;
+ this.returnHeader = returnHeader;
+ this.indent = indent;
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Registers an option with the set.
+ */
+ public void register(Option option)
+ {
+ affirm(option != null);
+ option.set = this;
+ options.add(option);
+
+ affirm(option.name != null);
+ Object obj = names.put(lprefix + option.name, option);
+ affirm(obj == null, "Option already registered: " + option.name);
+
+ if (option.abbrev != null) {
+ obj = abbrevs.put(prefix + option.abbrev, option);
+ affirm(obj == null, "Option already registered: " + option.name);
+ }
+ }
+
+ /**
+ * Creates and registers an option representing a usage-help request.
+ */
+ public HelpOption createHelpOption(String name,
+ String abbrev,
+ String descr)
+ {
+ final HelpOption opt = new HelpOption(name, abbrev, descr);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a boolean flag.
+ */
+ public FlagOption createFlagOption(String name,
+ String abbrev,
+ String descr)
+ {
+ final FlagOption opt = new FlagOption(name, abbrev, descr);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a boolean flag.
+ */
+ public FlagOption createFlagOption(String name,
+ String abbrev,
+ String descr,
+ boolean deflt)
+ {
+ final FlagOption opt = new FlagOption(name, abbrev, descr, deflt);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a <code>int</code>
+ * value.
+ */
+ public IntOption createIntOption(String name,
+ String abbrev,
+ String descr)
+ {
+ final IntOption opt = new IntOption(name, abbrev, descr);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a <code>int</code>
+ * value.
+ */
+ public IntOption createIntOption(String name,
+ String abbrev,
+ String descr,
+ int deflt)
+ {
+ final IntOption opt = new IntOption(name, abbrev, descr, deflt);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a <code>String</code>
+ * value.
+ */
+ public StringOption createStringOption(String name,
+ String abbrev,
+ String descr)
+ {
+ final StringOption opt = new StringOption(name, abbrev, descr);
+ register(opt);
+ return opt;
+ }
+
+ /**
+ * Creates and registers an option representing a <code>String</code>
+ * value.
+ */
+ public StringOption createStringOption(String name,
+ String abbrev,
+ String descr,
+ String deflt)
+ {
+ final StringOption opt
+ = new StringOption(name, abbrev, descr, deflt);
+ register(opt);
+ return opt;
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Parses options and arguments.
+ */
+ public int parse(String[] argv)
+ {
+ affirm(argv != null);
+ for (Iterator i = Arrays.asList(argv).iterator(); i.hasNext();) {
+ final String arg = (String)i.next();
+
+ // ignore empty arguments
+ if (arg == null || arg.length() == 0) {
+ //println("Ignoring empty command line argument.");
+ continue;
+ }
+
+ // collect as argument if not option
+ if (!arg.startsWith(prefix)) {
+ arguments.add(arg);
+ continue;
+ }
+
+ // lookup option by short and long form
+ Option option = (Option)abbrevs.get(arg);
+ if (option == null) {
+ option = (Option)names.get(arg);
+ }
+
+ // return if option still not recognized
+ if (option == null) {
+ printlnErr("Unrecognized option: " + arg);
+ return USAGE_ERROR;
+ }
+
+ // parse option for arguments
+ int res = option.parse(i);
+ if (res != OK) {
+ return res;
+ }
+ }
+ return OK;
+ }
+
+ /**
+ * Checks options and arguments.
+ */
+ public int check()
+ {
+ return OK;
+ }
+
+ /**
+ * Parse and check options and arguments.
+ */
+ public int process(String[] args)
+ {
+ int res = OK;
+ if ((res = parse(args)) != OK) {
+ printUsage();
+ return res;
+ }
+ if ((res = check()) != OK) {
+ printUsage();
+ return res;
+ }
+ return res;
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Print a usage error message to System.err.
+ */
+ public void printUsageError(String msg)
+ {
+ printlnErr("USAGE ERROR: " + msg);
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printUsage()
+ {
+ println();
+ printUsageHeader();
+ printOptionHeader();
+ printOptionUsage();
+ printArgumentHeader();
+ printArgumentUsage();
+ printReturnHeader();
+ printReturnUsage();
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printUsageHeader()
+ {
+ printlnErr(usageHeader);
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printOptionHeader()
+ {
+ printlnErr();
+ printlnErr(optionsHeader);
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printOptionUsage()
+ {
+ for (Iterator i = options.iterator(); i.hasNext();) {
+ printlnErr(indent + ((Option)i.next()).asUsageHelp());
+ }
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printArgumentHeader()
+ {
+ printlnErr();
+ printlnErr(argumentsHeader);
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printArgumentUsage()
+ {}
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printReturnHeader()
+ {
+ printlnErr();
+ printlnErr(returnHeader);
+ }
+
+ /**
+ * Print a usage message to System.err.
+ */
+ public void printReturnUsage()
+ {}
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Print options and arguments.
+ */
+ public void printAll()
+ {
+ printOptions();
+ printArguments();
+ }
+
+ /**
+ * Print options.
+ */
+ public void printOptions()
+ {
+ println();
+ println(optionsHeader);
+ for (Iterator i = options.iterator(); i.hasNext();) {
+ println(indent + ((Option)i.next()).asNameValue());
+ }
+ }
+
+ /**
+ * Print arguments.
+ */
+ public void printArguments()
+ {
+ println();
+ println(argumentsHeader);
+ print(indent);
+ for (Iterator i = arguments.iterator(); i.hasNext();) {
+ print(" " + i.next());
+ }
+ }
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Tests the class.
+ */
+ static public void main(String[] args)
+ {
+ final PrintWriter out = new PrintWriter(System.out, true);
+ out.println("--> OptionSet.main()");
+ final OptionSet options = new OptionSet(out, out);
+ out.println(" options.process() ...");
+ int res = options.process(args);
+ out.println(" return value: " + res);
+ out.println("<-- OptionSet.main()");
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OutputStreamWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OutputStreamWrapper.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OutputStreamWrapper.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/OutputStreamWrapper.java Sun May 22 10:55:51 2005
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer;
+
+import java.io.OutputStream;
+
+/**
+ * This class serves as a wrapper for an output stream of a class file. The
+ * stream is passed as a parameter to the byte code enhancer, that can
+ * sets the classname of the written Java class to the wrapper.
+ * <br>
+ * This wrapper is necessary to determine the classname outside the enhancer,
+ * after the class has been enhanced, since do do not always know the
+ * classname of an opened input stream.
+ *
+ */
+public class OutputStreamWrapper
+{
+ /**
+ * The wrapped output stream.
+ */
+ private OutputStream out;
+
+ /**
+ * The classname of the written Java class. This parameter
+ * is set by the enhancer.
+ */
+ private String className = null;
+
+ /**
+ * Constructs a new object.
+ *
+ * @param out The output stream to wrap.
+ */
+ public OutputStreamWrapper(OutputStream out)
+ {
+ this.out = out;
+ }
+
+ /**
+ * Gets the wrapped output stream.
+ *
+ * @return The wrapped output stream.
+ */
+ public final OutputStream getStream()
+ {
+ return out;
+ }
+
+ /**
+ * Gets the classname of the written Java class. This method should be
+ * called after the class has been enhanced.
+ *
+ * @return The name of the written Java class.
+ */
+ public final String getClassName()
+ {
+ return className;
+ }
+
+ /**
+ * Sets the name of the written Java class. This method should be called
+ * by the enhancer.
+ *
+ * @param classname The name of the Java class.
+ */
+ public final void setClassName(String classname)
+ {
+ this.className = classname;
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/PersistenceLauncher.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/PersistenceLauncher.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/PersistenceLauncher.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/PersistenceLauncher.java Sun May 22 10:55:51 2005
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer;
+
+import java.util.Properties;
+
+import java.io.PrintWriter;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.jdo.impl.enhancer.util.Support;
+
+
+
+/**
+ * Application launcher for persistence-capable classes.
+ *
+ * @author Martin Zaun
+ */
+public class PersistenceLauncher {
+
+ // chose whether to separate or join out and err channels
+ //static private final PrintWriter err = new PrintWriter(System.err, true);
+ static private final PrintWriter err = new PrintWriter(System.out, true);
+ static private final PrintWriter out = new PrintWriter(System.out, true);
+ static private final String prefix = "PersistenceLauncher.main() : ";
+
+ /**
+ * Creates new PersistenceLauncher.
+ */
+ private PersistenceLauncher() {
+ }
+
+ /**
+ * Prints usage message.
+ */
+ static void usage()
+ {
+ out.flush();
+ err.println("PersistenceLauncher:");
+ err.println(" usage: <options> ... <target class name> <args> ...");
+ err.println(" options:");
+ err.println(" -h | --help");
+ err.println(" -n | --noEnhancement");
+ err.println(" -q | --quiet");
+ err.println(" -w | --warn");
+ err.println(" -d | --debug");
+ err.println(" -t | --timing");
+ err.println(" class names have to be fully qualified");
+ err.println("done.");
+ err.println();
+ err.flush();
+ }
+
+ /**
+ * Creates a class loader and launches a target class.
+ * @param args the command line arguments
+ */
+ public static void main(String[] args)
+ throws ClassNotFoundException,
+ NoSuchMethodException,
+ SecurityException,
+ IllegalAccessException,
+ IllegalArgumentException,
+ InvocationTargetException {
+/*
+ message("property PersistenceExecutor.TAG_REPOSITORY = "
+ + System.getProperty("PersistenceExecutor.TAG_REPOSITORY"));
+ message("property PersistenceExecutor.TAG_CLASSPATH = "
+ + System.getProperty("PersistenceExecutor.TAG_CLASSPATH"));
+ message("property PersistenceExecutor.TAG_LIBRARY = "
+ + System.getProperty("PersistenceExecutor.TAG_LIBRARY"));
+ message("property PersistenceExecutor.TAG_CLASSNAME = "
+ + System.getProperty("PersistenceExecutor.TAG_CLASSNAME"));
+*/
+
+ // get launcher options
+ final String classpath = System.getProperty("java.class.path");
+ boolean noEnhancement = false;
+ boolean debug = false;
+ boolean timing = false;
+ Properties enhancerSettings = new Properties();
+ String targetClassname = null;
+ String[] targetClassArgs = null;
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if (arg.equals("-h")
+ || arg.equals("--help")) {
+ usage();
+
+ // exit gently
+ return;
+ }
+ if (arg.equals("-n")
+ || arg.equals("--noEnhancement")) {
+ noEnhancement = false;
+ continue;
+ }
+ if (arg.equals("-t")
+ || arg.equals("--timing")) {
+ timing = true;
+ enhancerSettings.setProperty(EnhancerClassLoader.DO_TIMING_STATISTICS,
+ "true");
+ continue;
+ }
+ if (arg.equals("-d")
+ || arg.equals("--debug")) {
+ debug = true;
+ enhancerSettings.setProperty(EnhancerClassLoader.VERBOSE_LEVEL,
+ EnhancerClassLoader.VERBOSE_LEVEL_DEBUG);
+ continue;
+ }
+ if (arg.equals("-w")
+ || arg.equals("--warn")) {
+ debug = false;
+ enhancerSettings.setProperty(EnhancerClassLoader.VERBOSE_LEVEL,
+ EnhancerClassLoader.VERBOSE_LEVEL_WARN);
+ continue;
+ }
+ if (arg.equals("-q")
+ || arg.equals("--quiet")) {
+ debug = false;
+ enhancerSettings.setProperty(EnhancerClassLoader.VERBOSE_LEVEL,
+ EnhancerClassLoader.VERBOSE_LEVEL_QUIET);
+ continue;
+ }
+
+ // get target class name
+ targetClassname = arg;
+
+ // copy remaining arguments and leave loop
+ i++;
+ final int length = args.length - i;
+ targetClassArgs = new String[length];
+ System.arraycopy(args, i, targetClassArgs, 0, length);
+ break;
+ }
+
+ // debugging oputput
+ if (debug) {
+ out.println(prefix + "...");
+ out.println("settings and arguments:");
+ out.println(" classpath = " + classpath);
+ out.println(" noEnhancement = " + noEnhancement);
+ out.println(" debug = " + debug);
+ out.println(" enhancerSettings = {");
+ enhancerSettings.list(out);
+ out.println(" }");
+ out.println(" targetClassname = " + targetClassname);
+ out.print(" targetClassArgs = { ");
+ for (int i = 0; i < targetClassArgs.length; i++) {
+ out.print(targetClassArgs[i] + " ");
+ }
+ out.println("}");
+ }
+
+ // check options
+ if (targetClassname == null) {
+ usage();
+ throw new IllegalArgumentException("targetClassname == null");
+ }
+
+ // get class loader
+ final ClassLoader loader;
+ if (noEnhancement) {
+ if (debug) {
+ out.println(prefix + "using system class loader");
+ }
+ //out.println("using system class loader");
+ loader = PersistenceLauncher.class.getClassLoader();
+ } else {
+ if (debug) {
+ out.println(prefix + "creating enhancer class loader");
+ }
+ final Properties settings = enhancerSettings;
+ final PrintWriter out = PersistenceLauncher.out;
+ loader = new EnhancerClassLoader(classpath, settings, out);
+ }
+
+ // get target class' main method
+ Class clazz;
+ Method main;
+ try {
+ final String mname = "main";
+ final Class[] mparams = new Class[]{ String[].class };
+ final boolean init = true;
+ if (debug) {
+ out.println(prefix + "getting method "
+ + targetClassname + "." + mname + "(String[])");
+ }
+ clazz = Class.forName(targetClassname, init, loader);
+ main = clazz.getDeclaredMethod(mname, mparams);
+ } catch (ClassNotFoundException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ } catch (NoSuchMethodException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ } catch (SecurityException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ }
+
+ // invoke target class' main method
+ try {
+ final Object[] margs = new Object[]{ targetClassArgs };
+ if (debug) {
+ out.println("invoking method " + clazz.getName()
+ + "." + main.getName() + "(String[])");
+ }
+ main.invoke(null, margs);
+ } catch (IllegalAccessException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ } catch (IllegalArgumentException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ } catch (InvocationTargetException e) {
+ // log exception only
+ if (debug) {
+ out.flush();
+ err.println("PersistenceLauncher: EXCEPTION SEEN: " + e);
+ e.printStackTrace(err);
+ err.flush();
+ }
+ throw e;
+ } finally {
+ if (timing) {
+ Support.timer.print();
+ }
+ }
+
+ if (debug) {
+ out.println(prefix + "done.");
+ out.flush();
+ err.flush();
+ }
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedClassAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedClassAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedClassAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedClassAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+
+/**
+ * AnnotatedClassAttribute represents a class level attribute
+ * class file which identifies the level of annotation of the class.
+ */
+public class AnnotatedClassAttribute extends ClassAttribute {
+
+ /* The expected attribute name */
+ public final static String expectedAttrName = "filter.annotatedClass";
+
+ /* The expected attribute version */
+ public final static short expectedAttrVersion = 1;
+
+ /* Bit mask indicating that the class was filter generated */
+ public final static short generatedFlag = 0x1;
+
+ /* Bit mask indicating that the class was filter annotated */
+ public final static short annotatedFlag = 0x2;
+
+ /* Bit mask indicating that the class was "repackaged" or similarly
+ * modified */
+ public final static short modifiedFlag = 0x4;
+
+ /* The version of the attribute */
+ private short attrVersion;
+
+ /* Flags associated with the annotation */
+ private short annotationFlags;
+
+ /* The modification date of the class file at the time of modification */
+ private long classModTime;
+
+ /* The date of the annotation */
+ private long classAnnotationTime;
+
+ /* public accessors */
+
+ public short getVersion() {
+ return attrVersion;
+ }
+
+ public void setVersion(short version) {
+ attrVersion = version;
+ }
+
+ public short getFlags() {
+ return annotationFlags;
+ }
+
+ public void setFlags(short flags) {
+ annotationFlags = flags;
+ }
+
+ public long getModTime() {
+ return classModTime;
+ }
+
+ public void setModTime(long time) {
+ classModTime = time;
+ }
+
+ public long getAnnotationTime() {
+ return classAnnotationTime;
+ }
+
+ public void setAnnotationTime(long time) {
+ classAnnotationTime = time;
+ }
+
+ /**
+ * Constructor
+ */
+ public AnnotatedClassAttribute(
+ ConstUtf8 nameAttr, short version, short annFlags,
+ long modTime, long annTime) {
+ super(nameAttr);
+ attrVersion = version;
+ annotationFlags = annFlags;
+ classModTime = modTime;
+ classAnnotationTime = annTime;
+ }
+
+ /* package local methods */
+
+ static AnnotatedClassAttribute read(
+ ConstUtf8 attrName, DataInputStream data, ConstantPool pool)
+ throws IOException {
+ short version = data.readShort();
+ short annFlags = data.readShort();
+ long modTime = data.readLong();
+ long annTime = data.readLong();
+ return new AnnotatedClassAttribute(attrName, version, annFlags,
+ modTime, annTime);
+ }
+
+ void write(DataOutputStream out) throws IOException {
+ out.writeShort(attrName().getIndex());
+ out.writeShort(20);
+ out.writeShort(attrVersion);
+ out.writeShort(annotationFlags);
+ out.writeLong(classModTime);
+ out.writeLong(classAnnotationTime);
+ }
+
+ void print(PrintStream out, int indent) {
+ ClassPrint.spaces(out, indent);
+ out.println("version: " + attrVersion);
+ out.println(" flags: " + annotationFlags);
+ out.println(" modTime: " + classModTime);
+ out.println(" annTime: " + classAnnotationTime);
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedMethodAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedMethodAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedMethodAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AnnotatedMethodAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+
+/**
+ * AnnotatedMethodAttribute represents a class level attribute
+ * class file which identifies the level of annotation of the class.
+ */
+public class AnnotatedMethodAttribute extends ClassAttribute {
+
+ /* The expected attribute name */
+ public final static String expectedAttrName = "filter.annotatedMethod";
+
+ /* The expected attribute version */
+ public final static short expectedAttrVersion = 1;
+
+ /* Bit mask indicating that the class was filter generated */
+ public final static short generatedFlag = 0x1;
+
+ /* Bit mask indicating that the class was filter annotated */
+ public final static short annotatedFlag = 0x2;
+
+ /* Bit mask indicating that the class was "repackaged" */
+ public final static short modifiedFlag = 0x4;
+
+ /* The version of the attribute */
+ private short attrVersion;
+
+ /* Flags associated with the annotation */
+ private short annotationFlags;
+
+ /* list of targets in the code sequence delimiting inserted instruction
+ * sequences. Even index targets are a range start (inclusive) and odd
+ * targets represent a range end (exclusive) */
+ private InsnTarget annotationRanges[];
+
+ /* public accessors */
+
+ public short getVersion() {
+ return attrVersion;
+ }
+
+ public void setVersion(short version) {
+ attrVersion = version;
+ }
+
+ public short getFlags() {
+ return annotationFlags;
+ }
+
+ public void setFlags(short flags) {
+ annotationFlags = flags;
+ }
+
+ public InsnTarget[] getAnnotationRanges() {
+ return annotationRanges;
+ }
+
+ public void setAnnotationRanges(InsnTarget[] ranges) {
+ annotationRanges = ranges;
+ }
+
+ /**
+ * Constructor
+ */
+ public AnnotatedMethodAttribute(
+ ConstUtf8 nameAttr, short version, short annFlags,
+ InsnTarget[] annRanges) {
+ super(nameAttr);
+ attrVersion = version;
+ annotationFlags = annFlags;
+ annotationRanges = annRanges;
+ }
+
+ /* package local methods */
+
+ static AnnotatedMethodAttribute read(
+ ConstUtf8 attrName, DataInputStream data, CodeEnv env)
+ throws IOException {
+ short version = data.readShort();
+ short annFlags = data.readShort();
+
+ short nRanges = data.readShort();
+
+ InsnTarget ranges[] = new InsnTarget[nRanges*2];
+ for (int i=0; i<nRanges; i++) {
+ ranges[i*2] = env.getTarget(data.readShort());
+ ranges[i*2+1] = env.getTarget(data.readShort());
+ }
+ return new AnnotatedMethodAttribute(attrName, version, annFlags, ranges);
+ }
+
+ void write(DataOutputStream out) throws IOException {
+ out.writeShort(attrName().getIndex());
+ if (annotationRanges == null)
+ out.writeShort(2);
+ else
+ out.writeShort(4 + 2 * annotationRanges.length);
+ out.writeShort(attrVersion);
+ out.writeShort(annotationFlags);
+ if (annotationRanges == null)
+ out.writeShort(0);
+ else {
+ out.writeShort(annotationRanges.length / 2);
+ for (int i=0; i<annotationRanges.length; i++)
+ out.writeShort(annotationRanges[i].offset());
+ }
+ }
+
+ void print(PrintStream out, int indent) {
+ ClassPrint.spaces(out, indent);
+ out.println("version: " + attrVersion);
+ out.println(" flags: " + annotationFlags);
+ if (annotationRanges != null) {
+ out.println("Annotations: ");
+ for (int i=0; i<annotationRanges.length/2; i++) {
+ ClassPrint.spaces(out, indent+2);
+ out.println(annotationRanges[i*2] + " to " +
+ annotationRanges[i*2+1]);
+ }
+ }
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AttributeVector.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AttributeVector.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AttributeVector.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/AttributeVector.java Sun May 22 10:55:51 2005
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+import java.util.Vector;
+import java.util.Stack;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * A list of attributes within a class file.
+ * These lists occur in several places within a class file
+ * - at class level
+ * - at method level
+ * - at field level
+ * - at attribute level
+ */
+public class AttributeVector {
+
+ /* Vector of ClassAttribute */
+ private ClassAttribute attributes[] = null;
+
+ /**
+ * Returns the i'th attribute in the array
+ */
+ private ClassAttribute attrAt(int i) {
+ return attributes[i];
+ }
+
+ /**
+ * Construct an empty AttributeVector
+ */
+ public AttributeVector() { }
+
+ /**
+ * Add an element to the vector
+ */
+ public void addElement(ClassAttribute attr) {
+ if (attributes == null)
+ attributes = new ClassAttribute[1];
+ else {
+ ClassAttribute newAttributes[] = new ClassAttribute[attributes.length+1];
+ System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
+ attributes = newAttributes;
+ }
+ attributes[attributes.length-1] = attr;
+ }
+
+ public Enumeration elements() {
+ class AttributeVectorEnumeration implements Enumeration {
+ private ClassAttribute[] attributes;
+ private int current = 0;
+
+ AttributeVectorEnumeration(ClassAttribute attrs[]) {
+ attributes = attrs;
+ }
+
+ public boolean hasMoreElements() {
+ return attributes != null && current < attributes.length;
+ }
+ public Object nextElement() {
+ if (!hasMoreElements())
+ throw new NoSuchElementException();
+ return attributes[current++];
+ }
+ }
+
+ return new AttributeVectorEnumeration(attributes);
+ }
+
+ /**
+ * Look for an attribute of a specific name
+ */
+ public ClassAttribute findAttribute(String attrName) {
+ Enumeration e = elements();
+ while (e.hasMoreElements()) {
+ ClassAttribute attr = (ClassAttribute) e.nextElement();
+ if (attr.attrName().asString().equals(attrName))
+ return attr;
+ }
+ return null;
+ }
+
+ /**
+ * Compares this instance with another for structural equality.
+ */
+ //@olsen: added method
+ public boolean isEqual(Stack msg, Object obj) {
+ if (!(obj instanceof AttributeVector)) {
+ msg.push("obj/obj.getClass() = "
+ + (obj == null ? null : obj.getClass()));
+ msg.push("this.getClass() = "
+ + this.getClass());
+ return false;
+ }
+ AttributeVector other = (AttributeVector)obj;
+
+ if (this.attributes.length != other.attributes.length) {
+ msg.push("attributes.length "
+ + String.valueOf(other.attributes.length));
+ msg.push("attributes.length "
+ + String.valueOf(this.attributes.length));
+ return false;
+ }
+
+ // sort attributes by name
+ class ClassAttributeComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ ClassAttribute a1 = (ClassAttribute)o1;
+ ClassAttribute a2 = (ClassAttribute)o2;
+ String s1 = a1.attrName().asString();
+ String s2 = a2.attrName().asString();
+ return s1.compareTo(s2);
+ }
+ }
+ ClassAttributeComparator comparator = new ClassAttributeComparator();
+ ClassAttribute[] thisAttributes
+ = (ClassAttribute[])this.attributes.clone();
+ ClassAttribute[] otherAttributes
+ = (ClassAttribute[])other.attributes.clone();
+ Arrays.sort(thisAttributes, comparator);
+ Arrays.sort(otherAttributes, comparator);
+ for (int i = 0; i < attributes.length; i++) {
+ ClassAttribute a1 = thisAttributes[i];
+ ClassAttribute a2 = otherAttributes[i];
+ if (!a1.isEqual(msg, a2)) {
+ msg.push("attributes[i] = " + String.valueOf(a2));
+ msg.push("attributes[i] = " + String.valueOf(a1));
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * General attribute reader
+ */
+ static AttributeVector readAttributes(
+ DataInputStream data, ConstantPool constantPool)
+ throws IOException {
+ AttributeVector attribs = new AttributeVector();
+ int n_attrs = data.readUnsignedShort();
+ while (n_attrs-- > 0) {
+ attribs.addElement(ClassAttribute.read(data, constantPool));
+ }
+ return attribs;
+ }
+
+ /**
+ * ClassMethod attribute reader
+ */
+ static AttributeVector readAttributes(
+ DataInputStream data, CodeEnv codeEnv)
+ throws IOException {
+ AttributeVector attribs = new AttributeVector();
+ int n_attrs = data.readUnsignedShort();
+ while (n_attrs-- > 0) {
+ attribs.addElement(ClassAttribute.read(data, codeEnv));
+ }
+ return attribs;
+ }
+
+ /**
+ * Write the attributes to the output stream
+ */
+ void write(DataOutputStream out) throws IOException {
+ if (attributes == null) {
+ out.writeShort(0);
+ } else {
+ out.writeShort(attributes.length);
+ for (int i=0; i<attributes.length; i++)
+ attributes[i].write(out);
+ }
+ }
+
+ /**
+ * Print a description of the attributes
+ */
+ void print(PrintStream out, int indent) {
+ if (attributes != null) {
+ for (int i=0; i<attributes.length; i++)
+ attributes[i].print(out, indent);
+ }
+ }
+
+ /**
+ * Print a brief summary of the attributes
+ */
+ //@olsen: added 'out' and 'indent' parameters
+ void summarize(PrintStream out, int indent) {
+ ClassPrint.spaces(out, indent);
+ out.println((attributes == null ? 0 : attributes.length) +
+ " attributes");
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassAttribute.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassAttribute.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassAttribute.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassAttribute.java Sun May 22 10:55:51 2005
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.util.Stack;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.io.*;
+
+/**
+ * An abstract base class for the attributes within a class file
+ */
+public abstract class ClassAttribute implements VMConstants {
+
+ /* The name of the attribute */
+ private ConstUtf8 attributeName;
+
+ /**
+ * Returns the name of the attribute
+ */
+ public ConstUtf8 attrName() {
+ return attributeName;
+ }
+
+ /**
+ * Compares this instance with another for structural equality.
+ */
+ //@olsen: added method
+ public boolean isEqual(Stack msg, Object obj) {
+ if (!(obj instanceof ClassAttribute)) {
+ msg.push("obj/obj.getClass() = "
+ + (obj == null ? null : obj.getClass()));
+ msg.push("this.getClass() = "
+ + this.getClass());
+ return false;
+ }
+ ClassAttribute other = (ClassAttribute)obj;
+
+ if (!this.attributeName.isEqual(msg, other.attributeName)) {
+ msg.push(String.valueOf("attributeName = "
+ + other.attributeName));
+ msg.push(String.valueOf("attributeName = "
+ + this.attributeName));
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Constructor
+ */
+ ClassAttribute(ConstUtf8 theAttrName) {
+ attributeName = theAttrName;
+ }
+
+ /**
+ * General attribute reader
+ */
+ static ClassAttribute read(DataInputStream data, ConstantPool pool)
+ throws IOException {
+
+ ClassAttribute attr = null;
+ int attrNameIndex = data.readUnsignedShort();
+ ConstUtf8 attrName8 = (ConstUtf8) pool.constantAt(attrNameIndex);
+ String attrName = attrName8.asString();
+ int attrLength = data.readInt();
+
+ if (attrName.equals(CodeAttribute.expectedAttrName)) {
+ /* The old style code attribute reader uses more memory and
+ cpu when the instructions don't need to be examined than the
+ new deferred attribute reader. We may at some point decide that
+ we want to change the default based on the current situation
+ but for now we will just use the deferred reader in all cases. */
+ if (true) {
+ attr = CodeAttribute.read(attrName8, attrLength, data, pool);
+ } else {
+ attr = CodeAttribute.read(attrName8, data, pool);
+ }
+ }
+ else if (attrName.equals(SourceFileAttribute.expectedAttrName)) {
+ attr = SourceFileAttribute.read(attrName8, data, pool);
+ }
+ else if (attrName.equals(ConstantValueAttribute.expectedAttrName)) {
+ attr = ConstantValueAttribute.read(attrName8, data, pool);
+ }
+ else if (attrName.equals(ExceptionsAttribute.expectedAttrName)) {
+ attr = ExceptionsAttribute.read(attrName8, data, pool);
+ }
+ else if (attrName.equals(AnnotatedClassAttribute.expectedAttrName)) {
+ attr = AnnotatedClassAttribute.read(attrName8, data, pool);
+ }
+ else {
+ /* Unrecognized method attribute */
+ byte attrBytes[] = new byte[attrLength];
+ data.readFully(attrBytes);
+ attr = new GenericAttribute (attrName8, attrBytes);
+ }
+
+ return attr;
+ }
+
+ /*
+ * CodeAttribute attribute reader
+ */
+
+ static ClassAttribute read(DataInputStream data, CodeEnv env)
+ throws IOException {
+ ClassAttribute attr = null;
+ int attrNameIndex = data.readUnsignedShort();
+ ConstUtf8 attrName8 = (ConstUtf8) env.pool().constantAt(attrNameIndex);
+ String attrName = attrName8.asString();
+ int attrLength = data.readInt();
+
+ if (attrName.equals(LineNumberTableAttribute.expectedAttrName)) {
+ attr = LineNumberTableAttribute.read(attrName8, data, env);
+ }
+ else if (attrName.equals(LocalVariableTableAttribute.expectedAttrName)) {
+ attr = LocalVariableTableAttribute.read(attrName8, data, env);
+ }
+ else if (attrName.equals(AnnotatedMethodAttribute.expectedAttrName)) {
+ attr = AnnotatedMethodAttribute.read(attrName8, data, env);
+ }
+ //@olsen: fix 4467428, added support for synthetic code attribute
+ else if (attrName.equals(SyntheticAttribute.expectedAttrName)) {
+ attr = SyntheticAttribute.read(attrName8, data, env.pool());
+ }
+ else {
+ /* Unrecognized method attribute */
+ byte attrBytes[] = new byte[attrLength];
+ data.readFully(attrBytes);
+ attr = new GenericAttribute (attrName8, attrBytes);
+ }
+
+ return attr;
+ }
+
+ /**
+ * Write the attribute to the output stream
+ */
+ abstract void write(DataOutputStream out) throws IOException;
+
+ /**
+ * Print a description of the attribute to the print stream
+ */
+ abstract void print(PrintStream out, int indent);
+}
+
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassField.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassField.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassField.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassField.java Sun May 22 10:55:51 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.io.*;
+
+/**
+ * ClassField models the static and non-static fields of a class within
+ * a class file.
+ */
+
+final public class ClassField extends ClassMember {
+ /* access flag bit mask - see VMConstants */
+ private int accessFlags;
+
+ /* The name of the field */
+ private ConstUtf8 fieldName;
+
+ /* The type signature of the field */
+ private ConstUtf8 fieldSignature;
+
+ /* The attributes associated with the field */
+ private AttributeVector fieldAttributes;
+
+
+ /* public accessors */
+
+ /**
+ * Is the field transient?
+ */
+ public boolean isTransient() {
+ return (accessFlags & ACCTransient) != 0;
+ }
+
+ /**
+ * Return the access flags for the field - see VMConstants
+ */
+ public int access() {
+ return accessFlags;
+ }
+
+ /**
+ * Update the access flags for the field - see VMConstants
+ */
+ public void setAccess(int newFlags) {
+ accessFlags = newFlags;
+ }
+
+ /**
+ * Return the name of the field
+ */
+ public ConstUtf8 name() {
+ return fieldName;
+ }
+
+ /**
+ * Change the name of the field
+ */
+ public void changeName(ConstUtf8 name) {
+ fieldName = name;
+ }
+
+ /**
+ * Return the type signature of the field
+ */
+ public ConstUtf8 signature() {
+ return fieldSignature;
+ }
+
+ /**
+ * Change the type signature of the field
+ */
+ public void changeSignature(ConstUtf8 newSig) {
+ fieldSignature = newSig;
+ }
+
+ /**
+ * Return the attributes associated with the field
+ */
+ public AttributeVector attributes() {
+ return fieldAttributes;
+ }
+
+ /**
+ * Construct a class field object
+ */
+ public ClassField(int accFlags, ConstUtf8 name, ConstUtf8 sig,
+ AttributeVector field_attrs) {
+ accessFlags = accFlags;
+ fieldName = name;
+ fieldSignature = sig;
+ fieldAttributes = field_attrs;
+ }
+
+ /* package local methods */
+
+ static ClassField read(DataInputStream data, ConstantPool pool)
+ throws IOException {
+ ClassField f = null;
+ int accessFlags = data.readUnsignedShort();
+ int name_index = data.readUnsignedShort();
+ int sig_index = data.readUnsignedShort();
+ AttributeVector fieldAttribs = AttributeVector.readAttributes(data, pool);
+ f = new ClassField(accessFlags,
+ (ConstUtf8) pool.constantAt(name_index),
+ (ConstUtf8) pool.constantAt(sig_index),
+ fieldAttribs);
+ return f;
+ }
+
+ void write (DataOutputStream data) throws IOException {
+ data.writeShort(accessFlags);
+ data.writeShort(fieldName.getIndex());
+ data.writeShort(fieldSignature.getIndex());
+ fieldAttributes.write(data);
+ }
+
+ void print(PrintStream out, int indent) {
+ ClassPrint.spaces(out, indent);
+ out.print("'" + fieldName.asString() + "'");
+ out.print(" sig = " + fieldSignature.asString());
+ out.print(" access_flags = " + Integer.toString(accessFlags));
+ out.println(" attributes:");
+ fieldAttributes.print(out, indent+2);
+ }
+}
+
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassFile.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassFile.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassFile.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassFile.java Sun May 22 10:55:51 2005
@@ -0,0 +1,676 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.io.*;
+import java.security.MessageDigest;
+import java.security.DigestOutputStream;
+import java.security.NoSuchAlgorithmException;
+import java.io.DataOutputStream;
+
+
+/**
+ * ClassFile models the structure of a class as represented within
+ * a class file.
+ */
+final public class ClassFile implements VMConstants, Serializable {
+
+ /* Class file constants */
+ public static final int magic = 0xcafebabe;
+
+ /*@craig added more flexible version checking.
+ */
+ public static final short[] [] jdkMajorMinorVersions = new short[][] {
+ new short[] {45,3}, // jdk 1.1
+ new short[] {46,0}, // jdk 1.2
+ new short[] {47,0}, // jdk 1.3
+ new short[] {48,0} // jdk 1.4
+ };
+ public static final List jdkVersions =
+ convertMajorMinorVersions(jdkMajorMinorVersions);
+
+ public static final String supportedVersions = printSupportedVersions();
+
+ private int majorVersion = 0;
+ private int minorVersion = 0;
+
+ /* The constant pool for the class file */
+ private ConstantPool constantPool = new ConstantPool();
+
+ /* access flag bit mask - see VMConstants */
+ private int accessFlags = 0;
+
+ /* The name of the class */
+ private ConstClass thisClassName;
+
+ /* The name of the super class */
+ private ConstClass superClassName;
+
+ /* A list of the interfaces which the class implements
+ * The contents are ConstClass objects
+ */
+ private Vector classInterfaces = new Vector();
+
+ /* A list of the fields which the class contains
+ * The contents are ClassField objects
+ */
+ private Vector classFields = new Vector();
+
+ /* A list of the methods which the class defines
+ * The contents are ClassMethod objects
+ */
+ private Vector classMethods = new Vector();
+
+ /* A list of the attributes associated with the class */
+ private AttributeVector classAttributes = new AttributeVector();
+
+ /** Static methods
+ * Added for major.minor compatibility checking
+ */
+ private static List convertMajorMinorVersions(short[][] majorMinor) {
+ int length = majorMinor.length;
+ List result = new ArrayList(length);
+ for (int i = 0; i < length; i++) {
+ result.add(new Integer(majorMinor[i][0] * 65536 + majorMinor[i][1]));
+ }
+ return result;
+ }
+
+ private static boolean isSupportedVersion(short major, short minor) {
+ Integer version = new Integer(major*65536 + minor);
+ return jdkVersions.contains(version);
+ }
+
+ public static final String printSupportedVersions() {
+ StringBuffer buf = new StringBuffer("{"); //NOI18N
+ int length = jdkMajorMinorVersions.length;
+ for (int i = 0; i < length; i++) {
+ int major = jdkMajorMinorVersions[i][0];
+ int minor = jdkMajorMinorVersions[i][1];
+ buf.append("{"); buf.append(major); buf.append(",");
+ buf.append(minor); buf.append("}"); //NOI18N
+ }
+ buf.append("}"); //NOI18N
+ return buf.toString();
+ }
+
+ /* public accessors */
+
+
+
+ /**
+ * Return the constant pool for the class file
+ */
+ public ConstantPool pool() {
+ return constantPool;
+ }
+
+ /**
+ * Return the access flags for the class - see VMConstants
+ */
+ public int access() {
+ return accessFlags;
+ }
+
+ /**
+ * Is the class final?
+ */
+ final public boolean isFinal() {
+ return (accessFlags & ACCFinal) != 0;
+ }
+
+ /**
+ * Is the class an interface?
+ */
+ final public boolean isInterface() {
+ return (accessFlags & ACCInterface) != 0;
+ }
+
+ /**
+ * Is the class public?
+ */
+ final public boolean isPublic() {
+ return (accessFlags & ACCPublic) != 0;
+ }
+
+ /**
+ * Is the class abstract?
+ */
+ final public boolean isAbstract() {
+ return (accessFlags & ACCAbstract) != 0;
+ }
+
+
+ /**
+ * Set the access flags for the class - see VMConstants
+ */
+ public void setAccessFlags (int flags) {
+ accessFlags = flags;
+ }
+
+ /**
+ * Return the name of the class
+ */
+ public ConstClass className() {
+ return thisClassName;
+ }
+
+ /**
+ * Return the name of the class as a string
+ */
+ //@olsen: added method
+ public String classNameString() {
+ return (thisClassName == null) ? null : thisClassName.asString();
+ }
+
+ /**
+ * Return the name of the super class
+ */
+ public ConstClass superName() {
+ return superClassName;
+ }
+
+ /**
+ * Return the name of the super class as a string
+ */
+ public String superNameString() {
+ return (superClassName == null) ? null : superClassName.asString();
+ }
+
+ /**
+ * Set the name of the super class
+ */
+ public void setSuperName(ConstClass superCl) {
+ superClassName = superCl;
+ }
+
+ /**
+ * Return the list of the interfaces which the class implements
+ * The contents are ConstClass objects
+ */
+ public Vector interfaces() {
+ return classInterfaces;
+ }
+
+ /**
+ * Add an interface to the list of the interfaces which the class implements
+ */
+ public void addInterface (ConstClass iface) {
+ classInterfaces.addElement(iface);
+ }
+
+ /**
+ * Return the list of the fields which the class contains
+ * The contents are ClassField objects
+ */
+ public Vector fields() {
+ return classFields;
+ }
+
+ /**
+ * Add a field to the list of the fields which the class contains
+ */
+ public void addField (ClassField field) {
+ classFields.addElement(field);
+ }
+
+ /**
+ * Add a field to the list of the fields which the class contains,
+ * at the index'th position.
+ */
+ public void addField(ClassField field, int index) {
+ classFields.insertElementAt(field, index);
+ }
+
+ /**
+ * Return the list of the methods which the class defines
+ * The contents are ClassMethod objects
+ */
+ public Vector methods() {
+ return classMethods;
+ }
+
+ /**
+ * Look for a method with the specified name and type signature
+ */
+ public ClassMethod findMethod(String methodName, String methodSig) {
+ for (Enumeration e = methods().elements(); e.hasMoreElements();) {
+ ClassMethod method = (ClassMethod) e.nextElement();
+ if (method.name().asString().equals(methodName) &&
+ method.signature().asString().equals(methodSig))
+ return method;
+ }
+ return null;
+ }
+
+ /**
+ * Add a method to the list of the methods which the class defines
+ */
+ public void addMethod(ClassMethod method) {
+ classMethods.addElement(method);
+ }
+
+ /**
+ * Look for a field with the specified name
+ */
+ public ClassField findField(String fieldName) {
+ for (Enumeration e = fields().elements(); e.hasMoreElements();) {
+ ClassField field = (ClassField) e.nextElement();
+ if (field.name().asString().equals(fieldName))
+ return field;
+ }
+ return null;
+ }
+
+ /**
+ * Return the list of the attributes associated with the class
+ */
+ public AttributeVector attributes() {
+ return classAttributes;
+ }
+
+ /**
+ * Returns the class name in user ('.' delimited) form.
+ */
+ //@olsen: moved from ClassControl to ClassFile
+ public String userClassName()
+ {
+ return userClassFromVMClass(classNameString());
+ }
+
+ /**
+ * Returns the class name in user ('.' delimited) form.
+ */
+ //@olsen: moved from ClassControl to ClassFile
+ static public String userClassFromVMClass(String vmName)
+ {
+ return vmName.replace('/', '.');
+ }
+
+ /**
+ * Returns the class name in VM ('/' delimited) form.
+ */
+ //@olsen: moved from ClassControl to ClassFile
+ static public String vmClassFromUserClass(String userName)
+ {
+ return userName.replace('.', '/');
+ }
+
+ /**
+ * Returns the vm package name for this class.
+ */
+ //@olsen: moved from ClassControl to ClassFile
+ public String pkg()
+ {
+ return packageOf(classNameString());
+ }
+
+ /**
+ * Returns the vm package name for the vm class name.
+ */
+ //@olsen: moved from ClassControl to ClassFile
+ static public String packageOf(String vmName)
+ {
+ int last = vmName.lastIndexOf('/');
+ if (last < 0)
+ return "";
+ return vmName.substring(0, last);
+ }
+
+
+ /* Constructors */
+
+ /**
+ * Construct a ClassFile from an input stream
+ */
+ public ClassFile(DataInputStream data) throws ClassFormatError {
+ this(data, true);
+ }
+
+ public ClassFile(DataInputStream data,
+ boolean allowJDK12ClassFiles) throws ClassFormatError {
+ try {
+ int thisMagic = data.readInt();
+ if (thisMagic != magic)
+ throw new ClassFormatError("Bad magic value for input");
+
+ short thisMinorVersion = data.readShort();
+ short thisMajorVersion = data.readShort();
+ /*@craig changed checking only target 1.1 and 1.2 to more
+ * general check for a list of versions.
+ */
+ if (isSupportedVersion(thisMajorVersion, thisMinorVersion)) {
+ minorVersion = thisMinorVersion;
+ majorVersion = thisMajorVersion;
+ } else {
+ throw new ClassFormatError("Bad version number: {" +
+ thisMajorVersion + "," +
+ thisMinorVersion +
+ "} expected one of: " +
+ supportedVersions);
+ }
+
+ readConstants(data);
+ accessFlags = data.readUnsignedShort();
+ thisClassName = (ConstClass)
+ constantPool.constantAt(data.readUnsignedShort());
+ superClassName = (ConstClass)
+ constantPool.constantAt(data.readUnsignedShort());
+ readInterfaces(data);
+ readFields(data);
+ readMethods(data);
+ classAttributes = AttributeVector.readAttributes(data, constantPool);
+ } catch (IOException e) {
+ throw new ClassFormatError("IOException during reading: " +
+ e.getMessage());
+ }
+ //@olsen: added println() for debugging
+ //System.out.println("ClassFile(): new class = " +
+ //thisClassName.asString());
+ }
+
+ /**
+ * Construct a bare bones class, ready for additions
+ */
+ public ClassFile(String cname, String supername) {
+ thisClassName = constantPool.addClass(cname);
+ superClassName = constantPool.addClass(supername);
+ //@olsen: added println() for debugging
+ //System.out.println("ClassFile(): new bare class file = " +
+ //thisClassName);
+ }
+
+ /**
+ * Write the Class file to the data output stream
+ */
+ public
+ void write (DataOutputStream buff) throws IOException {
+ buff.writeInt(magic);
+ buff.writeShort(minorVersion);
+ buff.writeShort(majorVersion);
+ constantPool.write(buff);
+ buff.writeShort(accessFlags);
+ buff.writeShort(thisClassName.getIndex());
+ //@lars: superclass may be null (java.lang.Object);
+ //VMSpec 2nd ed., section 4.1
+ buff.writeShort(superClassName == null ? 0 : superClassName.getIndex());
+ //buff.writeShort(superClassName.getIndex());
+ writeInterfaces(buff);
+ writeFields(buff);
+ writeMethods(buff);
+ classAttributes.write(buff);
+ }
+
+ /**
+ * Returns a byte array representation of this class.
+ */
+ public byte[] getBytes() throws java.io.IOException {
+ /* Write the class bytes to a file, for debugging. */
+
+ String writeClassToDirectory =
+ System.getProperty("filter.writeClassToDirectory");
+ if (writeClassToDirectory != null) {
+ String filename = writeClassToDirectory + java.io.File.separator +
+ thisClassName.asString() + ".class";
+ System.err.println("Writing class to file " + filename);
+ DataOutputStream stream = new DataOutputStream(
+ new java.io.FileOutputStream(filename));
+ write(stream);
+ stream.close();
+ }
+
+ /* Get the class bytes and return them. */
+
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ write(new DataOutputStream(byteStream));
+
+ return byteStream.toByteArray();
+ }
+
+ //@olsen: added method
+ public void print(PrintStream out) {
+ print(out, 0);
+ }
+
+ //@olsen: added 'indent' parameter
+ public void print(PrintStream out, int indent) {
+ constantPool.print(out, indent);
+ out.println();
+
+ ClassPrint.spaces(out, indent);
+ out.println("majorVersion = " + Integer.toString(majorVersion));
+ ClassPrint.spaces(out, indent);
+ out.println("minorVersion = " + Integer.toString(minorVersion));
+ ClassPrint.spaces(out, indent);
+ out.println("accessFlags = " + Integer.toString(accessFlags));
+ ClassPrint.spaces(out, indent);
+ out.println("className = " + thisClassName.asString());
+ ClassPrint.spaces(out, indent);
+ out.println("superClassName = " + superClassName.asString());
+ ClassPrint.spaces(out, indent);
+ out.print("Interfaces =");
+ for (int i=0; i<classInterfaces.size(); i++) {
+ out.print(" "
+ + ((ConstClass)classInterfaces.elementAt(i)).asString());
+ }
+ out.println();
+
+ ClassPrint.spaces(out, indent);
+ out.println("fields =");
+ for (int i=0; i<classFields.size(); i++) {
+ ((ClassField) classFields.elementAt(i)).print(out, indent + 3);
+ }
+
+ ClassPrint.spaces(out, indent);
+ out.println("methods =");
+ for (int i=0; i<classMethods.size(); i++) {
+ ((ClassMethod) classMethods.elementAt(i)).print(out, indent + 3);
+ }
+
+ ClassPrint.spaces(out, indent);
+ out.println("attributes =");
+ classAttributes.print(out, indent + 3);
+
+ }
+
+ //@olsen: made public
+ //@olsen: added 'out' and 'indent' parameters
+ public void summarize(PrintStream out, int indent) {
+ constantPool.summarize(out, indent);
+ int codeSize = 0;
+ for (int i=0; i<classMethods.size(); i++) {
+ codeSize += ((ClassMethod)classMethods.elementAt(i)).codeSize();
+ }
+ ClassPrint.spaces(out, indent);
+ out.println(classMethods.size() + " methods in "
+ + codeSize + " bytes");
+ ClassPrint.spaces(out, indent);
+ out.println(classFields.size() + " fields");
+ }
+
+ /* package local methods */
+
+ /*
+ * class file reading helpers
+ */
+ private void readConstants (DataInputStream data) throws IOException {
+ constantPool = new ConstantPool(data);
+ }
+
+ private void readInterfaces(DataInputStream data) throws IOException {
+ int nInterfaces = data.readUnsignedShort();
+ while (nInterfaces-- > 0) {
+ int interfaceIndex = data.readUnsignedShort();
+ ConstClass ci = null;
+ if (interfaceIndex != 0)
+ ci = (ConstClass) constantPool.constantAt(interfaceIndex);
+ classInterfaces.addElement(ci);
+ }
+ }
+
+ private void writeInterfaces(DataOutputStream data) throws IOException {
+ data.writeShort(classInterfaces.size());
+ for (int i=0; i<classInterfaces.size(); i++) {
+ ConstClass ci = (ConstClass) classInterfaces.elementAt(i);
+ int interfaceIndex = 0;
+ if (ci != null)
+ interfaceIndex = ci.getIndex();
+ data.writeShort(interfaceIndex);
+ }
+ }
+
+ private void readFields(DataInputStream data) throws IOException {
+ int nFields = data.readUnsignedShort();
+ while (nFields-- > 0) {
+ classFields.addElement (ClassField.read(data, constantPool));
+ }
+ }
+
+ private void writeFields (DataOutputStream data) throws IOException {
+ data.writeShort(classFields.size());
+ for (int i=0; i<classFields.size(); i++)
+ ((ClassField)classFields.elementAt(i)).write(data);
+ }
+
+ private void readMethods (DataInputStream data) throws IOException {
+ int nMethods = data.readUnsignedShort();
+ while (nMethods-- > 0) {
+ classMethods.addElement (ClassMethod.read(data, constantPool));
+ }
+ }
+
+ private void writeMethods (DataOutputStream data) throws IOException {
+ data.writeShort(classMethods.size());
+ for (int i=0; i<classMethods.size(); i++)
+ ((ClassMethod)classMethods.elementAt(i)).write(data);
+ }
+
+}
+
+abstract class ArraySorter {
+ protected ArraySorter() {}
+
+ /* return the size of the array being sorted */
+ abstract int size();
+
+ /* return -1 if o1 < o2, 0 if o1 == o2, 1 if o1 > o2 */
+ abstract int compare(int o1Index, int o2Index);
+
+ /* Swap the elements at index o1Index and o2Index */
+ abstract void swap(int o1Index, int o2Index);
+
+ void sortArray() {
+ sortArray(0, size()-1);
+ }
+
+ private void sortArray(int start, int end) {
+ if (end > start) {
+ swap(start, (start+end)/2);
+ int last = start;
+ for (int i = start+1; i<=end; i++) {
+ if (compare(i, start) < 0)
+ swap (++last, i);
+ }
+ swap(start, last);
+ sortArray(start, last-1);
+ sortArray(last+1, end);
+ }
+ }
+}
+
+class InterfaceArraySorter extends ArraySorter {
+ private ConstClass theArray[];
+
+ InterfaceArraySorter(ConstClass[] interfaces) {
+ theArray = interfaces;
+ }
+
+ /* return the size of the array being sorted */
+ int size() { return theArray.length; }
+
+ /* return -1 if o1 < o2, 0 if o1 == o2, 1 if o1 > o2 */
+ int compare(int o1Index, int o2Index) {
+ return theArray[o1Index].asString().compareTo(
+ theArray[o2Index].asString());
+ }
+
+ /* Swap the elements at index o1Index and o2Index */
+ void swap(int o1Index, int o2Index) {
+ ConstClass tmp = theArray[o1Index];
+ theArray[o1Index] = theArray[o2Index];
+ theArray[o2Index] = tmp;
+ }
+}
+
+class FieldArraySorter extends ArraySorter {
+ private ClassField theArray[];
+
+ FieldArraySorter(ClassField[] fields) {
+ theArray = fields;
+ }
+
+ /* return the size of the array being sorted */
+ int size() { return theArray.length; }
+
+ /* return -1 if o1 < o2, 0 if o1 == o2, 1 if o1 > o2 */
+ int compare(int o1Index, int o2Index) {
+ return theArray[o1Index].name().asString().compareTo(
+ theArray[o2Index].name().asString());
+ }
+
+ /* Swap the elements at index o1Index and o2Index */
+ void swap(int o1Index, int o2Index) {
+ ClassField tmp = theArray[o1Index];
+ theArray[o1Index] = theArray[o2Index];
+ theArray[o2Index] = tmp;
+ }
+}
+
+class MethodArraySorter extends ArraySorter {
+ private ClassMethod theArray[];
+
+ MethodArraySorter(ClassMethod[] methods) {
+ theArray = methods;
+ }
+
+ /* return the size of the array being sorted */
+ int size() { return theArray.length; }
+
+ /* return -1 if o1 < o2, 0 if o1 == o2, 1 if o1 > o2 */
+ int compare(int o1Index, int o2Index) {
+ int cmp = theArray[o1Index].name().asString().compareTo(
+ theArray[o2Index].name().asString());
+ if (cmp == 0) {
+ cmp = theArray[o1Index].signature().asString().compareTo(
+ theArray[o2Index].signature().asString());
+ }
+ return cmp;
+ }
+
+ /* Swap the elements at index o1Index and o2Index */
+ void swap(int o1Index, int o2Index) {
+ ClassMethod tmp = theArray[o1Index];
+ theArray[o1Index] = theArray[o2Index];
+ theArray[o2Index] = tmp;
+ }
+}
Added: incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassMember.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassMember.java?rev=171351&view=auto
==============================================================================
--- incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassMember.java (added)
+++ incubator/jdo/trunk/enhancer20/src/java/org/apache/jdo/impl/enhancer/classfile/ClassMember.java Sun May 22 10:55:51 2005
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jdo.impl.enhancer.classfile;
+import java.util.Stack;
+
+/**
+ * ClassMember is a common base class for ClassMethod and ClassField
+ */
+abstract public class ClassMember implements VMConstants {
+
+ /* public accessors */
+
+ /**
+ * Is the member static?
+ */
+ final public boolean isStatic() {
+ return (access() & ACCStatic) != 0;
+ }
+
+ /**
+ * Is the member final?
+ */
+ final public boolean isFinal() {
+ return (access() & ACCFinal) != 0;
+ }
+
+ /**
+ * Turn on or off the final qualifier for the member.
+ */
+ public void setIsFinal(boolean newFinal) {
+ if (newFinal)
+ setAccess(access() | ACCFinal);
+ else
+ setAccess(access() & ~ACCFinal);
+ }
+
+ /**
+ * Is the member private?
+ */
+ final public boolean isPrivate() {
+ return (access() & ACCPrivate) != 0;
+ }
+
+ /**
+ * Is the member protected?
+ */
+ final public boolean isProtected() {
+ return (access() & ACCProtected) != 0;
+ }
+
+ /**
+ * Is the member public?
+ */
+ final public boolean isPublic() {
+ return (access() & ACCPublic) != 0;
+ }
+
+ /* These are expected to be implemented by subtypes */
+
+ /**
+ * Return the access flags for the method - see VMConstants
+ */
+ abstract public int access();
+
+ /**
+ * Set the access flags for the method - see VMConstants
+ */
+ abstract public void setAccess(int newAccess);
+
+ /**
+ * Return the name of the member
+ */
+ abstract public ConstUtf8 name();
+
+ /**
+ * Return the type signature of the method
+ */
+ abstract public ConstUtf8 signature();
+
+ /**
+ * Return the attributes associated with the member
+ */
+ abstract public AttributeVector attributes();
+
+ /**
+ * Compares this instance with another for structural equality.
+ */
+ //@olsen: added method
+ public boolean isEqual(Stack msg, Object obj) {
+ if (!(obj instanceof ClassMember)) {
+ msg.push("obj/obj.getClass() = "
+ + (obj == null ? null : obj.getClass()));
+ msg.push("this.getClass() = "
+ + this.getClass());
+ return false;
+ }
+ ClassMember other = (ClassMember)obj;
+
+ return true;
+ }
+}