001: /*
002: * Copyright 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.rebind;
017:
018: import com.google.gwt.core.ext.GeneratorContext;
019: import com.google.gwt.core.ext.TreeLogger;
020: import com.google.gwt.user.rebind.ClassSourceFileComposerFactory.JavaSourceCategory;
021:
022: import java.io.PrintWriter;
023:
024: class ClassSourceFileComposer implements SourceWriter {
025:
026: /**
027: * For the interior of a '*' style comment.
028: */
029: private static final String STAR_COMMENT_LINE = " * ";
030:
031: private boolean atStart;
032:
033: /**
034: * Either STAR/BLOCK comment line, not pulled out into a ENUM class because
035: * only used by this class.
036: */
037: private String commentIndicator;
038:
039: private final GeneratorContext ctx;
040:
041: /**
042: * Are you currently in a comment?
043: */
044: private boolean inComment;
045:
046: private int indent;
047:
048: private final PrintWriter printWriter;
049:
050: ClassSourceFileComposer(GeneratorContext ctx,
051: PrintWriter printWriter, String targetPackageName,
052: String targetClassShortName, String super ClassName,
053: String[] interfaceNames, String[] imports,
054: JavaSourceCategory category, String classJavaDocComment) {
055: this .ctx = ctx;
056: this .printWriter = printWriter;
057: if (targetPackageName == null) {
058: throw new IllegalArgumentException(
059: "Cannot supply a null package name to"
060: + targetClassShortName);
061: }
062: // Inlined header to only have one method with a huge number of methods.
063: if (targetPackageName.length() > 0) {
064: println("package " + targetPackageName + ";");
065: }
066:
067: println();
068: if (imports != null && imports.length > 0) {
069: for (int i = 0, n = imports.length; i < n; ++i) {
070: println("import " + imports[i] + ";");
071: }
072: println();
073: }
074: if (classJavaDocComment != null) {
075: beginJavaDocComment();
076: print(classJavaDocComment);
077: endJavaDocComment();
078: }
079: if (category == JavaSourceCategory.CLASS) {
080: emitClassDecl(targetClassShortName, super ClassName,
081: interfaceNames);
082: } else {
083: emitInterfaceDecl(targetClassShortName, super ClassName,
084: interfaceNames);
085: }
086: println(" {");
087: indent();
088: }
089:
090: /**
091: * Begin emitting a JavaDoc comment.
092: */
093: public void beginJavaDocComment() {
094: println("\n/**");
095: inComment = true;
096: commentIndicator = STAR_COMMENT_LINE;
097: }
098:
099: public void commit(TreeLogger logger) {
100: outdent();
101: println("}");
102: printWriter.close();
103: // If generating a class on the command line, may not have a
104: if (ctx != null) {
105: ctx.commit(logger, printWriter);
106: }
107: }
108:
109: /**
110: * End emitting a JavaDoc comment.
111: */
112: public void endJavaDocComment() {
113: inComment = false;
114: println("\n */");
115: }
116:
117: public void indent() {
118: ++indent;
119: }
120:
121: public void indentln(String s) {
122: indent();
123: println(s);
124: outdent();
125: }
126:
127: public void outdent() {
128: --indent;
129: }
130:
131: public void print(String s) {
132: // If we just printed a newline, print an indent.
133: //
134: if (atStart) {
135: for (int j = 0; j < indent; ++j) {
136: printWriter.print(" ");
137: }
138: if (inComment) {
139: printWriter.print(commentIndicator);
140: }
141: atStart = false;
142: }
143: // Now print up to the end of the string or the next newline.
144: //
145: String rest = null;
146: int i = s.indexOf("\n");
147: if (i > -1 && i < s.length() - 1) {
148: rest = s.substring(i + 1);
149: s = s.substring(0, i + 1);
150: }
151: printWriter.print(s);
152: // If rest is non-null, then s ended with a newline and we recurse.
153: //
154: if (rest != null) {
155: atStart = true;
156: print(rest);
157: }
158: }
159:
160: public void println() {
161: print("\n");
162: atStart = true;
163: }
164:
165: public void println(String s) {
166: print(s + "\n");
167: atStart = true;
168: }
169:
170: private void emitClassDecl(String targetClassShortName,
171: String super ClassName, String[] interfaceNames) {
172: print("public class " + targetClassShortName);
173: if (super ClassName != null) {
174: print(" extends " + super ClassName);
175: }
176: if (interfaceNames != null && interfaceNames.length > 0) {
177: print(" implements ");
178: for (int i = 0, n = interfaceNames.length; i < n; ++i) {
179: if (i > 0) {
180: print(", ");
181: }
182: print(interfaceNames[i]);
183: }
184: }
185: }
186:
187: private void emitInterfaceDecl(String targetClassShortName,
188: String super ClassName, String[] interfaceNames) {
189: if (super ClassName != null) {
190: throw new IllegalArgumentException(
191: "Cannot set superclass name " + super ClassName
192: + " on a interface.");
193: }
194: print("public interface " + targetClassShortName);
195: if (interfaceNames != null && interfaceNames.length > 0) {
196: print(" extends ");
197: for (int i = 0; i < interfaceNames.length; ++i) {
198: if (i > 0) {
199: print(", ");
200: }
201: print(interfaceNames[i]);
202: }
203: }
204: }
205: }
|