Xcos writers: indent ".xcos" files
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / writer / IndentingXMLStreamWriter.java
1 /*
2  * Copyright (c) 2005, 2010, 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25
26 package org.scilab.modules.xcos.io.writer;
27
28 import javax.xml.stream.XMLStreamException;
29 import javax.xml.stream.XMLStreamWriter;
30 import java.util.Stack;
31
32 /**
33  * @author Kohsuke Kawaguchi
34  */
35 public class IndentingXMLStreamWriter extends DelegatingXMLStreamWriter {
36     private final static Object SEEN_NOTHING = new Object();
37     private final static Object SEEN_ELEMENT = new Object();
38     private final static Object SEEN_DATA = new Object();
39
40     private Object state = SEEN_NOTHING;
41     private Stack<Object> stateStack = new Stack<Object>();
42
43     private String indentStep = "  ";
44     private int depth = 0;
45
46     public IndentingXMLStreamWriter(XMLStreamWriter writer) {
47         super(writer);
48     }
49
50     /**
51      * Return the current indent step.
52      *
53      * <p>Return the current indent step: each start tag will be
54      * indented by this number of spaces times the number of
55      * ancestors that the element has.</p>
56      *
57      * @return The number of spaces in each indentation step,
58      *         or 0 or less for no indentation.
59      * @see #setIndentStep(int)
60      *
61      * @deprecated
62      *      Only return the length of the indent string.
63      */
64     public int getIndentStep() {
65         return indentStep.length();
66     }
67
68
69     /**
70      * Set the current indent step.
71      *
72      * @param indentStep The new indent step (0 or less for no
73      *        indentation).
74      * @see #getIndentStep()
75      *
76      * @deprecated
77      *      Should use the version that takes string.
78      */
79     public void setIndentStep(int indentStep) {
80         StringBuilder s = new StringBuilder();
81         for (; indentStep > 0; indentStep--) {
82             s.append(' ');
83         }
84         setIndentStep(s.toString());
85     }
86
87     public void setIndentStep(String s) {
88         this.indentStep = s;
89     }
90
91     private void onStartElement() throws XMLStreamException {
92         stateStack.push(SEEN_ELEMENT);
93         state = SEEN_NOTHING;
94         if (depth > 0) {
95             super.writeCharacters("\n");
96         }
97         doIndent();
98         depth++;
99     }
100
101     private void onEndElement() throws XMLStreamException {
102         depth--;
103         if (state == SEEN_ELEMENT) {
104             super.writeCharacters("\n");
105             doIndent();
106         }
107         state = stateStack.pop();
108     }
109
110     private void onEmptyElement() throws XMLStreamException {
111         state = SEEN_ELEMENT;
112         if (depth > 0) {
113             super.writeCharacters("\n");
114         }
115         doIndent();
116     }
117
118     /**
119      * Print indentation for the current level.
120      *
121      * @exception org.xml.sax.SAXException If there is an error
122      *            writing the indentation characters, or if a filter
123      *            further down the chain raises an exception.
124      */
125     private void doIndent() throws XMLStreamException {
126         if (depth > 0) {
127             for (int i = 0; i < depth; i++) {
128                 super.writeCharacters(indentStep);
129             }
130         }
131     }
132
133
134     public void writeStartDocument() throws XMLStreamException {
135         super.writeStartDocument();
136         super.writeCharacters("\n");
137     }
138
139     public void writeStartDocument(String version) throws XMLStreamException {
140         super.writeStartDocument(version);
141         super.writeCharacters("\n");
142     }
143
144     public void writeStartDocument(String encoding, String version) throws XMLStreamException {
145         super.writeStartDocument(encoding, version);
146         super.writeCharacters("\n");
147     }
148
149     public void writeStartElement(String localName) throws XMLStreamException {
150         onStartElement();
151         super.writeStartElement(localName);
152     }
153
154     public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
155         onStartElement();
156         super.writeStartElement(namespaceURI, localName);
157     }
158
159     public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
160         onStartElement();
161         super.writeStartElement(prefix, localName, namespaceURI);
162     }
163
164     public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
165         onEmptyElement();
166         super.writeEmptyElement(namespaceURI, localName);
167     }
168
169     public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
170         onEmptyElement();
171         super.writeEmptyElement(prefix, localName, namespaceURI);
172     }
173
174     public void writeEmptyElement(String localName) throws XMLStreamException {
175         onEmptyElement();
176         super.writeEmptyElement(localName);
177     }
178
179     public void writeEndElement() throws XMLStreamException {
180         onEndElement();
181         super.writeEndElement();
182     }
183
184     public void writeCharacters(String text) throws XMLStreamException {
185         state = SEEN_DATA;
186         super.writeCharacters(text);
187     }
188
189     public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
190         state = SEEN_DATA;
191         super.writeCharacters(text, start, len);
192     }
193
194     public void writeCData(String data) throws XMLStreamException {
195         state = SEEN_DATA;
196         super.writeCData(data);
197     }
198 }