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 * Abstract base class for fields in a <tt>RMsg</tt>.
22 *
23 * @author Jawaid Hakim.
24 */
25 public abstract class RFld implements RFldInterface
26 {
27 /***
28 * Default constructor.
29 */
30 protected RFld()
31 {
32 init(null, 0, null, false, false, null);
33 }
34
35 /***
36 * Constructor.
37 *
38 * @param name
39 * Field name.
40 * @param fieldId
41 * Field id. Field ids must be either <tt>0</tt> to indicate
42 * that there is no id on the field, or greater. In addition,
43 * field ids must be unique within a messages - no two fields are
44 * allowed to have the same field id.
45 */
46 protected RFld(String name, int fieldId)
47 {
48 init(name, fieldId, null, false, false, null);
49 }
50
51 /***
52 * Constructor.
53 *
54 * @param name
55 * Field name.
56 * @param fieldId
57 * Field id. Field ids must be either <tt>0</tt> to indicate
58 * that there is no id on the field, or greater. In addition,
59 * field ids must be unique within a messages - no two fields are
60 * allowed to have the same field id.
61 * @param desc
62 * Field description.
63 * @see RFldType
64 */
65 protected RFld(String name, int fieldId, String desc)
66 {
67 init(name, fieldId, desc, false, false, null);
68 }
69
70 /***
71 * Constructor.
72 *
73 * @param name
74 * Field name.
75 * @param fieldId
76 * Field id. Field ids must be either <tt>0</tt> to indicate
77 * that there is no id on the field, or greater. In addition,
78 * field ids must be unique within a messages - no two fields are
79 * allowed to have the same field id.
80 * @param desc
81 * Field description.
82 * @param isOptional
83 * <tt>true</tt> to indicate if the field is optional.
84 * Otherwise <tt>false</tt>.
85 * @param isTransient
86 * <tt>true</tt> to indicate if the field is transient.
87 * Otherwise <tt>false</tt>.
88 */
89 protected RFld(String name, int fieldId, String desc, boolean isOptional,
90 boolean isTransient)
91 {
92 init(name, fieldId, desc, isOptional, isTransient, null);
93 }
94
95 /***
96 * Constructor.
97 *
98 * @param name
99 * Field name.
100 * @param fieldId
101 * Field id. Field ids must be either <tt>0</tt> to indicate
102 * that there is no id on the field, or greater. In addition,
103 * field ids must be unique within a messages - no two fields are
104 * allowed to have the same field id.
105 * @param desc
106 * Field description.
107 * @param isOptional
108 * <tt>true</tt> to indicate if the field is optional.
109 * Otherwise <tt>false</tt>.
110 * @param isTransient
111 * <tt>true</tt> to indicate if the field is transient.
112 * Otherwise <tt>false</tt>.
113 * @param propertyName
114 * Property name for field. Set to <code>null</code> if field
115 * is nto a property. When property fields are marshaled to some
116 * protocols - e.g. JMS - their values are added as properties to
117 * the message in addition to the payload.
118 */
119 protected RFld(String name, int fieldId, String desc, boolean isOptional,
120 boolean isTransient, String propertyName)
121 {
122 init(name, fieldId, desc, isOptional, isTransient, propertyName);
123 }
124
125 /***
126 * Initialize.
127 *
128 * @param name
129 * Field name.
130 * @param fieldId
131 * Field id. <tt>0</tt> means the field has no id.
132 * @param desc
133 * Description of field.
134 * @param isOptional
135 * <tt>true</tt> to indicate if the field is optional.
136 * Otherwise <tt>false</tt>.
137 * @param isTransient
138 * <tt>true</tt> to indicate if the field is transient.
139 * Otherwise <tt>false</tt>.
140 * @param propertyName
141 * Property name for field. Set to <code>null</code> if field
142 * is nto a property. When property fields are marshaled to some
143 * protocols - e.g. JMS - their values are added as properties to
144 * the message in addition to the payload.
145 */
146 private void init(String name, int fieldId, String desc,
147 boolean isOptional, boolean isTransient, String propertyName)
148 {
149 name_ = name;
150 fieldId_ = (fieldId > 0) ? fieldId : 0;
151 desc_ = (desc != null) ? desc : RFldString.NA_VALUE;
152 optional_ = isOptional;
153 transient_ = isTransient;
154 propertyName_ = propertyName;
155 }
156
157 /***
158 * Get field name.
159 *
160 * @return Field name.
161 */
162 public final String getName()
163 {
164 return name_;
165 }
166
167 /***
168 * Set field name.
169 *
170 * @param name
171 * Field name.
172 */
173 public final void setName(String name)
174 {
175 name_ = name;
176 }
177
178 /***
179 * Get field id.
180 *
181 * @return Field id.
182 */
183 public final int getId()
184 {
185 return fieldId_;
186 }
187
188 /***
189 * Set field id.
190 *
191 * @param fieldId
192 * Field id.
193 */
194 public final void setId(int fieldId)
195 {
196 fieldId_ = fieldId;
197
198 }
199
200 /***
201 * Get field description.
202 *
203 * @return Field description.
204 */
205 public final String getDesc()
206 {
207 return desc_;
208 }
209
210 /***
211 * Check if this field is optional.
212 *
213 * @return <tt>true</tt> if field is optional. Otherwise, return
214 * <tt>false</tt>.
215 * @see #setOptional(boolean)
216 */
217 public final boolean getOptional()
218 {
219 return optional_;
220 }
221
222 /***
223 * Set optional property.
224 *
225 * @param optional
226 * Optional flag -<tt>true</tt> if this field is optional,
227 * otherwise <tt>false</tt>. Default is <tt>false</tt>.
228 */
229 public final void setOptional(boolean optional)
230 {
231 optional_ = optional;
232 }
233
234 /***
235 * Check if this field is transient.
236 *
237 * @return <tt>true</tt> if field is transient. Otherwise, return
238 * <tt>false</tt>.
239 * @see #setTransient(boolean)
240 */
241 public final boolean getTransient()
242 {
243 return transient_;
244 }
245
246 /***
247 * Set transient property.
248 *
249 * @param isTransient
250 * Transient flag -<tt>true</tt> if this field is transient,
251 * otherwise <tt>false</tt>. Default is <tt>false</tt>.
252 */
253 public final void setTransient(boolean isTransient)
254 {
255 transient_ = isTransient;
256 }
257
258 /***
259 * Get Lock/Unlock property of the field object. If a message is locked then
260 * all the setter methods are disabled.
261 *
262 * @return Returns <tt>true</tt> if field is locked. Otherwise, returns
263 * <tt>false</tt>.
264 */
265 public final boolean isLocked()
266 {
267 return locked_;
268 }
269
270 /***
271 * Lock/Unlock the field object.
272 *
273 * @param locked
274 * <tt>true</tt> to lock the field. Otherwise, <tt>false</tt>
275 * to unlock the field.
276 */
277 public final void setLocked(boolean locked)
278 {
279 locked_ = locked;
280 }
281
282 /***
283 * Get the <tt>tags</tt> for this field. Each field can have one or more
284 * associated tags.
285 *
286 * @return Tags for the field. Returns <tt>null</tt> if this field does
287 * not have any associated tags.
288 */
289 public final String[] getTags()
290 {
291 return tags_;
292 }
293
294 /***
295 * Set the <tt>tags</tt> for this field. Each field can have one or more
296 * tags.
297 *
298 * @param tags
299 * Tags for this field.
300 */
301 public final void setTags(String[] tags)
302 {
303 tags_ = tags;
304 }
305
306 /***
307 * Add a constraint.
308 *
309 * @param cons
310 * Constraint.
311 * @throws IllegalArgumentException
312 * if constraint is null.
313 */
314 public final void addConstraint(RFldConstraint cons)
315 throws FieldValidationException
316 {
317 if (cons == null)
318 throw new java.lang.IllegalArgumentException("NULL constraint");
319
320 if (constraints_ == null)
321 {
322 constraints_ = new RFldConstraint[1];
323 }
324 else if (constraintsIndex_ == constraints_.length)
325 {
326 RFldConstraint[] tmp = new RFldConstraint[constraints_.length * 2];
327 System.arraycopy(constraints_, 0, tmp, 0, constraints_.length);
328 constraints_ = tmp;
329 }
330 constraints_[constraintsIndex_++] = cons;
331 }
332
333 /***
334 * Get the number of constraints.
335 *
336 * @return Number of constraints.
337 * @see #getConstraint(int)
338 */
339 protected final int getConstraintCount()
340 {
341 return constraintsIndex_;
342 }
343
344 /***
345 * Get a specified constraint.
346 *
347 * @param index
348 * Index of constraint.
349 * @return Specified constraint.
350 * @see #getConstraintCount()
351 * @throws NullPointerException
352 * if no constraints have been set on this field.
353 */
354 protected final RFldConstraint getConstraint(int index)
355 {
356 return constraints_[index];
357 }
358
359 /***
360 * Check if the field value is set.
361 *
362 * @return <tt>true if the field value has been set. Otherwise,
363 * returns <tt>false</tt>.
364 */
365 public final boolean isValSet()
366 {
367 return valSet_;
368 }
369
370 /***
371 * Check if the field value is constrained.
372 *
373 * @return <tt>true</tt> if the field value has constraints. Otherwise,
374 * returns <tt>false</tt>.
375 */
376 public final boolean isConstrained()
377 {
378 return (constraintsIndex_ != 0);
379 }
380
381 /***
382 * Check if this field is a property.
383 *
384 * @return Returns <code>true</code> if this field is a property.
385 * @see #getPropertyName()
386 */
387 public boolean isProperty()
388 {
389 return (propertyName_ != null);
390 }
391
392 /***
393 * Get property name.
394 *
395 * @return Returns property name if this field is a property. Returns
396 * <code>null</code> if this field is not a property.
397 * @see #isProperty()
398 */
399 public String getPropertyName()
400 {
401 return propertyName_;
402 }
403
404 /***
405 * Set property name.
406 *
407 * @param name
408 * Property name.
409 * @see #getPropertyName()
410 * @see #isProperty()
411 */
412 public void setPropertyName(final String name)
413 {
414 propertyName_ = name;
415 }
416
417 /***
418 * Get field type.
419 *
420 * @return Field type.
421 * @see RFldType
422 */
423 public abstract RFldType getType();
424
425 /***
426 * Validate against constraints. A field is valid if either it's value is
427 * set and satisfies all constraints, or the the field is optional.
428 */
429 public abstract void validate() throws FieldValidationException;
430
431 /***
432 * Check if another field is equal to this field. Equality is defined as the
433 * fields having the same value.
434 *
435 * @param anObject
436 * Another object.
437 * @return <tt>true</tt> if another message is equal to this message.
438 * Otherwise, returns <tt>false</tt>.
439 */
440 public abstract boolean equals(Object anObject);
441
442 /***
443 * Supply an implementation that is compatable with equals.
444 *
445 * @return hash code of the field.
446 */
447 public abstract int hashCode();
448
449 /***
450 * Set the value of the field from a JDOM element.
451 *
452 * @return Reference to self so method chaining can be used.
453 * @param elem
454 * New field value.
455 */
456 public abstract RFld set(org.jdom.Element elem)
457 throws FieldValidationException;
458
459 /***
460 * Set the value of the field from an <tt>Object</tt>.
461 *
462 * @param newData
463 * New field value.
464 * @return Reference to self so method chaining can be used.
465 */
466 public abstract RFld set(Object newData) throws FieldValidationException;
467
468 /***
469 * Reset the field value.
470 *
471 * @see #isValSet()
472 */
473 public abstract void reset() throws FieldValidationException;
474
475 /***
476 * Get the field value as a string.
477 *
478 * @return Field value as a string. Returns <tt>null</tt> if the field
479 * value is not set.
480 */
481 public abstract String getValueAsString();
482
483 /***
484 * Get the XML tag for this field type.
485 *
486 * @return XML tag for this field type.
487 */
488 public abstract String getTag();
489
490 /***
491 * Write the field as XML to target writer.
492 *
493 * @param writer
494 * Output target.
495 * @param indent
496 * Indentation.
497 * @param newLines
498 * Newlines are inserted after each element if <tt>true</tt>.
499 * @param expandEmptyElements
500 * Empty elements - elements with no content - are expanded if
501 * <tt>true</tt>.
502 */
503 public void marshal(java.io.Writer writer, int indentLevel, String indent,
504 boolean newLines, boolean expandEmptyElements)
505 throws ConverterException
506 {
507 if (!isValSet())
508 throw new ConverterException("Field not set: " + getName());
509
510 Object obj = getValueAsObject();
511 if (getType() == RFldType.DECIMAL)
512 {
513 marshal(writer, getTag(), getName(), Converter
514 .getBigDecimalFormatter().format(obj),
515 getType().toString(), indentLevel, indent, newLines,
516 expandEmptyElements);
517 }
518 else if (getType() == RFldType.DATETIME)
519 {
520 marshal(writer, getTag(), getName(), RDateFormat.getInstance()
521 .format(obj), getType().toString(), indentLevel, indent,
522 newLines, expandEmptyElements);
523
524 }
525 else
526 {
527 marshal(writer, getTag(), getName(), getValueAsObject().toString(),
528 getType().toString(), indentLevel, indent, newLines,
529 expandEmptyElements);
530 }
531 }
532
533 /***
534 * Register custom XML field tags.
535 *
536 * @param xmlTags
537 * A mapping of old tags to new custom tags.
538 */
539 public static final void setXmlTags(java.util.Map xmlTags)
540 throws FieldValidationException
541 {
542 try
543 {
544 java.lang.Object[] args = new java.lang.Object[1];
545 java.lang.Class[] paramTypes = { java.lang.Class
546 .forName("java.lang.String") };
547 for (java.util.Iterator iter = xmlTags.keySet().iterator(); iter
548 .hasNext();)
549 {
550 String oldTag = (String) iter.next();
551 args[0] = xmlTags.get(oldTag);
552 java.lang.Class cls = RFldFactory.getClass(oldTag);
553 java.lang.reflect.Method method = cls.getMethod("setTag",
554 paramTypes);
555 method.invoke(null, args);
556 }
557
558 // Rebuild tag mappings
559 RFldFactory.buildTags();
560 RFldTibrvMsg.buildTags();
561 }
562 catch (Exception ex)
563 {
564 throw new FieldValidationException(ex);
565 }
566 }
567
568 /***
569 * Register custom XML attribute names.
570 *
571 * @param name
572 * New name of the field name attribute.
573 * @param val
574 * New name of the field value attribute.
575 * @param id
576 * New name of the id field attribute.
577 */
578 public static final void setXmlAttrNames(String name, String val, String id)
579 {
580 XML_ATTR_NAME = name;
581 XML_ATTR_VALUE = val;
582 XML_ATTR_ID = id;
583 }
584
585 public static final String buildMinMaxConstraintKey(Object min, Object max)
586 {
587 StringBuffer key = new StringBuffer();
588 key.append('<');
589 if (min != null)
590 key.append(min);
591 key.append('>');
592 key.append('<');
593 if (max != null)
594 key.append(max);
595 key.append('>');
596 return key.toString();
597 }
598
599 /***
600 * Write the field as XML to target writer.
601 *
602 * @param writer
603 * Output target.
604 * @param indent
605 * Indentation.
606 * @param newLines
607 * Newlines are inserted after each element if <tt>true</tt>.
608 * @param expandEmptyElements
609 * Empty elements - elements with no content - are expanded if
610 * <tt>true</tt>.
611 */
612 protected final static void marshal(java.io.Writer writer, String tag,
613 String name, String val, String type, int indentLevel,
614 String indent, boolean newLines, boolean expandEmptyElements)
615 throws ConverterException
616 {
617 try
618 {
619 ConverterXML.openTag(writer, tag, indentLevel, indent);
620 ConverterXML.writeAttribute(writer, XML_ATTR_NAME, name,
621 XML_ATTR_VALUE, val);
622 ConverterXML.closeTag(writer, newLines);
623 }
624 catch (java.io.IOException ex)
625 {
626 throw new ConverterException(ex);
627 }
628 }
629
630 /***
631 * Field name.
632 */
633 protected String name_;
634
635 /***
636 * Field id.
637 */
638 protected int fieldId_;
639
640 /***
641 * Field description.
642 */
643 protected String desc_;
644
645 /***
646 * Optional flag -<tt>true</tt> if this field is optional. Otherwise,
647 * <tt>false</tt>. Default is <tt>false</tt>.
648 */
649 protected boolean optional_;
650
651 /***
652 * Transient flag -<tt>true</tt> if this field is transient. Otherwise,
653 * <tt>false</tt>. Default is <tt>false</tt>.
654 */
655 protected boolean transient_;
656
657 /***
658 * Lock flag -<tt>true</tt> indicated that the field is locked,
659 * <tt>false</tt> indicated that the field is not locked.
660 */
661 protected boolean locked_;
662
663 /***
664 * Flag to check if value is set. <tt>true</tt> indicates that the field's
665 * value has been set. <tt>false</tt> indicates that the field's value has
666 * not been set.
667 */
668 protected boolean valSet_;
669
670 /***
671 * Property name. Should be set for fields that have been tagged as
672 * properties.
673 */
674 protected String propertyName_;
675
676 /***
677 * Field tags.
678 */
679 protected String[] tags_;
680
681 /***
682 * Attribute 'name' of JDOM element.
683 */
684 static transient String XML_ATTR_NAME = "name";
685
686 /***
687 * Attribute 'val' of JDOM element.
688 */
689 static transient String XML_ATTR_VALUE = "val";
690
691 /***
692 * Attribute 'id' of JDOM element.
693 */
694 static transient String XML_ATTR_ID = "id";
695
696 /***
697 * Field constraints.
698 */
699 private RFldConstraint[] constraints_;
700
701 private int constraintsIndex_;
702 }
This page was automatically generated by Maven