KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > mdrxml > util > XMLGenerator


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 package org.netbeans.modules.mdrxml.util;
20
21 import javax.jmi.reflect.*;
22 import xmlmodel.*;
23
24 import java.util.*;
25 import java.io.*;
26
27 public class XMLGenerator {
28
29     private static final char QUOTE = '\'';
30     private static final String JavaDoc INDENT = " ";
31     private static final int INDENT_LENGTH = INDENT.length ();
32     /** An upper bound on the number of characters that can be printed to the output stream
33      * per one line. A new line is started every time when the number of characters in a line
34      * (excluding indent spaces) after @link #startElement or @link #addAttribute exceeds MAX.
35      */

36     private static final int MAX = 70;
37     
38     // output stream
39
private PrintStream stream;
40     // true if the currently written XML element has at least one sub-element
41
private boolean hasContent = true; // inited by true due to condition in @link #startElement
42
// true if the currently written XML element has some characters in its content
43
private boolean hasCharacters = false;
44     // indentation spaces to be currently used
45
private String JavaDoc indentSpaces = "";
46     // number of charecters written on current line so far (excluding indent spaces)
47
private int charsCount = 0;
48     
49     // **************************************************************************
50
// Methods related to writing to the output stream.
51
// **************************************************************************
52

53     /**
54      * Writes a string to the output string.
55      *
56      * @param text a string to be written in the output stream
57      */

58     private void write (String JavaDoc text) {
59         stream.print (text);
60     }
61     
62     /**
63      * Writes end of line to the output stream.
64      */

65     private void writeln () {
66         stream.println ();
67         charsCount = 0;
68     }
69
70     /**
71      * Locates occurences of special XML charecters (like '<', '&', etc.) in a string
72      * and replaces them by sequences of the form &X...X;
73      */

74     private String JavaDoc replaceSpecialChars (String JavaDoc s) {
75         int length = s.length ();
76         char [] chars = new char [6 * length];
77         int n = 0;
78         for (int x = 0; x < length; x++) {
79             char c = s.charAt (x);
80             switch (c) {
81                 case '&':
82                     chars [n] = '&'; n++; chars [n] = 'a'; n++;
83                     chars [n] = 'm'; n++; chars [n] = 'p'; n++;
84                     chars [n] = ';'; n++;
85                 break;
86                 case '\'':
87                     chars [n] = '&'; n++; chars [n] = 'a'; n++;
88                     chars [n] = 'p'; n++; chars [n] = 'o'; n++;
89                     chars [n] = 's'; n++; chars [n] = ';'; n++;
90                 break;
91                 case '\"':
92                     chars [n] = '&'; n++; chars [n] = 'q'; n++;
93                     chars [n] = 'u'; n++; chars [n] = 'o'; n++;
94                     chars [n] = 't'; n++; chars [n] = ';'; n++;
95                 break;
96                 case '<':
97                     chars [n] = '&'; n++; chars [n] = 'l'; n++;
98                     chars [n] = 't'; n++; chars [n] = ';'; n++;
99                 break;
100                 case '>':
101                     chars [n] = '&'; n++; chars [n] = 'g'; n++;
102                     chars [n] = 't'; n++; chars [n] = ';'; n++;
103                 break;
104                 default:
105                     chars [n] = c; n++;
106             } // switch
107
} // for
108
return new String JavaDoc (chars, 0, n);
109     }
110     
111     /**
112      * Writes start of a XML element to the output stream.
113      *
114      * @param name name of the XML element to be written
115      */

116     private void startElement (String JavaDoc name) {
117         if (!hasContent && !hasCharacters) {
118             write (">");
119             writeln ();
120         }
121         hasContent = false;
122         hasCharacters = false;
123         write (indentSpaces);
124         write ("<" + name);
125         charsCount += name.length () + 1;
126         indentSpaces = indentSpaces + INDENT;
127     }
128     
129     /**
130      * Writes end of an XML element to the output stream.
131      *
132      * @param name name of the XML element to be written
133      */

134     private void endElement (String JavaDoc name) {
135         indentSpaces = indentSpaces.substring (0, indentSpaces.length () - INDENT_LENGTH);
136         if (hasContent) {
137             write (indentSpaces);
138             write ("</" + name + ">");
139         } else if (hasCharacters) {
140             write ("</" + name + ">");
141         } else
142             write ("/>");
143         writeln ();
144         hasContent = true;
145     }
146     
147     /**
148      * Writes an attribute of the currenly written XML elemnt to the output stream.
149      *
150      * @param name attribute name
151      * @param value value of the attribute
152      */

153     private void addAttribute (String JavaDoc name, String JavaDoc value) {
154         value = replaceSpecialChars (value);
155         // [PENDING] ??? can be special characters in name too ???
156
if (charsCount > MAX) {
157             writeln ();
158             write (indentSpaces);
159         } else {
160             write (" ");
161             charsCount++;
162         }
163         write (name + " = " + QUOTE + value + QUOTE);
164         charsCount += name.length () + value.length () + 5;
165     }
166     
167     /**
168      * Writes characters into body of the currenly written XML elemnt.
169      * Before the string is written, @link #replaceSpecialChars is called
170      * on it to replace special XML characters.
171      *
172      * @param text string to be written
173      */

174     private void characters (String JavaDoc text) {
175         text = replaceSpecialChars (text);
176         if (!hasContent)
177             write (">");
178         write (text);
179         hasCharacters = true;
180     }
181     
182     // **************************************************************************
183

184     // XML Generation
185
public void generateXML (OutputStream os, ElementNode elementNode) {
186         stream = new PrintStream (os);
187         write ("<?xml version = '1.0' encoding = 'ISO-8859-1' ?>\n");
188         generateElement (elementNode);
189     }
190     
191     private void generateElement (ElementNode element) {
192         String JavaDoc name = element.getName ();
193         startElement (name);
194         List nodes = element.getNodes ();
195         Iterator iter = nodes.iterator ();
196         while (iter.hasNext ()) {
197             Object JavaDoc subNode = iter.next ();
198             if (subNode instanceof AttributeNode) {
199                 AttributeNode attrNode = (AttributeNode) subNode;
200                 addAttribute (attrNode.getName (), attrNode.getValue ());
201             } // if
202
} // while
203
iter = nodes.iterator ();
204         while (iter.hasNext ()) {
205             Object JavaDoc subNode = iter.next ();
206             if (subNode instanceof TextNode)
207                 characters (((TextNode) subNode).getName ());
208             else if (subNode instanceof ElementNode)
209                 generateElement ((ElementNode) subNode);
210         }
211         endElement (name);
212     }
213     
214 }
Popular Tags