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 + -
显示快捷键?