001 package com.sptci.prevayler;
002
003 import java.io.Serializable;
004 import java.util.Collection;
005 import java.util.LinkedHashMap;
006 import java.util.LinkedHashSet;
007 import java.util.Map;
008
009 /**
010 * A class used as the storage mechanism for storing the references to
011 * other prevalent objects from prevalent objects stored in the system.
012 *
013 * <p>© Copyright 2008 <a href='http://sptci.com/' target='_top'>Sans Pareil Technologies, Inc.</a></p>
014 * @author Rakesh Vidyadharan 2008-05-23
015 * @version $Id: ReferenceStorage.java 4345 2008-06-30 21:22:03Z rakesh $
016 */
017 public class ReferenceStorage implements Serializable
018 {
019 private static final long serialVersionUID = 1L;
020
021 /**
022 * A map used to maintain the references for a prevalent object identified
023 * by its object id.
024 */
025 private final Map<Object,FieldStorage> storage =
026 new LinkedHashMap<Object,FieldStorage>();
027
028 /**
029 * Add the specified reference information for the prevalent object to
030 * the store.
031 *
032 * @see ReferenceStorage.FieldStorage#add
033 * @param object The prevalent object whose reference information is being
034 * added to the store.
035 * @param name The name of the field that contains a reference.
036 * @param oid The oid for the referenced field.
037 */
038 public void add( final PrevalentObject object, final String name,
039 final Object oid )
040 {
041 if ( ! storage.containsKey( object.getObjectId() ) )
042 {
043 storage.put( object.getObjectId(), new FieldStorage() );
044 }
045
046 storage.get( object.getObjectId() ).add( name, oid );
047 }
048
049 /**
050 * Return a collection of field names that represent the references to
051 * other prevalent objects in the store for the specified prevalent
052 * object.
053 *
054 * @see ReferenceStorage.FieldStorage#getFields
055 * @param object The prevalent object whose references are to be fetched.
056 * @return The collection of referenced field names.
057 */
058 public Collection<String> getFields( final PrevalentObject object )
059 {
060 final Collection<String> collection = new LinkedHashSet<String>();
061 if ( object == null ) return collection;
062
063 final FieldStorage store = storage.get( object.getObjectId() );
064 if ( store != null ) collection.addAll( store.getFields() );
065
066 return collection;
067 }
068
069 /**
070 * Return the value associated with the specified prevalent object and
071 * reference field name.
072 *
073 * @see ReferenceStorage.FieldStorage#getValue
074 * @param object The prevalent object in which the referenced field exists
075 * @param name The name of the reference field.
076 * @return The value associated with the object in the store.
077 */
078 public Object getValue( final PrevalentObject object, final String name )
079 {
080 Object value = null;
081 if ( object == null ) return value;
082
083 final FieldStorage store = storage.get( object.getObjectId() );
084 if ( store != null ) value = store.getValue( name );
085
086 return value;
087 }
088
089 /**
090 * Remove the specified prevalent object from the store.
091 *
092 * @param object The prevalent object to remove from the store.
093 */
094 public void remove( final PrevalentObject object )
095 {
096 if ( object == null ) return;
097 storage.remove( object.getObjectId() );
098 }
099
100 /**
101 * Remove the reference(s) for the specified field in the specified
102 * prevalent object.
103 *
104 * @param object The prevalent object whose field reference(s) are to be
105 * removed.
106 * @param field The field whose reference(s) are to be removed.
107 */
108 public void remove( final PrevalentObject object, final String field )
109 {
110 if ( object == null ) return;
111 final FieldStorage store = storage.get( object.getObjectId() );
112 if ( store != null ) store.remove( field );
113 }
114
115 /**
116 * Remove the reference for the specified prevalent object from the
117 * specified field.
118 *
119 * @param object The prevalent object whose reference is to be removed.
120 * @param field The field in the prevalent object whose reference is to
121 * be removed.
122 * @param objectId The reference that is to be removed.
123 */
124 public void remove( final PrevalentObject object, final String field,
125 final Object objectId )
126 {
127 if ( object == null ) return;
128 final FieldStorage store = storage.get( object.getObjectId() );
129 if ( store != null ) store.remove( field, objectId );
130 }
131
132 /**
133 * The storage for all the references fields in a prevalent object.
134 */
135 private class FieldStorage implements Serializable
136 {
137 private static final long serialVersionUID = 1L;
138
139 /** The map used to maintain the field name to object id mappings. */
140 private final Map<String,Object> fieldStorage =
141 new LinkedHashMap<String,Object>();
142
143 /**
144 * Add the specified mapping to the store.
145 *
146 * @param name The name of the reference field.
147 * @param oid The oid value for the referenced object.
148 */
149 private void add( final String name, final Object oid )
150 {
151 fieldStorage.put( name, oid );
152 }
153
154 /**
155 * Remove the mapping for the specified field from {@link #fieldStorage}.
156 *
157 * @param name The name of the reference field whose mapping is to be
158 * removed.
159 */
160 private void remove( final String name )
161 {
162 fieldStorage.remove( name );
163 }
164
165 /**
166 * Remove the specified reference from the field. If the field contains
167 * a collection of references, then the specified reference is removed
168 * from the collection. Otherwise this method is identical to {@link
169 * #remove( String )}.
170 *
171 * @param name The name of the reference field whose mapping is to be
172 * removed.
173 * @param objectId The object id that is to be removed from the mapping.
174 */
175 private void remove( final String name, final Object objectId )
176 {
177 final Object value = fieldStorage.get( name );
178 if ( value instanceof Collection )
179 {
180 ( (Collection) value ).remove( objectId );
181 }
182 else
183 {
184 remove( name );
185 }
186 }
187
188 /**
189 * Return a collection of field names that are stored in in this store.
190 *
191 * @return The collection of field names.
192 */
193 private Collection<String> getFields()
194 {
195 return fieldStorage.keySet();
196 }
197
198 /**
199 * Return the value associated with the field with the specified name.
200 *
201 * @param name The name of the field whose value is to be retrieved.
202 * @return The value associated with the name.
203 */
204 private Object getValue( final String name )
205 {
206 return fieldStorage.get( name );
207 }
208 }
209 }