001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.internal.util; 014 015 import java.io.IOException; 016 import java.io.Serializable; 017 import java.lang.reflect.Constructor; 018 import java.util.WeakHashMap; 019 020 import net.sf.oval.internal.Log; 021 022 /** 023 * Serializable Wrapper for java.lang.reflect.Constructor objects since they do not implement Serializable 024 * 025 * @author Sebastian Thomschke 026 */ 027 public final class SerializableConstructor implements Serializable 028 { 029 private static final Log LOG = Log.getLog(SerializableConstructor.class); 030 031 private static final WeakHashMap<Constructor< ? >, SerializableConstructor> CACHE = // 032 new WeakHashMap<Constructor< ? >, SerializableConstructor>(); 033 034 private static final long serialVersionUID = 1L; 035 036 public static SerializableConstructor getInstance(final Constructor< ? > constructor) 037 { 038 /* 039 * intentionally the following code is not synchronized 040 */ 041 SerializableConstructor sm = CACHE.get(constructor); 042 if (sm == null) 043 { 044 sm = new SerializableConstructor(constructor); 045 CACHE.put(constructor, sm); 046 } 047 return sm; 048 } 049 050 private transient Constructor< ? > constructor; 051 052 private final Class< ? > declaringClass; 053 054 private final Class< ? >[] parameterTypes; 055 056 private SerializableConstructor(final Constructor< ? > constructor) 057 { 058 this.constructor = constructor; 059 parameterTypes = constructor.getParameterTypes(); 060 declaringClass = constructor.getDeclaringClass(); 061 } 062 063 /** 064 * @return the constructor 065 */ 066 public Constructor< ? > getConstructor() 067 { 068 return constructor; 069 } 070 071 /** 072 * @return the declaringClass 073 */ 074 public Class< ? > getDeclaringClass() 075 { 076 return declaringClass; 077 } 078 079 /** 080 * @return the parameterTypes 081 */ 082 public Class< ? >[] getParameterTypes() 083 { 084 return parameterTypes; 085 } 086 087 private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException 088 { 089 in.defaultReadObject(); 090 try 091 { 092 constructor = declaringClass.getDeclaredConstructor(parameterTypes); 093 } 094 catch (final NoSuchMethodException ex) 095 { 096 LOG.debug("Unexpected NoSuchMethodException occured", ex); 097 throw new IOException(ex.getMessage()); 098 } 099 } 100 }