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