1 19 20 package org.netbeans.modules.dbschema.migration.archiver.serializer; 21 22 import java.lang.reflect.Array ; 23 import java.lang.reflect.Field ; 24 import java.lang.reflect.Modifier ; 25 26 import java.util.HashMap ; 27 import java.util.Collection ; 28 import java.util.Iterator ; 29 import java.util.ArrayList ; 30 31 import java.io.IOException ; 32 import java.io.BufferedWriter ; 33 import java.io.File ; 34 import java.io.FileWriter ; 35 import java.io.OutputStreamWriter ; 36 import java.io.OutputStream ; 37 38 43 public class XMLGraphSerializer extends Object { 44 45 47 private BufferedWriter outStream; 48 private int indentLevel; 49 private boolean indent = true; 50 private HashMap ObjectMap; 51 52 private static String indentChar = " "; 53 private static String startTag = "<"; 54 private static String endTagNL = ">\n"; 55 private static String endTag = ">"; 56 private static String endEmptyTagNL = "/>\n"; 57 private static String endEmptyTag = "/>"; 58 private static String objectTag = "OBJECT"; 59 private static String arrayTag = "ARRAY"; 60 private static String rowTag = "ROW"; 61 private static String classAttrib = "CLASS"; 62 private static String IDAttrib = "ID"; 63 private static String refAttrib = "REFERENCE"; 64 private static String rowAttrib = "ROW"; 65 private static String rowClassAttrib = "ROWCLASS"; 66 private static String sizeAttrib = "SIZE"; 67 private static String primitiveArray = "PRIMITIVE"; 68 private static String startCDATA = "<![CDATA["; 69 private static String endCDATA = "]]>"; 70 71 private static final String encoding = "UTF-8"; 73 74 75 private XMLGraphSerializer() 76 { 77 this.ObjectMap = new HashMap (); 78 } 79 80 107 108 public XMLGraphSerializer(OutputStream outStream) 109 { 110 this(); 111 try 114 { 115 this.outStream = new BufferedWriter ( new OutputStreamWriter (outStream, encoding)); 116 } 117 catch(java.io.UnsupportedEncodingException ex) 118 { 119 throw new java.lang.RuntimeException ("Problems creating OutputStreamWriter: " + ex); 120 } 121 } 122 123 125 private String getObjectName(Object obj) 126 { 127 128 133 StringBuffer lReturn = new StringBuffer (); 134 lReturn.append(obj.getClass().getName()); 135 lReturn.append(obj.hashCode()); 136 137 return lReturn.toString(); 138 } 139 140 private void writeLevel(String value) throws IOException 141 { 142 if ( indent ) 143 { 144 for (int i = 0; i < this.indentLevel; i++) 145 { 146 outStream.write(indentChar); 147 } 148 } 149 150 outStream.write(value); 151 } 152 private void writeLevel(char[] value) throws IOException 153 { 154 if ( indent ) 155 { 156 for (int i = 0; i < this.indentLevel; i++) 157 { 158 outStream.write(indentChar); 159 } 160 } 161 162 outStream.write(value); 163 } 164 165 private void writeCDATA(String value) throws IOException 166 { 167 outStream.write(startCDATA); 175 outStream.write(value); 176 outStream.write(endCDATA); 177 } 178 179 private boolean recordObject(Object obj) 180 { 181 182 boolean lObjectRecordedAlready = false; 183 184 String lObjectName = this.getObjectName(obj); 185 186 if ( !this.ObjectMap.containsKey(lObjectName) ) 187 { 188 189 this.ObjectMap.put(lObjectName, obj); 191 } 192 else 193 lObjectRecordedAlready = true; 194 195 return lObjectRecordedAlready; 196 } 197 198 private void addAttribute(String attributeName, String attributeValue, StringBuffer tag) 199 { 200 if (tag.length() > 0 ) 201 tag.append(' '); 202 tag.append(attributeName); 203 tag.append('='); 204 tag.append('\u0022'); 205 tag.append(attributeValue); 206 tag.append('\u0022'); 207 208 } 209 210 private boolean needsCDATA(String value) 211 { 212 213 boolean lNeedsCDATA = false; 214 char lChar; 215 int lStringLength = value.length(); 216 217 for ( int i = 0; i < lStringLength; i++) 218 { 219 lChar = value.charAt(i); 220 if ( lChar == '<' || lChar == '>' || lChar == '&' ) 221 { 222 lNeedsCDATA = true; 223 break; 224 } 225 226 } 227 return lNeedsCDATA; 228 } 229 230 public void DumpStatus() 231 { 232 System.out.println("Dumping state information for XMLGraphSerializer"); 233 System.out.println("Object Map contains "); 234 Iterator lIterator = this.ObjectMap.values().iterator(); 235 while (lIterator.hasNext()) 236 { 237 Object lNext = lIterator.next(); 238 System.out.println("Object Map contains object or class " + lNext.getClass().getName()); 239 System.out.println("Object state is " + lNext.toString()); 240 } 241 System.out.println("Dumping state information for XMLGraphSerializer - END"); 242 } 243 244 246 private void putStartTag(String tag, String elements, boolean empty, boolean newLine) throws IOException 247 { 248 this.writeLevel(startTag); 249 outStream.write(tag); 250 if ( elements != null ) 251 { 252 outStream.write(' '); 253 outStream.write(elements); 254 } 255 if ( empty ) 256 { 257 if ( newLine ) 258 outStream.write(endEmptyTagNL); 259 else 260 outStream.write(endEmptyTag); 261 } 262 else 263 { 264 if ( newLine ) 265 outStream.write(endTagNL); 266 else 267 outStream.write(endTag); 268 269 if ( this.indent ) 270 this.indentLevel++; 271 } 272 } 273 274 private void putEndTag(String tag, boolean doIndent) throws IOException 275 { 276 if ( indent ) 277 this.indentLevel--; 278 279 if ( indent && doIndent) 280 this.writeLevel("</"); 281 else 282 outStream.write("</"); 283 outStream.write(tag); 284 outStream.write(">\n"); 285 } 286 287 private void xlateObject(Object obj) throws IOException , IllegalAccessException 288 { 289 290 try 291 { 292 293 if ( obj == null ) 294 { 295 this.putStartTag(objectTag, null, true, true); 296 297 } 298 else if ( obj instanceof String || 299 obj instanceof StringBuffer 300 ) 301 { 302 this.xlateString(null, obj); 303 } 304 305 else 306 { 307 if ( this.recordObject(obj) ) 308 { 309 this.xlateObjectReference(obj); 311 } 312 else 313 { 314 Class lClassType = obj.getClass(); 315 316 StringBuffer lClassAttributes = new StringBuffer (); 317 this.addAttribute(classAttrib, org.netbeans.modules.dbschema.migration.archiver.MapClassName.getClassNameToken( lClassType.getName()), lClassAttributes); 318 this.addAttribute(IDAttrib, this.getObjectName(obj), lClassAttributes); 319 320 this.putStartTag(objectTag, lClassAttributes.toString(), false, true); 321 322 324 ArrayList lFields; 325 326 HashMap lFieldsMap = new HashMap (); 327 328 Class lClass = lClassType; 329 Field [] lTFields = null; 330 331 while (lClass != null) 332 { 333 lTFields = lClass.getDeclaredFields(); 334 336 for (int i = 0; i < lTFields.length; i++) 337 { 338 if ( ! lFieldsMap.containsKey(lTFields[i].getName()) ) 340 lFieldsMap.put(lTFields[i].getName(), lTFields[i]); 341 } 342 343 lClass = lClass.getSuperclass(); 344 } 345 346 lFields = new ArrayList (lFieldsMap.values()); 347 348 for ( int i = 0; i < lFields.size(); i++) 349 { 350 Field lCurrentField = (Field )(lFields.get(i)); 351 352 if ( !Modifier.isTransient(lCurrentField.getModifiers()) && 353 !Modifier.isStatic(lCurrentField.getModifiers()) 354 ) 355 { 356 357 Class lCurrentFieldType = lCurrentField.getType(); 358 lCurrentField.setAccessible(true); 359 Object lRealValue = lCurrentField.get(obj); 360 String lFieldName = lCurrentField.getName(); 361 if ( lRealValue != null ) 362 { 363 if ( lCurrentFieldType.isPrimitive()) 364 { 365 this.xlatePrimitive(lFieldName,lRealValue); 366 } 367 else if ( lRealValue instanceof java.lang.String || 368 lRealValue instanceof java.lang.StringBuffer 369 ) 370 { 371 this.xlateString(lFieldName,lRealValue); 372 } 373 else if ( lCurrentFieldType.isArray() ) 374 { 375 this.xlateArray(lFieldName, lRealValue); 376 } 377 else if ( lRealValue instanceof Collection ) 378 { 379 this.xlateCollection(lFieldName, lRealValue); 380 } 381 else 382 { 383 this.putStartTag(lFieldName, null, false, true); 384 this.xlateObject(lRealValue); 385 this.putEndTag(lFieldName, true); 386 } 387 } 388 else 389 { 390 this.putStartTag(lFieldName, null, false, true); 391 this.putStartTag(objectTag, null, true, true); 392 this.putEndTag(lFieldName, true); 393 394 } 395 396 } 397 } 398 this.putEndTag(objectTag, true); 399 } 400 } 401 402 } 403 catch (IOException e1) 404 { 405 e1.printStackTrace(); 406 this.DumpStatus(); 407 System.out.println("IO Exception in XLateObject current object class " + obj.getClass().getName()); 408 System.out.println("IO Exception in XLateObject current object is " + obj); 409 this.outStream.close(); 410 throw e1; 411 412 } 413 catch (IllegalAccessException e2) 414 { 415 e2.printStackTrace(); 416 this.DumpStatus(); 417 System.out.println("IO Exception in XLateObject current object class " + obj.getClass().getName()); 418 System.out.println("IO Exception in XLateObject current object is " + obj); 419 this.outStream.close(); 420 throw e2; 421 422 } 423 catch (RuntimeException e3) 424 { 425 e3.printStackTrace(); 426 this.DumpStatus(); 427 System.out.println("IO Exception in XLateObject current object class " + obj.getClass().getName()); 428 System.out.println("IO Exception in XLateObject current object is " + obj); 429 this.outStream.close(); 430 throw e3; 431 } 432 } 433 434 private void xlateObjectReference(Object obj) throws IOException 435 { 436 StringBuffer lReferenceAttributes = new StringBuffer (); 437 this.addAttribute(refAttrib, this.getObjectName(obj), lReferenceAttributes); 438 439 this.putStartTag(objectTag, lReferenceAttributes.toString(), true, true); 440 441 } 442 443 private void xlatePrimitive(String name, Object obj) throws IOException 444 { 445 Class lType = obj.getClass(); 446 String lValue = obj.toString(); 447 448 this.putStartTag(name, null, false, false); 449 450 if ( lType == java.lang.Character.TYPE ) 451 { 452 if ( this.needsCDATA(lValue) ) 454 { 455 this.writeCDATA(lValue); 456 } 457 else 458 outStream.write(lValue); 459 } 460 else 461 outStream.write(lValue); 462 463 this.putEndTag(name, false); 464 } 465 466 private void xlateString(String name, Object obj) throws IOException 467 { 468 469 if ( name != null ) 470 this.putStartTag(name, null, false, false); 471 472 String lValue = obj.toString(); 473 474 if ( this.needsCDATA(lValue) ) 475 { 476 this.writeCDATA(lValue); 477 } 478 else 479 outStream.write(lValue); 480 481 if ( name != null ) 482 this.putEndTag(name, false); 483 } 484 485 private void xlateArray(String name, Object obj) throws IOException , IllegalAccessException 486 { 487 488 StringBuffer lArrayAttributes = new StringBuffer (); 489 490 int lArraySize = Array.getLength(obj); 491 492 this.addAttribute(sizeAttrib, Integer.toString(lArraySize), lArrayAttributes); 493 this.addAttribute(classAttrib, primitiveArray, lArrayAttributes); 494 this.addAttribute(rowClassAttrib,org.netbeans.modules.dbschema.migration.archiver.MapClassName.getClassNameToken( obj.getClass().getComponentType().getName()), lArrayAttributes); 495 496 499 this.putStartTag(name, null, false, true); 500 this.putStartTag(arrayTag, lArrayAttributes.toString(), false, true); 501 502 for ( int i = 0; i < lArraySize; i++) 503 { 504 505 Object lRow = Array.get(obj, i); 506 507 if ( lRow instanceof java.lang.String || 508 lRow instanceof java.lang.Number || 509 lRow instanceof java.lang.Character || 510 lRow instanceof java.lang.Boolean 511 ) 512 { 513 this.xlateSimpleRow(i, lRow); 514 } 515 else 516 { 517 StringBuffer lRowAttributes = new StringBuffer (); 518 this.addAttribute(rowAttrib, Integer.toString(i), lRowAttributes); 519 this.putStartTag(rowTag, lRowAttributes.toString(), false, true); 520 this.xlateObject(lRow); 521 this.putEndTag(rowTag, true); 522 } 523 } 524 525 this.putEndTag(arrayTag, true); 526 this.putEndTag(name, true); 527 528 } 529 530 private void xlateCollection(String name, Object obj) throws IOException , IllegalAccessException 531 { 532 533 StringBuffer lArrayAttributes = new StringBuffer (); 534 535 Collection lArray = (Collection )(obj); 536 537 int lArraySize = lArray.size(); 538 539 this.addAttribute(sizeAttrib, Integer.toString(lArraySize), lArrayAttributes); 540 this.addAttribute(classAttrib, lArray.getClass().getName(), lArrayAttributes); 541 this.addAttribute(rowClassAttrib, "", lArrayAttributes); 542 this.putStartTag(name, null, false, true); 543 this.putStartTag(arrayTag, lArrayAttributes.toString(), false, true); 544 545 546 Iterator lIterator = lArray.iterator(); 547 int lRowCount = 0; 548 549 while (lIterator.hasNext()) 550 { 551 Object lRow = lIterator.next(); 552 553 if ( lRow instanceof java.lang.String || 554 lRow instanceof java.lang.Number || 555 lRow instanceof java.lang.Character || 556 lRow instanceof java.lang.Boolean 557 ) 558 { 559 this.xlateSimpleRow(lRowCount, lRow); 560 } 561 else 562 { 563 StringBuffer lRowAttributes = new StringBuffer (); 564 this.addAttribute(rowAttrib, Integer.toString(lRowCount), lRowAttributes); 565 this.putStartTag(rowTag, lRowAttributes.toString(), false, true); 566 this.xlateObject(lRow); 567 this.putEndTag(rowTag, true); 568 } 569 lRowCount++; 570 } 571 572 this.putEndTag(arrayTag, true); 573 this.putEndTag(name, true); 574 575 } 576 577 private void xlateSimpleRow(int rowNumber, Object obj) throws IOException 578 { 579 580 StringBuffer lRowAttributes = new StringBuffer (); 581 this.addAttribute(rowAttrib, Integer.toString(rowNumber), lRowAttributes); 582 583 Class lObjectClass = obj.getClass(); 584 585 if ( lObjectClass.isPrimitive() ) 586 { 587 if (lObjectClass == java.lang.Integer.TYPE) 588 this.addAttribute("ROWCLASS", "int" , lRowAttributes); 589 else if (lObjectClass == java.lang.Short.TYPE) 590 this.addAttribute("ROWCLASS", "short" , lRowAttributes); 591 else if (lObjectClass == java.lang.Long.TYPE) 592 this.addAttribute("ROWCLASS", "long" , lRowAttributes); 593 else if (lObjectClass == java.lang.Float.TYPE) 594 this.addAttribute("ROWCLASS", "float" , lRowAttributes); 595 else if (lObjectClass == java.lang.Double.TYPE) 596 this.addAttribute("ROWCLASS", "double" , lRowAttributes); 597 else if (lObjectClass == java.lang.Boolean.TYPE) 598 this.addAttribute("ROWCLASS", "boolean" , lRowAttributes); 599 else if (lObjectClass == java.lang.Character.TYPE) 600 this.addAttribute("ROWCLASS", "char" , lRowAttributes); 601 else 602 this.addAttribute("ROWCLASS", "unknown" , lRowAttributes); 603 604 } 605 else 606 this.addAttribute("ROWCLASS", org.netbeans.modules.dbschema.migration.archiver.MapClassName.getClassNameToken( lObjectClass.getName()) , lRowAttributes); 607 608 609 this.addAttribute("VALUE", obj.toString(), lRowAttributes); 610 611 this.putStartTag(rowTag, lRowAttributes.toString(), true, true); 612 613 } 614 615 616 public void writeObject(Object obj) throws IOException 617 { 618 try 619 { 620 outStream.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>\n\n"); 621 622 this.xlateObject(obj); 623 this.outStream.close(); 624 } 625 catch (IOException e1) 626 { 627 e1.printStackTrace(); 628 this.DumpStatus(); 629 try 630 { 631 this.outStream.close(); 632 } 633 catch (IOException lNotClosed) 634 { 635 } 637 throw e1; 638 } 639 catch (IllegalAccessException e2) 640 { 641 e2.printStackTrace(); 642 this.DumpStatus(); 643 try 644 { 645 this.outStream.close(); 646 } 647 catch (IOException lNotClosed) 648 { 649 } 651 } 652 653 } 654 655 } 656 | Popular Tags |