1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.caleigo.core;
19
20
21 import java.util.*;
22
23 import org.caleigo.core.exception.*;
24 import org.caleigo.toolkit.log.*;
25 import org.caleigo.toolkit.util.*;
26
27
28
29 /*** <Description of FieldDescriptor>
30 *
31 * @author Dennis Zikovic
32 * @version 1.00
33 *
34 *//*
35 *
36 * WHEN WHO WHY & WHAT
37 * ------------------------------------------------------------------------------
38 * 2001-03-12 Dennis Zikovic Creation
39 * 2003-07-03 Niklas Norberg changed constructor removed the parameter int index
40 */
41 public class FieldDescriptor implements IFieldDescriptor
42 {
43
44 private String mCodeName;
45 private String mSourceName;
46 private String mDisplayName;
47 private String mEntityDescriptorName;
48 private DataType mDataType;
49 private int mLength;
50 private int mFlags;
51 private Object mDefaultValue;
52
53 private List mValidatorList;
54
55
56
57
58 /*** The FieldDescriptor constructor has package scope to avoid missuse.
59 */
60 protected FieldDescriptor(String codeName, String sourceName, String displayName, String entityDescriptorName, DataType dataType, int length, int flags, Object defValue)
61 {
62 mCodeName = codeName;
63 mSourceName = sourceName;
64 mDisplayName = displayName;
65 mEntityDescriptorName = entityDescriptorName;
66 mDataType = dataType;
67 mLength = length;
68 mFlags = flags;
69 mDefaultValue = defValue;
70 }
71
72
73 public String toString()
74 {
75 return this.getEntityDescriptor().getDataSourceDescriptor().getCodeName()+"."+this.getEntityDescriptor().getCodeName()+"."+this.getCodeName();
76 }
77
78
79 protected Object writeReplace() throws java.io.ObjectStreamException
80 {
81 return new Dezerializer(mEntityDescriptorName, mCodeName);
82 }
83
84
85
86 public String getCodeName()
87 {
88 return mCodeName;
89 }
90
91 public String getSourceName()
92 {
93 return mSourceName;
94 }
95
96 public String getDisplayName()
97 {
98 return ResourceProvider.getString(this.getEntityDescriptor().getCodeName(), mCodeName, mDisplayName);
99 }
100
101 public DataType getDataType()
102 {
103 return mDataType;
104 }
105
106 public int getLength()
107 {
108 return mLength;
109 }
110
111 public Object getDefaultValue()
112 {
113 if(mDefaultValue instanceof IProxyData)
114 return ((IProxyData)mDefaultValue).getData();
115 else
116 return mDefaultValue;
117 }
118
119 public boolean isIdentityField()
120 {
121 return (mFlags & IDENTITY_FIELD)!=0;
122 }
123
124 public boolean isReferenceField()
125 {
126 return this.getReferenceFieldRelation()!=null;
127 }
128
129 public boolean isRequired()
130 {
131 return (mFlags & REQUIRED)!=0;
132 }
133
134 public boolean isIndexed()
135 {
136 return (mFlags & INDEXED)!=0;
137 }
138
139 public boolean isAutoGenerated()
140 {
141 return (mFlags & AUTOGEN)!=0;
142 }
143
144 public boolean isNameField()
145 {
146 return (mFlags & NAME_FIELD)!=0;
147 }
148
149 public boolean isOverviewField()
150 {
151 return (mFlags & OVERVIEW_FIELD)!=0;
152 }
153
154 public boolean isHintField()
155 {
156 return (mFlags & HINT_FIELD)!=0;
157 }
158
159 public boolean isHiddenField()
160 {
161 return (mFlags & HIDDEN_FIELD)!=0;
162 }
163
164 public boolean isReadOnly()
165 {
166 return (mFlags & READ_ONLY_FIELD)!=0;
167 }
168
169 public boolean isNaturalOrder()
170 {
171 return (mFlags & NATURAL_ORDER)!=0;
172 }
173
174 public IEntityDescriptor getEntityDescriptor()
175 {
176 IEntityDescriptor entityDescriptor = null;
177 try
178 {
179 Class entityClass = Class.forName(mEntityDescriptorName);
180 java.lang.reflect.Field field = entityClass.getField("instance");
181 entityDescriptor = (IEntityDescriptor)field.get(null);
182 }
183 catch(Exception e)
184 {
185 String msg = "Invalid entity descriptor data: "+mEntityDescriptorName;
186 Log.printError(this, msg);
187 throw new InvalidDescriptorException(msg, e);
188 }
189 return entityDescriptor;
190 }
191
192 /*** This method returns true if the called field descriptor can validate
193 * data described by the field in the context of the provided IDataProvider
194 * object. The minimum requiriment is that described field data can be
195 * provided but in some cases other data resources is also required.
196 */
197 public boolean canValidate(IDataProvider dataProvider)
198 {
199 boolean valid = true;
200 for(int j=0; valid && mValidatorList!=null && j<mValidatorList.size(); j++)
201 valid = ((IDataValidator)mValidatorList.get(j)).canValidate(dataProvider);
202 return valid;
203 }
204
205 /*** This method validates the provided data object as described by the
206 * called field descriptor in the context of the provided IDataProvider
207 * object.
208 */
209 public ValidationResult validateData(Object data, IDataProvider dataProvider)
210 {
211 ValidationResult result = ValidationResult.VALID_RESULT;
212
213
214 result = this.performBaseValidation(data);
215
216
217 for(int j=0; result.isValid() && mValidatorList!=null && j<mValidatorList.size(); j++)
218 if(!((IDataValidator)mValidatorList.get(j)).isDataValid(data, dataProvider))
219 result = new ValidationResult(this, ((IDataValidator)mValidatorList.get(j)).getInvalidMessage(data, dataProvider));
220
221 return result;
222 }
223
224 /*** Access method that returns the field relation that the called field
225 * is a reference to. If the called field descriptor is not a reference
226 * field then null is returned.
227 */
228 public IFieldRelation getReferenceFieldRelation()
229 {
230 IFieldRelation refRelation = null;
231 java.util.Iterator it = this.getFieldRelations();
232 while(refRelation==null && it.hasNext())
233 {
234 IFieldRelation relation = (IFieldRelation)it.next();
235 if(relation.getReferenceField()==this)
236 refRelation = relation;
237 }
238 return refRelation;
239 }
240
241 /*** Access method that returns an iterator for all IFieldRelation
242 * objects that the called field descripyor is a part of.
243 */
244 public java.util.Iterator getFieldRelations()
245 {
246 return new FieldRelationIterator();
247 }
248
249
250
251 protected void addValidator(IDataValidator dataValidator)
252 {
253 if(mValidatorList!=null)
254 mValidatorList = new ArrayList(5);
255 mValidatorList.add(dataValidator);
256 }
257
258 /*** Performs basic validations that are relevant for all fields like
259 * checking for null values in reguired field data.
260 */
261 public ValidationResult performBaseValidation(Object dataValue)
262 {
263
264 if(dataValue==null && this.isRequired() && !this.isAutoGenerated())
265 return new ValidationResult(this, ResourceProvider.getString(this.getEntityDescriptor().getCodeName(), mCodeName+".RequiredMSG", "The "+this.getDisplayName()+" field may not be empty."));
266
267
268 if(this.getDataType()==DataType.STRING && dataValue!=null && ((String)dataValue).length()>mLength && mLength>0)
269 return new ValidationResult(this, ResourceProvider.getString(this.getEntityDescriptor().getCodeName(), mCodeName+".ToLongMSG", "The "+this.getDisplayName()+" field is to long. It may only contain "+mLength+" characters."));
270
271 return ValidationResult.VALID_RESULT;
272 }
273
274
275 protected class FieldRelationIterator implements java.util.Iterator
276 {
277 private int mEntityRelationIndex;
278 private int mFieldRelationIndex;
279 private Object mNextObject;
280
281 public FieldRelationIterator()
282 {
283 mEntityRelationIndex = 0;
284 mFieldRelationIndex = 0;
285 this.next();
286 }
287
288 public Object next()
289 {
290 Object retObject = mNextObject;
291
292 mNextObject = null;
293 while(mNextObject==null && mEntityRelationIndex<getEntityDescriptor().getEntityRelationCount())
294 {
295
296 while(mNextObject==null && mFieldRelationIndex<getEntityDescriptor().getEntityRelation(mEntityRelationIndex).getFieldCount())
297 {
298
299 IFieldRelation rel = getEntityDescriptor().getEntityRelation(mEntityRelationIndex).getFieldRelation(mFieldRelationIndex);
300 if(rel.getReferenceField()==FieldDescriptor.this || rel.getTargetField()==FieldDescriptor.this)
301 mNextObject = rel;
302
303
304 mFieldRelationIndex++;
305 }
306
307
308 if(mFieldRelationIndex>=getEntityDescriptor().getEntityRelation(mEntityRelationIndex).getFieldCount())
309 {
310 mEntityRelationIndex++;
311 mFieldRelationIndex = 0;
312 }
313 }
314
315 return retObject;
316 }
317
318 public boolean hasNext()
319 {
320 return mNextObject!=null;
321 }
322
323 public void remove()
324 {
325 throw new java.lang.UnsupportedOperationException();
326 }
327 }
328
329 protected static class Dezerializer implements java.io.Serializable
330 {
331
332 protected String mEntityDescriptorClassName;
333 protected String mFieldDescriptorCodeName;
334
335
336 public Dezerializer(String entityDescriptorClassName, String fieldDescriptorCodeName)
337 {
338 mEntityDescriptorClassName = entityDescriptorClassName;
339 mFieldDescriptorCodeName = fieldDescriptorCodeName;
340 }
341
342
343 protected Object readResolve() throws java.io.ObjectStreamException
344 {
345 try
346 {
347 Class entityDescriptorClass = Class.forName(mEntityDescriptorClassName);
348 java.lang.reflect.Field entityDescriptorInstanceField = entityDescriptorClass.getField("instance");
349 IEntityDescriptor entityDescriptor = (IEntityDescriptor) entityDescriptorInstanceField.get(null);
350 return entityDescriptor.getFieldDescriptor(mFieldDescriptorCodeName);
351 }
352 catch (Exception e)
353 {
354 Log.printError(this, "Error in readResolve", e);
355 throw new java.io.InvalidObjectException(e.getMessage());
356 }
357 }
358 }
359 }