diff -r 000000000000 -r 373ffda63c9a src/share/jaxws_classes/com/sun/xml/internal/bind/v2/bytecode/ClassTailor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/bytecode/ClassTailor.java Wed Apr 27 01:27:09 2016 +0800 @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.bind.v2.bytecode; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.sun.xml.internal.bind.Util; + +/** + * Replaces a few constant pool tokens from a class "template" and then loads it into the VM. + * + * @author Kohsuke Kawaguchi + */ +public final class ClassTailor { + + private ClassTailor() {} // no instanciation please + + private static final Logger logger = Util.getClassLogger(); + + /** + * Returns the class name in the JVM format (such as "java/lang/String") + */ + public static String toVMClassName( Class c ) { + assert !c.isPrimitive(); + if(c.isArray()) + // I have no idea why it is designed like this, but javap says so. + return toVMTypeName(c); + return c.getName().replace('.','/'); + } + + public static String toVMTypeName( Class c ) { + if(c.isArray()) { + // TODO: study how an array type is encoded. + return '['+toVMTypeName(c.getComponentType()); + } + if(c.isPrimitive()) { + if(c==Boolean.TYPE) return "Z"; + if(c==Character.TYPE) return "C"; + if(c==Byte.TYPE) return "B"; + if(c==Double.TYPE) return "D"; + if(c==Float.TYPE) return "F"; + if(c==Integer.TYPE) return "I"; + if(c==Long.TYPE) return "J"; + if(c==Short.TYPE) return "S"; + + throw new IllegalArgumentException(c.getName()); + } + return 'L'+c.getName().replace('.','/')+';'; + } + + + + public static byte[] tailor( Class templateClass, String newClassName, String... replacements ) { + String vmname = toVMClassName(templateClass); + return tailor( + SecureLoader.getClassClassLoader(templateClass).getResourceAsStream(vmname+".class"), + vmname, newClassName, replacements ); + } + + + /** + * Customizes a class file by replacing constant pools. + * + * @param image + * The image of the template class. + * @param replacements + * A list of pair of strings that specify the substitution + * {@code String[]{search_0, replace_0, search_1, replace_1, ..., search_n, replace_n }} + * + * The search strings found in the constant pool will be replaced by the corresponding + * replacement string. + */ + public static byte[] tailor( InputStream image, String templateClassName, String newClassName, String... replacements ) { + DataInputStream in = new DataInputStream(image); + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + DataOutputStream out = new DataOutputStream(baos); + + // skip until the constant pool count + long l = in.readLong(); + out.writeLong(l); + + // read the constant pool size + short count = in.readShort(); + out.writeShort(count); + + // replace constant pools + for( int i=0; i0) + out.write(buf,0,len); + + in.close(); + out.close(); + + // by now we got the properly tailored class file image + return baos.toByteArray(); + + } catch( IOException e ) { + // never happen + logger.log(Level.WARNING,"failed to tailor",e); + return null; + } + } +}