001 /**
002 * Copyright (C) 2009-2011 the original author or authors.
003 * See the notice.md file distributed with this work for additional
004 * information regarding copyright ownership.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.fusesource.restygwt.rebind;
020
021 import java.io.PrintWriter;
022 import java.util.HashSet;
023
024 import com.google.gwt.core.ext.GeneratorContext;
025 import com.google.gwt.core.ext.TreeLogger;
026 import com.google.gwt.core.ext.UnableToCompleteException;
027 import com.google.gwt.core.ext.typeinfo.JClassType;
028 import com.google.gwt.core.ext.typeinfo.JParameterizedType;
029 import com.google.gwt.user.rebind.AbstractSourceCreator;
030 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
031 import com.google.gwt.user.rebind.SourceWriter;
032
033 /**
034 * provides additional helper methods for generating source..
035 *
036 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
037 */
038 public abstract class BaseSourceCreator extends AbstractSourceCreator {
039
040 public static final TreeLogger.Type ERROR = TreeLogger.ERROR;
041 public static final TreeLogger.Type WARN = TreeLogger.WARN;
042 public static final TreeLogger.Type INFO = TreeLogger.INFO;
043 public static final TreeLogger.Type TRACE = TreeLogger.TRACE;
044 public static final TreeLogger.Type DEBUG = TreeLogger.DEBUG;
045 public static final TreeLogger.Type SPAM = TreeLogger.SPAM;
046 public static final TreeLogger.Type ALL = TreeLogger.ALL;
047
048 protected final GeneratorContext context;
049 protected final JClassType source;
050 protected final String packageName;
051 protected final String shortName;
052 protected final String name;
053 protected TreeLogger logger;
054 protected SourceWriter sourceWriter;
055 private PrintWriter writer;
056
057 static final private ThreadLocal<HashSet<String>> GENERATED_CLASSES = new ThreadLocal<HashSet<String>>();
058
059 static public HashSet<String> getGeneratedClasses() {
060 HashSet<String> rc = GENERATED_CLASSES.get();
061 if (rc == null) {
062 rc = new HashSet<String>();
063 GENERATED_CLASSES.set(rc);
064 }
065 return rc;
066 }
067
068 static public void clearGeneratedClasses() {
069 GENERATED_CLASSES.set(null);
070 }
071
072 public BaseSourceCreator(TreeLogger logger, GeneratorContext context, JClassType source, String suffix) {
073 this.logger = logger;
074 this.context = context;
075 this.source = source;
076 this.packageName = source.getPackage().getName();
077
078 if(source instanceof JParameterizedType)
079 {
080 JParameterizedType ptype = (JParameterizedType)source;
081 StringBuilder builder = new StringBuilder();
082 for(JClassType type : ptype.getTypeArgs())
083 {
084 builder.append("__");
085 builder.append(type.getParameterizedQualifiedSourceName().replace('.', '_'));
086 }
087 this.shortName = source.getSimpleSourceName() + builder.toString() + suffix;
088 }
089 else
090 {
091 this.shortName = source.getSimpleSourceName() + suffix;
092 }
093
094 this.name = packageName + "." + shortName;
095 }
096
097 protected PrintWriter writer() throws UnableToCompleteException {
098 HashSet<String> classes = getGeneratedClasses();
099 if (classes.contains(name)) {
100 return null;
101 }
102 classes.add(name);
103 PrintWriter writer = context.tryCreate(logger, packageName, shortName);
104 if (writer == null) {
105 return null;
106 }
107 return writer;
108 }
109
110 public interface Branch<R> {
111 R execute() throws UnableToCompleteException;
112 }
113
114 protected <R> R branch(String msg, Branch<R> callable) throws UnableToCompleteException {
115 return branch(DEBUG, msg, callable);
116 }
117
118 protected <R> R branch(TreeLogger.Type level, String msg, Branch<R> callable) throws UnableToCompleteException {
119 TreeLogger original = logger;
120 try {
121 logger = logger.branch(level, msg);
122 return callable.execute();
123 } finally {
124 logger = original;
125 }
126 }
127
128 protected void error(String msg) throws UnableToCompleteException {
129 logger.log(ERROR, msg);
130 throw new UnableToCompleteException();
131 }
132
133 protected void warn(String msg) throws UnableToCompleteException {
134 logger.log(WARN, msg);
135 throw new UnableToCompleteException();
136 }
137
138 protected void info(String msg) throws UnableToCompleteException {
139 logger.log(INFO, msg);
140 }
141
142 protected void debug(String msg) throws UnableToCompleteException {
143 logger.log(DEBUG, msg);
144 }
145
146 protected void trace(String msg) throws UnableToCompleteException {
147 logger.log(TRACE, msg);
148 }
149
150 protected JClassType find(Class<?> type) throws UnableToCompleteException {
151 return find(type.getName().replace('$', '.'));
152 }
153
154 protected JClassType find(String type) throws UnableToCompleteException {
155 return RestServiceGenerator.find(logger, context, type);
156 }
157
158 protected BaseSourceCreator i(int i) {
159 if (i == 1) {
160 this.sourceWriter.indent();
161 } else if (i == -1) {
162 this.sourceWriter.outdent();
163 } else {
164 throw new IllegalArgumentException();
165 }
166 return this;
167 }
168
169 protected BaseSourceCreator p(String value) {
170 this.sourceWriter.println(value);
171
172 // System.out.println(value);
173 return this;
174 }
175
176 protected BaseSourceCreator p() {
177 this.sourceWriter.println();
178 return this;
179 }
180
181 static String join(int []values, String sep) {
182 StringBuilder sb = new StringBuilder();
183 for(int i =0; i < values.length; i++) {
184 if( i!=0 ) {
185 sb.append(sep);
186 }
187 sb.append(values[i]);
188 }
189 return sb.toString();
190 }
191
192 static String join(Object []values, String sep) {
193 StringBuilder sb = new StringBuilder();
194 for(int i =0; i < values.length; i++) {
195 if( i!=0 ) {
196 sb.append(sep);
197 }
198 sb.append(values[i]);
199 }
200 return sb.toString();
201 }
202
203 final public String create() throws UnableToCompleteException {
204 writer = writer();
205 if (writer == null) {
206 return name;
207 }
208 logger = logger.branch(TreeLogger.DEBUG, "Generating: " + name);
209
210 ClassSourceFileComposerFactory composerFactory = createComposerFactory();
211 sourceWriter = composerFactory.createSourceWriter(context, writer);
212
213 generate();
214 sourceWriter.commit(logger);
215 return name;
216 }
217
218 abstract protected ClassSourceFileComposerFactory createComposerFactory() throws UnableToCompleteException;
219
220 abstract protected void generate() throws UnableToCompleteException;
221 }