KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > jmi > xmi > DefaultWriter


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.lib.jmi.xmi;
20
21 import java.io.*;
22 import java.nio.charset.*;
23 import java.util.*;
24 import java.net.URL JavaDoc;
25 import org.xml.sax.*;
26 import org.xml.sax.helpers.DefaultHandler JavaDoc;
27
28 import org.netbeans.lib.jmi.util.DebugException;
29
30 public class DefaultWriter extends DefaultHandler JavaDoc {
31
32     private static final char QUOTE = '\'';
33     private static final String JavaDoc EOL = System.getProperty("line.separator");
34     private static final String JavaDoc INDENT = " ";
35     private static final int INDENT_LENGTH = INDENT.length ();
36     /** An upper bound on the number of characters that can be printed to the output writer
37      * per one line. A new line is started every time when the number of characters in a line
38      * (excluding indent spaces) after @link #startElement or @link #addAttribute exceeds MAX.
39      */

40     private static final int MAX = 70;
41     
42     private static final String JavaDoc XMI_VERSION = "1.2";
43     private static final String JavaDoc EXPORTER_NAME = "Netbeans XMI Writer";
44     private static final String JavaDoc EXPORTER_VERSION = "1.0";
45     
46     // variables ................................................................
47

48     //
49
private OutputStreamWriter writer;
50     // document locator
51
private Locator locator;
52     //
53
private String JavaDoc encoding = null;
54     
55     // true if the currently written XML element has at least one sub-element
56
private boolean hasContent = true; // inited by true due to condition in @link #startElement
57
// true if the currently written XML element has some characters in its content
58
private boolean hasCharacters = false;
59     // indentation spaces to be currently used
60
private String JavaDoc indentSpaces = "";
61     // number of charecters written on current line so far (excluding indent spaces)
62
private int charsCount = 0;
63     
64     // init .....................................................................
65

66     public DefaultWriter() {
67     }
68     
69     public DefaultWriter(OutputStreamWriter writer, String JavaDoc encoding) {
70         this.writer = writer;
71         this.encoding = encoding;
72     }
73     
74     public void init () throws SAXException {
75         hasContent = true;
76         hasCharacters = true;
77         indentSpaces = "";
78         charsCount = 0;
79         
80         if (writer == null) {
81             try {
82                 OutputStream ostr = new URL JavaDoc (locator.getSystemId()).openConnection().getOutputStream();
83                 writer = new OutputStreamWriter (ostr);
84             } catch (IOException e) {
85                 throw new SAXException (e);
86             }
87         }
88         String JavaDoc enc = (encoding != null) ? encoding : canonicalNameFor(writer.getEncoding());
89         write ("<?xml version = '1.0' encoding = '" + enc + "' ?>");
90         writeln ();
91     }
92
93     /**
94      * Tries to convert the specified encoding name, which may be an historical
95      * Java encoding name, to the equivalent canonical IANA registered charset
96      * name.
97      */

98     private static String JavaDoc canonicalNameFor(String JavaDoc encoding) {
99         try {
100             encoding = Charset.forName(encoding).name();
101         } catch (IllegalCharsetNameException e) {
102         } catch (UnsupportedCharsetException e) {
103         }
104         return encoding;
105     }
106     
107     // methods ..................................................................
108

109     public Writer getWriter () {
110         return writer;
111     }
112     
113     /**
114      * Writes a string to the output writer.
115      *
116      * @param text a string to be written in the output writer
117      */

118     private void write (String JavaDoc text) throws SAXException {
119         try {
120             writer.write (text);
121         } catch (IOException e) {
122             throw new SAXException (e);
123         }
124     }
125     
126     /**
127      * Writes end of line to the output writer.
128      */

129     private void writeln () throws SAXException {
130         try {
131             writer.write (EOL);
132         } catch (IOException e) {
133             throw new SAXException (e);
134         }
135         charsCount = 0;
136     }
137     
138     /**
139      * Locates occurences of special XML charecters (like '<', '&', etc.) in a string
140      * and replaces them by sequences of the form &X...X;
141      *
142      * In addition, if replaceWhitechars parameter is true, '\n', '\r' and '\t' are replaced
143      * by &#NN; sequences.
144      */

145     private String JavaDoc replaceSpecialChars (String JavaDoc s, boolean replaceWhitechars) {
146         int length = s.length ();
147         char [] chars = new char [6 * length];
148         int n = 0;
149         for (int x = 0; x < length; x++) {
150             char c = s.charAt (x);
151             switch (c) {
152                 case '&':
153                     chars [n] = '&'; n++; chars [n] = 'a'; n++;
154                     chars [n] = 'm'; n++; chars [n] = 'p'; n++;
155                     chars [n] = ';'; n++;
156                 break;
157                 case '\'':
158                     chars [n] = '&'; n++; chars [n] = 'a'; n++;
159                     chars [n] = 'p'; n++; chars [n] = 'o'; n++;
160                     chars [n] = 's'; n++; chars [n] = ';'; n++;
161                 break;
162                 case '\"':
163                     chars [n] = '&'; n++; chars [n] = 'q'; n++;
164                     chars [n] = 'u'; n++; chars [n] = 'o'; n++;
165                     chars [n] = 't'; n++; chars [n] = ';'; n++;
166                 break;
167                 case '<':
168                     chars [n] = '&'; n++; chars [n] = 'l'; n++;
169                     chars [n] = 't'; n++; chars [n] = ';'; n++;
170                 break;
171                 case '>':
172                     chars [n] = '&'; n++; chars [n] = 'g'; n++;
173                     chars [n] = 't'; n++; chars [n] = ';'; n++;
174                 break;
175                 default:
176                     if (replaceWhitechars) {
177                         switch (c) {
178                             case '\n':
179                                 chars [n] = '&'; n++; chars [n] = '#'; n++;
180                                 chars [n] = '1'; n++; chars [n] = '0'; n++;
181                                 chars [n] = ';'; n++;
182                             break;
183                             case '\r':
184                                 chars [n] = '&'; n++; chars [n] = '#'; n++;
185                                 chars [n] = '1'; n++; chars [n] = '3'; n++;
186                                 chars [n] = ';'; n++;
187                             break;
188                             case '\t':
189                                 chars [n] = '&'; n++; chars [n] = '#'; n++;
190                                 chars [n] = '9'; n++; chars [n] = ';'; n++;
191                             break;
192                             default:
193                                 chars [n] = c; n++;
194                         }
195                     } else {
196                         chars [n] = c; n++;
197                     }
198             } // switch
199
} // for
200
return new String JavaDoc (chars, 0, n);
201     }
202     
203     /**
204      * Writes start of a XML element to the output writer.
205      *
206      * @param name name of the XML element to be written
207      */

208     private void startElement (String JavaDoc name, Attributes attrs) throws SAXException {
209         if (!hasContent && !hasCharacters) {
210             write (">");
211             writeln ();
212         }
213         hasContent = false;
214         hasCharacters = false;
215         write (indentSpaces);
216         write ("<" + name);
217         charsCount += name.length () + 1;
218         indentSpaces = indentSpaces + INDENT;
219         for (int x = 0; x < attrs.getLength(); x++) {
220             addAttribute (attrs.getQName(x), attrs.getValue(x));
221         }
222     }
223     
224     /**
225      * Writes end of an XML element to the output writer.
226      *
227      * @param name name of the XML element to be written
228      */

229     private void endElement (String JavaDoc name) throws SAXException {
230         indentSpaces = indentSpaces.substring (0, indentSpaces.length () - INDENT_LENGTH);
231         if (hasContent) {
232             write (indentSpaces);
233             write ("</" + name + ">");
234         } else if (hasCharacters) {
235             write ("</" + name + ">");
236         } else
237             write ("/>");
238         writeln ();
239         hasContent = true;
240     }
241     
242     /**
243      * Writes an attribute of the currenly written XML elemnt to the output writer.
244      *
245      * @param name attribute name
246      * @param value value of the attribute
247      */

248     private void addAttribute (String JavaDoc name, String JavaDoc value) throws SAXException {
249         value = replaceSpecialChars (value, true);
250         // [PENDING] ??? can be special characters in name too ???
251
if (charsCount > MAX) {
252             writeln ();
253             write (indentSpaces);
254         } else {
255             write (" ");
256             charsCount++;
257         }
258         write (name + " = " + QUOTE + value + QUOTE);
259         charsCount += name.length () + value.length () + 5;
260     }
261     
262     /**
263      * Writes characters into body of the currenly written XML elemnt.
264      * Before the string is written, @link #replaceSpecialChars is called
265      * on it to replace special XML characters.
266      *
267      * @param text string to be written
268      */

269     private void characters (String JavaDoc text) throws SAXException {
270         text = replaceSpecialChars (text, false);
271         if (!hasContent)
272             write (">");
273         write (text);
274         hasCharacters = true;
275     }
276     
277     // org.xml.sax.ContentHandler interface implementation ......................
278

279     public void startDocument() throws org.xml.sax.SAXException JavaDoc {
280         init ();
281     }
282     
283     public void endDocument() throws org.xml.sax.SAXException JavaDoc {
284         try {
285             writer.flush();
286             writer.close();
287         } catch (IOException e) {
288             throw new SAXException (e);
289         }
290     }
291     
292     public void startElement(String JavaDoc uri, String JavaDoc sName, String JavaDoc qName, Attributes attributes) throws org.xml.sax.SAXException JavaDoc {
293         startElement (qName, attributes);
294     }
295     
296     public void endElement(String JavaDoc uri, String JavaDoc sName, String JavaDoc qName) throws org.xml.sax.SAXException JavaDoc {
297         endElement (qName);
298     }
299     
300     public void characters(char[] buf, int offset, int len) throws org.xml.sax.SAXException JavaDoc {
301         characters (new String JavaDoc (buf, offset, len));
302     }
303
304     public void setDocumentLocator(Locator locator) {
305         this.locator = locator;
306     }
307     
308     /*
309     public void skippedEntity(String str) throws org.xml.sax.SAXException {
310     }
311     
312     public void processingInstruction(String str, String str1) throws org.xml.sax.SAXException {
313     }
314     
315     public void endPrefixMapping(String str) throws org.xml.sax.SAXException {
316     }
317     
318     public void startPrefixMapping(String str, String str1) throws org.xml.sax.SAXException {
319     }
320         
321     public void ignorableWhitespace(char[] values, int param, int param2) throws org.xml.sax.SAXException {
322     }
323      */

324     
325 }
326
Popular Tags