/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2012, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.apmrouter.instrumentation;
import javassist.ClassPool;
import javassist.CtClass;
import org.helios.apmrouter.util.SimpleLogger;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
/**
* <p>Title: SocketStreamClassTransformer</p>
* <p>Description: Modifies accessors on socket input and output streams</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.instrumentation.SocketStreamClassTransformer</code></p>
*/
public class SocketStreamClassTransformer implements ClassFileTransformer {
public static final String SOS = "java/net/SocketOutputStream";
/**
* {@inheritDoc}
* @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
*/
@Override
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
ClassPool tClassPool = null;
try {
if(SOS.equals(className)) {
tClassPool = new ClassPool();
tClassPool.appendSystemPath();
CtClass clazz = tClassPool.get("java.net.SocketOutputStream");
clazz.setModifiers(clazz.getModifiers() | Modifier.PUBLIC);
byte[] byteCode = clazz.toBytecode();
SimpleLogger.info("\n\tGenerated Byte Code for [" , clazz.getName(), "]\n");
return byteCode;
}
} catch (Throwable ex) {
SimpleLogger.warn("Failed to instrument [", className, "]", ex);
return classfileBuffer;
}
return classfileBuffer;
}
/**
* Converts a class name to the binary name used by the class file transformer, or returns the passed name if it is already a binary name
* @param name The class name to convert
* @return the binary name
*/
protected String convertToBinaryName(String name) {
int index = name.indexOf('.');
if(index!=-1) {
return name.replace('.', '/');
}
return name;
}
/**
* Converts a class name from the binary name used by the class file transformer to the standard dot notated form, or returns the passed name if it is already a binary name
* @param name The class name to convert
* @return the standard dot notated class name
*/
protected String convertFromBinaryName(String name) {
int index = name.indexOf('/');
if(index!=-1) {
return name.replace('/', '.');
}
return name;
}
}