001: /*
002: * JavaVariable.java
003: *
004: * This work is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published
006: * by the Free Software Foundation; either version 2 of the License,
007: * or (at your option) any later version.
008: *
009: * This work is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017: * USA
018: *
019: * As a special exception, the copyright holders of this library give
020: * you permission to link this library with independent modules to
021: * produce an executable, regardless of the license terms of these
022: * independent modules, and to copy and distribute the resulting
023: * executable under terms of your choice, provided that you also meet,
024: * for each linked independent module, the terms and conditions of the
025: * license of that module. An independent module is a module which is
026: * not derived from or based on this library. If you modify this
027: * library, you may extend this exception to your version of the
028: * library, but you are not obligated to do so. If you do not wish to
029: * do so, delete this exception statement from your version.
030: *
031: * Copyright (c) 2003 Per Cederberg. All rights reserved.
032: */
033:
034: package net.percederberg.grammatica.code.java;
035:
036: import java.io.PrintWriter;
037: import java.util.Vector;
038:
039: import net.percederberg.grammatica.code.CodeElement;
040: import net.percederberg.grammatica.code.CodeStyle;
041:
042: /**
043: * A class generating a Java variable declaration. The variable
044: * declaration should be placed as a member in a class.
045: *
046: * @author Per Cederberg, <per at percederberg dot net>
047: * @version 1.0
048: */
049: public class JavaVariable extends CodeElement {
050:
051: /**
052: * The public access modifier constant.
053: */
054: public static final int PUBLIC = JavaModifier.PUBLIC;
055:
056: /**
057: * The protected access modifier constant.
058: */
059: public static final int PROTECTED = JavaModifier.PROTECTED;
060:
061: /**
062: * The package local access modifier constant (i.e. no modifier).
063: */
064: public static final int PACKAGE_LOCAL = JavaModifier.PACKAGE_LOCAL;
065:
066: /**
067: * The private access modifier constant.
068: */
069: public static final int PRIVATE = JavaModifier.PRIVATE;
070:
071: /**
072: * The static modifier constant.
073: */
074: public static final int STATIC = JavaModifier.STATIC;
075:
076: /**
077: * The final modifier constant.
078: */
079: public static final int FINAL = JavaModifier.FINAL;
080:
081: /**
082: * The transient modifier constant.
083: */
084: public static final int TRANSIENT = JavaModifier.TRANSIENT;
085:
086: /**
087: * The volatile modifier constant.
088: */
089: public static final int VOLATILE = JavaModifier.VOLATILE;
090:
091: /**
092: * The variable modifiers.
093: */
094: private int modifiers;
095:
096: /**
097: * The variable type.
098: */
099: private String type;
100:
101: /**
102: * The variable name.
103: */
104: private String name;
105:
106: /**
107: * The variable init value. This initialization value is only used
108: * if a single initialization value is added. Otherwise the vector
109: * initialization is used.
110: *
111: * @see #vectorInit
112: */
113: private String initValue;
114:
115: /**
116: * The vector init values. These initialization values are only
117: * used for vector initializations, not for single values.
118: *
119: * @see #initValue
120: */
121: private Vector initValueVector;
122:
123: /**
124: * The variable comment.
125: */
126: private JavaComment comment;
127:
128: /**
129: * Creates a new variable with the specified type and name.
130: *
131: * @param type the variable type
132: * @param name the variable name
133: */
134: public JavaVariable(String type, String name) {
135: this (PUBLIC, type, name);
136: }
137:
138: /**
139: * Creates a new variable with the specified modifiers, type and
140: * name.
141: *
142: * @param modifiers the modifier flags to use
143: * @param type the variable type
144: * @param name the variable name
145: */
146: public JavaVariable(int modifiers, String type, String name) {
147: this (modifiers, type, name, null);
148: }
149:
150: /**
151: * Creates a new variable with the specified type, name and
152: * initializer.
153: *
154: * @param type the variable type
155: * @param name the variable name
156: * @param initValue the initialize value
157: */
158: public JavaVariable(String type, String name, String initValue) {
159: this (PUBLIC, type, name, initValue);
160: }
161:
162: /**
163: * Creates a new variable with the specified modifiers, type, name
164: * and initializer.
165: *
166: * @param modifiers the modifier flags to use
167: * @param type the variable type
168: * @param name the variable name
169: * @param initValue the initialize value
170: */
171: public JavaVariable(int modifiers, String type, String name,
172: String initValue) {
173:
174: this .modifiers = modifiers;
175: this .type = type;
176: this .name = name;
177: this .initValue = initValue;
178: this .initValueVector = new Vector();
179: this .comment = null;
180: }
181:
182: /**
183: * Adds a comment to this variable.
184: *
185: * @param comment the comment to add
186: */
187: public void addComment(JavaComment comment) {
188: this .comment = comment;
189: }
190:
191: /**
192: * Adds initialization code for a vector element value. Each
193: * vector element value added will be added last in the list of
194: * initialization values. If an init value has been specified with
195: * the constructor, it will be added first in the vector.
196: *
197: * @param elementValue the vector element value
198: */
199: public void addVectorInit(String elementValue) {
200: if (this .initValue != null) {
201: this .initValueVector.add(this .initValue);
202: this .initValue = null;
203: }
204: this .initValueVector.add(elementValue);
205: }
206:
207: /**
208: * Returns a numeric category number for the code element. A lower
209: * category number implies that the code element should be placed
210: * before code elements with a higher category number within a
211: * declaration.
212: *
213: * @return the category number
214: */
215: public int category() {
216: return ((modifiers & STATIC) > 0) ? 4 : 5;
217: }
218:
219: /**
220: * Prints the code element to the specified output stream.
221: *
222: * @param out the output stream
223: * @param style the code style to use
224: * @param indent the indentation level
225: */
226: public void print(PrintWriter out, CodeStyle style, int indent) {
227: String indentStr = style.getIndent(indent);
228: String prefix = JavaModifier.createModifierDecl(modifiers);
229: String init;
230:
231: if (comment != null) {
232: comment.print(out, style, indent);
233: }
234: init = getInitCode(style, indent);
235: if (init == null) {
236: out.println(indentStr + prefix + type + " " + name + ";");
237: } else {
238: out.println(indentStr + prefix + type + " " + name + " = "
239: + init + ";");
240: }
241: }
242:
243: /**
244: * Returns indented initialization code lines. If not init code is
245: * available, the method returns null.
246: *
247: * @param style the Java code style
248: * @param indent the indentation level
249: *
250: * @return the indented initialization code
251: */
252: private String getInitCode(CodeStyle style, int indent) {
253: String indentStr = style.getIndent(indent);
254: String codeIndentStr = style.getIndent(indent + 1);
255: StringBuffer res;
256:
257: // Check for simple init values
258: if (initValueVector.size() == 0 && initValue == null) {
259: return null;
260: } else if (initValue != null) {
261: return initValue;
262: }
263:
264: // Create array of init values
265: res = new StringBuffer("{\n");
266: for (int i = 0; i < initValueVector.size(); i++) {
267: res.append(codeIndentStr);
268: res.append(initValueVector.elementAt(i).toString());
269: if (i + 1 < initValueVector.size()) {
270: res.append(",\n");
271: } else {
272: res.append("\n");
273: }
274: }
275: res.append(indentStr);
276: res.append("}");
277:
278: return res.toString();
279: }
280: }
|