// You can redistribute this software and/or modify it under the terms of
// the Ozone Library License version 1 published by ozone-db.org.
//
// The original code and portions created by SMB are
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
//
// $Id: OPP.java,v 1.4 2002/06/08 00:49:39 mediumnet Exp $
package org.ozoneDB.tools.OPP;
import java.io.File;
import org.ozoneDB.DxLib.DxHashSet;
import org.ozoneDB.DxLib.DxIterator;
import org.ozoneDB.core.ObjectContainer;
/**
* Command line driver of the OPP tool.
*
* @author <a href="http://www.softwarebuero.de/">SMB</a>
* @version $Revision: 1.4 $Date: 2002/06/08 00:49:39 $
*/
public class OPP {
public final static String SIGNATURE_DELIMITER = "|";
/**
* Update methods can marked with a
* <pre>
* /*update * /
* </pre>
* in the lines following the method signature.
*/
public final static String UPDATE_SIGN = "/[*]+ *update *[*]/|// *update";
/**
* All method signatures in java interfaces must look like:
* <pre>
* public package.return.Class[] methodname (
* </pre>
* Otherwise OPP is unable to find them.
*/
public final static String METHOD_PATTERN
= "^[ \\t]*public[ \\t]+[_a-zA-Z][_a-zA-Z0-9\\.\\[\\]]*[ \\t]+([_a-zA-Z][\\w]*)[ \\t]*\\(";
/**
* Update methods can marked with a
* <pre>
* @update
* </pre>
* in its appropriate Javadoc Comment.
*/
public final static String JAVADOC_PATTERN
= "^[ \\t]+\\*[ \\t]*@update";
static boolean odmg = false;
static boolean quiet = false;
static boolean cache = true;
static boolean keepSource = false;
static boolean compileSource = true;
static boolean printStackTrace = false;
static boolean searchInterfaceSource = true;
static String methodPattern = ".*_update";
static String outputDirName = "." + File.separator;
static String sourceDirName = "." + File.separator;
public static void main(String[] args) {
DxHashSet classes = new DxHashSet();
if (args.length == 0) {
printUsage();
System.exit(0);
}
boolean preservePackageNames = true;
for (int argCount = 0; argCount < args.length; argCount++) {
if (args[argCount].equals("-q")) {
quiet = true;
} else if (args[argCount].equals("-ks")) {
keepSource = true;
} else if (args[argCount].equals("-KS")) {
keepSource = true;
compileSource = false;
} else if (args[argCount].equals("-odmg")) {
odmg = true;
} else if (args[argCount].equals("-nc")) {
cache = false;
} else if (args[argCount].equals("-st")) {
printStackTrace = true;
} else if (args[argCount].equals("-ni")) {
searchInterfaceSource = false;
} else if (args[argCount].startsWith("-p")) {
methodPattern = args[argCount].substring(2);
} else if (args[argCount].equals("-version")) {
System.out.println("$Id: OPP.java,v 1.4 2002/06/08 00:49:39 mediumnet Exp $");
System.exit(0);
} else if (args[argCount].equals("-h")) {
printUsage();
System.exit(0);
} else if (args[argCount].startsWith("-o")) {
outputDirName = args[argCount].substring(2) + File.separator;
} else if (args[argCount].startsWith("-s")) {
sourceDirName = args[argCount].substring(2) + File.separator;
} else if (args[argCount].equals("-ip")) {
preservePackageNames = false;
} else {
if (args[argCount].startsWith("-")) {
System.out.println("Unknown option '" + args[argCount] + "'!\n");
printUsage();
System.exit(0);
} else {
classes.add(args[argCount]);
}
}
}
// We internally use the new directory parameter format,
// but the user has specified the directory parameters in the old format
// where packages were ignored
if (!preservePackageNames) {
DxIterator i = classes.iterator();
if (i.next() != null) {
String className = (String) i.key();
if (className != null) {
int dotCount = 0;
int index = 0;
while ((index = className.indexOf('.', index)) != -1) {
dotCount++;
index++;
}
outputDirName = parentDirectoryName(outputDirName, dotCount);
sourceDirName = parentDirectoryName(sourceDirName, dotCount);
}
}
}
try {
if (odmg) {
makeODMGProxies(classes);
} else {
makeProxies(classes);
}
} catch (Exception e) {
e.printStackTrace(System.out);
System.exit(1);
}
}
protected static String parentDirectoryName(String directoryName, int dotCount) {
StringBuffer b = new StringBuffer(directoryName);
for (int i = 0; i < dotCount; i++) {
b.append("..");
b.append(File.separatorChar);
}
return b.toString();
}
protected static void makeODMGProxies(DxHashSet classes) throws Exception {
DxIterator it = classes.iterator();
while (it.next() != null) {
String name = (String) it.object();
OPPHelper.progressMsg(name + ":", quiet);
// create the *_Impl class of the original class
Class cl = Class.forName(name);
String newClassName = cl.getName() + ObjectContainer.IMPLNAME_POSTFIX;
ImplManipulator manipulator = new ImplManipulator(cl, outputDirName, quiet);
manipulator.changeClassFile( classes, outputDirName + OPPHelper.classFileBasename( cl ) + ".class",
newClassName);
// generate source and class file of the *_Proxy proxy class
makeProxy(name);
// create the *_Impl class of the original class
cl = Class.forName(name + ObjectContainer.PROXYNAME_POSTFIX);
newClassName = name;
manipulator.changeClassFile( null, outputDirName + OPPHelper.classFileBasename( cl ) + ".class", newClassName );
}
}
protected static void makeProxies(DxHashSet classes) throws Exception {
DxIterator it = classes.iterator();
while (it.next() != null) {
String name = (String) it.object();
OPPHelper.progressMsg(name + ":", quiet);
makeProxy(name);
}
}
protected static void makeODMGProxy(String arg) throws Exception {
// create the *_Impl class of the original class
Class cl = Class.forName(arg);
ImplManipulator manipulator = new ImplManipulator(cl, outputDirName, quiet);
String newClassName = cl.getName() + ObjectContainer.IMPLNAME_POSTFIX;
manipulator.changeClassFile( null, outputDirName + OPPHelper.classFileBasename( cl ) + ".class", newClassName );
// generate source and class file of the *_Proxy proxy class
makeProxy(arg);
// create the *_Impl class of the original class
cl = Class.forName(arg + ObjectContainer.PROXYNAME_POSTFIX);
manipulator = new ImplManipulator(cl, outputDirName, quiet);
newClassName = arg;
manipulator.changeClassFile( null, outputDirName + OPPHelper.classFileBasename( cl ) + ".class", newClassName );
}
protected static void makeProxy(String arg) throws Exception {
Class cl = Class.forName(arg);
ProxyGenerator generator = new ProxyGenerator(cl, methodPattern, outputDirName, quiet, cache);
generator.generateSource(searchInterfaceSource);
if (compileSource) {
generator.compileSource();
}
if (!keepSource) {
generator.deleteSource();
}
}
public static void printUsage() {
System.out.println("Ozone Post Processor");
System.out.println(
"usage: opp [-ks] [-st] [-p<pattern>] [-ni] [-nc] [-q] [-h] [-o<directory>] [-odmg] [-ip] class [class]*");
System.out.println(" -ks save the generated source files");
System.out.println(" -KS save the generated source files; do not invoke compiler");
System.out.println(" -st print stack trace");
System.out.println(" -p regular expression to specify update methods");
System.out.println(" -ni do not search interface code for update methods");
System.out.println(" -q supress output of any messages");
System.out.println(" -o output directory");
System.out.println(" -s source directory");
System.out.println(" -odmg create proxies for the ozone ODMG interface");
System.out.println(" -ip ignore package names");
System.out.println(" -nc do not create code needed for direct invokes and ClientCacheDatabase");
System.out.println(" -version shows version information");
System.out.println(" -h shows this help");
}
}