KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > dbschema > migration > archiver > serializer > XMLGraphSerializer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.dbschema.migration.archiver.serializer;
21
22 import java.lang.reflect.Array JavaDoc;
23 import java.lang.reflect.Field JavaDoc;
24 import java.lang.reflect.Modifier JavaDoc;
25
26 import java.util.HashMap JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.ArrayList JavaDoc;
30
31 import java.io.IOException JavaDoc;
32 import java.io.BufferedWriter JavaDoc;
33 import java.io.File JavaDoc;
34 import java.io.FileWriter JavaDoc;
35 import java.io.OutputStreamWriter JavaDoc;
36 import java.io.OutputStream JavaDoc;
37
38 /**
39  *
40  * @author Mark Munro
41  * @version %I%
42  */

43 public class XMLGraphSerializer extends Object JavaDoc {
44
45     // Fields
46

47     private BufferedWriter JavaDoc outStream;
48     private int indentLevel;
49     private boolean indent = true;
50     private HashMap JavaDoc ObjectMap;
51
52     private static String JavaDoc indentChar = " ";
53     private static String JavaDoc startTag = "<";
54     private static String JavaDoc endTagNL = ">\n";
55     private static String JavaDoc endTag = ">";
56     private static String JavaDoc endEmptyTagNL = "/>\n";
57     private static String JavaDoc endEmptyTag = "/>";
58     private static String JavaDoc objectTag = "OBJECT";
59     private static String JavaDoc arrayTag = "ARRAY";
60     private static String JavaDoc rowTag = "ROW";
61     private static String JavaDoc classAttrib = "CLASS";
62     private static String JavaDoc IDAttrib = "ID";
63     private static String JavaDoc refAttrib = "REFERENCE";
64     private static String JavaDoc rowAttrib = "ROW";
65     private static String JavaDoc rowClassAttrib = "ROWCLASS";
66     private static String JavaDoc sizeAttrib = "SIZE";
67     private static String JavaDoc primitiveArray = "PRIMITIVE";
68     private static String JavaDoc startCDATA = "<![CDATA[";
69     private static String JavaDoc endCDATA = "]]>";
70
71     //MBO added
72
private static final String JavaDoc encoding = "UTF-8";
73
74     /** Creates new XMLGraphSerialzer */
75     private XMLGraphSerializer()
76     {
77         this.ObjectMap = new HashMap JavaDoc();
78     }
79     
80     // MBO remove constructor
81
/*
82     public XMLGraphSerializer(File outputFile)
83     {
84         this();
85         try
86         {
87             this.outStream = new BufferedWriter( new FileWriter(outputFile));
88         }
89         catch (IOException lError)
90         {
91             lError.printStackTrace();
92         }
93     }
94     public XMLGraphSerializer(String outputFile)
95     {
96         this();
97         try
98         {
99             this.outStream = new BufferedWriter( new FileWriter(outputFile));
100         }
101         catch (IOException lError)
102         {
103             lError.printStackTrace();
104         }
105     }
106     */

107
108    public XMLGraphSerializer(OutputStream JavaDoc outStream)
109     {
110         this();
111         //MBO
112
//this.outStream = new BufferedWriter( new OutputStreamWriter(outStream));
113
try
114         {
115             this.outStream = new BufferedWriter JavaDoc( new OutputStreamWriter JavaDoc(outStream, encoding));
116         }
117         catch(java.io.UnsupportedEncodingException JavaDoc ex)
118         {
119             throw new java.lang.RuntimeException JavaDoc("Problems creating OutputStreamWriter: " + ex);
120         }
121     }
122
123     // Support / utility methods
124

125     private String JavaDoc getObjectName(Object JavaDoc obj)
126     {
127
128         // The following methodf generates a uniqie name for the object.
129
// This name is used to reference the object within the XML document.
130
// Use the class name and hash code that way we produce a name that is
131
// at least partically readable.
132

133         StringBuffer JavaDoc lReturn = new StringBuffer JavaDoc();
134         lReturn.append(obj.getClass().getName());
135         lReturn.append(obj.hashCode());
136      
137         return lReturn.toString();
138     }
139
140     private void writeLevel(String JavaDoc value) throws IOException JavaDoc
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 JavaDoc
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 JavaDoc value) throws IOException JavaDoc
166     {
167 // if ( indent )
168
// {
169
// for (int i = 0; i < this.indentLevel; i++)
170
// {
171
// outStream.write(indentChar);
172
// }
173
// }
174
outStream.write(startCDATA);
175     outStream.write(value);
176     outStream.write(endCDATA);
177     }
178
179     private boolean recordObject(Object JavaDoc obj)
180     {
181
182         boolean lObjectRecordedAlready = false;
183
184         String JavaDoc lObjectName = this.getObjectName(obj);
185
186         if ( !this.ObjectMap.containsKey(lObjectName) )
187         {
188
189             // This adds the object to the hash table for the first time
190
this.ObjectMap.put(lObjectName, obj);
191         }
192         else
193             lObjectRecordedAlready = true;
194             
195         return lObjectRecordedAlready;
196     }
197
198     private void addAttribute(String JavaDoc attributeName, String JavaDoc attributeValue, StringBuffer JavaDoc 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 JavaDoc 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 JavaDoc lIterator = this.ObjectMap.values().iterator();
235         while (lIterator.hasNext())
236         {
237             Object JavaDoc 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     // main methods
245

246     private void putStartTag(String JavaDoc tag, String JavaDoc elements, boolean empty, boolean newLine) throws IOException JavaDoc
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 JavaDoc tag, boolean doIndent) throws IOException JavaDoc
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 JavaDoc obj) throws IOException JavaDoc, IllegalAccessException JavaDoc
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 JavaDoc ||
299                       obj instanceof StringBuffer JavaDoc
300                     )
301             {
302                 this.xlateString(null, obj);
303             }
304
305             else
306             {
307                 if ( this.recordObject(obj) )
308                 {
309                     // OK this object has already been recorded so process as a reference
310
this.xlateObjectReference(obj);
311                 }
312                 else
313                 {
314                     Class JavaDoc lClassType = obj.getClass();
315
316                     StringBuffer JavaDoc lClassAttributes = new StringBuffer JavaDoc();
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 //
323

324                     ArrayList JavaDoc lFields;
325                 
326                     HashMap JavaDoc lFieldsMap = new HashMap JavaDoc();
327
328                     Class JavaDoc lClass = lClassType;
329                     Field JavaDoc[] lTFields = null;
330
331                     while (lClass != null)
332                     {
333                         lTFields = lClass.getDeclaredFields();
334 // lFields.ensureCapacity(lTFields.length);
335

336                         for (int i = 0; i < lTFields.length; i++)
337                         {
338 // lFields.add(lTFields[i]);
339
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 JavaDoc(lFieldsMap.values());
347
348                     for ( int i = 0; i < lFields.size(); i++)
349                     {
350                         Field JavaDoc lCurrentField = (Field JavaDoc)(lFields.get(i));
351
352                         if ( !Modifier.isTransient(lCurrentField.getModifiers()) &&
353                              !Modifier.isStatic(lCurrentField.getModifiers())
354                            )
355                         {
356
357                             Class JavaDoc lCurrentFieldType = lCurrentField.getType();
358                             lCurrentField.setAccessible(true);
359                             Object JavaDoc lRealValue = lCurrentField.get(obj);
360                             String JavaDoc 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 JavaDoc ||
368                                           lRealValue instanceof java.lang.StringBuffer JavaDoc
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 JavaDoc )
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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc obj) throws IOException JavaDoc
435     {
436         StringBuffer JavaDoc lReferenceAttributes = new StringBuffer JavaDoc();
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 JavaDoc name, Object JavaDoc obj) throws IOException JavaDoc
444     {
445         Class JavaDoc lType = obj.getClass();
446         String JavaDoc lValue = obj.toString();
447
448         this.putStartTag(name, null, false, false);
449
450         if ( lType == java.lang.Character.TYPE )
451         {
452             // This is a character so check for CDATA requirements
453
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 JavaDoc name, Object JavaDoc obj) throws IOException JavaDoc
467     {
468
469         if ( name != null )
470             this.putStartTag(name, null, false, false);
471
472         String JavaDoc 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 JavaDoc name, Object JavaDoc obj) throws IOException JavaDoc, IllegalAccessException JavaDoc
486     {
487
488         StringBuffer JavaDoc lArrayAttributes = new StringBuffer JavaDoc();
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 // System.out.println( "Component Type is " + obj.getClass().getComponentType().getName() );
497
// System.out.println( "Class Type is " + obj.getClass().getName() );
498

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 JavaDoc lRow = Array.get(obj, i);
506
507             if ( lRow instanceof java.lang.String JavaDoc ||
508                  lRow instanceof java.lang.Number JavaDoc ||
509                  lRow instanceof java.lang.Character JavaDoc ||
510                  lRow instanceof java.lang.Boolean JavaDoc
511                )
512             {
513                 this.xlateSimpleRow(i, lRow);
514             }
515             else
516             {
517                 StringBuffer JavaDoc lRowAttributes = new StringBuffer JavaDoc();
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 JavaDoc name, Object JavaDoc obj) throws IOException JavaDoc, IllegalAccessException JavaDoc
531     {
532
533         StringBuffer JavaDoc lArrayAttributes = new StringBuffer JavaDoc();
534
535         Collection JavaDoc lArray = (Collection JavaDoc)(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 JavaDoc lIterator = lArray.iterator();
547         int lRowCount = 0;
548
549         while (lIterator.hasNext())
550         {
551             Object JavaDoc lRow = lIterator.next();
552             
553             if ( lRow instanceof java.lang.String JavaDoc ||
554                  lRow instanceof java.lang.Number JavaDoc ||
555                  lRow instanceof java.lang.Character JavaDoc ||
556                  lRow instanceof java.lang.Boolean JavaDoc
557                )
558             {
559                 this.xlateSimpleRow(lRowCount, lRow);
560             }
561             else
562             {
563                 StringBuffer JavaDoc lRowAttributes = new StringBuffer JavaDoc();
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 JavaDoc obj) throws IOException JavaDoc
578     {
579     
580         StringBuffer JavaDoc lRowAttributes = new StringBuffer JavaDoc();
581         this.addAttribute(rowAttrib, Integer.toString(rowNumber), lRowAttributes);
582
583         Class JavaDoc 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 JavaDoc obj) throws IOException JavaDoc
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 JavaDoc e1)
626         {
627             e1.printStackTrace();
628             this.DumpStatus();
629             try
630             {
631                 this.outStream.close();
632             }
633             catch (IOException JavaDoc lNotClosed)
634             {
635                 // Do nothing
636
}
637             throw e1;
638         }
639         catch (IllegalAccessException JavaDoc e2)
640         {
641             e2.printStackTrace();
642             this.DumpStatus();
643             try
644             {
645                 this.outStream.close();
646             }
647             catch (IOException JavaDoc lNotClosed)
648             {
649                 // Do nothing
650
}
651         }
652
653     }
654
655 }
656
Popular Tags