001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: *
019: *
020: * Authors: S.Chassande-Barrioz.
021: * Created on 26 mars 2005
022: *
023: */package org.objectweb.speedo.tools;
024:
025: import java.io.File;
026: import java.io.FileInputStream;
027: import java.io.FileOutputStream;
028: import java.io.IOException;
029:
030: import org.objectweb.asm.Attribute;
031: import org.objectweb.asm.ClassAdapter;
032: import org.objectweb.asm.ClassReader;
033: import org.objectweb.asm.ClassVisitor;
034: import org.objectweb.asm.ClassWriter;
035: import org.objectweb.asm.Constants;
036: import org.objectweb.asm.attrs.Attributes;
037:
038: /**
039: * This ASM visitor assignes a value to a static field. If the field does not
040: * exist, it is added.
041: *
042: * @author S.Chassande-Barrioz
043: */
044: public class ClassFieldModifier extends ClassAdapter {
045:
046: private String className;
047:
048: /**
049: * The name of the field to modify
050: */
051: private String fieldName;
052:
053: /**
054: * The value to set to the field
055: */
056: private String fieldValue;
057:
058: /**
059: * indicates if the field has been found in the class
060: */
061: private boolean fieldFound;
062:
063: private boolean classModified = false;
064:
065: /**
066: * @param fieldName is the name of the field to modify
067: * @param fieldValue is the value to set to the field
068: */
069: public ClassFieldModifier(final ClassVisitor cv,
070: final String fieldName, final String fieldValue) {
071: super (cv);
072: this .fieldName = fieldName;
073: this .fieldValue = fieldValue;
074: fieldFound = false;
075: }
076:
077: public void visit(final int version, final int access,
078: final String name, final String super Name,
079: final String[] interfaces, final String sourceFile) {
080: className = name;
081: super .visit(version, access, name, super Name, interfaces,
082: sourceFile);
083: }
084:
085: public void visitField(final int access, final String name,
086: final String desc, final Object value, final Attribute attrs) {
087: Object val = value;
088: if (name.equals(fieldName)) {
089: fieldFound = true;
090: if (value == null || !value.equals(fieldValue)) {
091: val = fieldValue;
092: classModified = true;
093: System.out.println("Set the field '" + fieldName
094: + "' of the class '" + className + "' to '"
095: + val + "' (old value: '" + value + "').");
096: }
097: }
098: super .visitField(access, name, desc, val, attrs);
099: }
100:
101: public void visitEnd() {
102: if (!fieldFound) {
103: classModified = true;
104: super .visitField(Constants.ACC_PUBLIC
105: | Constants.ACC_STATIC | Constants.ACC_FINAL,
106: fieldName, "Ljava/lang/String;", fieldValue, null);
107: System.out.println("Add the field '" + fieldName
108: + "' to the class '" + className
109: + "' with the value '" + fieldValue + "'.");
110: }
111: super .visitEnd();
112: }
113:
114: public boolean isClassModified() {
115: return classModified;
116: }
117:
118: public static void main(String[] args) throws IOException {
119: if (args == null || args.length < 3) {
120: usage();
121: return;
122: }
123: String classFileName = args[0];
124: String fieldName = args[1];
125: String fieldValue = args[2];
126: ClassReader cr;
127: File f = new File(classFileName);
128: FileInputStream fis = new FileInputStream(f);
129: cr = new ClassReader(fis);
130: fis.close();
131: ClassWriter cw = new ClassWriter(true);
132: ClassFieldModifier cfm = new ClassFieldModifier(cw, fieldName,
133: fieldValue);
134: cr.accept(cfm, Attributes.getDefaultAttributes(), false);
135: if (cfm.isClassModified()) {
136: FileOutputStream fos = new FileOutputStream(f);
137: fos.write(cw.toByteArray());
138: fos.close();
139: }
140: }
141:
142: public final static void usage() {
143: System.out
144: .println("Usage: <class file> <field name> <field value>");
145: }
146: }
|