View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@codehaus.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.codehaus.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 1999-2001 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  package org.codehaus.modello.plugin.java.javasource;
46  
47  /*
48   * Copyright (c) 2004, Codehaus.org
49   *
50   * Permission is hereby granted, free of charge, to any person obtaining a copy of
51   * this software and associated documentation files (the "Software"), to deal in
52   * the Software without restriction, including without limitation the rights to
53   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
54   * of the Software, and to permit persons to whom the Software is furnished to do
55   * so, subject to the following conditions:
56   *
57   * The above copyright notice and this permission notice shall be included in all
58   * copies or substantial portions of the Software.
59   *
60   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
66   * SOFTWARE.
67   */
68  
69  import java.util.ArrayList;
70  import java.util.List;
71  
72  import org.codehaus.modello.ModelloRuntimeException;
73  
74  /**
75   * A class for holding in-memory Java source code.
76   *
77   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
78   * @version $Revision$ $Date$
79   **/
80  public class JSourceCode {
81  
82      /**
83       * A list of JCodeStatements
84       **/
85      private List<JCodeStatement> source = null;
86  
87      /**
88       * The indent size
89       **/
90      private short indentSize = 4;
91  
92      /**
93       * The current indent size
94       **/
95      private short currentIndent = indentSize;
96  
97      /**
98       * Creates an empty JSourceCode
99       **/
100     public JSourceCode() {
101         super();
102         source = new ArrayList<JCodeStatement>();
103     } // -- JSourceCode
104 
105     /**
106      * Creates a JSourceCode and adds the given String
107      * to it's contents
108      * @param sourceCode the source to add
109      **/
110     public JSourceCode(String sourceCode) {
111         this();
112         this.source.add(new JCodeStatement(sourceCode, currentIndent));
113     } // -- JSourceCode
114 
115     /**
116      * Adds the given statement to this JSourceCode. The statement
117      * will be added on a new line.
118      * @param statement the statement to add
119      **/
120     public void add(String statement) {
121         JCodeStatement jcs = new JCodeStatement(statement, currentIndent);
122         source.add(jcs);
123     } // -- add
124 
125     /**
126      * Adds the given statement to this JSourceCode. The statement
127      * will be added on a new line.
128      * @param statement the statement to add
129      * @param indentSize the indentSize is the size of the indentation to use
130      * when printing this JSourceCode
131      * @see #print
132      * @deprecated this method is not here any mode in castor codegen 1.3rc1
133      **/
134     public void add(String statement, short indentSize) {
135         JCodeStatement jcs = new JCodeStatement(statement, indentSize);
136         source.add(jcs);
137     } // -- add
138 
139     /**
140      * Adds the given statement to this JSourceCode. The statement
141      * will be added on a new line and added with increased indent.
142      * This is a convenience method for the sequence
143      * <code>
144      * indent();
145      * add(statement);
146      * unindent();
147      * </code>
148      * @param statement the statement to add
149      **/
150     public void addIndented(String statement) {
151         indent();
152         JCodeStatement jcs = new JCodeStatement(statement, currentIndent);
153         source.add(jcs);
154         unindent();
155     } // -- add
156 
157     /**
158      * Appends the given String to the last line in this
159      * JSourceCode
160      * @param segment the String to append
161      **/
162     public void append(String segment) {
163 
164         if (source.isEmpty()) add(segment);
165         else {
166             JCodeStatement jcs = (JCodeStatement) source.get(source.size() - 1);
167             jcs.append(segment);
168         }
169     } // -- append(String)
170 
171     /**
172      * Clears all the code statements from this JSourceCode
173      **/
174     public void clear() {
175         source.clear();
176     } // -- clear();
177 
178     /**
179      * Copies the contents of this JSourceCode into the given JSourceCode
180      * @param jsc the JSourceCode to copy this JSourceCode into
181      **/
182     public void copyInto(JSourceCode jsc) {
183         for (int i = 0; i < source.size(); i++) {
184             jsc.addCodeStatement(source.get(i));
185         }
186     } // -- copyInto
187 
188     /**
189      * Increases the current indent level by 1
190      **/
191     public void indent() {
192         currentIndent += indentSize;
193     } // -- indent();
194 
195     /**
196      * Returns true if this JSourceCode is empty (ie. no source).
197      * @return true if this JSourceCode is empty.
198      **/
199     public boolean isEmpty() {
200         return source.isEmpty();
201     } // -- isEmpty
202 
203     /**
204      * Prints this JSourceCode to the given JSourceWriter
205      * @param jsw the JSourceWriter to print to
206      **/
207     public void print(JSourceWriter jsw) {
208         for (int i = 0; i < source.size(); i++) jsw.writeln(source.get(i).toString());
209     } // -- print
210 
211     /**
212      * Decreases the indent level by 1
213      **/
214     public void unindent() {
215         if (currentIndent == 0) {
216             throw new ModelloRuntimeException("Cannot unindent: current indent is 0.");
217         }
218         currentIndent -= indentSize;
219     } // -- unindent
220 
221     /**
222      * Returns the String representation of this JSourceCode
223      * @return the String representation of this JSourceCode
224      **/
225     public String toString() {
226         StringBuilder sb = new StringBuilder();
227         String lineSeparator = System.getProperty("line.separator");
228         for (int i = 0; i < source.size(); i++) {
229             sb.append(source.get(i).toString());
230             sb.append(lineSeparator);
231         }
232         return sb.toString();
233     } // -- toString
234 
235     /**
236      * Adds the given JCodeStatement to this JSourceCode
237      * @param jcs the JCodeStatement to add
238      **/
239     private void addCodeStatement(JCodeStatement jcs) {
240         short indent = (short) (jcs.getIndent() + currentIndent - JCodeStatement.DEFAULT_INDENTSIZE);
241         source.add(new JCodeStatement(jcs.getStatement(), indent));
242     } // -- addCodeStatement(JCodeStatement)
243 } // -- JSourceCode
244 
245 /**
246  * Represents a line of code, used by JSourceCode class
247  * @author <a href="kvisco@intalio.com">Keith Visco</a>
248  **/
249 class JCodeStatement {
250 
251     private StringBuilder value = null;
252     public static short DEFAULT_INDENTSIZE = 4;
253     private short indentSize = DEFAULT_INDENTSIZE;
254 
255     JCodeStatement() {
256         super();
257         value = new StringBuilder();
258     } // -- JCodeStatement
259 
260     JCodeStatement(String statement) {
261         this();
262         this.value.append(statement);
263     } // -- JCodeStatement
264 
265     JCodeStatement(String statement, short indentSize) {
266         this(statement);
267         this.indentSize = indentSize;
268     } // -- JCodeStatement
269 
270     void append(String segment) {
271         value.append(segment);
272     }
273 
274     short getIndent() {
275         return indentSize;
276     } // -- getIndent
277 
278     String getStatement() {
279         return value.toString();
280     } // -- getStatement
281 
282     public String toString() {
283         if (value.length() == 0) {
284             return "";
285         }
286 
287         StringBuilder sb = new StringBuilder(indentSize + value.length());
288         for (int i = 0; i < indentSize; i++) sb.append(' ');
289         sb.append(value.toString());
290         return sb.toString();
291     }
292 } // -- JCodeStatement