001 /*
002 // $Id: //open/util/resgen/src/org/eigenbase/resgen/AbstractGenerator.java#3 $
003 // Package org.eigenbase.resgen is an i18n resource generator.
004 // Copyright (C) 2005-2005 The Eigenbase Project
005 // Copyright (C) 2005-2005 Disruptive Tech
006 // Copyright (C) 2005-2005 LucidEra, Inc.
007 // Portions Copyright (C) 2001-2005 Kana Software, Inc. and others.
008 //
009 // This library is free software; you can redistribute it and/or modify it
010 // under the terms of the GNU Lesser General Public License as published by the
011 // Free Software Foundation; either version 2 of the License, or (at your
012 // option) any later version approved by The Eigenbase Project.
013 //
014 // This library is distributed in the hope that it will be useful,
015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
017 // GNU Lesser General Public License for more details.
018 //
019 // You should have received a copy of the GNU Lesser General Public License
020 // along with this library; if not, write to the Free Software
021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022 */
023 package org.eigenbase.resgen;
024
025 import java.io.PrintWriter;
026 import java.io.File;
027 import java.util.Date;
028 import java.text.Format;
029 import java.text.MessageFormat;
030 import java.text.NumberFormat;
031 import java.text.DateFormat;
032 import java.lang.reflect.Method;
033 import java.lang.reflect.InvocationTargetException;
034
035 /**
036 * Abstract base for all generators.
037 *
038 * @author jhyde
039 * @since 19 September, 2005
040 * @version $Id: //open/util/resgen/src/org/eigenbase/resgen/AbstractGenerator.java#3 $
041 */
042 abstract class AbstractGenerator implements Generator
043 {
044 private final File srcFile;
045 private final File file;
046 private Boolean scmSafeComments = null;
047
048 public AbstractGenerator(File srcFile, File file)
049 {
050 this.srcFile = srcFile;
051 this.file = file;
052 }
053
054 public void setScmSafeComments(boolean enabled)
055 {
056 if (scmSafeComments != null) {
057 throw new AssertionError(
058 "SCM safe comment style may only be configured once.");
059 }
060
061 scmSafeComments = enabled ? Boolean.TRUE : Boolean.FALSE;
062 }
063
064 protected boolean useScmSafeComments()
065 {
066 return scmSafeComments != null && scmSafeComments.booleanValue();
067 }
068
069 /**
070 * Generates code for a particular resource.
071 */
072 protected abstract void generateResource(
073 ResourceDef.Resource resource,
074 PrintWriter pw);
075
076 protected void generateDoNotModifyHeader(PrintWriter pw) {
077 if (useScmSafeComments()) {
078 pw.println(
079 "// This class is generated. Do NOT modify it manually.");
080 } else {
081 pw.println("// This class is generated. Do NOT modify it, or");
082 pw.println("// add it to source control.");
083 }
084 pw.println();
085 }
086
087 protected void generateGeneratedByBlock(PrintWriter pw) {
088 pw.println("/**");
089 pw.println(" * This class was generated");
090 pw.println(" * by " + ResourceGen.class);
091
092 String file = getSrcFileForComment();
093 pw.println(" * from " + file);
094 if (!useScmSafeComments()) {
095 pw.println(" * on " + new Date().toString() + ".");
096 }
097 pw.println(" * It contains a list of messages, and methods to");
098 pw.println(" * retrieve and format those messages.");
099 pw.println(" */");
100 pw.println();
101 }
102
103 /**
104 * Returns the generator's output file. e.g., "BirthdayResource.java"
105 */
106 protected File getFile()
107 {
108 return file;
109 }
110
111 /**
112 * Returns the XML or .properties source file, in a manner suitable
113 * for use in source code comments. Path information is stripped if
114 * SCM-safe comment style is enabled.
115 *
116 * @see #setScmSafeComments(boolean)
117 */
118 protected String getSrcFileForComment()
119 {
120 String filename = srcFile.toString().replace('\\', '/');
121
122 if (useScmSafeComments()) {
123 int slashPos = filename.lastIndexOf('/');
124 if (slashPos > 0) {
125 filename = "..." + filename.substring(slashPos);
126 }
127 }
128
129 return filename;
130 }
131
132 /**
133 * Returns the fully-qualified name of the class being generated,
134 * for example "happy.BirthdayResource_en_US".
135 */
136 protected abstract String getClassName();
137
138 /**
139 * Returns the fully-qualified name of the base class.
140 */
141 protected abstract String getBaseClassName();
142
143 /**
144 * Returns a parameter list string, e.g. "String p0, int p1".
145 */
146 protected String getParameterList(String message) {
147 final String [] types = getArgTypes(message);
148 if (types.length == 0) {
149 return "";
150 }
151 StringBuffer sb = new StringBuffer();
152 for (int i = 0; i < types.length; i++) {
153 String type = types[i];
154 if (i > 0) {
155 sb.append(", ");
156 }
157 sb.append(type);
158
159 // If this is a C++ pointer type, say "const char *", don't put
160 // a space between it and the variable name.
161 if (!type.endsWith("&") && !type.endsWith("*")) {
162 sb.append(" ");
163 }
164 sb.append("p");
165 sb.append(Integer.toString(i));
166 }
167 return sb.toString();
168 }
169
170 /**
171 * Returns the number and types of parameters in the given error message,
172 * expressed as an array of Strings (legal values are
173 * currently "String", "Number", "java.util.Date", and null) ordered by
174 * parameter number.
175 */
176 protected abstract String [] getArgTypes(String message);
177
178 protected String getArgumentList(String message)
179 {
180 final String [] types = getArgTypes(message);
181
182 if (types.length == 0) {
183 return "";
184 }
185
186 StringBuffer sb = new StringBuffer();
187 for (int i = 0; i < types.length; i++) {
188 if (i > 0) {
189 sb.append(", ");
190 }
191 sb.append("p");
192 sb.append(Integer.toString(i));
193 }
194 return sb.toString();
195 }
196
197 }
198
199 // End AbstractGenerator.java