View Javadoc
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 import com.tibco.tibrv.TibrvMsg; 21 import com.tibco.tibrv.TibrvMsgField; 22 import com.tibco.tibrv.TibrvException; 23 import java.io.IOException; 24 import java.io.ObjectInputStream; 25 import java.io.ObjectOutputStream; 26 27 /*** 28 * Class to represent a <tt>TibrvMsg[]</tt> field. 29 * @see com.tibco.tibrv.TibrvMsg 30 * @author Jawaid Hakim. 31 */ 32 public class RFldTibrvMsgArray extends RFldArray 33 { 34 /*** 35 * Constructor. 36 * @param name Field name. Field names must follow the TibrvMsg 37 * field naming conventions. 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 * @see com.tibco.tibrv.TibrvMsg 43 */ 44 public RFldTibrvMsgArray(String name, int fieldId) 45 { 46 super(name, fieldId); 47 } 48 49 /*** 50 * Constructor. 51 * @param name Field name. Field names must follow the TibrvMsg 52 * field naming conventions. 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 * @see com.tibco.tibrv.TibrvMsg 59 */ 60 public RFldTibrvMsgArray(String name, int fieldId, String desc) 61 { 62 super(name, fieldId, desc); 63 } 64 65 /*** 66 * Get field type. 67 * @return Field type <tt>MSGARRAY</tt>. 68 * @see RFldType 69 */ 70 public final RFldType getType() 71 { 72 return RFldType.MSGARRAY; 73 } 74 75 /*** 76 * Check if another field is equal to this field. Equality is defined as both array instances 77 * having the same number of elements, and each element containing fields with same name 78 * and type. 79 * @param anObject Another field. 80 * @return <tt>true</tt> if another field is equal to this field. 81 * Otherwise, returns <tt>false</tt>. 82 */ 83 public boolean equals(Object anObject) 84 { 85 if (this == anObject) 86 { 87 return true; 88 } 89 else if (! (anObject instanceof RFldTibrvMsgArray)) 90 { 91 return false; 92 } 93 94 RFldTibrvMsgArray another = (RFldTibrvMsgArray)anObject; 95 96 if (valSet_ != another.isValSet()) 97 return false; 98 else if (! valSet_) 99 return true; 100 else if (dataObj_.length != another.length()) 101 return false; 102 103 TibrvMsg[] anotherElems = another.getValue(); 104 for (int i = dataObj_.length - 1; i >= 0; --i) 105 { 106 TibrvMsg elem = dataObj_[i]; 107 TibrvMsg anotherElem = anotherElems[i]; 108 for (int j = elem.getNumFields() - 1; j >= 0; --j) 109 { 110 try 111 { 112 TibrvMsgField rvFld = elem.getFieldByIndex(j); 113 TibrvMsgField anotherRvFld = anotherElem.getField(rvFld.name); 114 if (rvFld.type != anotherRvFld.type) 115 return false; 116 } 117 catch (TibrvException ex) 118 { 119 return false; 120 } 121 } 122 } 123 return true; 124 } 125 126 /*** 127 * Get the number of elements in the array. 128 * @return Number of elements in the array. If the value is not set 129 * returns <tt>-1</tt>. 130 */ 131 public int length() 132 { 133 return (! valSet_) ? -1 : dataObj_.length; 134 } 135 136 /*** 137 * Get an element from the array. 138 * @param index Array index. 139 * @return Specified element. Returns <tt>null</tt> if the index 140 * is out of bounds or the value is not set. 141 * @see #length() 142 */ 143 public TibrvMsg getElement(int index) 144 { 145 return (valSet_ && index >= 0 && index < dataObj_.length) ? dataObj_[index] : null; 146 } 147 148 /*** 149 * Returns the hash code value for the field. Since the equals method 150 * is using the comparison of the string representation of the TibrvMsg 151 * then the hashcode is the hashcode of this string. 152 * @return A hash code value for the field. 153 */ 154 public int hashCode() 155 { 156 int hash = 17; 157 if (valSet_) 158 { 159 for (int i = dataObj_.length - 1; i >= 0; --i) 160 hash = 31 * hash + dataObj_[i].hashCode(); 161 } 162 return hash; 163 } 164 165 /*** 166 * Reset the field value. 167 * @see #isValSet() 168 */ 169 public void reset() throws FieldValidationException 170 { 171 if (isLocked()) 172 throw new FieldValidationException("Field " + getName() + " is locked"); 173 174 if (valSet_) 175 { 176 valSet_ = false; 177 dataObj_ = null; 178 } 179 } 180 181 /*** 182 * Set data. 183 * @param newData New data. 184 */ 185 public RFld set(Object newData) throws FieldValidationException 186 { 187 if (newData instanceof TibrvMsg[]) 188 return set((TibrvMsg[])newData); 189 else if (newData instanceof TibrvMsg) 190 return set((TibrvMsg)newData); 191 else if (newData != null) 192 throw new FieldValidationException("Unsupported value type: " + newData.getClass().getName()); 193 else 194 throw new FieldValidationException("New value is NULL for field: " + getName()); 195 } 196 197 /*** 198 * Set data. 199 * @param newData New data. 200 */ 201 public RFld set(TibrvMsg newData) throws FieldValidationException 202 { 203 try 204 { 205 TibrvMsg[] elements = new TibrvMsg[newData.getNumFields()]; 206 for (int i = 0; i < elements.length; ++i) 207 { 208 elements[i] = (TibrvMsg)newData.get(String.valueOf(i)); 209 } 210 211 return set(elements); 212 } 213 catch (Exception ex) 214 { 215 throw new FieldValidationException(ex); 216 } 217 } 218 219 /*** 220 * Set data. 221 * @param newData New data. 222 */ 223 public RFld set(TibrvMsg[] newData) throws FieldValidationException 224 { 225 validate(newData); 226 227 dataObj_ = newData; 228 valSet_ = true; 229 230 return this; 231 } 232 233 /*** 234 * Set data. 235 * @param newData New data. 236 */ 237 public RFld set(java.util.Hashtable newData) throws FieldValidationException 238 { 239 try 240 { 241 synchronized (newData) 242 { 243 TibrvMsg[] elements = new TibrvMsg[newData.size()]; 244 for (int i = elements.length - 1; i >= 0; --i) 245 { 246 Object fldValue = newData.get(String.valueOf(i)); 247 if (fldValue instanceof java.util.Hashtable) 248 { 249 elements[i] = new TibrvMsg(); 250 set((java.util.Hashtable)fldValue, elements[i]); 251 } 252 else 253 throw new FieldValidationException("Expected a java.util.Hashtable"); 254 } 255 return set(elements); 256 } 257 } 258 catch (ProtocolException ex) 259 { 260 throw new FieldValidationException(ex); 261 } 262 } 263 264 /*** 265 * Set data. 266 * @param source Source <tt>java.util.Hashtable</tt>. 267 * @param target Target <tt>com.tibco.tibrv.TibrvMsg</tt>. 268 */ 269 protected void set(java.util.Hashtable source, TibrvMsg target) throws ProtocolException 270 { 271 try 272 { 273 synchronized (source) 274 { 275 for (java.util.Enumeration enum = source.keys(); enum.hasMoreElements(); ) 276 { 277 String nestedFldName = (String)enum.nextElement(); 278 Object nestedFldValue = source.get(nestedFldName); 279 if (nestedFldValue instanceof java.util.Hashtable) 280 { 281 TibrvMsg nestedRvMsg = new TibrvMsg(); 282 set((java.util.Hashtable)nestedFldValue, nestedRvMsg); 283 target.add(nestedFldName, nestedRvMsg); 284 } 285 else 286 target.add(nestedFldName, nestedFldValue); 287 } 288 } 289 } 290 catch (TibrvException ex) 291 { 292 throw new ProtocolException(ex); 293 } 294 } 295 296 /*** 297 * Set the field value from a JDOM element. 298 * @param elem Field value as a JDOM element. 299 */ 300 public final RFld set(org.jdom.Element elem) throws FieldValidationException 301 { 302 java.util.List children = elem.getChildren(); 303 if (children.size() > 0) 304 { 305 TibrvMsg[] newData = new TibrvMsg[children.size()]; 306 for (int i = newData.length - 1; i >= 0; --i) 307 { 308 org.jdom.Element child = (org.jdom.Element)children.get(i); 309 TibrvMsg rvMsg = new TibrvMsg(); 310 RFldTibrvMsg.set(rvMsg, child.getChildren()); 311 312 int index = Integer.valueOf(child.getAttributeValue(XML_ATTR_NAME)).intValue(); 313 newData[index] = rvMsg; 314 } 315 set(newData); 316 } 317 return this; 318 } 319 320 /*** 321 * Validate against constraints. A field is valid if either it's value is set 322 * and satisfies all constraints, or the the field is optional. 323 */ 324 public void validate() throws FieldValidationException 325 { 326 // Only need to check that non-optional fields have been set. If a 327 // field has been set then it must be valid since validation is done 328 // with each set. 329 if (! valSet_ && !optional_) 330 throw new FieldValidationException("Field not set: " + getName()); 331 } 332 333 /*** 334 * Check if a new value will satifsy constraints. 335 * @param newData New value. 336 */ 337 public void validate(TibrvMsg[] newData) throws FieldValidationException 338 { 339 if (locked_) 340 throw new FieldValidationException("Cannot modify locked field: " + getName()); 341 342 if (newData == null) 343 throw new FieldValidationException("New value is NULL for field: " + getName());; 344 } 345 346 /*** 347 * Get data. 348 * @return data Data. Returns <tt>null</tt> if 349 * the field value is not set 350 */ 351 public TibrvMsg[] getValue() 352 { 353 return dataObj_; 354 } 355 356 /*** 357 * Get the field value as an object. 358 * @return Field value as an object. Reference to data is passed out so be 359 * very careful about modifying the data. Returns <tt>null</tt> if 360 * the field value is not set 361 */ 362 public Object getValueAsObject() 363 { 364 return dataObj_; 365 } 366 367 /*** 368 * Get the field value as a string. Throws an exception if the field 369 * value is not set. 370 * @return Field value as a string. 371 */ 372 public String getValueAsString() 373 { 374 if (valSet_) 375 return null; 376 377 StringBuffer buf = new StringBuffer((80 * dataObj_.length) + 1); 378 buf.append(RMsg.NESTED_FIELD_START); 379 for (int i = 0; i < dataObj_.length; ++i) 380 { 381 buf.append(String.valueOf(i)).append(RMsg.FIELD_EQUAL).append(dataObj_[i].toString()); 382 } 383 buf.append(RMsg.NESTED_FIELD_END); 384 385 return buf.toString(); 386 } 387 388 /*** 389 * Get the field value as a <tt>java.util.Hashtable</tt>. 390 * @return Field value as a <tt>java.util.Hashtable</tt>. 391 */ 392 public java.util.Hashtable getValueAsHashtable() throws FieldValidationException 393 { 394 if (! valSet_) 395 throw new FieldValidationException("Field not set: " + getName()); 396 397 java.util.Hashtable hashTbl = new java.util.Hashtable(2 * dataObj_.length + 1); 398 synchronized (hashTbl) 399 { 400 for (int i = 0; i < dataObj_.length; ++i) 401 hashTbl.put(String.valueOf(i), getValueAsHashtable(dataObj_[i])); 402 } 403 return hashTbl; 404 } 405 406 /*** 407 * Convert a TibrvMsg to a java.util.Hashtable. 408 * @param rvMsg TibrvMsg. 409 * @return TibrvMsg value as java.util.Hashtable. 410 */ 411 protected java.util.Hashtable getValueAsHashtable(TibrvMsg rvMsg) throws FieldValidationException 412 { 413 try 414 { 415 int fldCount = rvMsg.getNumFields(); 416 java.util.Hashtable flds = new java.util.Hashtable(2 * fldCount + 1); 417 synchronized (flds) 418 { 419 for (int i = 0; i < fldCount; ++i) 420 { 421 TibrvMsgField fld = rvMsg.getFieldByIndex(i); 422 if (fld.data instanceof TibrvMsg) 423 flds.put(fld.name, getValueAsHashtable((TibrvMsg)fld.data)); 424 else 425 flds.put(fld.name, fld.data); 426 } 427 } 428 return flds; 429 } 430 catch (TibrvException ex) 431 { 432 throw new FieldValidationException(ex); 433 } 434 } 435 436 437 /*** 438 * Write the field as XML to target writer. 439 * @param writer Output target. 440 * @param indent Indentation. 441 * @param newLines Newlines are inserted after each element if <tt>true</tt>. 442 * @param expandEmptyElements Empty elements - elements with no content - are expanded if <tt>true</tt>. 443 */ 444 public void marshal(java.io.Writer writer, int indentLevel, String indent, boolean newLines, boolean expandEmptyElements) throws ConverterException 445 { 446 if (! isValSet()) 447 throw new ConverterException("Field not set: " + getName()); 448 449 marshal(writer, getTag(), getName(), getValueAsObject(), getType().toString(), indentLevel, indent, newLines, expandEmptyElements); 450 } 451 452 /*** 453 * Write the field as XML to target writer. 454 * @param writer Output target. 455 * @param tag XML tag. 456 * @param name Field name. 457 * @param value Field value. 458 * @param type Field type. 459 * @param indentLevel Indentation level. 460 * @param indent Indentation <tt>String</tt>. 461 * @param newLines Newlines are inserted after each element if <tt>true</tt>. 462 * @param expandEmptyElements Empty elements - elements with no content - are expanded if <tt>true</tt>. 463 */ 464 static void marshal(java.io.Writer writer, String tag, String name, Object value, String type, int indentLevel, String indent, boolean newLines, boolean expandEmptyElements) throws ConverterException 465 { 466 try 467 { 468 ConverterXML.openTag(writer, tag, indentLevel, indent); 469 ConverterXML.writeAttribute(writer, XML_ATTR_NAME, name); 470 ConverterXML.closeStartTag(writer, newLines); 471 472 ++indentLevel; 473 TibrvMsg[] elems = (TibrvMsg[])value; 474 for (int i = elems.length - 1; i >= 0; --i) 475 { 476 RFldTibrvMsg.marshal(writer, RFldTibrvMsg.XML_TAG, String.valueOf(i), elems[i], RFldType.MSG.toString(), indentLevel + 1, indent, newLines, expandEmptyElements); 477 } 478 479 --indentLevel; 480 ConverterXML.closeTag(writer, tag, indentLevel, indent, newLines); 481 } 482 catch (java.io.IOException ex) 483 { 484 throw new ConverterException(ex); 485 } 486 } 487 488 489 /*** 490 * Write state of object to object output stream. 491 * @param out Object output stream. 492 */ 493 private void writeObject(ObjectOutputStream out) throws IOException 494 { 495 try 496 { 497 if (valSet_) 498 { 499 out.writeInt(dataObj_.length); 500 for (int i = 0; i < dataObj_.length; ++i) 501 out.write(dataObj_[i].getAsBytes()); 502 } 503 } 504 catch (TibrvException ex) 505 { 506 throw new IOException(ex.toString()); 507 } 508 } 509 510 /*** 511 * Read state of object from object input stream. 512 * @param in Object input stream. 513 */ 514 private void readObject(ObjectInputStream in) throws IOException 515 { 516 try 517 { 518 if (valSet_) 519 { 520 int length = in.readInt(); 521 dataObj_ = new TibrvMsg[length]; 522 for (int i = 0; i < length; ++i) 523 dataObj_[i] = new TibrvMsg((byte[])in.readObject()); 524 } 525 } 526 catch (TibrvException ex) 527 { 528 throw new IOException(ex.toString()); 529 } 530 catch (ClassNotFoundException ex) 531 { 532 throw new IOException(ex.toString()); 533 } 534 } 535 536 /*** 537 * Get the XML tag for this field type. 538 * @return XML tag for this field type. 539 */ 540 public final String getTag() 541 { 542 return XML_TAG; 543 } 544 545 /*** 546 * Set the XML tag for this field type. 547 * @param tag New XML tag for this field type. 548 */ 549 public static void setTag(String tag) 550 { 551 XML_TAG = tag; 552 } 553 554 /*** 555 * XML tag for this element type. 556 */ 557 static transient String XML_TAG = "tibrvmsgarray"; 558 559 /*** 560 * Data. 561 */ 562 protected TibrvMsg[] dataObj_; 563 }

This page was automatically generated by Maven