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;
17  
18  
19  import java.awt.Dimension;
20  import java.awt.Point;
21  import java.awt.Rectangle;
22  import java.util.Date;
23  
24  
25  /**
26   * A helper class to get formatted value out of XML element text.
27   * 
28   * @author Olivier Berlanger
29   */
30  public class ElementText {
31  
32  
33      /**
34       * Get the current text from the given parser. <br>
35       * If there is no current text or if this text is only made of white spaces, null is returned.
36       * 
37       * @param parser
38       *            the parser.
39       * @return the text of the current element of the given parser.
40       */
41      public static String getString(XMLEventParser parser) throws XMLParseException {
42          return getString(null, parser, false);
43      }
44  
45  
46      /**
47       * Get the current text from the given parser. <br>
48       * If there is no current text or if this text is only made of white spaces, the given default value is returned.
49       * 
50       * @param defaultValue
51       *            the value to return if no text is defined.
52       * @param parser
53       *            the parser.
54       * @return the text of the current element of the given parser.
55       */
56      public static String getString(String defaultValue, XMLEventParser parser) throws XMLParseException {
57          return getString(defaultValue, parser, false);
58      }
59  
60  
61      /**
62       * Get the current text from the given parser. <br>
63       * If there is no current text or if this text is only made of white spaces, an exception is throw saying that this text is
64       * mandatory.
65       * 
66       * @param parser
67       *            the parser.
68       * @return the text of the current element of the given parser.
69       * @throws XMLParseException
70       *             if no text is defined.
71       */
72      public static String getMandatoryString(XMLEventParser parser) throws XMLParseException {
73          return getString(null, parser, true);
74      }
75  
76  
77      /**
78       * Get a multi-line text. <br>
79       * This method removes from the given multi-line text the witespace that was added for indentation at the begin of each text
80       * line. This method does the invert operation of the <code>XMLSerializer.charactersMultiLine(String text)</code> method.
81       * 
82       * @param defaultValue
83       *            the value to return if no text is defined.
84       * @param parser
85       *            the parser.
86       * @return the text of the current element of the given parser.
87       * @see XMLSerializer#charactersMultiLine(String)
88       */
89      public static String getMultilineText(String defaultValue, XMLEventParser parser) throws XMLParseException {
90          return getMultilineText(defaultValue, parser, false);
91      }
92  
93  
94      /**
95       * Get a mandatory multi-line text. <br>
96       * This method removes from the given multi-line text the witespace that was added for indentation at the begin of each text
97       * line. This method does the invert operation of the <code>XMLSerializer.charactersMultiLine(String text)</code> method.
98       * <p>
99       * If there is no current text or if this text is only made of white spaces, an exception is throw saying that this text is
100      * mandatory.
101      * </p>
102      * 
103      * @param parser
104      *            the parser.
105      * @return the text of the current element of the given parser.
106      * @throws XMLParseException
107      *             if no text is defined.
108      * @see XMLSerializer#charactersMultiLine(String)
109      */
110     public static String getMandatoryMultilineText(XMLEventParser parser) throws XMLParseException {
111         return getMultilineText(null, parser, true);
112     }
113 
114 
115     public static int getInt(int defaultValue, XMLEventParser parser) throws XMLParseException {
116         return getInt(defaultValue, parser, false);
117     }
118 
119 
120     public static int getMandatoryInt(XMLEventParser parser) throws XMLParseException {
121         return getInt(0, parser, true);
122     }
123 
124 
125     public static <T extends Enum<T>> T getEnum(T defaultValue, Class<T> enumType, XMLEventParser parser)
126             throws XMLParseException {
127         return getEnum(defaultValue, enumType, parser, false);
128     }
129 
130 
131     public static <T extends Enum<T>> T getMandatoryEnum(Class<T> enumType, XMLEventParser parser) throws XMLParseException {
132         return getEnum(null, enumType, parser, true);
133     }
134 
135 
136     public static double getDouble(double defaultValue, XMLEventParser parser) throws XMLParseException {
137         return getDouble(defaultValue, parser, false);
138     }
139 
140 
141     public static double getMandatoryDouble(XMLEventParser parser) throws XMLParseException {
142         return getDouble(0.0, parser, true);
143     }
144 
145 
146     public static int[] getIntArray(int[] defaultValue, XMLEventParser parser) throws XMLParseException {
147         return getIntArray(defaultValue, parser, false);
148     }
149 
150 
151     public static int[] getMandatoryIntArray(XMLEventParser parser) throws XMLParseException {
152         return getIntArray(null, parser, true);
153     }
154 
155 
156     public static long getLong(long defaultValue, XMLEventParser parser) throws XMLParseException {
157         return getLong(defaultValue, parser, false);
158     }
159 
160 
161     public static long getMandatoryLong(XMLEventParser parser) throws XMLParseException {
162         return getLong(0, parser, true);
163     }
164 
165 
166     public static boolean getBoolean(boolean defaultValue, XMLEventParser parser) throws XMLParseException {
167         return getBoolean(defaultValue, parser, false);
168     }
169 
170 
171     public static boolean getMandatoryBoolean(XMLEventParser parser) throws XMLParseException {
172         return getBoolean(false, parser, true);
173     }
174 
175 
176     public static Point getPoint(Point defaultValue, XMLEventParser parser) throws XMLParseException {
177         return getPoint(defaultValue, false, parser);
178     }
179 
180 
181     public static Point getMandatoryPoint(XMLEventParser parser) throws XMLParseException {
182         return getPoint(null, true, parser);
183     }
184 
185 
186     public static Dimension getDimension(Dimension defaultValue, XMLEventParser parser) throws XMLParseException {
187         return getDimension(defaultValue, false, parser);
188     }
189 
190 
191     public static Dimension getMandatoryDimension(XMLEventParser parser) throws XMLParseException {
192         return getDimension(null, true, parser);
193     }
194 
195 
196     public static Rectangle getRectangle(Rectangle defaultValue, XMLEventParser parser) throws XMLParseException {
197         return getRectangle(defaultValue, false, parser);
198     }
199 
200 
201     public static Rectangle getMandatoryRectangle(XMLEventParser parser) throws XMLParseException {
202         return getRectangle(null, true, parser);
203     }
204 
205 
206     public static Date getDate(String pattern, Date defaultValue, XMLEventParser parser) throws XMLParseException {
207         return getDate(pattern, defaultValue, false, parser);
208     }
209 
210 
211     public static Date getMandatoryDate(String pattern, XMLEventParser parser) throws XMLParseException {
212         return getDate(pattern, null, true, parser);
213     }
214 
215 
216     protected static String getString(String defaultValue, XMLEventParser parser, boolean mandatory) throws XMLParseException {
217         String text = defaultValue;
218         String elementText = getTrimmedText(mandatory, parser);
219         if (elementText != null) {
220             text = elementText;
221         }
222         return text;
223     }
224 
225 
226     protected static String getMultilineText(String defaultValue, XMLEventParser parser, boolean mandatory)
227             throws XMLParseException {
228         String multilineText = defaultValue;
229         String text = parser.getElementText();
230         if ((text != null) && text.trim().equals("")) text = null;
231         if (text == null) {
232             if (mandatory) {
233                 parser.throwParseException("Element text is mandatory", null);
234             }
235         } else {
236             multilineText = trimMultiLine(text);
237         }
238         return multilineText;
239     }
240 
241 
242     protected static boolean getBoolean(boolean defaultValue, XMLEventParser parser, boolean mandatory)
243             throws XMLParseException {
244         boolean result = defaultValue;
245         String elementText = getTrimmedText(mandatory, parser);
246         if (elementText != null) {
247             result = Attributes.stringToBoolean(elementText);
248         }
249         return result;
250     }
251 
252 
253     protected static int getInt(int defaultValue, XMLEventParser parser, boolean mandatory) throws XMLParseException {
254         int result = defaultValue;
255         String elementText = getTrimmedText(mandatory, parser);
256         if (elementText != null) {
257             try {
258                 result = Integer.parseInt(elementText);
259             } catch (Exception e) {
260                 parser.throwParseException("Element text '" + elementText + "' must be a coma-separated list of integers", e);
261             }
262         }
263         return result;
264     }
265 
266 
267     protected static <T extends Enum<T>> T getEnum(T defaultValue, Class<T> enumType, XMLEventParser parser, boolean mandatory)
268             throws XMLParseException {
269         T result = defaultValue;
270         String elementText = getTrimmedText(mandatory, parser);
271         if (elementText != null) {
272             try {
273                 result = Enum.valueOf(enumType, elementText);
274             } catch (Exception e) {
275                 parser.throwParseException("Element text '" + elementText + "' must a enum value of type " + enumType, e);
276             }
277         }
278         return result;
279     }
280 
281 
282     protected static double getDouble(double defaultValue, XMLEventParser parser, boolean mandatory) throws XMLParseException {
283         double result = defaultValue;
284         String elementText = getTrimmedText(mandatory, parser);
285         if (elementText != null) {
286             try {
287                 result = Double.parseDouble(elementText);
288             } catch (Exception e) {
289                 parser.throwParseException("Element text '" + elementText + "' must have an Double value.", e);
290             }
291         }
292         return result;
293     }
294 
295 
296     protected static int[] getIntArray(int[] defaultValue, XMLEventParser parser, boolean mandatory) throws XMLParseException {
297         int[] result = defaultValue;
298         String elementText = getTrimmedText(mandatory, parser);
299         if (elementText != null) {
300             try {
301                 result = Attributes.stringToIntArray(elementText);
302             } catch (Exception e) {
303                 parser.throwParseException("Element text '" + elementText + "' must be a coma-separated list of integers", e);
304             }
305         }
306         return result;
307     }
308 
309 
310     protected static long getLong(long defaultValue, XMLEventParser parser, boolean mandatory) throws XMLParseException {
311         long result = defaultValue;
312         String elementText = getTrimmedText(mandatory, parser);
313         if (elementText != null) {
314             try {
315                 result = Long.parseLong(elementText);
316             } catch (Exception e) {
317                 parser.throwParseException("Element text '" + elementText + "' must have an Long value.", e);
318             }
319         }
320         return result;
321     }
322 
323 
324     protected static Dimension getDimension(Dimension defaultValue, boolean mandatory, XMLEventParser parser)
325             throws XMLParseException {
326         Dimension result = defaultValue;
327         String elementText = getTrimmedText(mandatory, parser);
328         if (elementText != null) {
329             try {
330                 int[] vals = Attributes.stringToIntArray(elementText);
331                 if (vals.length != 2) {
332                     throw new IllegalArgumentException("Bad dimension value --> it should be 2 integers, not " + vals.length);
333                 }
334                 result = new Dimension(vals[0], vals[1]);
335             } catch (Exception e) {
336                 parser.throwParseException("Element text '" + elementText
337                         + "' must be a Dimension (coma-separated list of 2 integers)", e);
338             }
339         }
340         return result;
341     }
342 
343 
344     protected static Point getPoint(Point defaultValue, boolean mandatory, XMLEventParser parser) throws XMLParseException {
345         Point result = defaultValue;
346         String elementText = getTrimmedText(mandatory, parser);
347         if (elementText != null) {
348             try {
349                 int[] vals = Attributes.stringToIntArray(elementText);
350                 if (vals.length != 2) {
351                     throw new IllegalArgumentException("Bad point value --> it should be 2 integers, not " + vals.length);
352                 }
353                 result = new Point(vals[0], vals[1]);
354             } catch (Exception e) {
355                 parser.throwParseException("Element text '" + elementText
356                         + "' must be a Point (coma-separated list of 2 integers)", e);
357             }
358         }
359         return result;
360     }
361 
362 
363     protected static Rectangle getRectangle(Rectangle defaultValue, boolean mandatory, XMLEventParser parser)
364             throws XMLParseException {
365         Rectangle result = defaultValue;
366         String elementText = getTrimmedText(mandatory, parser);
367         if (elementText != null) {
368             try {
369                 int[] vals = Attributes.stringToIntArray(elementText);
370                 if (vals.length != 4) {
371                     throw new IllegalArgumentException("Bad rectangle value --> it should be 4 integers, not " + vals.length);
372                 }
373                 result = new Rectangle(vals[0], vals[1], vals[2], vals[3]);
374             } catch (Exception e) {
375                 parser.throwParseException("Element text '" + elementText
376                         + "' must be a Rectangle (coma-separated list of 4 integers)", e);
377             }
378         }
379         return result;
380     }
381 
382 
383     protected static Date getDate(String pattern, Date defaultValue, boolean mandatory, XMLEventParser parser)
384             throws XMLParseException {
385         Date result = defaultValue;
386         String elementText = getTrimmedText(mandatory, parser);
387         if (elementText != null) {
388             try {
389                 result = Attributes.stringToDate(elementText, pattern);
390             } catch (Exception e) {
391                 parser.throwParseException("Element text '" + elementText + "' must be a Date with pattern [" + pattern + "]",
392                         e);
393             }
394         }
395         return result;
396     }
397 
398 
399     protected static String getTrimmedText(boolean mandatory, XMLEventParser parser) throws XMLParseException {
400         String text = parser.getElementText();
401         if (text != null) {
402             text = text.trim();
403             if (text.equals("")) text = null;
404         }
405         if ((text == null) && mandatory) {
406             parser.throwParseException("Element text is mandatory", null);
407         }
408         return text;
409     }
410 
411 
412     /**
413      * Remove extra whitespaces that were added by the XMLSerializer.charactersMultiLine(text) method. <br>
414      * Each line of the string is 'smartly trimmed' to get back the input text. If the given string contains only one line (new
415      * 'new-line' characters) it is simply trimmed.
416      * 
417      * @param str
418      *            The multi-line string to be trimmed at each line.
419      * @return The input string trimmed at each line.
420      */
421     public static final String trimMultiLine(String str) {
422         if (str == null) return null;
423         if (str.indexOf("\n") < 0) return str.trim();
424         String[] lines = str.split("\n");
425         int nbrLine = lines.length;
426         String line;
427         char ch;
428         // get start index
429         int startIndex = Integer.MAX_VALUE;
430         int j;
431         for (int i = 0; i < nbrLine; i++) {
432             line = lines[i];
433             int lineLen = line.length();
434             for (j = 0; j < lineLen; j++) {
435                 if (line.charAt(j) > 32) {
436                     if (((j > 0) || (i > 0)) && (startIndex > j)) startIndex = j;
437                     break;
438                 }
439             }
440         }
441         if (startIndex == Integer.MAX_VALUE) startIndex = 0;
442         // add trimmed lines to a buffer
443         StringBuffer sb = new StringBuffer(str.length());
444         // eat leading white lines
445         int start = 0;
446         for (int i = 0; i < nbrLine; i++) {
447             if (!Attributes.isEmpty(lines[i])) {
448                 start = i;
449                 break;
450             }
451         }
452         for (int i = start; i < nbrLine; i++) {
453             line = lines[i];
454             int lineLen = line.length();
455             // add new line
456             if (i > start) sb.append('\n');
457             // get the trimmed end index
458             int endIndex = lineLen;
459             for (j = lineLen - 1; j >= 0; j--) {
460                 if (line.charAt(j) > 32) {
461                     endIndex = j + 1;
462                     break;
463                 }
464             }
465             // add the line
466             for (j = 0; j < endIndex; j++) {
467                 ch = line.charAt(j);
468                 if (j < startIndex) {
469                     if (ch > 32) sb.append(ch);
470                 } else {
471                     sb.append(ch);
472                 }
473             }
474         }
475         return sb.toString();
476     }
477 
478 
479     public static void simpleElementMultiline(String uri, String tag, String text, XMLSerializer serilalizer)
480             throws XMLSerializeException {
481         serilalizer.startElement(uri, tag);
482         serilalizer.charactersMultiLine(text);
483         serilalizer.endElement(uri, tag);
484     }
485 
486 }