⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classstreamhandler.java

📁 Wicket一个开发Java Web应用程序框架。它使得开发web应用程序变得容易而轻松。 Wicket利用一个POJO data beans组件使得它可以与任何持久层技术相结合。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.util.io;import java.io.IOException;import java.io.NotSerializableException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ObjectStreamClass;import java.io.Serializable;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Proxy;import java.security.AccessController;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import sun.misc.Unsafe;import sun.reflect.ReflectionFactory;/** * TODO DOC ME! *  * NOTE: this class uses Sun-specific features: we use {@link Unsafe} because we need to set the * final fields, and we use {@link ReflectionFactory} to be able to find constructors appropriate * for serialization. *  * @author jcompagner */public final class ClassStreamHandler{	private static Unsafe unsafe;	static	{		try		{			Class[] classes = ObjectStreamClass.class.getDeclaredClasses();			for (int i = 0; i < classes.length; i++)			{				if (classes[i].getName().equals("java.io.ObjectStreamClass$FieldReflector"))				{					Field unsafeField = classes[i].getDeclaredField("unsafe");					unsafeField.setAccessible(true);					unsafe = (Unsafe)unsafeField.get(null);					break;				}			}		}		catch (Throwable e)		{			// e.printStackTrace()		}	}	private static final ReflectionFactory reflFactory = (ReflectionFactory)AccessController			.doPrivileged(new ReflectionFactory.GetReflectionFactoryAction());	private static Map handlesClasses = new HashMap();	private static short classCounter = 0;	/**	 * 	 */	public static final byte HANDLE = 1;	/**	 * 	 */	public static final byte NULL = 0;	/**	 * 	 */	public static final byte CLASS_DEF = 2;	/**	 * 	 */	public static final byte ARRAY = 3;	/**	 * 	 */	public static final byte PRIMITIVE_ARRAY = 4;	/**	 * 	 */	public static final int CLASS = 5;	static ClassStreamHandler lookup(Class cls) throws NotSerializableException	{		ClassStreamHandler classHandler = (ClassStreamHandler)handlesClasses.get(cls.getName());		if (classHandler == null)		{			classHandler = new ClassStreamHandler(cls);			handlesClasses.put(cls.getName(), classHandler);			handlesClasses.put(new Short(classHandler.getClassId()), classHandler);		}		return classHandler;	}	static ClassStreamHandler lookup(short s)	{		ClassStreamHandler classHandler = (ClassStreamHandler)handlesClasses.get(new Short(s));		if (classHandler == null)		{			throw new RuntimeException("class not found for: " + s);		}		return classHandler;	}	/**	 * 	 */	private final Class clz;	private final List fields;	private final short classId;	private final Constructor cons;	private final Method writeReplaceMethod;	private final Method readResolveMethod;	private final List writeObjectMethods;	private final List readObjectMethods;	private final PrimitiveArray primitiveArray;	/**	 * Construct.	 * 	 * @param cls	 *            TODO	 * @throws WicketSerializeableException	 */	private ClassStreamHandler(Class cls) throws WicketSerializeableException	{		this.classId = classCounter++;		this.clz = cls;		if (cls.isPrimitive())		{			fields = null;			cons = null;			writeObjectMethods = null;			readObjectMethods = null;			writeReplaceMethod = null;			readResolveMethod = null;			if (clz == boolean.class)			{				primitiveArray = new BooleanPrimitiveArray();			}			else if (clz == byte.class)			{				primitiveArray = new BytePrimitiveArray();			}			else if (clz == short.class)			{				primitiveArray = new ShortPrimitiveArray();			}			else if (clz == char.class)			{				primitiveArray = new CharPrimitiveArray();			}			else if (clz == int.class)			{				primitiveArray = new IntPrimitiveArray();			}			else if (clz == long.class)			{				primitiveArray = new LongPrimitiveArray();			}			else if (clz == float.class)			{				primitiveArray = new FloatPrimitiveArray();			}			else if (clz == double.class)			{				primitiveArray = new DoublePrimitiveArray();			}			else			{				throw new RuntimeException("Unsupported primitive " + cls);			}		}		else if (cls.isInterface())		{			fields = null;			cons = null;			writeObjectMethods = null;			readObjectMethods = null;			writeReplaceMethod = null;			readResolveMethod = null;			primitiveArray = null;		}		else if (Proxy.isProxyClass(clz))		{			fields = null;			cons = null;			writeObjectMethods = null;			writeReplaceMethod = null;			readResolveMethod = null;			readObjectMethods = null;			primitiveArray = null;		}		else		{			fields = new ArrayList();			primitiveArray = null;			writeObjectMethods = new ArrayList(2);			readObjectMethods = new ArrayList(2);			writeReplaceMethod = getInheritableMethod(clz, "writeReplace", null, Object.class);			readResolveMethod = getInheritableMethod(clz, "readResolve", null, Object.class);			if (readResolveMethod == null)			{				cons = getSerializableConstructor(clz);				if (cons == null)				{					throw new WicketSerializeableException(							"No Serializable constructor found for " + cls);				}			}			else			{				cons = getSerializableConstructor(clz);			}			Class parent = cls;			while (parent != Object.class)			{				Method method = getPrivateMethod(parent, "writeObject",						new Class[] { ObjectOutputStream.class }, Void.TYPE);				if (method != null)				{					writeObjectMethods.add(method);				}				method = getPrivateMethod(parent, "readObject",						new Class[] { ObjectInputStream.class }, Void.TYPE);				if (method != null)				{					readObjectMethods.add(method);				}				parent = parent.getSuperclass();			}			fillFields(cls);		}	}	/**	 * @return	 */	public Class getStreamClass()	{		return clz;	}	/**	 * @return	 */	public short getClassId()	{		return classId;	}	/**	 * @return	 * @throws InvocationTargetException	 * @throws IllegalAccessException	 * @throws InstantiationException	 * @throws IllegalArgumentException	 */	public Object createObject() throws IllegalArgumentException, InstantiationException,			IllegalAccessException, InvocationTargetException	{		return cons.newInstance(null);	}	/**	 * @param cls	 */	private void fillFields(Class cls)	{		if (cls == null)		{			return;		}		Field[] fields = cls.getDeclaredFields();		for (int i = 0; i < fields.length; i++)		{			Field field = fields[i];			field.setAccessible(true);			if (!Modifier.isStatic(field.getModifiers()) &&					!Modifier.isTransient(field.getModifiers()))			{				FieldAndIndex fai = null;				Class clz = field.getType();				long offset = unsafe.objectFieldOffset(field);				if (clz == boolean.class)				{					fai = new BooleanFieldAndIndex(field);				}				else if (clz == byte.class)				{					fai = new ByteFieldAndIndex(field);				}				else if (clz == short.class)				{					fai = new ShortFieldAndIndex(field);				}				else if (clz == char.class)				{					fai = new CharFieldAndIndex(field);				}				else if (clz == int.class)				{					fai = new IntFieldAndIndex(field);				}				else if (clz == long.class)				{					fai = new LongFieldAndIndex(field);				}				else if (clz == float.class)				{					fai = new FloatFieldAndIndex(field);				}				else if (clz == double.class)				{					fai = new DoubleFieldAndIndex(field);				}				else				{					fai = new ObjectFieldAndIndex(field);				}				this.fields.add(fai);			}		}		cls = cls.getSuperclass();		if (cls != Object.class)		{			fillFields(cls);		}		return;	}	/**	 * @param woos	 * @param obj	 * @throws WicketSerializeableException	 */	public void writeFields(WicketObjectOutputStream woos, Object obj)			throws WicketSerializeableException	{		FieldAndIndex fai = null;		try		{			for (int i = 0; fields != null && i < fields.size(); i++)			{				fai = (FieldAndIndex)fields.get(i);				fai.writeField(obj, woos);			}		}		catch (WicketSerializeableException wse)		{			wse.addTrace(fai.field.getName());			throw wse;		}		catch (Exception ex)		{			String field = fai == null || fai.field == null ? "" : fai.field.getName();			String msg = "Error writing field: " + field + " for object class: " + obj.getClass();			throw new WicketSerializeableException(msg, ex);		}	}	/**	 * @param wois	 * @throws WicketSerializeableException	 */	public void readFields(WicketObjectInputStream wois, Object object)			throws WicketSerializeableException	{		FieldAndIndex fai = null;		try		{			for (int i = 0; i < fields.size(); i++)			{				fai = (FieldAndIndex)fields.get(i);				fai.readField(object, wois);			}		}		catch (WicketSerializeableException wse)		{			wse.addTrace(fai.field.getName());			throw wse;		}		catch (Exception ex)		{			throw new WicketSerializeableException("Error reading field: " + fai.field.getName() +					" for object class: " + object.getClass(), ex);		}	}	public void writeArray(Object obj, WicketObjectOutputStream wois) throws IOException	{		primitiveArray.writeArray(obj, wois);	}	public Object readArray(WicketObjectInputStream wois) throws IOException	{		return primitiveArray.readArray(wois);	}	/**	 * @param woos	 * @param obj	 * @return	 * @throws InvocationTargetException	 * @throws IllegalAccessException	 * @throws IllegalArgumentException	 */	public boolean invokeWriteMethod(WicketObjectOutputStream woos, Object obj)	{		if ((writeObjectMethods != null) && writeObjectMethods.size() > 0)		{			for (int i = writeObjectMethods.size(); --i >= 0;)			{				Method method = (Method)writeObjectMethods.get(i);				try				{					method.invoke(obj, new Object[] { woos });				}				catch (IllegalArgumentException ex)				{					throw new RuntimeException(ex);				}				catch (IllegalAccessException ex)				{					throw new RuntimeException(ex);				}				catch (InvocationTargetException ex)				{					throw new RuntimeException(ex);				}			}			return true;		}		return false;	}	/**	 * @param wois	 * @return	 */	public boolean invokeReadMethod(WicketObjectInputStream wois, Object obj)	{		if ((readObjectMethods != null) && readObjectMethods.size() > 0)		{			for (int i = readObjectMethods.size(); --i >= 0;)			{				Method method = (Method)readObjectMethods.get(i);				try				{					method.invoke(obj, new Object[] { wois });				}				catch (IllegalArgumentException ex)				{					throw new RuntimeException(ex);				}				catch (IllegalAccessException ex)				{					throw new RuntimeException(ex);				}				catch (InvocationTargetException ex)				{					throw new RuntimeException(ex);				}			}			return true;		}		return false;	}	private static Constructor getSerializableConstructor(Class cl)	{		Class initCl = cl;		while (Serializable.class.isAssignableFrom(initCl))		{			if ((initCl = initCl.getSuperclass()) == null)			{				return null;			}		}		try		{			Constructor cons = initCl.getDeclaredConstructor((Class[])null);			int mods = cons.getModifiers();			if ((mods & Modifier.PRIVATE) != 0 ||					((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && !packageEquals(cl,							initCl)))			{				return null;			}			cons = reflFactory.newConstructorForSerialization(cl, cons);			cons.setAccessible(true);			return cons;		}		catch (NoSuchMethodException ex)		{			return null;		}	}	/**	 * Returns non-static private method with given signature defined by given class, or null if	 * none found. Access checks are disabled on the returned method (if any).	 */	private static Method getPrivateMethod(Class cl, String name, Class[] argTypes, Class returnType)	{		try		{			Method meth = cl.getDeclaredMethod(name, argTypes);			meth.setAccessible(true);			int mods = meth.getModifiers();			return ((meth.getReturnType() == returnType) && ((mods & Modifier.STATIC) == 0) && ((mods & Modifier.PRIVATE) != 0))					? meth					: null;		}		catch (NoSuchMethodException ex)		{			return null;		}	}	/**	 * Returns non-static, non-abstract method with given signature provided it is defined by or	 * accessible (via inheritance) by the given class, or null if no match found. Access checks are	 * disabled on the returned method (if any).	 */	private static Method getInheritableMethod(Class cl, String name, Class[] argTypes,			Class returnType)	{		Method meth = null;		Class defCl = cl;		while (defCl != null)		{			try			{				meth = defCl.getDeclaredMethod(name, argTypes);				break;			}			catch (NoSuchMethodException ex)			{				defCl = defCl.getSuperclass();			}		}		if ((meth == null) || (meth.getReturnType() != returnType))		{			return null;		}		meth.setAccessible(true);		int mods = meth.getModifiers();		if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0)		{			return null;		}		else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0)

⌨️ 快捷键说明

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