1 /***
2 * Copyright (c) 2002, CodeStreet LLC. All rights reserved.<p>
3 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
4 * conditions are met:<p>
5 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
7 * in the documentation and/or other materials provided with the distribution. Neither the name of CodeStreet LLC. nor the
8 * names of its contributors may be used to endorse or promote products derived from this software without specific prior written
9 * permission.<p>
10 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
11 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
12 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<p>
16 */
17
18 package com.codestreet.messageforge;
19
20 /***
21 * Class to represent a <tt>Hashtable</tt> of <tt>RMsg</tt>.
22 * @see RFldHashtable
23 * @author Jawaid Hakim.
24 */
25 public class RFldMsgObjHashtable extends RFldHashtable
26 {
27 /***
28 * Default constructor.
29 */
30 public RFldMsgObjHashtable()
31 {
32 }
33
34 /***
35 * Constructor.
36 * @param cls Class object of hashtable entries.
37 * @param name Field name.
38 * @param fieldId Field id. Field ids must be either <tt>0</tt>
39 * to indicate that there is no id on the field, or greater. In addition,
40 * field ids must be unique within a messages - no two fields are allowed
41 * to have the same field id.
42 */
43 public RFldMsgObjHashtable(Class cls, String name, int fieldId)
44 {
45 super(name, fieldId);
46 cls_ = cls;
47 }
48
49 /***
50 * Constructor.
51 * @param cls Class object of hashtable entries.
52 * @param name Field name.
53 * @param fieldId Field id. Field ids must be either <tt>0</tt>
54 * to indicate that there is no id on the field, or greater. In addition,
55 * field ids must be unique within a messages - no two fields are allowed
56 * to have the same field id.
57 * @param desc Field description.
58 */
59 public RFldMsgObjHashtable(Class cls, String name, int fieldId, String desc)
60 {
61 super(name, fieldId, desc);
62 cls_ = cls;
63 }
64
65 /***
66 * Get field type.
67 * @return Field type <tt>MSGOBJHASHTABLE</tt>.
68 * @see RFldType
69 */
70 public final RFldType getType()
71 {
72 return RFldType.MSGOBJHASHTABLE;
73 }
74
75 /***
76 * Get the <tt>Class</tt> of the data for this object.
77 * @return <tt>Class</tt> of the data for this object.
78 */
79 public Class getClassObject()
80 {
81 return cls_;
82 }
83
84 /***
85 * Check if another field is equal to this field. Equality is defined
86 * as the fields having the same string representation. A short cut
87 * that needs to be fixed for cases where the string representation is
88 * rounding off numbers etc.
89 * @param anObject Another field.
90 * @return <tt>true</tt> if another field is equal to this field.
91 * Otherwise, returns <tt>false</tt>.
92 */
93 public boolean equals(Object anObject)
94 {
95 if (this == anObject)
96 return true;
97 else if (! (anObject instanceof RFldMsgObjHashtable))
98 return false;
99
100 RFldMsgObjHashtable another = (RFldMsgObjHashtable)anObject;
101
102 if (valSet_ != another.isValSet())
103 return false;
104 else if (! valSet_)
105 return true;
106 else if (dataObj_.size() != another.size())
107 return false;
108
109 try
110 {
111 java.util.Enumeration enum = dataObj_.keys();
112 while (enum.hasMoreElements())
113 {
114 String key = (String)enum.nextElement();
115 RMsg thisVal = (RMsg)dataObj_.get(key);
116 RMsg anotherVal = another.get(key);
117 if (anotherVal == null || ! thisVal.equals(anotherVal))
118 return false;
119 }
120 }
121 catch (ClassCastException ex)
122 {
123 return false;
124 }
125 return true;
126 }
127
128 /***
129 * Get the number of elements in the hashtable.
130 * @return Number of elements in the hashtable. If the value is not set
131 * returns <tt>-1</tt>.
132 */
133 public int size()
134 {
135 if (! valSet_)
136 return -1;
137
138 return dataObj_.size();
139 }
140
141 /***
142 * Get an element from the hashtable.
143 * @param key Key.
144 * @return Specified element. Returns <tt>null</tt> if the index
145 * is out of bounds of the value is not set;
146 * @see #size()
147 */
148 public RMsg get(String key)
149 {
150 if (! valSet_)
151 return null;
152
153 return (RMsg)dataObj_.get(key);
154 }
155
156 /***
157 * Returns the hash code value for the field.
158 * @return A hash code value for the field.
159 */
160 public int hashCode()
161 {
162 int hash = 17;
163 if (valSet_)
164 {
165 java.util.Enumeration enum = dataObj_.elements();
166 while (enum.hasMoreElements())
167 hash = 31 * hash + enum.nextElement().hashCode();
168 }
169 return hash;
170 }
171
172 /***
173 * Reset the field value.
174 * @see #isValSet()
175 */
176 public void reset() throws FieldValidationException
177 {
178 if (locked_)
179 throw new FieldValidationException("Field " + getName() + " is locked");
180
181 if (valSet_)
182 {
183 valSet_ = false;
184 dataObj_ = null;
185 }
186 }
187
188 /***
189 * Set data.
190 * @param newData New data.
191 */
192 public RFld set(Object newData) throws FieldValidationException
193 {
194 if (newData instanceof java.util.Hashtable)
195 return set((java.util.Hashtable)newData);
196 else if (newData != null)
197 throw new FieldValidationException("Unsupported value type: " + newData.getClass().getName());
198 else
199 throw new FieldValidationException("New value is NULL for field: " + getName());
200 }
201
202 /***
203 * Set data.
204 * @param newData New value.
205 */
206 public RFld set(java.util.Hashtable newData) throws FieldValidationException
207 {
208 if (locked_)
209 throw new FieldValidationException("Cannot modify locked field: " + getName());
210
211 if (newData == null)
212 throw new FieldValidationException("New value is NULL for field: " + getName());;
213
214 try
215 {
216 synchronized (newData)
217 {
218 java.util.Hashtable hashTbl = new java.util.Hashtable();
219 synchronized (hashTbl)
220 {
221 java.util.Enumeration enum = newData.keys();
222 while (enum.hasMoreElements())
223 {
224 String fldName = (String)enum.nextElement();
225 Object fldValue = newData.get(fldName);
226 if (fldValue instanceof RMsg)
227 {
228 RMsg msgObj = (RMsg)fldValue;
229
230 // Validate
231 if (! cls_.isInstance(msgObj))
232 throw new FieldValidationException("Invalid data type. Expected " + cls_.getName() + " saw " + msgObj.getClass().getName());
233
234 hashTbl.put(fldName, msgObj);
235 }
236 else
237 throw new FieldValidationException("Invalid data type. Expected " + cls_.getName() + " or java.util.Hashtable saw " + fldValue.getClass().getName());
238 }
239 }
240 reset();
241 dataObj_ = hashTbl;
242 valSet_ = true;
243
244 return this;
245 }
246 }
247 catch (Exception ex)
248 {
249 throw new FieldValidationException(ex);
250 }
251 }
252
253 /***
254 * Set data.
255 * @param newData New data.
256 */
257 public RFld set(org.jdom.Element newData) throws FieldValidationException
258 {
259 if (locked_)
260 throw new FieldValidationException("Cannot modify locked field: " + getName());
261
262 if (newData == null)
263 throw new FieldValidationException("New value is NULL for field: " + getName());;
264
265
266 try
267 {
268 java.util.Hashtable hashTbl = new java.util.Hashtable();
269 synchronized (hashTbl)
270 {
271 java.util.List children = newData.getChildren();
272 for (int i = children.size() - 1; i >= 0; --i)
273 {
274 org.jdom.Element child = (org.jdom.Element)children.get(i);
275 String key = child.getAttributeValue(XML_ATTR_NAME);
276 RMsg msg = (RMsg)ConverterXML.unmarshal(child.getChild(RMsg.XML_TAG));
277 hashTbl.put(key, msg);
278 }
279 }
280 reset();
281 dataObj_ = hashTbl;
282 valSet_ = true;
283
284 return this;
285 }
286 catch (Exception ex)
287 {
288 throw new FieldValidationException(ex);
289 }
290 }
291
292 /***
293 * Validate against constraints. A field is valid if either it's value is set
294 * and satisfies all constraints, or the the field is optional.
295 */
296 public void validate() throws FieldValidationException
297 {
298 // Only need to check that non-optional fields have been set. If a
299 // field has been set then it must be valid since validation is done
300 // with each set.
301 if (! valSet_ && ! optional_)
302 throw new FieldValidationException("Field not set: " + getName());
303 }
304
305 /***
306 * Get data.
307 * @return data Data. If the value of the field has not
308 * been set then <tt>null</tt> is returned.
309 */
310 public java.util.Hashtable getValue()
311 {
312 return dataObj_;
313 }
314
315 /***
316 * Get the field value as an object.
317 * @return Field value as an object. Reference to data is passed out so be
318 * very careful about modifying the data. If the value of the field has not
319 * been set then <tt>null</tt> is returned.
320 */
321 public Object getValueAsObject()
322 {
323 return dataObj_;
324 }
325
326 /***
327 * Get the field value as a string. Throws an exception if the field value is not set.
328 * @return Field value as a string.
329 */
330 public String getValueAsString()
331 {
332 if (! valSet_)
333 return null;
334
335 StringBuffer buf = new StringBuffer((80 * dataObj_.size()) + 1);
336 buf.append(RMsg.NESTED_FIELD_START);
337
338 int i = 0;
339 java.util.Enumeration enum = dataObj_.keys();
340 while (enum.hasMoreElements())
341 {
342 if (++i > 1)
343 buf.append(RFldHashtable.ELEMENT_DELIMITER).append(' ');
344
345 String fldName = (String)enum.nextElement();
346 RMsg fldValue = (RMsg)dataObj_.get(fldName);
347 buf.append(fldName).append(RMsg.FIELD_EQUAL).append(fldValue.toString());
348 }
349 buf.append(RMsg.NESTED_FIELD_END);
350
351 return buf.toString();
352 }
353
354 /***
355 * Get the field value as a <tt>java.util.Hashtable</tt>. Throws an exception
356 * if the field value is not set.
357 * @return Field value as a <tt>java.util.Hashtable</tt>.
358 */
359 public java.util.Hashtable getValueAsHashtable() throws FieldValidationException
360 {
361 return null;
362 }
363
364 /***
365 * Get the XML tag for this field type.
366 * @return XML tag for this field type.
367 */
368 public final String getTag()
369 {
370 return XML_TAG;
371 }
372
373 /***
374 * Set the XML tag for this field type.
375 * @param tag New XML tag for this field type.
376 */
377 public static void setTag(String tag)
378 {
379 XML_TAG = tag;
380 }
381
382 /***
383 * XML tag for this element type.
384 */
385 static transient String XML_TAG = "msgobjhashtbl";
386
387 /***
388 * Data.
389 */
390 protected java.util.Hashtable dataObj_;
391 protected Class cls_;
392 }
This page was automatically generated by Maven