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