serializationadapter.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 302 行

JAVA
302
字号
/* * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.webbeans.bytecode;import java.io.*;import java.util.*;import java.lang.reflect.*;import com.caucho.bytecode.*;import com.caucho.config.*;import com.caucho.loader.*;import com.caucho.webbeans.cfg.*;import com.caucho.webbeans.component.*;import com.caucho.vfs.*;/** * interceptor generation */public class SerializationAdapter {  private final Class _cl;    private Class _proxyClass;  private SerializationAdapter(Class cl)  {    _cl = cl;  }  public static Class gen(Class cl)  {    if (Modifier.isFinal(cl.getModifiers()))      return cl;    if (HandleAware.class.isAssignableFrom(cl))      return cl;    SerializationAdapter gen = new SerializationAdapter(cl);    Class proxyClass = gen.generateProxy();    return proxyClass;  }  public static void setHandle(Object obj, Object handle)  {    try {      Class cl = obj.getClass();      for (Field field : cl.getDeclaredFields()) {	if (field.getName().equals("__caucho_handle")) {	  field.setAccessible(true);	  field.set(obj, handle);	}      }    } catch (Exception e) {      throw ConfigException.create(e);    }  }  private Class generateProxy()  {    try {      JavaClassLoader jLoader = new JavaClassLoader(_cl.getClassLoader());            JavaClass jClass = new JavaClass(jLoader);      jClass.setAccessFlags(Modifier.PUBLIC);      ConstantPool cp = jClass.getConstantPool();      jClass.setWrite(true);            jClass.setMajor(49);      jClass.setMinor(0);      String superClassName = _cl.getName().replace('.', '/');      String thisClassName = superClassName + "$BeanProxy";      jClass.setSuperClass(superClassName);      jClass.setThisClass(thisClassName);      jClass.addInterface("java/io/Serializable");      generateConstructors(jClass, superClassName);            generateWriteReplace(jClass);      ByteArrayOutputStream bos = new ByteArrayOutputStream();      WriteStream out = Vfs.openWrite(bos);      jClass.write(out);          out.close();      byte []buffer = bos.toByteArray();      if (false) {	out = Vfs.lookup("file:/tmp/caucho/qa/temp.class").openWrite();	out.write(buffer, 0, buffer.length);	out.close();      }            String cleanName = thisClassName.replace('/', '.');      _proxyClass = new ProxyClassLoader().loadClass(cleanName, buffer);    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw new RuntimeException(e);    }    return _proxyClass;  }  private void generateConstructors(JavaClass jClass, String superClassName)  {    for (Constructor baseCtor : _cl.getDeclaredConstructors()) {      if (Modifier.isPrivate(baseCtor.getModifiers()))	continue;      generateConstructor(jClass, superClassName, baseCtor);    }  }  public static void generateConstructor(JavaClass jClass,					 String superClassName,					 Constructor baseCtor)  {    Class []types = baseCtor.getParameterTypes();    StringBuilder sb = new StringBuilder();    createDescriptor(sb, types);    sb.append("V");    String descriptor = sb.toString();          JavaMethod ctor = jClass.createMethod("<init>", descriptor);          ctor.setAccessFlags(Modifier.PUBLIC);          CodeWriterAttribute code = ctor.createCodeWriter();    code.setMaxLocals(5 + 2 * types.length);    code.setMaxStack(5 + 2 * types.length);    code.pushObjectVar(0);    marshal(code, types);    code.invokespecial(superClassName, "<init>", descriptor, 1, 0);    code.addReturn();    code.close();  }  private void generateWriteReplace(JavaClass jClass)  {    JavaField jField      = jClass.createField("__caucho_handle", "Ljava/lang/Object;");    jField.setAccessFlags(Modifier.PRIVATE);        JavaMethod jMethod      = jClass.createMethod("writeReplace", "()Ljava/lang/Object;");        jMethod.setAccessFlags(Modifier.PRIVATE);          CodeWriterAttribute code = jMethod.createCodeWriter();    code.setMaxLocals(5);    code.setMaxStack(5);    code.pushObjectVar(0);    code.getField(jClass.getThisClass(), "__caucho_handle",		   "Ljava/lang/Object;");    code.addObjectReturn();        code.close();  }  public static void marshal(CodeWriterAttribute code, Class []param)  {    int stack = 1;    int index = 1;        for (int i = 0; i < param.length; i++) {      Class type = param[i];            if (boolean.class.equals(type)	  || byte.class.equals(type)	  || short.class.equals(type)	  || int.class.equals(type)) {	code.pushIntVar(index);	index += 1;	stack += 1;      }      else if (long.class.equals(type)) {	code.pushLongVar(index);	index += 2;	stack += 2;      }      else if (float.class.equals(type)) {	code.pushFloatVar(index);	index += 1;	stack += 1;      }      else if (double.class.equals(type)) {	code.pushDoubleVar(index);	index += 2;	stack += 2;      }      else {	code.pushObjectVar(index);	index += 1;	stack += 1;      }    }  }  private int parameterCount(Class []parameters)  {    int count = 0;    for (Class param : parameters) {      if (long.class.equals(param) || double.class.equals(param))	count += 2;      else	count += 1;    }    return count;  }  public static void createDescriptor(StringBuilder sb, Class []params)  {    sb.append("(");        for (Class param : params) {      sb.append(createDescriptor(param));    }        sb.append(")");  }  public static String createDescriptor(Class cl)  {    if (cl.isArray())      return "[" + createDescriptor(cl.getComponentType());    String primValue = _prim.get(cl);    if (primValue != null)      return primValue;    return "L" + cl.getName().replace('.', '/') + ";";  }  private static HashMap<Class,String> _prim = new HashMap<Class,String>();  private static HashMap<Class,String> _boxClass = new HashMap<Class,String>();  static {    _prim.put(boolean.class, "Z");    _prim.put(byte.class, "B");    _prim.put(char.class, "C");    _prim.put(short.class, "S");    _prim.put(int.class, "I");    _prim.put(long.class, "J");    _prim.put(float.class, "F");    _prim.put(double.class, "D");    _prim.put(void.class, "V");        _boxClass.put(boolean.class, "java/lang/Boolean");    _boxClass.put(byte.class, "java/lang/Byte");    _boxClass.put(char.class, "java/lang/Character");    _boxClass.put(short.class, "java/lang/Short");    _boxClass.put(int.class, "java/lang/Integer");    _boxClass.put(long.class, "java/lang/Long");    _boxClass.put(float.class, "java/lang/Float");    _boxClass.put(double.class, "java/lang/Double");  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?