KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > lang > GString


1 /*
2  * $Id: GString.java,v 1.12 2004/05/04 02:54:44 spullara Exp $
3  *
4  * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5  *
6  * Redistribution and use of this software and associated documentation
7  * ("Software"), with or without modification, are permitted provided that the
8  * following conditions are met: 1. Redistributions of source code must retain
9  * copyright statements and notices. Redistributions must also contain a copy
10  * of this document. 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer in
12  * the documentation and/or other materials provided with the distribution. 3.
13  * The name "groovy" must not be used to endorse or promote products derived
14  * from this Software without prior written permission of The Codehaus. For
15  * written permission, please contact info@codehaus.org. 4. Products derived
16  * from this Software may not be called "groovy" nor may "groovy" appear in
17  * their names without prior written permission of The Codehaus. "groovy" is a
18  * registered trademark of The Codehaus. 5. Due credit should be given to The
19  * Codehaus - http://groovy.codehaus.org/
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  *
33  */

34 package groovy.lang;
35
36 import java.io.IOException JavaDoc;
37 import java.io.StringWriter JavaDoc;
38 import java.io.Writer JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Arrays JavaDoc;
41 import java.util.List JavaDoc;
42
43 import org.codehaus.groovy.runtime.InvokerHelper;
44
45 /**
46  * Represents a String which contains embedded values such as "hello there
47  * ${user} how are you?" which can be evaluated lazily. Advanced users can
48  * iterate over the text and values to perform special processing, such as for
49  * performing SQL operations, the values can be substituted for ? and the
50  * actual value objects can be bound to a JDBC statement. The lovely name of
51  * this class was suggested by Jules Gosnell and was such a good idea, I
52  * couldn't resist :)
53  *
54  * @author <a HREF="mailto:james@coredevelopers.net">James Strachan</a>
55  * @version $Revision: 1.12 $
56  */

57 public abstract class GString extends GroovyObjectSupport implements Comparable JavaDoc, CharSequence JavaDoc, Writable {
58
59     private Object JavaDoc[] values;
60
61     public GString(Object JavaDoc values) {
62         this.values = (Object JavaDoc[]) values;
63     }
64
65     public GString(Object JavaDoc[] values) {
66         this.values = values;
67     }
68
69     // will be static in an instance
70
public abstract String JavaDoc[] getStrings();
71
72     /**
73      * Overloaded to implement duck typing for Strings
74      * so that any method that can't be evaluated on this
75      * object will be forwarded to the toString() object instead.
76      */

77     public Object JavaDoc invokeMethod(String JavaDoc name, Object JavaDoc args) {
78         try {
79             return super.invokeMethod(name, args);
80         }
81         catch (MissingMethodException e) {
82             // lets try invoke the method on the real String
83
return InvokerHelper.invokeMethod(toString(), name, args);
84         }
85     }
86
87     public Object JavaDoc[] getValues() {
88         return values;
89     }
90
91     public GString plus(GString that) {
92         List JavaDoc stringList = new ArrayList JavaDoc();
93         List JavaDoc valueList = new ArrayList JavaDoc();
94
95         stringList.addAll(Arrays.asList(getStrings()));
96         valueList.addAll(Arrays.asList(getValues()));
97
98         if (stringList.size() > valueList.size()) {
99             valueList.add("");
100         }
101
102         stringList.addAll(Arrays.asList(that.getStrings()));
103         valueList.addAll(Arrays.asList(that.getValues()));
104
105         final String JavaDoc[] newStrings = new String JavaDoc[stringList.size()];
106         stringList.toArray(newStrings);
107         Object JavaDoc[] newValues = valueList.toArray();
108
109         return new GString(newValues) {
110             public String JavaDoc[] getStrings() {
111                 return newStrings;
112             }
113         };
114     }
115
116     public GString plus(String JavaDoc that) {
117         String JavaDoc[] currentStrings = getStrings();
118         String JavaDoc[] newStrings = null;
119         Object JavaDoc[] newValues = null;
120
121         newStrings = new String JavaDoc[currentStrings.length + 1];
122         newValues = new Object JavaDoc[getValues().length + 1];
123         int lastIndex = currentStrings.length;
124         System.arraycopy(currentStrings, 0, newStrings, 0, lastIndex);
125         System.arraycopy(getValues(), 0, newValues, 0, getValues().length);
126         newStrings[lastIndex] = that;
127         newValues[getValues().length] = "";
128
129         final String JavaDoc[] finalStrings = newStrings;
130         return new GString(newValues) {
131
132             public String JavaDoc[] getStrings() {
133                 return finalStrings;
134             }
135         };
136     }
137
138     public int getValueCount() {
139         return values.length;
140     }
141
142     public Object JavaDoc getValue(int idx) {
143         return values[idx];
144     }
145
146     public String JavaDoc toString() {
147         StringWriter JavaDoc buffer = new StringWriter JavaDoc();
148         try {
149             writeTo(buffer);
150         }
151         catch (IOException JavaDoc e) {
152             throw new StringWriterIOException(e);
153         }
154         return buffer.toString();
155     }
156
157     public Writer JavaDoc writeTo(Writer JavaDoc out) throws IOException JavaDoc {
158         String JavaDoc[] s = getStrings();
159         int numberOfValues = values.length;
160         for (int i = 0, size = s.length; i < size; i++) {
161             out.write(s[i]);
162             if (i < numberOfValues) {
163                 InvokerHelper.write(out, values[i]);
164             }
165         }
166         return out;
167     }
168
169     public boolean equals(Object JavaDoc that) {
170         if (that instanceof GString) {
171             return equals((GString) that);
172         }
173         return false;
174     }
175
176     public boolean equals(GString that) {
177         return toString().equals(that.toString());
178     }
179
180     public int hashCode() {
181         return 37 + toString().hashCode();
182     }
183
184     public int compareTo(Object JavaDoc that) {
185         return toString().compareTo(that.toString());
186     }
187
188     public char charAt(int index) {
189         return toString().charAt(index);
190     }
191
192     public int length() {
193         return toString().length();
194     }
195
196     public CharSequence JavaDoc subSequence(int start, int end) {
197         return toString().subSequence(start, end);
198     }
199 }
200
Popular Tags