OSDN Git Service

imported from subversion repository
[xerial/xerial-core.git] / src / main / java / org / xerial / lens / XMLSilkLens.java
1 /*--------------------------------------------------------------------------\r
2  *  Copyright 2009 Taro L. Saito\r
3  *\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
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\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
17 // XerialJ\r
18 //\r
19 // XMLSilkLens.java\r
20 // Since: Jul 28, 2009 11:41:27 AM\r
21 //\r
22 // $URL$\r
23 // $Author$\r
24 //--------------------------------------\r
25 package org.xerial.lens;\r
26 \r
27 import java.io.Reader;\r
28 import java.io.StringWriter;\r
29 import java.io.Writer;\r
30 \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
42 \r
43 /**\r
44  * XML to Silk format converter\r
45  * \r
46  * @author leo\r
47  * \r
48  */\r
49 public class XMLSilkLens {\r
50 \r
51     private static class XMLToSilkSAXHandler extends DefaultHandler2 {\r
52         private SilkWriter context;\r
53 \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
59 \r
60             public TagContext(String tagName, XMLAttribute attribute) {\r
61                 this.tagName = tagName;\r
62                 this.attribute = attribute;\r
63             }\r
64 \r
65             @Override\r
66             public String toString() {\r
67                 return String.format("%s (%s) : %s", tagName, attribute.toXMLString(), textBuf\r
68                         .toString());\r
69             }\r
70         }\r
71 \r
72         private ArrayDeque<TagContext> contextStack = new ArrayDeque<TagContext>();\r
73         private ArrayDeque<TagContext> unopendContextStack = new ArrayDeque<TagContext>();\r
74 \r
75         public XMLToSilkSAXHandler(Writer out) {\r
76             this.context = new SilkWriter(out);\r
77         }\r
78 \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
83 \r
84         }\r
85 \r
86         public void endDocument() throws SAXException {\r
87             context.endDocument();\r
88         }\r
89 \r
90         public void endElement(String uri, String localName, String name) throws SAXException {\r
91 \r
92             // start node\r
93             openContext();\r
94 \r
95             context = context.getParent();\r
96 \r
97             contextStack.removeLast();\r
98         }\r
99 \r
100         public void processingInstruction(String target, String data) throws SAXException {\r
101             context.commentLine("PI: " + data);\r
102         }\r
103 \r
104         @Override\r
105         public void comment(char[] ch, int start, int length) throws SAXException {\r
106             context.commentLine(new String(ch, start, length));\r
107         }\r
108 \r
109         public void startDocument() throws SAXException {\r
110             context.preamble();\r
111         }\r
112 \r
113         private void openContext() {\r
114 \r
115             for (TagContext tc : unopendContextStack) {\r
116                 // start node\r
117                 if (!tc.isOpen) {\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
121                     }\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
126                     }\r
127 \r
128                     tc.isOpen = true;\r
129                 }\r
130 \r
131                 contextStack.addLast(tc);\r
132             }\r
133 \r
134             unopendContextStack.clear();\r
135         }\r
136 \r
137         public void startElement(String uri, String localName, String name, Attributes atts)\r
138                 throws SAXException {\r
139 \r
140             openContext();\r
141 \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
145 \r
146             unopendContextStack.addLast(new TagContext(name, at));\r
147         }\r
148 \r
149     }\r
150 \r
151     public static String toSilk(Reader xml) throws XerialException {\r
152 \r
153         StringWriter buf = new StringWriter();\r
154 \r
155         try {\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
159 \r
160             // Validation part 1: set whether validation is on\r
161             //spf.setValidating(dtdValidate || xsdValidate);\r
162 \r
163             // Create a JAXP SAXParser\r
164 \r
165             // Get the encapsulated SAX XMLReader\r
166             XMLReader xmlReader = XMLReaderFactory.createXMLReader();\r
167 \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
172 \r
173             xmlReader.parse(new InputSource(xml));\r
174 \r
175         }\r
176         catch (Exception e) {\r
177             throw new XerialException(XerialErrorCode.INVALID_STATE,\r
178                     "failed to instantiate the XML parser: " + e);\r
179         }\r
180 \r
181         //        XMLTreeWalker treeWalker = new XMLTreeWalker(xml);\r
182         //      treeWalker.walk(new XMLToSilk(buf));\r
183 \r
184         return buf.toString();\r
185     }\r
186 \r
187 }\r