001: /*
002: * ============================================================================
003: * The Apache Software License, Version 1.1
004: * ============================================================================
005: *
006: * Copyright (C) 2000-2003 Lucas Bruand. All
007: * rights reserved.
008: *
009: * Redistribution and use in source and binary forms, with or without modifica-
010: * tion, are permitted provided that the following conditions are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright notice,
013: * this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright notice,
016: * this list of conditions and the following disclaimer in the documentation
017: * and/or other materials provided with the distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if any, must
020: * include the following acknowledgment: "This product includes software
021: * developed by the Apache Software Foundation (http://www.apache.org/)."
022: * Alternately, this acknowledgment may appear in the software itself, if
023: * and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "Just4Log" and "Apache Software Foundation" must not be used to
026: * endorse or promote products derived from this software without prior
027: * written permission. For written permission, please contact
028: * apache@apache.org.
029: *
030: * 5. Products derived from this software may not be called "Apache", nor may
031: * "Apache" appear in their name, without prior written permission of the
032: * Apache Software Foundation.
033: *
034: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
035: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
036: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
037: * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
038: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
039: * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
040: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
041: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044: *
045: * This software consists of voluntary contributions made by many individuals
046: * on behalf of the Apache Software Foundation. For more information on the
047: * Apache Software Foundation, please see <http://www.apache.org/>.
048: *
049: */
050:
051: package net.sf.just4log;
052:
053: import java.io.ByteArrayInputStream;
054: import java.io.ByteArrayOutputStream;
055: import java.io.File;
056: import java.io.FileInputStream;
057: import java.io.FileOutputStream;
058: import java.io.IOException;
059: import java.io.InputStream;
060: import java.io.OutputStream;
061: import java.util.zip.ZipEntry;
062: import java.util.zip.ZipInputStream;
063: import java.util.zip.ZipOutputStream;
064:
065: import net.sf.just4log.transform.Transform;
066: import net.sf.just4log.util.NotClosingInputStream;
067:
068: import org.apache.bcel.Repository;
069: import org.apache.bcel.classfile.ClassFormatException;
070: import org.apache.bcel.classfile.ClassParser;
071: import org.apache.bcel.classfile.JavaClass;
072: import org.apache.bcel.util.ClassPath;
073: import org.apache.bcel.util.SyntheticRepository;
074: import org.apache.commons.logging.Log;
075: import org.apache.commons.logging.LogFactory;
076:
077: /**
078: * This is the core class of Just4log. It actually performs all the bytecode transforming.
079: * @author Lucas Bruand
080: * @version $Id: JustLog.java,v 1.11 2003/07/23 23:59:10 lbruand Exp $
081: */
082:
083: public class JustLog {
084:
085: private static Log logger = LogFactory.getLog(JustLog.class);
086: private static String CLASSID = "$Id: JustLog.java,v 1.11 2003/07/23 23:59:10 lbruand Exp $";
087:
088: /**
089: * Constructor private. not used.
090: */
091: private JustLog() {
092: super ();
093: }
094:
095: public static void setClasspath(String cp) {
096: String extracp = ClassPath.SYSTEM_CLASS_PATH.toString()
097: + File.pathSeparatorChar + cp;
098: logger.info("using " + extracp + "as classpath.");
099: System.out.println("using " + extracp + "as classpath.");
100: Repository.setRepository(SyntheticRepository
101: .getInstance(new ClassPath(extracp)));
102: }
103:
104: private static NotClosingInputStream input = new NotClosingInputStream(
105: null);
106:
107: public static void speedup(InputStream in, String filename,
108: OutputStream out) throws ClassFormatException, IOException {
109: input.setInput(in);
110: JavaClass source = (new ClassParser(input, filename)).parse();
111: logger.info("Source size:" + source.getBytes().length);
112: JavaClass target = Transform.speedup(source);
113: logger.info("after optimization: " + target.getBytes().length);
114: byte[] tmp = target.getBytes();
115: out.write(tmp);
116: }
117:
118: /**
119: * Optimize a classfile for faster logging.
120: *
121: * @param source A file to read from.
122: * @param target A file to read to.
123: * @throws ClassFormatException The source file is not in the valid JDK1.2 classformat.
124: * @throws IOException An error happened while accessing disks.
125: */
126: public static void speedup(File source, File target)
127: throws ClassFormatException, IOException {
128: FileInputStream in = null;
129: FileOutputStream out = null;
130: byte[] buffer = new byte[BUFFER];
131: int count;
132: try {
133: in = new FileInputStream(source);
134: ByteArrayOutputStream outb = new ByteArrayOutputStream();
135: while ((count = in.read(buffer, 0, BUFFER)) != -1) {
136: outb.write(buffer, 0, count);
137: }
138: out = new FileOutputStream(target);
139: speedup(new ByteArrayInputStream(outb.toByteArray()),
140: source.getName(), out);
141: } finally {
142: try {
143: in.close();
144: out.close();
145: } catch (IOException e) {
146: logger.warn("problem with IOException " + e);
147: } catch (NullPointerException e) {
148: logger.warn("problem with Exception " + e);
149: }
150: }
151: }
152:
153: public static final int BUFFER = 4096;
154:
155: public static void speedupZip(InputStream input, OutputStream output)
156: throws IOException {
157: ZipInputStream in = new ZipInputStream(input);
158: ZipOutputStream out = new ZipOutputStream(output);
159: ZipEntry inentry;
160: ZipEntry outentry;
161: int count;
162: byte[] buffer = new byte[BUFFER];
163: while ((inentry = in.getNextEntry()) != null) {
164: outentry = new ZipEntry(inentry.getName());
165: logger.debug("Extra: " + inentry.getExtra());
166: outentry.setExtra(inentry.getExtra());
167: logger.debug("time: " + inentry.getTime());
168: outentry.setTime(inentry.getTime());
169: logger.debug("method: " + inentry.getMethod());
170: outentry.setMethod(inentry.getMethod());
171: logger.debug("comment: " + inentry.getComment());
172: outentry.setComment(inentry.getComment());
173: logger.debug("CRC: " + inentry.getCrc());
174: if (inentry.getCrc() != -1) {
175: outentry.setCrc(inentry.getCrc());
176: }
177: logger.debug("size: " + inentry.getSize());
178: if (inentry.getSize() != -1) {
179: outentry.setSize(inentry.getSize());
180: }
181: out.putNextEntry(outentry);
182: if (!inentry.isDirectory()) {
183: if (inentry.getName().endsWith(".jar")
184: || inentry.getName().endsWith(".zip")
185: || inentry.getName().endsWith(".war")
186: || inentry.getName().endsWith(".ear")) {
187: speedupZip(in, out);
188: } else if (inentry.getName().endsWith(".class")) {
189: speedup(in, inentry.getName(), out);
190: } else {
191: while ((count = in.read(buffer, 0, BUFFER)) != -1) {
192: out.write(buffer, 0, count);
193: }
194: }
195:
196: }
197: out.closeEntry();
198: in.closeEntry();
199: }
200: out.close();
201: in.close();
202: }
203: }
|