View Javadoc

1   package org.sourceforge.jemm.lifecycle;
2   
3   import java.util.HashMap;
4   import java.util.HashSet;
5   import java.util.Map;
6   import java.util.Set;
7   
8   import org.sourceforge.jemm.database.FieldInfo;
9   import org.sourceforge.jemm.database.FieldType;
10  import org.sourceforge.jemm.types.ID;
11  
12  /**
13   * The data store for the ShadowObject that is associated with an Enhanced
14   * class.
15   * 
16   * Stores the ID of Shadowed Objects.
17   * 
18   * @author Paul Keeble
19   * 
20   */
21  public class ShadowData {
22  	ID id;
23  	int version;
24  	Map<FieldInfo, ID> fieldData;
25  	Set<FieldInfo> initialisations;
26  	
27  	public ShadowData(ID id, int version) {
28  		if (id == null)
29  			throw new IllegalArgumentException("ID may not be null");
30  		this.id = id;
31  		this.version = version;
32  	}
33  
34  	/**
35  	 * Sets a field value.
36  	 * 
37  	 * @param type
38  	 *            The type of the field
39  	 * @param name
40  	 *            The name of the field
41  	 * @param value
42  	 *            The value the field should take
43  	 */
44  	@SuppressWarnings("unchecked")
45  	public void setField(Class declaringClass, FieldType type, String name, ID value) {
46  		initialiseFieldData();
47  		if(type==FieldType.OBJECT || type==FieldType.OBJECT_ARRAY) {
48  			fieldData.put(new FieldInfo(name,declaringClass, type), value);
49  		}
50  	}
51  	
52  	/**
53  	 * Allows lazy initialisation of the fieldData if its not needed for a
54  	 * class, which could save a dramatic amount of RAM on large numbers of such
55  	 * instances.
56  	 */
57  	private void initialiseFieldData() {
58  		if (fieldData == null)
59  			fieldData = new HashMap<FieldInfo, ID>();
60  	}
61  
62  	/**
63  	 * Returns a field if it exists, otherwise throws an exception
64  	 * 
65  	 * @param type
66  	 *            The class type of the field
67  	 * @param name
68  	 *            The name of the field
69  	 * @return The value stored, which can be null
70  	 * @throws RuntimeException
71  	 *             if the field does not exist
72  	 */
73  	@SuppressWarnings("unchecked")
74  	public ID getField(Class declaringClass, FieldType type, String name) {
75  		FieldInfo key = new FieldInfo(name,declaringClass,type);
76  		
77  		if (fieldData == null)
78  			throw new RuntimeException("Field " + key + " does not exist");
79  		
80  		if (fieldData.containsKey(key))
81  			return fieldData.get(key);
82  		
83  		throw new RuntimeException("Field " + key + " does not exist");
84  	}
85  	
86  	/**
87  	 * Returns an array of all the fields, which could be zero length if none
88  	 * exist.
89  	 * 
90  	 * @return The fields contained within this ShadowData
91  	 */
92  	public FieldInfo[] getFields() {
93  		if (fieldData == null)
94  			return new FieldInfo[0];
95  		return fieldData.keySet().toArray(new FieldInfo[0]);
96  	}
97  	
98  	public boolean hasField(Class<?> declaringClass, FieldType type, String name) {
99  		if(fieldData==null)
100 			return false;
101 		return fieldData.containsKey(new FieldInfo(name,declaringClass,type));
102 	}
103 	
104 	/**
105 	 * Gets the Object ID the ShadowData is associated with.
106 	 * 
107 	 * @return The ID
108 	 */
109 	public ID getID() {
110 		return id;
111 	}
112 
113 	/**
114 	 * The version of the Object has defined by the Database that gave the ID to
115 	 * the enhanced object.
116 	 * 
117 	 * @return The version id.
118 	 */
119 	public int getVersion() {
120 		return version;
121 	}
122 
123 	/**
124 	 * Sets the version to a new value.
125 	 * 
126 	 * @param newVersion
127 	 *            The new version parameter.
128 	 */
129 	public void setVersion(int newVersion) {
130 		version = newVersion;
131 	}
132 	
133 	private void initialiseMapSetup() {
134 		if(initialisations==null)
135 			initialisations = new HashSet<FieldInfo>();
136 	}
137 	
138 	/**
139 	 * Sets the status of a Field to say that it has already been initialised to the
140 	 * Entity.
141 	 * 
142 	 * @param declaringClass
143 	 * @param type
144 	 * @param name
145 	 */
146 	public void initialiseField(Class<?> declaringClass, FieldType type, String name) {
147 		if(!hasField(declaringClass,type,name)) 
148 			return;
149 		initialiseMapSetup();
150 		initialisations.add(new FieldInfo(name,declaringClass,type));
151 	}
152 	
153 	/**
154 	 * Removes the initialisation flag for a field.
155 	 * 
156 	 * @param declaringClass
157 	 * @param type
158 	 * @param name
159 	 */
160 	public void clearInitialisation(Class<?> declaringClass, FieldType type, String name) {
161 		if(initialisations==null)
162 			return;
163 		initialisations.remove(new FieldInfo(name,declaringClass, type));
164 	}
165 	
166 	public void clearInitialisations() {
167 		if(initialisations==null)
168 			return;
169 		initialisations = null;
170 	}
171 	
172 	/**
173 	 * Returns the current known initialisation state of an Object.
174 	 * 
175 	 * @param declaringClass
176 	 * @param type
177 	 * @param name
178 	 * @return True if the object is currently initialised, otherwise false.
179 	 */
180 	public boolean isFieldInitialised(Class<?> declaringClass, FieldType type, String name) {
181 		FieldInfo key = new FieldInfo(name,declaringClass,type);
182 		if(initialisations!=null && initialisations.contains(key)) {
183 			return true;
184 		}
185 		return false;
186 	}
187 	
188 	public String toString() {
189 		StringBuilder builder = new StringBuilder("ShadowData[");
190 		for(FieldInfo fi : fieldData.keySet()) {
191 			builder.append(fi);
192 			builder.append("=");
193 			builder.append(fieldData.get(fi));
194 			if(initialisations.contains(fi))
195 				builder.append("*");
196 			builder.append(",");
197 		}
198 		builder.append("]");
199 		return builder.toString();
200 	}
201 
202 }