001 /* 002 // $Id: //open/util/resgen/src/org/eigenbase/resgen/FileTask.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.*; 028 import java.util.Locale; 029 030 /** 031 * Abstract base class for an Ant task which processes a file containing 032 * resources. 033 * 034 * @author jhyde 035 * @since 19 September, 2005 036 * @version $Id: //open/util/resgen/src/org/eigenbase/resgen/FileTask.java#4 $ 037 */ 038 abstract class FileTask 039 { 040 ResourceGenTask.Include include; 041 String className; 042 String fileName; 043 044 String cppClassName; 045 046 boolean outputJava; 047 boolean outputCpp; 048 049 abstract void process(ResourceGen generator) throws IOException; 050 051 /** 052 * Returns the XML source file, e.g. happy/BirthdayResource_en.xml. 053 */ 054 File getFile() { 055 return new File(include.root.src, fileName); 056 } 057 058 /** 059 * Returns the XML source file, mangled for use in comments. 060 * e.g. .../BirthdayResource_en.xml if SCM-safe comments are enabled. 061 */ 062 String getFileForComments() 063 { 064 String file = getFile().toString().replace('\\', '/'); 065 066 if (include.root.commentStyle == 067 ResourceGenTask.COMMENT_STYLE_SCM_SAFE) { 068 int slashPos = file.lastIndexOf('/'); 069 if (slashPos > 0) { 070 file = "..." + file.substring(slashPos); 071 } 072 } 073 074 return file; 075 } 076 077 boolean checkUpToDate(ResourceGen generator, File file) { 078 if (file.exists() && 079 file.lastModified() >= getFile().lastModified()) { 080 generator.comment(file + " is up to date"); 081 return true; 082 } 083 084 return false; 085 } 086 087 void makeParentDirs(File file) 088 { 089 if (file.getParentFile() != null) { 090 file.getParentFile().mkdirs(); 091 } 092 } 093 094 private String getPackageName() 095 { 096 int lastDot = className.lastIndexOf('.'); 097 if (lastDot < 0) { 098 return null; 099 } else { 100 return className.substring(0, lastDot); 101 } 102 } 103 104 private File getPackageDirectory(File file) 105 { 106 final String packageName = getPackageName(); 107 if (packageName == null) { 108 return file; 109 } 110 return new File(file, packageName.replace('.', Util.fileSep)); 111 } 112 113 /** 114 * Returns the directory from which to read source files. 115 */ 116 File getSrcDirectory() 117 { 118 return getPackageDirectory(include.root.src); 119 } 120 121 /** 122 * Returns the directory to which to generate Java or C++ files. 123 */ 124 File getDestDirectory() 125 { 126 return getPackageDirectory(include.root.dest); 127 } 128 129 130 /** 131 * Returns the directory to which to generate .properties and .xml 132 * files. 133 */ 134 File getResourceDirectory() 135 { 136 return getPackageDirectory(include.root.res); 137 } 138 139 /** 140 * Generates a Java class, e.g. com/foo/MyResource.java or 141 * com/foo/MyResource_en_US.java, depending upon whether locale is 142 * null. 143 */ 144 void generateJava( 145 ResourceGen generator, 146 ResourceDef.ResourceBundle resourceList, 147 Locale locale) { 148 String fileName = Util.getClassNameSansPackage(className, locale) + 149 ".java"; 150 File file = new File(getDestDirectory(), fileName); 151 152 if (!include.root.force && 153 checkUpToDate(generator, file)) { 154 return; 155 } 156 157 generator.comment("Generating " + file); 158 final FileOutputStream out; 159 try { 160 makeParentDirs(file); 161 162 out = new FileOutputStream(file); 163 } catch (FileNotFoundException e) { 164 throw new BuildException("Error while writing " + file, e); 165 } 166 PrintWriter pw = new PrintWriter(out); 167 try { 168 Generator gen; 169 if (locale == null) { 170 String baseClassName = include.baseClassName; 171 if (baseClassName == null) { 172 baseClassName = "org.eigenbase.resgen.ShadowResourceBundle"; 173 } 174 switch (include.root.style) { 175 case ResourceGenTask.STYLE_DYNAMIC: 176 gen = new JavaBaseGenerator(getFile(), file, 177 className, baseClassName, resourceList); 178 break; 179 case ResourceGenTask.STYLE_FUNCTOR: 180 gen = new JavaFunctorBaseGenerator(getFile(), file, 181 className, baseClassName, resourceList); 182 break; 183 default: 184 throw new AssertionError("unexpected style " + 185 include.root.style); 186 } 187 } else { 188 // e.g. "mondrian.resource.MondrianResource_en_US" 189 String className = this.className + "_" + locale.toString(); 190 // e.g. "mondrian.resource.MondrianResource" 191 String baseClassName = this.className; 192 gen = new JavaLocaleGenerator(getFile(), file, className, 193 resourceList, locale, baseClassName); 194 } 195 196 configureCommentStyle(gen); 197 198 gen.generateModule(generator, resourceList, pw); 199 } finally { 200 pw.close(); 201 } 202 } 203 204 protected void configureCommentStyle(Generator gen) 205 { 206 switch(include.root.commentStyle) { 207 case ResourceGenTask.COMMENT_STYLE_NORMAL: 208 gen.setScmSafeComments(false); 209 break; 210 211 case ResourceGenTask.COMMENT_STYLE_SCM_SAFE: 212 gen.setScmSafeComments(true); 213 break; 214 215 default: 216 throw new AssertionError( 217 "unexpected comment style " + include.root.commentStyle); 218 } 219 220 } 221 }