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.Field; 018 import java.util.WeakHashMap; 019 020 import net.sf.oval.internal.Log; 021 022 /** 023 * Serializable Wrapper for java.lang.reflect.Field objects since they do not implement Serializable 024 * 025 * @author Sebastian Thomschke 026 */ 027 public final class SerializableField implements Serializable 028 { 029 private static final Log LOG = Log.getLog(SerializableField.class); 030 031 private static final WeakHashMap<Field, SerializableField> CACHE = new WeakHashMap<Field, SerializableField>(); 032 033 private static final long serialVersionUID = 1L; 034 035 public static SerializableField getInstance(final Field field) 036 { 037 /* 038 * intentionally the following code is not synchronized 039 */ 040 SerializableField sm = CACHE.get(field); 041 if (sm == null) 042 { 043 sm = new SerializableField(field); 044 CACHE.put(field, sm); 045 } 046 return sm; 047 } 048 049 private final Class< ? > declaringClass; 050 private transient Field field; 051 private final String name; 052 053 private SerializableField(final Field field) 054 { 055 this.field = field; 056 name = field.getName(); 057 declaringClass = field.getDeclaringClass(); 058 } 059 060 /** 061 * @return the declaringClass 062 */ 063 public Class< ? > getDeclaringClass() 064 { 065 return declaringClass; 066 } 067 068 /** 069 * @return the field 070 */ 071 public Field getField() 072 { 073 return field; 074 } 075 076 /** 077 * @return the name 078 */ 079 public String getName() 080 { 081 return name; 082 } 083 084 private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException 085 { 086 in.defaultReadObject(); 087 try 088 { 089 field = declaringClass.getDeclaredField(name); 090 } 091 catch (final NoSuchFieldException ex) 092 { 093 LOG.debug("Unexpected NoSuchFieldException occured", ex); 094 throw new IOException(ex.getMessage()); 095 } 096 } 097 }