001 /* 002 // $Id: //open/util/resgen/src/org/eigenbase/resgen/JavaFunctorBaseGenerator.java#4 $ 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 org.apache.tools.ant.BuildException; 026 027 import java.io.File; 028 import java.io.PrintWriter; 029 import java.io.StringWriter; 030 import java.util.Arrays; 031 import java.util.HashMap; 032 import java.util.List; 033 import java.util.Map; 034 035 /** 036 * Generates a Java class for the base locale, 037 * using the 'functor' code-generation style. 038 * 039 * <p>For each resource, the generated Java class contains one public, final, 040 * non-static member. This member belongs to a class which has a number of 041 * methods for creating strings or exceptions based upon this resource. The 042 * methods are typesafe; that is, they have the same number and type of 043 * parameters as the resource itself. 044 * 045 * @author jhyde 046 * @since 19 September, 2005 047 * @version $Id: //open/util/resgen/src/org/eigenbase/resgen/JavaFunctorBaseGenerator.java#4 $ 048 */ 049 public class JavaFunctorBaseGenerator extends JavaBaseGenerator 050 { 051 private final Map functorMap = new HashMap(); 052 private final StringWriter functorSw = new StringWriter(); 053 private final PrintWriter functorPw = new PrintWriter(functorSw); 054 055 JavaFunctorBaseGenerator( 056 File srcFile, 057 File file, 058 String className, 059 String baseClassName, 060 ResourceDef.ResourceBundle resourceBundle) 061 { 062 super(srcFile, file, className, baseClassName, resourceBundle); 063 } 064 065 public void generateResource(ResourceDef.Resource resource, PrintWriter pw) { 066 if (resource.text == null) { 067 throw new BuildException( 068 "Resource '" + resource.name + "' has no message"); 069 } 070 String text = resource.text.cdata; 071 String comment = ResourceGen.getComment(resource); 072 final String resourceInitcap = ResourceGen.getResourceInitcap(resource);// e.g. "Internal" 073 074 String parameterList = getParameterList(text); 075 String argumentList = getArgumentList(text); 076 String propList = getPropList(resource); 077 String errorClassName; 078 if (resource instanceof ResourceDef.Exception) { 079 ResourceDef.Exception exception = (ResourceDef.Exception) resource; 080 errorClassName = getErrorClass(exception); 081 } else { 082 errorClassName = null; 083 } 084 String functorType = 085 getFunctorType(parameterList, argumentList, errorClassName); 086 087 pw.println(); 088 Util.generateCommentBlock(pw, resource.name, text, comment); 089 pw.println(" public final " + functorType + " " + resourceInitcap + " = new " + functorType + "(" + Util.quoteForJava(resourceInitcap) + ", " + Util.quoteForJava(text) + ", " + propList + ");"); 090 } 091 092 private String getPropList(ResourceDef.Resource resource) { 093 if (resource.properties == null || resource.properties.length == 0) { 094 return "null"; 095 } 096 final StringBuffer buf = new StringBuffer("new String[] {"); 097 for (int i = 0; i < resource.properties.length; i++) { 098 if (i > 0) { 099 buf.append(", "); 100 } 101 ResourceDef.Property property = resource.properties[i]; 102 buf.append(Util.quoteForJava(property.name)); 103 buf.append(", "); 104 buf.append(Util.quoteForJava(property.cdata)); 105 } 106 buf.append("}"); 107 return buf.toString(); 108 } 109 110 private String getFunctorType( 111 String parameterList, 112 String argumentList, 113 String errorClassName) 114 { 115 List key = Arrays.asList(new String[] {parameterList, errorClassName}); 116 String functorType = (String) functorMap.get(key); 117 if (functorType == null) { 118 functorType = "_Def" + functorMap.size(); 119 functorMap.put(key, functorType); 120 genFunctor(functorType, parameterList, argumentList, errorClassName, functorPw); 121 } 122 123 return functorType; 124 } 125 126 private void genFunctor(String functorType, String parameterList, String argumentList, String errorClassName, PrintWriter pw) { 127 String definitionClass = "org.eigenbase.resgen.ResourceDefinition"; 128 final String classNameSansPackage = Util.removePackage(className); 129 final String bundleThis = classNameSansPackage + ".this"; 130 String argumentArray = argumentList.equals("") ? 131 "emptyObjectArray" : 132 "new Object[] {" + argumentList + "}"; 133 pw.println(); 134 pw.println(" /**"); 135 pw.println(" * Definition for resources which"); 136 if (errorClassName != null) { 137 pw.println(" * return a {@link " + errorClassName + "} exception and"); 138 } 139 pw.println(" * take arguments '" + parameterList + "'."); 140 pw.println(" */"); 141 pw.println(" public final class " + functorType + " extends " + definitionClass + " {"); 142 pw.println(" " + functorType + "(String key, String baseMessage, String[] props) {"); 143 pw.println(" super(key, baseMessage, props);"); 144 pw.println(" }"); 145 pw.println(" public String str(" + parameterList + ") {"); 146 pw.println(" return instantiate(" + addLists(bundleThis, argumentArray) + ").toString();"); 147 pw.println(" }"); 148 if (errorClassName != null) { 149 final ExceptionDescription ed = new ExceptionDescription(errorClassName); 150 if (ed.hasInstCon) { 151 pw.println(" public " + errorClassName + " ex(" + parameterList + ") {"); 152 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + "));"); 153 pw.println(" }"); 154 } else if (ed.hasInstThrowCon) { 155 pw.println(" public " + errorClassName + " ex(" + parameterList + ") {"); 156 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + "), null);"); 157 pw.println(" }"); 158 } else if (ed.hasStringCon) { 159 pw.println(" public " + errorClassName + " ex(" + parameterList + ") {"); 160 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + ").toString());"); 161 pw.println(" }"); 162 } else if (ed.hasStringThrowCon) { 163 pw.println(" public " + errorClassName + " ex(" + parameterList + ") {"); 164 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + ").toString(), null);"); 165 pw.println(" }"); 166 } 167 if (ed.hasInstThrowCon) { 168 pw.println(" public " + errorClassName + " ex(" + addLists(parameterList, "Throwable err") + ") {"); 169 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + "), err);"); 170 pw.println(" }"); 171 } else if (ed.hasStringThrowCon) { 172 pw.println(" public " + errorClassName + " ex(" + addLists(parameterList, "Throwable err") + ") {"); 173 pw.println(" return new " + errorClassName + "(instantiate(" + addLists(bundleThis, argumentArray) + ").toString(), err);"); 174 pw.println(" }"); 175 } 176 } 177 pw.println(" }"); 178 } 179 180 protected void postModule(PrintWriter pw) { 181 functorPw.flush(); 182 pw.println(functorSw.toString()); 183 } 184 } 185 186 // End JavaFunctorBaseGenerator.java