1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id: XMLStringDefault.java 570109 2007-08-27 13:31:35Z zongaro $
20 */
21package org.apache.xml.utils;
22
23import java.util.Locale;
24
25/**
26 * The default implementation of the XMLString interface,
27 * which is just a simple wrapper of a String object.
28 */
29public class XMLStringDefault implements XMLString
30{
31
32  private String m_str;
33
34  /**
35   * Create a XMLStringDefault object from a String
36   */
37  public XMLStringDefault(String str)
38  {
39    m_str = str;
40  }
41
42  /**
43   * Directly call the
44   * characters method on the passed ContentHandler for the
45   * string-value. Multiple calls to the
46   * ContentHandler's characters methods may well occur for a single call to
47   * this method.
48   *
49   * @param ch A non-null reference to a ContentHandler.
50   *
51   * @throws org.xml.sax.SAXException
52   */
53  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
54    throws org.xml.sax.SAXException
55  {
56  }
57
58  /**
59   * Directly call the
60   * comment method on the passed LexicalHandler for the
61   * string-value.
62   *
63   * @param lh A non-null reference to a LexicalHandler.
64   *
65   * @throws org.xml.sax.SAXException
66   */
67  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
68    throws org.xml.sax.SAXException
69  {
70  }
71
72  /**
73   * Conditionally trim all leading and trailing whitespace in the specified String.
74   * All strings of white space are
75   * replaced by a single space character (#x20), except spaces after punctuation which
76   * receive double spaces if doublePunctuationSpaces is true.
77   * This function may be useful to a formatter, but to get first class
78   * results, the formatter should probably do it's own white space handling
79   * based on the semantics of the formatting object.
80   *
81   * @param   trimHead    Trim leading whitespace?
82   * @param   trimTail    Trim trailing whitespace?
83   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
84   * @return              The trimmed string.
85   */
86  public XMLString fixWhiteSpace(boolean trimHead,
87                                 boolean trimTail,
88                                 boolean doublePunctuationSpaces)
89  {
90    return new XMLStringDefault(m_str.trim());
91  }
92
93  /**
94   * Returns the length of this string.
95   *
96   * @return  the length of the sequence of characters represented by this
97   *          object.
98   */
99  public int length()
100  {
101    return m_str.length();
102  }
103
104  /**
105   * Returns the character at the specified index. An index ranges
106   * from <code>0</code> to <code>length() - 1</code>. The first character
107   * of the sequence is at index <code>0</code>, the next at index
108   * <code>1</code>, and so on, as for array indexing.
109   *
110   * @param      index   the index of the character.
111   * @return     the character at the specified index of this string.
112   *             The first character is at index <code>0</code>.
113   * @exception  IndexOutOfBoundsException  if the <code>index</code>
114   *             argument is negative or not less than the length of this
115   *             string.
116   */
117  public char charAt(int index)
118  {
119    return m_str.charAt(index);
120  }
121
122  /**
123   * Copies characters from this string into the destination character
124   * array.
125   *
126   * @param      srcBegin   index of the first character in the string
127   *                        to copy.
128   * @param      srcEnd     index after the last character in the string
129   *                        to copy.
130   * @param      dst        the destination array.
131   * @param      dstBegin   the start offset in the destination array.
132   * @exception IndexOutOfBoundsException If any of the following
133   *            is true:
134   *            <ul><li><code>srcBegin</code> is negative.
135   *            <li><code>srcBegin</code> is greater than <code>srcEnd</code>
136   *            <li><code>srcEnd</code> is greater than the length of this
137   *                string
138   *            <li><code>dstBegin</code> is negative
139   *            <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
140   *                <code>dst.length</code></ul>
141   * @exception NullPointerException if <code>dst</code> is <code>null</code>
142   */
143  public void getChars(int srcBegin, int srcEnd, char dst[],
144                                int dstBegin)
145  {
146    int destIndex = dstBegin;
147    for (int i = srcBegin; i < srcEnd; i++)
148    {
149      dst[destIndex++] = m_str.charAt(i);
150    }
151  }
152
153  /**
154   * Compares this string to the specified <code>String</code>.
155   * The result is <code>true</code> if and only if the argument is not
156   * <code>null</code> and is a <code>String</code> object that represents
157   * the same sequence of characters as this object.
158   *
159   * @param   obj2   the object to compare this <code>String</code> against.
160   * @return  <code>true</code> if the <code>String</code>s are equal;
161   *          <code>false</code> otherwise.
162   * @see     java.lang.String#compareTo(java.lang.String)
163   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
164   */
165  public boolean equals(String obj2) {
166      return m_str.equals(obj2);
167  }
168
169  /**
170   * Compares this string to the specified object.
171   * The result is <code>true</code> if and only if the argument is not
172   * <code>null</code> and is a <code>String</code> object that represents
173   * the same sequence of characters as this object.
174   *
175   * @param   anObject   the object to compare this <code>String</code>
176   *                     against.
177   * @return  <code>true</code> if the <code>String </code>are equal;
178   *          <code>false</code> otherwise.
179   * @see     java.lang.String#compareTo(java.lang.String)
180   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
181   */
182  public boolean equals(XMLString anObject)
183  {
184    return m_str.equals(anObject.toString());
185  }
186
187
188  /**
189   * Compares this string to the specified object.
190   * The result is <code>true</code> if and only if the argument is not
191   * <code>null</code> and is a <code>String</code> object that represents
192   * the same sequence of characters as this object.
193   *
194   * @param   anObject   the object to compare this <code>String</code>
195   *                     against.
196   * @return  <code>true</code> if the <code>String </code>are equal;
197   *          <code>false</code> otherwise.
198   * @see     java.lang.String#compareTo(java.lang.String)
199   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
200   */
201  public boolean equals(Object anObject)
202  {
203    return m_str.equals(anObject);
204  }
205
206  /**
207   * Compares this <code>String</code> to another <code>String</code>,
208   * ignoring case considerations.  Two strings are considered equal
209   * ignoring case if they are of the same length, and corresponding
210   * characters in the two strings are equal ignoring case.
211   *
212   * @param   anotherString   the <code>String</code> to compare this
213   *                          <code>String</code> against.
214   * @return  <code>true</code> if the argument is not <code>null</code>
215   *          and the <code>String</code>s are equal,
216   *          ignoring case; <code>false</code> otherwise.
217   * @see     #equals(Object)
218   * @see     java.lang.Character#toLowerCase(char)
219   * @see java.lang.Character#toUpperCase(char)
220   */
221  public boolean equalsIgnoreCase(String anotherString)
222  {
223    return m_str.equalsIgnoreCase(anotherString);
224  }
225
226  /**
227   * Compares two strings lexicographically.
228   *
229   * @param   anotherString   the <code>String</code> to be compared.
230   * @return  the value <code>0</code> if the argument string is equal to
231   *          this string; a value less than <code>0</code> if this string
232   *          is lexicographically less than the string argument; and a
233   *          value greater than <code>0</code> if this string is
234   *          lexicographically greater than the string argument.
235   * @exception java.lang.NullPointerException if <code>anotherString</code>
236   *          is <code>null</code>.
237   */
238  public int compareTo(XMLString anotherString)
239  {
240    return m_str.compareTo(anotherString.toString());
241  }
242
243  /**
244   * Compares two strings lexicographically, ignoring case considerations.
245   * This method returns an integer whose sign is that of
246   * <code>this.toUpperCase().toLowerCase().compareTo(
247   * str.toUpperCase().toLowerCase())</code>.
248   * <p>
249   * Note that this method does <em>not</em> take locale into account,
250   * and will result in an unsatisfactory ordering for certain locales.
251   * The java.text package provides <em>collators</em> to allow
252   * locale-sensitive ordering.
253   *
254   * @param   str   the <code>String</code> to be compared.
255   * @return  a negative integer, zero, or a positive integer as the
256   *          the specified String is greater than, equal to, or less
257   *          than this String, ignoring case considerations.
258   * @see     java.text.Collator#compare(String, String)
259   * @since   1.2
260   */
261  public int compareToIgnoreCase(XMLString str)
262  {
263    return m_str.compareToIgnoreCase(str.toString());
264  }
265
266  /**
267   * Tests if this string starts with the specified prefix beginning
268   * a specified index.
269   *
270   * @param   prefix    the prefix.
271   * @param   toffset   where to begin looking in the string.
272   * @return  <code>true</code> if the character sequence represented by the
273   *          argument is a prefix of the substring of this object starting
274   *          at index <code>toffset</code>; <code>false</code> otherwise.
275   *          The result is <code>false</code> if <code>toffset</code> is
276   *          negative or greater than the length of this
277   *          <code>String</code> object; otherwise the result is the same
278   *          as the result of the expression
279   *          <pre>
280   *          this.subString(toffset).startsWith(prefix)
281   *          </pre>
282   * @exception java.lang.NullPointerException if <code>prefix</code> is
283   *          <code>null</code>.
284   */
285  public boolean startsWith(String prefix, int toffset)
286  {
287    return m_str.startsWith(prefix, toffset);
288  }
289
290  /**
291   * Tests if this string starts with the specified prefix beginning
292   * a specified index.
293   *
294   * @param   prefix    the prefix.
295   * @param   toffset   where to begin looking in the string.
296   * @return  <code>true</code> if the character sequence represented by the
297   *          argument is a prefix of the substring of this object starting
298   *          at index <code>toffset</code>; <code>false</code> otherwise.
299   *          The result is <code>false</code> if <code>toffset</code> is
300   *          negative or greater than the length of this
301   *          <code>String</code> object; otherwise the result is the same
302   *          as the result of the expression
303   *          <pre>
304   *          this.subString(toffset).startsWith(prefix)
305   *          </pre>
306   * @exception java.lang.NullPointerException if <code>prefix</code> is
307   *          <code>null</code>.
308   */
309  public boolean startsWith(XMLString prefix, int toffset)
310  {
311    return m_str.startsWith(prefix.toString(), toffset);
312  }
313
314  /**
315   * Tests if this string starts with the specified prefix.
316   *
317   * @param   prefix   the prefix.
318   * @return  <code>true</code> if the character sequence represented by the
319   *          argument is a prefix of the character sequence represented by
320   *          this string; <code>false</code> otherwise.
321   *          Note also that <code>true</code> will be returned if the
322   *          argument is an empty string or is equal to this
323   *          <code>String</code> object as determined by the
324   *          {@link #equals(Object)} method.
325   * @exception java.lang.NullPointerException if <code>prefix</code> is
326   *          <code>null</code>.
327   * @since   JDK1. 0
328   */
329  public boolean startsWith(String prefix)
330  {
331    return m_str.startsWith(prefix);
332  }
333
334  /**
335   * Tests if this string starts with the specified prefix.
336   *
337   * @param   prefix   the prefix.
338   * @return  <code>true</code> if the character sequence represented by the
339   *          argument is a prefix of the character sequence represented by
340   *          this string; <code>false</code> otherwise.
341   *          Note also that <code>true</code> will be returned if the
342   *          argument is an empty string or is equal to this
343   *          <code>String</code> object as determined by the
344   *          {@link #equals(Object)} method.
345   * @exception java.lang.NullPointerException if <code>prefix</code> is
346   *          <code>null</code>.
347   * @since   JDK1. 0
348   */
349  public boolean startsWith(XMLString prefix)
350  {
351    return m_str.startsWith(prefix.toString());
352  }
353
354  /**
355   * Tests if this string ends with the specified suffix.
356   *
357   * @param   suffix   the suffix.
358   * @return  <code>true</code> if the character sequence represented by the
359   *          argument is a suffix of the character sequence represented by
360   *          this object; <code>false</code> otherwise. Note that the
361   *          result will be <code>true</code> if the argument is the
362   *          empty string or is equal to this <code>String</code> object
363   *          as determined by the {@link #equals(Object)} method.
364   * @exception java.lang.NullPointerException if <code>suffix</code> is
365   *          <code>null</code>.
366   */
367  public boolean endsWith(String suffix)
368  {
369    return m_str.endsWith(suffix);
370  }
371
372  /**
373   * Returns a hashcode for this string. The hashcode for a
374   * <code>String</code> object is computed as
375   * <blockquote><pre>
376   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
377   * </pre></blockquote>
378   * using <code>int</code> arithmetic, where <code>s[i]</code> is the
379   * <i>i</i>th character of the string, <code>n</code> is the length of
380   * the string, and <code>^</code> indicates exponentiation.
381   * (The hash value of the empty string is zero.)
382   *
383   * @return  a hash code value for this object.
384   */
385  public int hashCode()
386  {
387    return m_str.hashCode();
388  }
389
390  /**
391   * Returns the index within this string of the first occurrence of the
392   * specified character. If a character with value <code>ch</code> occurs
393   * in the character sequence represented by this <code>String</code>
394   * object, then the index of the first such occurrence is returned --
395   * that is, the smallest value <i>k</i> such that:
396   * <blockquote><pre>
397   * this.charAt(<i>k</i>) == ch
398   * </pre></blockquote>
399   * is <code>true</code>. If no such character occurs in this string,
400   * then <code>-1</code> is returned.
401   *
402   * @param   ch   a character.
403   * @return  the index of the first occurrence of the character in the
404   *          character sequence represented by this object, or
405   *          <code>-1</code> if the character does not occur.
406   */
407  public int indexOf(int ch)
408  {
409    return m_str.indexOf(ch);
410  }
411
412  /**
413   * Returns the index within this string of the first occurrence of the
414   * specified character, starting the search at the specified index.
415   * <p>
416   * If a character with value <code>ch</code> occurs in the character
417   * sequence represented by this <code>String</code> object at an index
418   * no smaller than <code>fromIndex</code>, then the index of the first
419   * such occurrence is returned--that is, the smallest value <i>k</i>
420   * such that:
421   * <blockquote><pre>
422   * (this.charAt(<i>k</i>) == ch) && (<i>k</i> >= fromIndex)
423   * </pre></blockquote>
424   * is true. If no such character occurs in this string at or after
425   * position <code>fromIndex</code>, then <code>-1</code> is returned.
426   * <p>
427   * There is no restriction on the value of <code>fromIndex</code>. If it
428   * is negative, it has the same effect as if it were zero: this entire
429   * string may be searched. If it is greater than the length of this
430   * string, it has the same effect as if it were equal to the length of
431   * this string: <code>-1</code> is returned.
432   *
433   * @param   ch          a character.
434   * @param   fromIndex   the index to start the search from.
435   * @return  the index of the first occurrence of the character in the
436   *          character sequence represented by this object that is greater
437   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
438   *          if the character does not occur.
439   */
440  public int indexOf(int ch, int fromIndex)
441  {
442    return m_str.indexOf(ch, fromIndex);
443  }
444
445  /**
446   * Returns the index within this string of the last occurrence of the
447   * specified character. That is, the index returned is the largest
448   * value <i>k</i> such that:
449   * <blockquote><pre>
450   * this.charAt(<i>k</i>) == ch
451   * </pre></blockquote>
452   * is true.
453   * The String is searched backwards starting at the last character.
454   *
455   * @param   ch   a character.
456   * @return  the index of the last occurrence of the character in the
457   *          character sequence represented by this object, or
458   *          <code>-1</code> if the character does not occur.
459   */
460  public int lastIndexOf(int ch)
461  {
462    return m_str.lastIndexOf(ch);
463  }
464
465  /**
466   * Returns the index within this string of the last occurrence of the
467   * specified character, searching backward starting at the specified
468   * index. That is, the index returned is the largest value <i>k</i>
469   * such that:
470   * <blockquote><pre>
471   * this.charAt(k) == ch) && (k <= fromIndex)
472   * </pre></blockquote>
473   * is true.
474   *
475   * @param   ch          a character.
476   * @param   fromIndex   the index to start the search from. There is no
477   *          restriction on the value of <code>fromIndex</code>. If it is
478   *          greater than or equal to the length of this string, it has
479   *          the same effect as if it were equal to one less than the
480   *          length of this string: this entire string may be searched.
481   *          If it is negative, it has the same effect as if it were -1:
482   *          -1 is returned.
483   * @return  the index of the last occurrence of the character in the
484   *          character sequence represented by this object that is less
485   *          than or equal to <code>fromIndex</code>, or <code>-1</code>
486   *          if the character does not occur before that point.
487   */
488  public int lastIndexOf(int ch, int fromIndex)
489  {
490    return m_str.lastIndexOf(ch, fromIndex);
491  }
492
493  /**
494   * Returns the index within this string of the first occurrence of the
495   * specified substring. The integer returned is the smallest value
496   * <i>k</i> such that:
497   * <blockquote><pre>
498   * this.startsWith(str, <i>k</i>)
499   * </pre></blockquote>
500   * is <code>true</code>.
501   *
502   * @param   str   any string.
503   * @return  if the string argument occurs as a substring within this
504   *          object, then the index of the first character of the first
505   *          such substring is returned; if it does not occur as a
506   *          substring, <code>-1</code> is returned.
507   * @exception java.lang.NullPointerException if <code>str</code> is
508   *          <code>null</code>.
509   */
510  public int indexOf(String str)
511  {
512    return m_str.indexOf(str);
513  }
514
515  /**
516   * Returns the index within this string of the first occurrence of the
517   * specified substring. The integer returned is the smallest value
518   * <i>k</i> such that:
519   * <blockquote><pre>
520   * this.startsWith(str, <i>k</i>)
521   * </pre></blockquote>
522   * is <code>true</code>.
523   *
524   * @param   str   any string.
525   * @return  if the string argument occurs as a substring within this
526   *          object, then the index of the first character of the first
527   *          such substring is returned; if it does not occur as a
528   *          substring, <code>-1</code> is returned.
529   * @exception java.lang.NullPointerException if <code>str</code> is
530   *          <code>null</code>.
531   */
532  public int indexOf(XMLString str)
533  {
534    return m_str.indexOf(str.toString());
535  }
536
537  /**
538   * Returns the index within this string of the first occurrence of the
539   * specified substring, starting at the specified index. The integer
540   * returned is the smallest value <i>k</i> such that:
541   * <blockquote><pre>
542   * this.startsWith(str, <i>k</i>) && (<i>k</i> >= fromIndex)
543   * </pre></blockquote>
544   * is <code>true</code>.
545   * <p>
546   * There is no restriction on the value of <code>fromIndex</code>. If
547   * it is negative, it has the same effect as if it were zero: this entire
548   * string may be searched. If it is greater than the length of this
549   * string, it has the same effect as if it were equal to the length of
550   * this string: <code>-1</code> is returned.
551   *
552   * @param   str         the substring to search for.
553   * @param   fromIndex   the index to start the search from.
554   * @return  If the string argument occurs as a substring within this
555   *          object at a starting index no smaller than
556   *          <code>fromIndex</code>, then the index of the first character
557   *          of the first such substring is returned. If it does not occur
558   *          as a substring starting at <code>fromIndex</code> or beyond,
559   *          <code>-1</code> is returned.
560   * @exception java.lang.NullPointerException if <code>str</code> is
561   *          <code>null</code>
562   */
563  public int indexOf(String str, int fromIndex)
564  {
565    return m_str.indexOf(str, fromIndex);
566  }
567
568  /**
569   * Returns the index within this string of the rightmost occurrence
570   * of the specified substring.  The rightmost empty string "" is
571   * considered to occur at the index value <code>this.length()</code>.
572   * The returned index is the largest value <i>k</i> such that
573   * <blockquote><pre>
574   * this.startsWith(str, k)
575   * </pre></blockquote>
576   * is true.
577   *
578   * @param   str   the substring to search for.
579   * @return  if the string argument occurs one or more times as a substring
580   *          within this object, then the index of the first character of
581   *          the last such substring is returned. If it does not occur as
582   *          a substring, <code>-1</code> is returned.
583   * @exception java.lang.NullPointerException  if <code>str</code> is
584   *          <code>null</code>.
585   */
586  public int lastIndexOf(String str)
587  {
588    return m_str.lastIndexOf(str);
589  }
590
591  /**
592   * Returns the index within this string of the last occurrence of
593   * the specified substring.
594   *
595   * @param   str         the substring to search for.
596   * @param   fromIndex   the index to start the search from. There is no
597   *          restriction on the value of fromIndex. If it is greater than
598   *          the length of this string, it has the same effect as if it
599   *          were equal to the length of this string: this entire string
600   *          may be searched. If it is negative, it has the same effect
601   *          as if it were -1: -1 is returned.
602   * @return  If the string argument occurs one or more times as a substring
603   *          within this object at a starting index no greater than
604   *          <code>fromIndex</code>, then the index of the first character of
605   *          the last such substring is returned. If it does not occur as a
606   *          substring starting at <code>fromIndex</code> or earlier,
607   *          <code>-1</code> is returned.
608   * @exception java.lang.NullPointerException if <code>str</code> is
609   *          <code>null</code>.
610   */
611  public int lastIndexOf(String str, int fromIndex)
612  {
613    return m_str.lastIndexOf(str, fromIndex);
614  }
615
616  /**
617   * Returns a new string that is a substring of this string. The
618   * substring begins with the character at the specified index and
619   * extends to the end of this string. <p>
620   * Examples:
621   * <blockquote><pre>
622   * "unhappy".substring(2) returns "happy"
623   * "Harbison".substring(3) returns "bison"
624   * "emptiness".substring(9) returns "" (an empty string)
625   * </pre></blockquote>
626   *
627   * @param      beginIndex   the beginning index, inclusive.
628   * @return     the specified substring.
629   * @exception  IndexOutOfBoundsException  if
630   *             <code>beginIndex</code> is negative or larger than the
631   *             length of this <code>String</code> object.
632   */
633  public XMLString substring(int beginIndex)
634  {
635    return new XMLStringDefault(m_str.substring(beginIndex));
636  }
637
638  /**
639   * Returns a new string that is a substring of this string. The
640   * substring begins at the specified <code>beginIndex</code> and
641   * extends to the character at index <code>endIndex - 1</code>.
642   * Thus the length of the substring is <code>endIndex-beginIndex</code>.
643   *
644   * @param      beginIndex   the beginning index, inclusive.
645   * @param      endIndex     the ending index, exclusive.
646   * @return     the specified substring.
647   * @exception  IndexOutOfBoundsException  if the
648   *             <code>beginIndex</code> is negative, or
649   *             <code>endIndex</code> is larger than the length of
650   *             this <code>String</code> object, or
651   *             <code>beginIndex</code> is larger than
652   *             <code>endIndex</code>.
653   */
654  public XMLString substring(int beginIndex, int endIndex)
655  {
656    return new XMLStringDefault(m_str.substring(beginIndex, endIndex));
657  }
658
659  /**
660   * Concatenates the specified string to the end of this string.
661   *
662   * @param   str   the <code>String</code> that is concatenated to the end
663   *                of this <code>String</code>.
664   * @return  a string that represents the concatenation of this object's
665   *          characters followed by the string argument's characters.
666   * @exception java.lang.NullPointerException if <code>str</code> is
667   *          <code>null</code>.
668   */
669  public XMLString concat(String str)
670  {
671    return new XMLStringDefault(m_str.concat(str));
672  }
673
674  /**
675   * Converts all of the characters in this <code>String</code> to lower
676   * case using the rules of the given <code>Locale</code>.
677   *
678   * @param locale use the case transformation rules for this locale
679   * @return the String, converted to lowercase.
680   * @see     java.lang.Character#toLowerCase(char)
681   * @see     java.lang.String#toUpperCase(Locale)
682   */
683  public XMLString toLowerCase(Locale locale)
684  {
685    return new XMLStringDefault(m_str.toLowerCase(locale));
686  }
687
688  /**
689   * Converts all of the characters in this <code>String</code> to lower
690   * case using the rules of the default locale, which is returned
691   * by <code>Locale.getDefault</code>.
692   * <p>
693   *
694   * @return  the string, converted to lowercase.
695   * @see     java.lang.Character#toLowerCase(char)
696   * @see     java.lang.String#toLowerCase(Locale)
697   */
698  public XMLString toLowerCase()
699  {
700    return new XMLStringDefault(m_str.toLowerCase());
701  }
702
703  /**
704   * Converts all of the characters in this <code>String</code> to upper
705   * case using the rules of the given locale.
706   * @param locale use the case transformation rules for this locale
707   * @return the String, converted to uppercase.
708   * @see     java.lang.Character#toUpperCase(char)
709   * @see     java.lang.String#toLowerCase(Locale)
710   */
711  public XMLString toUpperCase(Locale locale)
712  {
713    return new XMLStringDefault(m_str.toUpperCase(locale));
714  }
715
716  /**
717   * Converts all of the characters in this <code>String</code> to upper
718   * case using the rules of the default locale, which is returned
719   * by <code>Locale.getDefault</code>.
720   *
721   * <p>
722   * If no character in this string has a different uppercase version,
723   * based on calling the <code>toUpperCase</code> method defined by
724   * <code>Character</code>, then the original string is returned.
725   * <p>
726   * Otherwise, this method creates a new <code>String</code> object
727   * representing a character sequence identical in length to the
728   * character sequence represented by this <code>String</code> object and
729   * with every character equal to the result of applying the method
730   * <code>Character.toUpperCase</code> to the corresponding character of
731   * this <code>String</code> object. <p>
732   * Examples:
733   * <blockquote><pre>
734   * "Fahrvergn&uuml;gen".toUpperCase() returns "FAHRVERGN&Uuml;GEN"
735   * "Visit Ljubinje!".toUpperCase() returns "VISIT LJUBINJE!"
736   * </pre></blockquote>
737   *
738   * @return  the string, converted to uppercase.
739   * @see     java.lang.Character#toUpperCase(char)
740   * @see     java.lang.String#toUpperCase(Locale)
741   */
742  public XMLString toUpperCase()
743  {
744    return new XMLStringDefault(m_str.toUpperCase());
745  }
746
747  /**
748   * Removes white space from both ends of this string.
749   * <p>
750   * If this <code>String</code> object represents an empty character
751   * sequence, or the first and last characters of character sequence
752   * represented by this <code>String</code> object both have codes
753   * greater than <code>'&#92;u0020'</code> (the space character), then a
754   * reference to this <code>String</code> object is returned.
755   * <p>
756   * Otherwise, if there is no character with a code greater than
757   * <code>'&#92;u0020'</code> in the string, then a new
758   * <code>String</code> object representing an empty string is created
759   * and returned.
760   * <p>
761   * Otherwise, let <i>k</i> be the index of the first character in the
762   * string whose code is greater than <code>'&#92;u0020'</code>, and let
763   * <i>m</i> be the index of the last character in the string whose code
764   * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
765   * object is created, representing the substring of this string that
766   * begins with the character at index <i>k</i> and ends with the
767   * character at index <i>m</i>-that is, the result of
768   * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
769   * <p>
770   * This method may be used to trim
771   * {@link Character#isSpace(char) whitespace} from the beginning and end
772   * of a string; in fact, it trims all ASCII control characters as well.
773   *
774   * @return  this string, with white space removed from the front and end.
775   */
776  public XMLString trim()
777  {
778    return new XMLStringDefault(m_str.trim());
779  }
780
781  /**
782   * This object (which is already a string!) is itself returned.
783   *
784   * @return  the string itself.
785   */
786  public String toString()
787  {
788    return m_str;
789  }
790
791  /**
792   * Tell if this object contains a java String object.
793   *
794   * @return true if this XMLString can return a string without creating one.
795   */
796  public boolean hasString()
797  {
798    return true;
799  }
800
801  /**
802   * Convert a string to a double -- Allowed input is in fixed
803   * notation ddd.fff.
804   *
805   * @return A double value representation of the string, or return Double.NaN
806   * if the string can not be converted.
807   */
808  public double toDouble()
809  {
810    try {
811      return Double.valueOf(m_str).doubleValue();
812    }
813    catch (NumberFormatException nfe)
814    {
815      return Double.NaN;
816    }
817  }
818}
819