1 /*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
40 * that is parsed.
41 */
42 public class XInclHandler extends DefaultHandler implements LexicalHandler {
43 /**
44 * Print writer.
45 */
46 private final PrintWriter fOut;
47
48 /**
49 * Canonical output.
50 */
51 private volatile boolean fCanonical;
52
53 /**
54 * Element depth.
55 */
56 private volatile int fElementDepth;
57
58 /**
59 * Sets whether output is canonical.
60 */
61 public void setCanonical(boolean canonical) {
62 fCanonical = canonical;
63 }
64
65 /**
66 * Sets the output stream for printing.
67 * @param stream OutputStream for message output.
68 * @param encoding File encoding for message output.
69 */
70 public XInclHandler(OutputStream stream, String encoding)
71 throws UnsupportedEncodingException {
72 // At least set one encoding.
73 if (encoding == null) {
74 encoding = "UTF8";
75 }
76
77 fOut = new PrintWriter(new OutputStreamWriter(stream, encoding), false);
78 }
79
80 /**
81 * Receive notification of the beginning of the document. Write the start
82 * document tag if it's not canonical mode.
83 * @exception org.xml.sax.SAXException Any SAX exception, possibly
84 * wrapping another exception.
85 */
86 @Override
87 public void startDocument() throws SAXException {
88 fElementDepth = 0;
89
90 if (!fCanonical) {
91 writeFlush("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
92 }
93 }
94
95 /**
96 * Receive notification of a processing instruction.
97 * @param target The processing instruction target.
98 * @param data The processing instruction data, or null if
99 * none is supplied.
100 * @exception org.xml.sax.SAXException Any SAX exception, possibly
101 * wrapping another exception.
102 */
103 @Override
104 public void processingInstruction (String target, String data)
105 throws SAXException {
106 if (fElementDepth > 0) {
107 StringBuilder instruction = new StringBuilder("<?").append(target);
108 if (data != null && data.length() > 0) {
109 instruction.append(' ').append(data);
110 }
111 instruction.append("?>");
112 writeFlush(instruction.toString());
113 }
114 }
115
116 /**
117 * Receive notification of the start of an element then write the normalized
118 * output to the file.
119 * @param uri The Namespace URI, or the empty string if the
120 * element has no Namespace URI or if Namespace
121 * processing is not being performed.
122 * @param localName The local name (without prefix), or the
123 * empty string if Namespace processing is not being
124 * performed.
125 * @param qName The qualified name (with prefix), or the
126 * empty string if qualified names are not available.
127 * @param attributes The attributes attached to the element. If
128 * there are no attributes, it shall be an empty
129 * Attributes object.
130 */
131 @Override
132 public void startElement(String uri, String local, String raw,
133 Attributes attrs) throws SAXException {
134 fElementDepth++;
135 StringBuilder start = new StringBuilder().append('<').append(raw);
136 if (attrs != null) {
137 for (int i = 0; i < attrs.getLength(); i++) {
138 start.append(' ').append(attrs.getQName(i)).append("=\"").
139 append(normalizeAndPrint(attrs.getValue(i))).append('"');
140 }
141 }
142 start.append('>');
143 writeFlush(start.toString());
144 }
145
146 /**
147 * Receive notification of character data inside an element and write
148 * normalized characters to file.
149 * @param ch The characters.
164 * writing normalized ignorable characters to file.
165 * @param ch The characters.
166 * @param start The start position in the character array.
167 * @param length The number of characters to use from the
168 * character array.
169 * @exception org.xml.sax.SAXException Any SAX exception, possibly
170 * wrapping another exception.
171 */
172 @Override
173 public void ignorableWhitespace(char ch[], int start, int length)
174 throws SAXException {
175 characters(ch, start, length);
176 }
177
178 /**
179 * Receive notification of the end of an element and print end element.
180 *
181 * @param uri The Namespace URI, or the empty string if the
182 * element has no Namespace URI or if Namespace
183 * processing is not being performed.
184 * @param localName The local name (without prefix), or the
185 * empty string if Namespace processing is not being
186 * performed.
187 * @param qName The qualified name (with prefix), or the
188 * empty string if qualified names are not available.
189 */
190 @Override
191 public void endElement(String uri, String local, String raw)
192 throws SAXException {
193 fElementDepth--;
194 writeFlush("</" + raw + ">");
195 }
196
197 /**
198 * Receive notification of a parser warning and print it out.
199 * @param e The warning information encoded as an exception.
200 * @exception org.xml.sax.SAXException Any SAX exception, possibly
201 * wrapping another exception.
202 */
203 @Override
204 public void warning(SAXParseException ex) throws SAXException {
205 printError("Warning", ex);
206 }
207
208 /**
209 * Receive notification of a parser error and print it out.
210 * @param e The error information encoded as an exception.
211 * @exception org.xml.sax.SAXException Any SAX exception, possibly
212 * wrapping another exception.
213
214 */
215 @Override
216 public void error(SAXParseException ex) throws SAXException {
217 printError("Error", ex);
218 }
219
220 /**
221 * Receive notification of a parser fatal error. Throw out fatal error
222 * following print fatal error message.
223 * @param e The fatal error information encoded as an exception.
224 * @exception org.xml.sax.SAXException Any SAX exception, possibly
225 * wrapping another exception.
226
227 */
228 @Override
229 public void fatalError(SAXParseException ex) throws SAXException {
230 printError("Fatal Error", ex);
231 throw ex;
232 }
233
234 /**
235 * Do nothing on start DTD.
236 * @param name The document type name.
237 * @param publicId The declared public identifier for the
238 * external DTD subset, or null if none was declared.
239 * @param systemId The declared system identifier for the
240 * external DTD subset, or null if none was declared.
241 * (Note that this is not resolved against the document
242 * base URI.)
243 * @exception SAXException The application may raise an
|
1 /*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
40 * that is parsed.
41 */
42 public class XInclHandler extends DefaultHandler implements LexicalHandler {
43 /**
44 * Print writer.
45 */
46 private final PrintWriter fOut;
47
48 /**
49 * Canonical output.
50 */
51 private volatile boolean fCanonical;
52
53 /**
54 * Element depth.
55 */
56 private volatile int fElementDepth;
57
58 /**
59 * Sets whether output is canonical.
60 *
61 * @param canonical if the output is canonical format.
62 */
63 public void setCanonical(boolean canonical) {
64 fCanonical = canonical;
65 }
66
67 /**
68 * Sets the output stream for printing.
69 * @param stream OutputStream for message output.
70 * @param encoding File encoding for message output.
71 * @throws UnsupportedEncodingException if given encoding is an unsupported
72 * encoding name or invalid encoding name.
73 */
74 public XInclHandler(OutputStream stream, String encoding)
75 throws UnsupportedEncodingException {
76 // At least set one encoding.
77 if (encoding == null) {
78 encoding = "UTF8";
79 }
80
81 fOut = new PrintWriter(new OutputStreamWriter(stream, encoding), false);
82 }
83
84 /**
85 * Receive notification of the beginning of the document. Write the start
86 * document tag if it's not canonical mode.
87 * @exception org.xml.sax.SAXException Any SAX exception, possibly
88 * wrapping another exception.
89 */
90 @Override
91 public void startDocument() throws SAXException {
92 fElementDepth = 0;
93
94 if (!fCanonical) {
95 writeFlush("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
96 }
97 }
98
99 /**
100 * Receive notification of a processing instruction.
101 * @param target The processing instruction target.
102 * @param data The processing instruction data, or null if
103 * none is supplied.
104 * @exception SAXException Any SAX exception, possibly wrapping another
105 * exception.
106 */
107 @Override
108 public void processingInstruction (String target, String data)
109 throws SAXException {
110 if (fElementDepth > 0) {
111 StringBuilder instruction = new StringBuilder("<?").append(target);
112 if (data != null && data.length() > 0) {
113 instruction.append(' ').append(data);
114 }
115 instruction.append("?>");
116 writeFlush(instruction.toString());
117 }
118 }
119
120 /**
121 * Receive notification of the start of an element then write the normalized
122 * output to the file.
123 * @param uri The Namespace URI, or the empty string if the
124 * element has no Namespace URI or if Namespace
125 * processing is not being performed.
126 * @param local The local name (without prefix), or the
127 * empty string if Namespace processing is not being
128 * performed.
129 * @param raw The qualified name (with prefix), or the
130 * empty string if qualified names are not available.
131 * @param attrs The attributes attached to the element. If
132 * there are no attributes, it shall be an empty
133 * Attributes object.
134 * @throws SAXException Any SAX exception, possibly wrapping another
135 * exception.
136 */
137 @Override
138 public void startElement(String uri, String local, String raw,
139 Attributes attrs) throws SAXException {
140 fElementDepth++;
141 StringBuilder start = new StringBuilder().append('<').append(raw);
142 if (attrs != null) {
143 for (int i = 0; i < attrs.getLength(); i++) {
144 start.append(' ').append(attrs.getQName(i)).append("=\"").
145 append(normalizeAndPrint(attrs.getValue(i))).append('"');
146 }
147 }
148 start.append('>');
149 writeFlush(start.toString());
150 }
151
152 /**
153 * Receive notification of character data inside an element and write
154 * normalized characters to file.
155 * @param ch The characters.
170 * writing normalized ignorable characters to file.
171 * @param ch The characters.
172 * @param start The start position in the character array.
173 * @param length The number of characters to use from the
174 * character array.
175 * @exception org.xml.sax.SAXException Any SAX exception, possibly
176 * wrapping another exception.
177 */
178 @Override
179 public void ignorableWhitespace(char ch[], int start, int length)
180 throws SAXException {
181 characters(ch, start, length);
182 }
183
184 /**
185 * Receive notification of the end of an element and print end element.
186 *
187 * @param uri The Namespace URI, or the empty string if the
188 * element has no Namespace URI or if Namespace
189 * processing is not being performed.
190 * @param local The local name (without prefix), or the
191 * empty string if Namespace processing is not being
192 * performed.
193 * @param raw The qualified name (with prefix), or the
194 * empty string if qualified names are not available.
195 * @throws org.xml.sax.SAXException Any SAX exception, possibly
196 * wrapping another exception.
197 */
198 @Override
199 public void endElement(String uri, String local, String raw)
200 throws SAXException {
201 fElementDepth--;
202 writeFlush("</" + raw + ">");
203 }
204
205 /**
206 * Receive notification of a parser warning and print it out.
207 * @param ex The warning information encoded as an exception.
208 * @exception org.xml.sax.SAXException Any SAX exception, possibly
209 * wrapping another exception.
210 */
211 @Override
212 public void warning(SAXParseException ex) throws SAXException {
213 printError("Warning", ex);
214 }
215
216 /**
217 * Receive notification of a parser error and print it out.
218 * @param ex The error information encoded as an exception.
219 * @exception org.xml.sax.SAXException Any SAX exception, possibly
220 * wrapping another exception.
221 */
222 @Override
223 public void error(SAXParseException ex) throws SAXException {
224 printError("Error", ex);
225 }
226
227 /**
228 * Receive notification of a parser fatal error. Throw out fatal error
229 * following print fatal error message.
230 * @param ex The fatal error information encoded as an exception.
231 * @exception org.xml.sax.SAXException Any SAX exception, possibly
232 * wrapping another exception.
233
234 */
235 @Override
236 public void fatalError(SAXParseException ex) throws SAXException {
237 printError("Fatal Error", ex);
238 throw ex;
239 }
240
241 /**
242 * Do nothing on start DTD.
243 * @param name The document type name.
244 * @param publicId The declared public identifier for the
245 * external DTD subset, or null if none was declared.
246 * @param systemId The declared system identifier for the
247 * external DTD subset, or null if none was declared.
248 * (Note that this is not resolved against the document
249 * base URI.)
250 * @exception SAXException The application may raise an
|