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 }