/*
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* Copyright (C) 2000-2003 Lucas Bruand. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by the Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Just4Log" and "Apache Software Foundation" must not be used to
* endorse or promote products derived from this software without prior
* written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache", nor may
* "Apache" appear in their name, without prior written permission of the
* Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
* DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the Apache Software Foundation. For more information on the
* Apache Software Foundation, please see <http://www.apache.org/>.
*
*/
package net.sf.just4log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.sf.just4log.transform.Transform;
import net.sf.just4log.util.NotClosingInputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.ClassFormatException;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.util.ClassPath;
import org.apache.bcel.util.SyntheticRepository;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This is the core class of Just4log. It actually performs all the bytecode transforming.
* @author Lucas Bruand
* @version $Id: JustLog.java,v 1.11 2003/07/23 23:59:10 lbruand Exp $
*/
public class JustLog {
private static Log logger = LogFactory.getLog(JustLog.class);
private static String CLASSID =
"$Id: JustLog.java,v 1.11 2003/07/23 23:59:10 lbruand Exp $";
/**
* Constructor private. not used.
*/
private JustLog() {
super();
}
public static void setClasspath(String cp) {
String extracp =
ClassPath.SYSTEM_CLASS_PATH.toString()
+ File.pathSeparatorChar
+ cp;
logger.info("using " + extracp + "as classpath.");
System.out.println("using " + extracp + "as classpath.");
Repository.setRepository(
SyntheticRepository.getInstance(new ClassPath(extracp)));
}
private static NotClosingInputStream input =
new NotClosingInputStream(null);
public static void speedup(
InputStream in,
String filename,
OutputStream out)
throws ClassFormatException, IOException {
input.setInput(in);
JavaClass source = (new ClassParser(input, filename)).parse();
logger.info("Source size:" + source.getBytes().length);
JavaClass target = Transform.speedup(source);
logger.info("after optimization: " + target.getBytes().length);
byte[] tmp = target.getBytes();
out.write(tmp);
}
/**
* Optimize a classfile for faster logging.
*
* @param source A file to read from.
* @param target A file to read to.
* @throws ClassFormatException The source file is not in the valid JDK1.2 classformat.
* @throws IOException An error happened while accessing disks.
*/
public static void speedup(File source, File target)
throws ClassFormatException, IOException {
FileInputStream in = null;
FileOutputStream out = null;
byte[] buffer = new byte[BUFFER];
int count;
try {
in = new FileInputStream(source);
ByteArrayOutputStream outb = new ByteArrayOutputStream();
while ((count = in.read(buffer, 0, BUFFER)) != -1) {
outb.write(buffer, 0, count);
}
out = new FileOutputStream(target);
speedup(
new ByteArrayInputStream(outb.toByteArray()),
source.getName(),
out);
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
logger.warn("problem with IOException " + e);
} catch (NullPointerException e) {
logger.warn("problem with Exception " + e);
}
}
}
public static final int BUFFER = 4096;
public static void speedupZip(InputStream input, OutputStream output)
throws IOException {
ZipInputStream in = new ZipInputStream(input);
ZipOutputStream out = new ZipOutputStream(output);
ZipEntry inentry;
ZipEntry outentry;
int count;
byte[] buffer = new byte[BUFFER];
while ((inentry = in.getNextEntry()) != null) {
outentry = new ZipEntry(inentry.getName());
logger.debug("Extra: " + inentry.getExtra());
outentry.setExtra(inentry.getExtra());
logger.debug("time: " + inentry.getTime());
outentry.setTime(inentry.getTime());
logger.debug("method: " + inentry.getMethod());
outentry.setMethod(inentry.getMethod());
logger.debug("comment: " + inentry.getComment());
outentry.setComment(inentry.getComment());
logger.debug("CRC: " + inentry.getCrc());
if (inentry.getCrc() != -1) {
outentry.setCrc(inentry.getCrc());
}
logger.debug("size: " + inentry.getSize());
if (inentry.getSize() != -1) {
outentry.setSize(inentry.getSize());
}
out.putNextEntry(outentry);
if (!inentry.isDirectory()) {
if (inentry.getName().endsWith(".jar")
|| inentry.getName().endsWith(".zip")
|| inentry.getName().endsWith(".war")
|| inentry.getName().endsWith(".ear")) {
speedupZip(in, out);
} else if (inentry.getName().endsWith(".class")) {
speedup(in, inentry.getName(), out);
} else {
while ((count = in.read(buffer, 0, BUFFER)) != -1) {
out.write(buffer, 0, count);
}
}
}
out.closeEntry();
in.closeEntry();
}
out.close();
in.close();
}
}