001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.i18n.tools;
017:
018: import com.google.gwt.user.tools.util.ArgHandlerEclipse;
019: import com.google.gwt.user.tools.util.ArgHandlerIgnore;
020: import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
021: import com.google.gwt.util.tools.ArgHandlerExtra;
022: import com.google.gwt.util.tools.ArgHandlerFlag;
023: import com.google.gwt.util.tools.ArgHandlerOutDir;
024: import com.google.gwt.util.tools.ToolBase;
025: import com.google.gwt.util.tools.Utility;
026:
027: import java.io.File;
028: import java.io.IOException;
029: import java.util.HashMap;
030: import java.util.Map;
031:
032: /**
033: * Command line assistant for i18n.
034: */
035:
036: public final class I18NCreator extends ToolBase {
037:
038: /**
039: * Utility class to handle class name argument.
040: *
041: */
042: protected class ArgHandlerClassName extends ArgHandlerExtra {
043:
044: @Override
045: public boolean addExtraArg(String arg) {
046: if (fullInterfaceName != null) {
047: System.err.println("Too many arguments.");
048: return false;
049: }
050:
051: // Check className for certain properties
052: if (!arg.matches("[\\w\\$]+(\\.[\\w\\$]+)+")) {
053: System.err
054: .println("'"
055: + arg
056: + "' does not appear to be a valid fully-qualified Java class name.");
057: return false;
058: }
059:
060: // Check out the class name.
061: //
062: if (arg.indexOf('$') != -1) {
063: System.err
064: .println("'"
065: + arg
066: + "': This version of the tool does not support nested classes");
067: return false;
068: }
069:
070: String[] parts = arg.split("\\.");
071: if (parts.length < 2) {
072: System.err
073: .println("'"
074: + arg
075: + "': Cannot live in the root package. Please specify a package.");
076: return false;
077: }
078:
079: fullInterfaceName = arg;
080: return true;
081: }
082:
083: @Override
084: public String getPurpose() {
085: return "The fully qualified name of the interface to create";
086: }
087:
088: @Override
089: public String[] getTagArgs() {
090: return new String[] { "interfaceName" };
091: }
092:
093: @Override
094: public boolean isRequired() {
095: return true;
096: }
097: }
098:
099: private static final String PACKAGE_PATH;
100:
101: static {
102: String path = I18NCreator.class.getName();
103: path = path.substring(0, path.lastIndexOf('.') + 1);
104: PACKAGE_PATH = path.replace('.', '/');
105: }
106:
107: public static void main(String[] args) {
108: I18NCreator creator = new I18NCreator();
109: if (creator.processArgs(args)) {
110: if (creator.run()) {
111: return;
112: }
113: }
114:
115: System.exit(1);
116: }
117:
118: /**
119: * @param fullInterfaceName Name of the fully-qualified Java class to create
120: * as an Application.
121: * @param outDir Where to put the output files
122: * @param eclipse The name of a project to attach a .launch config to
123: * @param overwrite Overwrite an existing files if they exist.
124: * @param ignore Ignore existing files if they exist.
125: * @throws IOException
126: */
127: static void createLocalizable(String fullInterfaceName,
128: File outDir, String eclipse,
129: boolean createMessagesInterface, boolean overwrite,
130: boolean ignore) throws IOException {
131:
132: // Figure out the installation directory
133: String installPath = Utility.getInstallPath();
134: String gwtUserPath = installPath + '/' + "gwt-user.jar";
135: String gwtDevPath = installPath + '/' + Utility.getDevJarName();
136:
137: // Figure out what platform we're on
138: //
139: boolean isWindows = gwtDevPath.substring(
140: gwtDevPath.lastIndexOf('/') + 1).indexOf("windows") >= 0;
141:
142: // If the path from here to the install directory is relative, we need to
143: // set specific "base" directory tags; this is for sample creation during
144: // the
145: // build.
146: String basePathEnv;
147: if (!new File(installPath).isAbsolute()) {
148: if (isWindows) {
149: basePathEnv = "%~dp0\\";
150: } else {
151: basePathEnv = "$APPDIR/";
152: }
153: } else {
154: basePathEnv = "";
155: }
156:
157: // Check out the class and package names.
158: //
159: int pos = fullInterfaceName.lastIndexOf('.');
160: String clientPackageName = fullInterfaceName.substring(0, pos);
161: String interfaceName = fullInterfaceName.substring(pos + 1);
162:
163: // Compute module name and directories
164: //
165: pos = clientPackageName.lastIndexOf('.');
166: File clientDir = Utility.getDirectory(outDir, "src", true);
167: if (pos >= 0) {
168: String clientPackage = clientPackageName.replace('.', '/');
169: clientDir = Utility.getDirectory(clientDir, clientPackage,
170: true);
171: }
172:
173: // Create a map of replacements
174: //
175: Map<String, String> replacements = new HashMap<String, String>();
176: replacements.put("@className", fullInterfaceName);
177: replacements.put("@shortClassName", interfaceName);
178: replacements.put("@gwtUserPath", basePathEnv + gwtUserPath);
179: replacements.put("@gwtDevPath", basePathEnv + gwtDevPath);
180: replacements.put("@compileClass",
181: "com.google.gwt.dev.GWTCompiler");
182: replacements.put("@i18nClass",
183: "com.google.gwt.i18n.tools.I18NSync");
184: if (createMessagesInterface) {
185: replacements.put("@createMessages", "-createMessages");
186: } else {
187: replacements.put("@createMessages", "");
188: }
189:
190: if (createMessagesInterface) {
191: // Create a skeleton i18n messages properties class
192: File i18nMessageProperties = Utility.createNormalFile(
193: clientDir, interfaceName + ".properties",
194: overwrite, ignore);
195: if (i18nMessageProperties != null) {
196: String out = Utility.getFileFromClassPath(PACKAGE_PATH
197: + "i18nMessages.propertiessrc");
198: Utility.writeTemplateFile(i18nMessageProperties, out,
199: replacements);
200: }
201: } else {
202: // Create a skeleton i18n constants properties class
203: File i18nConstantProperties = Utility.createNormalFile(
204: clientDir, interfaceName + ".properties",
205: overwrite, ignore);
206: if (i18nConstantProperties != null) {
207: String out = Utility.getFileFromClassPath(PACKAGE_PATH
208: + "i18nConstants.propertiessrc");
209: Utility.writeTemplateFile(i18nConstantProperties, out,
210: replacements);
211: }
212: }
213:
214: if (eclipse != null) {
215: // Create an eclipse localizable creator launch config
216: replacements.put("@projectName", eclipse);
217: File updateLaunchConfig = Utility.createNormalFile(outDir,
218: interfaceName + "-i18n" + ".launch", overwrite,
219: ignore);
220: if (updateLaunchConfig != null) {
221: String out = Utility.getFileFromClassPath(PACKAGE_PATH
222: + "I18N-update.launchsrc");
223: Utility.writeTemplateFile(updateLaunchConfig, out,
224: replacements);
225: }
226: }
227:
228: // create startup files
229: String extension;
230: if (isWindows) {
231: extension = ".cmd";
232: } else {
233: extension = "";
234: }
235: File gwti18n = Utility.createNormalFile(outDir, interfaceName
236: + "-i18n" + extension, overwrite, ignore);
237: if (gwti18n != null) {
238: String out = Utility.getFileFromClassPath(PACKAGE_PATH
239: + "gwti18n" + extension + "src");
240: Utility.writeTemplateFile(gwti18n, out, replacements);
241: if (extension.length() == 0) {
242: Runtime.getRuntime().exec(
243: "chmod u+x " + gwti18n.getAbsolutePath());
244: }
245: }
246: }
247:
248: private boolean createMessagesInterface = false;
249:
250: private String eclipse = null;
251:
252: private String fullInterfaceName = null;
253: private boolean ignore = false;
254: private File outDir;
255: private boolean overwrite = false;
256:
257: protected I18NCreator() {
258:
259: registerHandler(new ArgHandlerEclipse() {
260: @Override
261: public String getPurpose() {
262: return "Creates a i18n update launch config for the named eclipse project";
263: }
264:
265: @Override
266: public boolean setString(String str) {
267: eclipse = str;
268: return true;
269: }
270: });
271:
272: registerHandler(new ArgHandlerOutDir() {
273:
274: @Override
275: public void setDir(File dir) {
276: outDir = dir;
277: }
278: });
279:
280: registerHandler(new ArgHandlerOverwrite() {
281:
282: @Override
283: public boolean setFlag() {
284: if (ignore) {
285: System.err
286: .println("-overwrite cannot be used with -ignore.");
287: return false;
288: }
289: overwrite = true;
290: return true;
291: }
292: });
293:
294: registerHandler(new ArgHandlerFlag() {
295:
296: @Override
297: public String getPurpose() {
298: return "Create scripts for a Messages interface "
299: + "rather than a Constants one";
300: }
301:
302: @Override
303: public String getTag() {
304: return "-createMessages";
305: }
306:
307: @Override
308: public boolean setFlag() {
309: createMessagesInterface = true;
310: return true;
311: }
312: });
313:
314: registerHandler(new ArgHandlerIgnore() {
315:
316: @Override
317: public boolean setFlag() {
318: if (overwrite) {
319: System.err
320: .println("-ignore cannot be used with -overwrite.");
321: return false;
322: }
323: ignore = true;
324: return true;
325: }
326: });
327:
328: registerHandler(new ArgHandlerClassName());
329: }
330:
331: protected boolean run() {
332: try {
333: createLocalizable(fullInterfaceName, outDir, eclipse,
334: createMessagesInterface, overwrite, ignore);
335: return true;
336: } catch (IOException e) {
337: System.err.println(e.getClass().getName() + ": "
338: + e.getMessage());
339: return false;
340: }
341: }
342: }
|