1 /*--------------------------------------------------------------------------
\r
2 * Copyright 2009 Taro L. Saito
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
15 *--------------------------------------------------------------------------*/
\r
16 //--------------------------------------
\r
20 // Since: Jul 28, 2009 11:41:27 AM
\r
24 //--------------------------------------
\r
25 package org.xerial.lens;
\r
27 import java.io.Reader;
\r
28 import java.io.StringWriter;
\r
29 import java.io.Writer;
\r
31 import org.xerial.core.XerialErrorCode;
\r
32 import org.xerial.core.XerialException;
\r
33 import org.xerial.silk.SilkWriter;
\r
34 import org.xerial.util.ArrayDeque;
\r
35 import org.xerial.util.xml.XMLAttribute;
\r
36 import org.xml.sax.Attributes;
\r
37 import org.xml.sax.InputSource;
\r
38 import org.xml.sax.SAXException;
\r
39 import org.xml.sax.XMLReader;
\r
40 import org.xml.sax.ext.DefaultHandler2;
\r
41 import org.xml.sax.helpers.XMLReaderFactory;
\r
44 * XML to Silk format converter
\r
49 public class XMLSilkLens {
\r
51 private static class XMLToSilkSAXHandler extends DefaultHandler2 {
\r
52 private SilkWriter context;
\r
54 private static class TagContext {
\r
55 public final String tagName;
\r
56 public final XMLAttribute attribute;
\r
57 public StringBuilder textBuf = new StringBuilder();
\r
58 public boolean isOpen = false;
\r
60 public TagContext(String tagName, XMLAttribute attribute) {
\r
61 this.tagName = tagName;
\r
62 this.attribute = attribute;
\r
66 public String toString() {
\r
67 return String.format("%s (%s) : %s", tagName, attribute.toXMLString(), textBuf
\r
72 private ArrayDeque<TagContext> contextStack = new ArrayDeque<TagContext>();
\r
73 private ArrayDeque<TagContext> unopendContextStack = new ArrayDeque<TagContext>();
\r
75 public XMLToSilkSAXHandler(Writer out) {
\r
76 this.context = new SilkWriter(out);
\r
79 public void characters(char[] ch, int start, int length) throws SAXException {
\r
80 TagContext tc = unopendContextStack.isEmpty() ? contextStack.getLast()
\r
81 : unopendContextStack.getLast();
\r
82 tc.textBuf.append(ch, start, length);
\r
86 public void endDocument() throws SAXException {
\r
87 context.endDocument();
\r
90 public void endElement(String uri, String localName, String name) throws SAXException {
\r
95 context = context.getParent();
\r
97 contextStack.removeLast();
\r
100 public void processingInstruction(String target, String data) throws SAXException {
\r
101 context.commentLine("PI: " + data);
\r
105 public void comment(char[] ch, int start, int length) throws SAXException {
\r
106 context.commentLine(new String(ch, start, length));
\r
109 public void startDocument() throws SAXException {
\r
110 context.preamble();
\r
113 private void openContext() {
\r
115 for (TagContext tc : unopendContextStack) {
\r
118 context = context.node(tc.tagName);
\r
119 for (int i = 0; i < tc.attribute.length(); ++i) {
\r
120 context.attribute(tc.attribute.getName(i), tc.attribute.getValue(i));
\r
122 if (tc.textBuf.length() > 0) {
\r
123 String value = tc.textBuf.toString().trim();
\r
124 if (value.length() > 0)
\r
125 context.nodeValue(value);
\r
131 contextStack.addLast(tc);
\r
134 unopendContextStack.clear();
\r
137 public void startElement(String uri, String localName, String name, Attributes atts)
\r
138 throws SAXException {
\r
142 XMLAttribute at = new XMLAttribute();
\r
143 for (int i = 0; i < atts.getLength(); ++i)
\r
144 at.add(atts.getQName(i), atts.getValue(i));
\r
146 unopendContextStack.addLast(new TagContext(name, at));
\r
151 public static String toSilk(Reader xml) throws XerialException {
\r
153 StringWriter buf = new StringWriter();
\r
156 // Set namespaceAware to true to get a parser that corresponds to
\r
157 // the default SAX2 namespace feature setting. This is necessary
\r
158 // because the default value from JAXP 1.0 was defined to be false.
\r
160 // Validation part 1: set whether validation is on
\r
161 //spf.setValidating(dtdValidate || xsdValidate);
\r
163 // Create a JAXP SAXParser
\r
165 // Get the encapsulated SAX XMLReader
\r
166 XMLReader xmlReader = XMLReaderFactory.createXMLReader();
\r
168 DefaultHandler2 ch = new XMLToSilkSAXHandler(buf);
\r
169 // Set the ContentHandler of the XMLReader
\r
170 xmlReader.setContentHandler(ch);
\r
171 xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", ch);
\r
173 xmlReader.parse(new InputSource(xml));
\r
176 catch (Exception e) {
\r
177 throw new XerialException(XerialErrorCode.INVALID_STATE,
\r
178 "failed to instantiate the XML parser: " + e);
\r
181 // XMLTreeWalker treeWalker = new XMLTreeWalker(xml);
\r
182 // treeWalker.walk(new XMLToSilk(buf));
\r
184 return buf.toString();
\r