001    /*******************************************************************************
002     * Portions created by Sebastian Thomschke are copyright (c) 2005-2015 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                    synchronized (CACHE)
038                    {
039                            SerializableField sm = CACHE.get(field);
040                            if (sm == null)
041                            {
042                                    sm = new SerializableField(field);
043                                    CACHE.put(field, sm);
044                            }
045                            return sm;
046                    }
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    }