View Javadoc

1   /*-------------------------------------------------------------------------
2    Copyright 2006 Olivier Berlanger
3   
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7   
8    http://www.apache.org/licenses/LICENSE-2.0
9   
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15   -------------------------------------------------------------------------*/
16  package net.sf.xolite.impl;
17  
18  
19  import java.io.IOException;
20  
21  import net.sf.xolite.XMLSerializeException;
22  
23  
24  /**
25   * A <code>XMLSerializer</code> base implementation for all serializer writing the XML in a byte or character stream.
26   * 
27   * @author Olivier Berlanger
28   * @see BaseXMLSerializer
29   */
30  public abstract class FlowXMLSerializer extends BaseXMLSerializer {
31  
32  
33      private static final String TAB_STRING = "\t";
34  
35      private int indentation = 4;
36      private boolean insertTabs = false;
37      private boolean insertLineBreaks = true;
38      private boolean breakFirstAttribute = false;
39      private boolean breakBetweenAttributes = false;
40      private boolean writeXmlHeader = true;
41      private String indentationString = "";
42  
43  
44      public void setFormatting(boolean useLineBreaks, boolean useTabs, int indentationSpaceCount) {
45          insertTabs = useTabs;
46          indentation = indentationSpaceCount;
47          insertLineBreaks = useLineBreaks;
48      }
49  
50  
51      public void setAttributeFormatting(boolean breakFirst, boolean breakOthers) {
52          breakFirstAttribute = breakFirst;
53          breakBetweenAttributes = breakOthers;
54      }
55  
56  
57      public int getIndentationSpaceCount() {
58          return indentation;
59      }
60  
61  
62      public boolean isUsingTabs() {
63          return insertTabs;
64      }
65  
66  
67      public boolean isUsingLineBreaks() {
68          return insertLineBreaks;
69      }
70  
71  
72      public boolean isBreakingForFirstAttribute() {
73          return breakFirstAttribute;
74      }
75  
76  
77      public boolean isBreakingBetweenAttributes() {
78          return breakBetweenAttributes;
79      }
80  
81  
82      public boolean getWriteXmlHeader() {
83          return writeXmlHeader;
84      }
85  
86  
87      public void setWriteXmlHeader(boolean newWriteXmlHeader) {
88          writeXmlHeader = newWriteXmlHeader;
89      }
90  
91  
92      // -------------------------------------- BaseXMLSerializer Implementation ---------------------------------------------
93  
94  
95      protected void startDocumentImpl() throws IOException {
96          if (writeXmlHeader) {
97              writeString("<?xml version=\"1.0\"?>");
98              if (insertLineBreaks) writeNewLine();
99          }
100     }
101 
102 
103     protected void startElementImpl(String uri, String prefix, String tag) throws IOException, XMLSerializeException {
104         writeIndentation(getLevel());
105         writeString("<");
106         writePrefixedName(prefix, tag);
107     }
108 
109 
110     protected void attributeImpl(String uri, String prefix, String name, String value, int index) throws IOException {
111         boolean breakLine = ((index == 0) ? breakFirstAttribute : breakBetweenAttributes) && insertLineBreaks;
112         if (breakLine) writeAttributeBreak(breakFirstAttribute);
113         else writeString(" ");
114         writePrefixedName(prefix, name);
115         writeString("=\"");
116         writeDataCharacters(value);
117         writeString("\"");
118     }
119 
120 
121     protected void closeElementStartImpl(boolean complexContent) throws IOException {
122         writeString(">");
123         if (complexContent && insertLineBreaks) writeNewLine();
124     }
125 
126 
127     protected void charactersImpl(String text, boolean multiLine) throws IOException {
128         if (multiLine && insertLineBreaks) {
129             if (text != null) {
130                 String[] lines = text.split("\n");
131                 int nbrLines = lines.length;
132                 for (int i = 0; i < nbrLines; i++) {
133                     writeNewLine();
134                     writeIndentation(getLevel() + 1);
135                     writeDataCharacters(lines[i]);
136                 }
137             }
138         } else {
139             writeDataCharacters(text);
140         }
141     }
142 
143 
144     protected void endInlineElementImpl(String uri, String prefix, String tag) throws Exception {
145         writeString("/>");
146         if (insertLineBreaks) writeNewLine();
147     }
148 
149 
150     protected void endTextElementImpl(String uri, String prefix, String tag, boolean multiLine) throws Exception {
151         if (multiLine && insertLineBreaks) {
152             writeNewLine();
153             writeIndentation(getLevel());
154         }
155         writeString("</");
156         writePrefixedName(prefix, tag);
157         writeString(">");
158         if (insertLineBreaks) writeNewLine();
159     }
160 
161 
162     protected void endComplexElementImpl(String uri, String prefix, String tag) throws Exception {
163         writeIndentation(getLevel());
164         writeString("</");
165         writePrefixedName(prefix, tag);
166         writeString(">");
167         if (insertLineBreaks) writeNewLine();
168     }
169 
170 
171     protected void writePrefixedName(String prefix, String tag) throws IOException {
172         if ((prefix != null) && (!prefix.equals(""))) {
173             writeString(prefix);
174             writeString(":");
175         }
176         writeString(tag);
177     }
178 
179 
180     protected void endDocumentImpl() throws Exception {
181     }
182 
183 
184     // ---------------------------------- implementation --------------------------------------------------
185 
186 
187     private String getIndentString() {
188         if (insertTabs) return TAB_STRING;
189         if (indentationString.length() == indentation) return indentationString;
190         StringBuffer sb = new StringBuffer();
191         for (int i = 0; i < indentation; i++)
192             sb.append(' ');
193         indentationString = sb.toString();
194         return indentationString;
195     }
196 
197 
198     protected void writeIndentation(int level) throws IOException {
199         if (insertLineBreaks && (insertTabs || (indentation > 0))) {
200             String str = getIndentString();
201             for (int i = 0; i < level; i++) {
202                 writeString(str);
203             }
204         }
205     }
206 
207 
208     protected void writeAttributeBreak(boolean simpleIndent) throws IOException {
209         writeNewLine();
210         if (simpleIndent) {
211             writeIndentation(getLevel() + 2);
212         } else {
213             writeIndentation(getLevel());
214             int len = getLastElementLength() + 2;
215             for (int i = 0; i < len; i++)
216                 writeCharacter(' ');
217         }
218     }
219 
220 
221     protected void writeDataCharacters(String text) throws IOException {
222         int len = (text == null) ? 0 : text.length();
223         char ch;
224         for (int i = 0; i < len; i++) {
225             ch = text.charAt(i);
226             switch (ch) {
227                 case '&':
228                     writeString("&amp;");
229                     break;
230                 case '<':
231                     writeString("&lt;");
232                     break;
233                 case '>':
234                     writeString("&gt;");
235                     break;
236                 case '"':
237                     writeString("&quot;");
238                     break;
239                 case '\'':
240                     writeString("&apos;");
241                     break;
242                 default:
243                     writeCharacter(ch);
244             }
245         }
246     }
247 
248 
249     // ---------------------------------- Methods to implements --------------------------------------------------
250 
251 
252     protected abstract void writeNewLine() throws IOException;
253 
254 
255     protected abstract void writeString(String text) throws IOException;
256 
257 
258     protected abstract void writeCharacter(char ch) throws IOException;
259 
260 
261 }