001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: ImplManipulator.java,v 1.2 2002/04/17 09:29:39 per_nyfelt Exp $
008:
009: package org.ozoneDB.tools.OPP;
010:
011: import java.io.*;
012: import org.ozoneDB.core.ObjectContainer;
013: import org.ozoneDB.DxLib.*;
014: import de.fub.bytecode.*;
015: import de.fub.bytecode.generic.*;
016: import de.fub.bytecode.classfile.*;
017:
018: /**
019: * Helper class that is responsible for all operations that are done on the
020: * byte code of class files.
021: *
022: *
023: * @author <a href="http://www.softwarebuero.de/">SMB</a>
024: * @version $Revision: 1.2 $Date: 2002/04/17 09:29:39 $
025: */
026: class ImplManipulator {
027:
028: protected PrintWriter out;
029:
030: //protected Class cl;
031:
032: protected String outputDir;
033:
034: protected boolean quiet;
035:
036: public ImplManipulator(Class _cl, String _outputDir, boolean _quiet)
037: throws Exception {
038: //cl = _cl;
039: outputDir = _outputDir;
040: quiet = _quiet;
041: }
042:
043: protected String slashedClassName(String className) {
044: StringBuffer sb = new StringBuffer(className);
045: for (int i = 0; i < sb.length(); i++) {
046: if (sb.charAt(i) == '.') {
047: sb.setCharAt(i, '/');
048: }
049: }
050: return sb.toString();
051: }
052:
053: /**
054: * Renames the class and (if classes != null) checks, if the superclass
055: * needs to be renamed too.
056: */
057: public void changeClassFile(DxHashSet classes, String fileName,
058: String newClassName) throws Exception {
059: String newFileName = outputDir
060: + OPPHelper.classFileBasename(newClassName) + ".class";
061:
062: OPPHelper.progressMsg(" creating " + newFileName + " from "
063: + fileName + " ...", quiet);
064:
065: ClassParser parser = new ClassParser(fileName);
066: JavaClass jcl = parser.parse();
067:
068: String name = jcl.getClassName();
069: OPPHelper.progressMsg("class name: " + name, quiet);
070: OPPHelper.progressMsg("new class name: " + newClassName, quiet);
071:
072: // im Constantpool den Eintrag mit dem Classennamen überschreiben
073: ClassGen cg = new ClassGen(jcl);
074: ConstantPoolGen cpg = new ConstantPoolGen(jcl.getConstantPool());
075:
076: // for (int i=0; i<cpg.getSize(); i++) {
077: // System.out.println (cpg.getConstant (i));
078: // }
079: int i = cpg.lookupClass(slashedClassName(name));
080: if (i == -1) {
081: throw new Exception("Unable to lookup class name in class.");
082: }
083:
084: // System.out.println ("ClassIndex: "+i);
085: ConstantClass cc = (ConstantClass) cpg.getConstant(i);
086: int x = cc.getNameIndex();
087: // System.out.println ("ClassConstant.nameIndex: "+x);
088: // System.out.println ("\nAlter Klassenname: "+((ConstantUtf8)cpg.getConstant (x)).getBytes ());
089: ((ConstantUtf8) cpg.getConstant(x))
090: .setBytes(slashedClassName(newClassName));
091: // System.out.println ("Neuer Klassenname: "+((ConstantUtf8)cpg.getConstant (x)).getBytes ()+"\n");
092:
093: cc.setNameIndex(cpg.addUtf8(slashedClassName(newClassName)));
094: // System.out.println ("ClassConstant.nameIndex: (new) "+cc.getNameIndex ());
095:
096: // check super class name and change this too, if needed
097: if (classes != null) {
098: if (!quiet) {
099: System.out.print(" checking super class... ");
100: }
101:
102: String sName = jcl.getSuperclassName();
103: // System.out.println ("superclassname: " + name);
104:
105: // change super class name if the <code>classes</code> set contains
106: // the name (so the super class *will* change too) or the super
107: // class is an proxy already (the super class has already be
108: // changed)
109: if (classes.contains(sName)
110: || Class.forName("org.ozoneDB.OzoneProxy")
111: .isAssignableFrom(Class.forName(sName))) {
112:
113: String newSClassName = sName
114: + ObjectContainer.IMPLNAME_POSTFIX;
115:
116: if (!quiet) {
117: System.out.println(sName + " changed to "
118: + newSClassName);
119: }
120:
121: // im Constantpool den Eintrag mit dem Superclassennamen überschreiben
122: i = cpg.lookupClass(slashedClassName(sName));
123: // System.out.println ("ClassIndex: "+i);
124: cc = (ConstantClass) cpg.getConstant(i);
125: x = cc.getNameIndex();
126: // System.out.println ("ClassConstant.nameIndex: "+x);
127: // System.out.println ("\nAlter Klassenname: "+((ConstantUtf8)cpg.getConstant (x)).getBytes ());
128: ((ConstantUtf8) cpg.getConstant(x))
129: .setBytes(slashedClassName(newSClassName));
130: // System.out.println ("Neuer Klassenname: "+((ConstantUtf8)cpg.getConstant (x)).getBytes ()+"\n");
131:
132: cc.setNameIndex(cpg
133: .addUtf8(slashedClassName(newSClassName)));
134: // System.out.println ("ClassConstant.nameIndex: (new) "+cc.getNameIndex ());
135: } else {
136: if (!quiet) {
137: System.out.println("nothing changed");
138: }
139: }
140: }
141:
142: // System.out.println ("new File: "+newFileName);
143: jcl.dump(newFileName);
144: }
145:
146: }
|