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*/ 023package org.eigenbase.resgen; 024 025import java.io.PrintWriter; 026import java.io.File; 027import java.util.Date; 028import java.text.Format; 029import java.text.MessageFormat; 030import java.text.NumberFormat; 031import java.text.DateFormat; 032import java.lang.reflect.Method; 033import 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 */ 042abstract 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