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: */package org.objectweb.speedo.generation.enhancer.common;
018:
019: import org.objectweb.asm.ClassReader;
020: import org.objectweb.asm.ClassWriter;
021: import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
022: import org.objectweb.speedo.lib.Personality;
023:
024: import java.io.File;
025: import java.io.FileInputStream;
026: import java.io.FileOutputStream;
027: import java.io.IOException;
028: import java.io.InputStream;
029:
030: /**
031: * Abstract enhancer component. Provides methods to read and write classes to
032: * or from the file system.
033: *
034: * Adapted from loadXXX and writeXXX methods in EnhancerTool.
035: */
036: public abstract class AbstractEnhancerComponent extends
037: AbstractGeneratorComponent {
038: /**
039: * Indicates whether the <code>.class</code> files would be found in an
040: * archive.
041: */
042: public boolean isSrcJar;
043: /**
044: * System separator character (e.g '/' under Unix systems)
045: */
046: private final static char SEPARATOR = File.separatorChar;
047:
048: public AbstractEnhancerComponent(Personality p) {
049: super (p);
050: }
051:
052: /**
053: * Loads a specified class placed indifferently in a directory or in
054: * a <code>.jar</code> archive.
055: *
056: * @param issrcjar indicates whether the <code>.class</code> file would be
057: * found in an archive
058: * @param completeName the name of the Java class to be loaded
059: * @param srcFiles location of the <code>.jar</code> file or base directory
060: * of <code>.class</code> file
061: * @return the JavaClass loaded
062: * @exception org.objectweb.speedo.generation.enhancer.common.SpeedoEnhancerException if the file cannot be loaded
063: */
064: public ClassReader loadJavaClass(final boolean issrcjar,
065: final String completeName, final String srcFiles,
066: final boolean remove) throws SpeedoEnhancerException {
067: ClassReader jclass = null;
068: // lookup class in cache
069: // if not found, parse the class from disk
070: String file = completeName.replace('.', SEPARATOR) + ".class";
071: if (!issrcjar) {
072: file = srcFiles + SEPARATOR + file;
073: }
074: try {
075: File f = new File(file);
076: if (f.exists()) {
077: FileInputStream fis = new FileInputStream(f);
078: jclass = new ClassReader(fis);
079: fis.close();
080: if (remove) {
081: f.delete();
082: }
083: } else {
084: file = completeName.replace('.', '/') + ".class";
085: InputStream is = getClass().getClassLoader()
086: .getResourceAsStream(file);
087: if (is == null) {
088: throw new SpeedoEnhancerException(
089: "Error during loading of the class: "
090: + file);
091: }
092: jclass = new ClassReader(is);
093: }
094: } catch (IOException e) {
095: throw new SpeedoEnhancerException("Error during loading "
096: + file, e);
097: }
098: return jclass;
099: }
100:
101: /**
102: * Loads a specified class placed indifferently in a directory or in
103: * a <code>.jar</code> archive and store it into a new directory.
104: *
105: * @param issrcjar indicates whether the <code>.class</code> file would be
106: * found in an archive
107: * @param completeName the name of the Java class to be loaded
108: * @param srcFiles location of the <code>.jar</code> file or base directory
109: * of <code>.class</code> file
110: * @param storeDir location of the base directory where the java class
111: * should be stored
112: * @return the JavaClass loaded
113: * @exception org.objectweb.speedo.generation.enhancer.common.SpeedoEnhancerException if the file cannot be loaded
114: */
115: public ClassReader loadJavaClass(final boolean issrcjar,
116: final String completeName, final String srcFiles,
117: final boolean remove, final String storeDir)
118: throws SpeedoEnhancerException {
119: ClassReader jclass = loadJavaClass(issrcjar, completeName,
120: srcFiles, remove);
121: ClassWriter cw = new ClassWriter(false);
122: jclass.accept(cw, false);
123: writeJavaClass(completeName, cw, storeDir);
124: return jclass;
125: }
126:
127: /**
128: * Saves the new bytecode of the specified Java class under a specified base
129: * directory. The file's location is created if necessary.
130: *
131: * @param jclass the Java class that has to be saved
132: * @param srcFiles the base directory where it has to be saved
133: * @exception org.objectweb.speedo.generation.enhancer.common.SpeedoEnhancerException if the file cannot be written
134: */
135: public void writeJavaClass(final String name,
136: final ClassWriter jclass, final String srcFiles)
137: throws SpeedoEnhancerException {
138: try {
139: int p = name.lastIndexOf('.');
140: String pkg;
141: String clas;
142: if (p == -1) {
143: pkg = "";
144: clas = name;
145: } else {
146: pkg = name.substring(0, p).replace('.', SEPARATOR);
147: clas = name.substring(p + 1);
148: }
149: File outputDir;
150: if (srcFiles == null) {
151: outputDir = new File(pkg);
152: } else {
153: outputDir = new File(srcFiles + SEPARATOR + pkg);
154: }
155: outputDir.mkdirs();
156: File outputFile = new File(outputDir, clas + ".class");
157: outputFile.createNewFile();
158: FileOutputStream fos = new FileOutputStream(outputFile);
159: fos.write(jclass.toByteArray());
160: fos.close();
161: } catch (IOException e) {
162: throw new SpeedoEnhancerException("Cannot write " + name, e);
163: }
164: }
165: }
|