/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.i18n.tools;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.ConstantsWithLookup;
import com.google.gwt.i18n.client.Localizable;
import com.google.gwt.i18n.client.Messages;
import com.google.gwt.user.tools.util.ArgHandlerEclipse;
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerOutDir;
import com.google.gwt.util.tools.ToolBase;
import com.google.gwt.util.tools.Utility;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Command line assistant for i18n.
*/
public final class I18NCreator extends ToolBase {
/**
* Utility class to handle class name argument.
*
*/
protected class ArgHandlerClassName extends ArgHandlerExtra {
@Override
public boolean addExtraArg(String arg) {
if (fullInterfaceName != null) {
System.err.println("Too many arguments.");
return false;
}
// Check className for certain properties
if (!arg.matches("[\\w\\$]+(\\.[\\w\\$]+)+")) {
System.err.println("'"
+ arg
+ "' does not appear to be a valid fully-qualified Java class name.");
return false;
}
// Check out the class name.
//
if (arg.indexOf('$') != -1) {
System.err.println("'" + arg
+ "': This version of the tool does not support nested classes");
return false;
}
String[] parts = arg.split("\\.");
if (parts.length < 2) {
System.err.println("'" + arg
+ "': Cannot live in the root package. Please specify a package.");
return false;
}
fullInterfaceName = arg;
return true;
}
@Override
public String getPurpose() {
return "The fully qualified name of the interface to create";
}
@Override
public String[] getTagArgs() {
return new String[] {
"interfaceName"
};
}
@Override
public boolean isRequired() {
return true;
}
}
private static final String PACKAGE_PATH;
static {
String path = I18NCreator.class.getName();
path = path.substring(0, path.lastIndexOf('.') + 1);
PACKAGE_PATH = path.replace('.', '/');
}
public static void main(String[] args) {
I18NCreator creator = new I18NCreator();
if (creator.processArgs(args)) {
if (creator.run()) {
return;
}
}
System.exit(1);
}
/**
* @param fullInterfaceName Name of the fully-qualified Java class to create
* as an Application.
* @param outDir Where to put the output files
* @param eclipse The name of a project to attach a .launch config to
* @param overwrite Overwrite an existing files if they exist.
* @param ignore Ignore existing files if they exist.
* @param interfaceToCreate the class instance to create - Constants,
* ConstantsWithLookup, or Messages
* @throws IOException
*/
static void createLocalizable(String fullInterfaceName, File outDir,
String eclipse, boolean overwrite, boolean ignore,
Class<? extends Localizable> interfaceToCreate) throws IOException {
// Figure out the installation directory
String installPath = Utility.getInstallPath();
String gwtUserPath = installPath + '/' + "gwt-user.jar";
String gwtDevPath = installPath + '/' + "gwt-dev.jar";
// Figure out what platform we're on
//
boolean isWindows = System.getProperty("os.name").contains("Windows");
// If the path from here to the install directory is relative, we need to
// set specific "base" directory tags; this is for sample creation during
// the
// build.
String basePathEnv;
if (!new File(installPath).isAbsolute()) {
if (isWindows) {
basePathEnv = "%~dp0\\";
} else {
basePathEnv = "$APPDIR/";
}
} else {
basePathEnv = "";
}
// Check out the class and package names.
//
int pos = fullInterfaceName.lastIndexOf('.');
String clientPackageName = fullInterfaceName.substring(0, pos);
String interfaceName = fullInterfaceName.substring(pos + 1);
// Compute module name and directories
//
pos = clientPackageName.lastIndexOf('.');
File clientDir = Utility.getDirectory(outDir, "src", true);
if (pos >= 0) {
String clientPackage = clientPackageName.replace('.', '/');
clientDir = Utility.getDirectory(clientDir, clientPackage, true);
}
// Create a map of replacements
//
Map<String, String> replacements = new HashMap<String, String>();
replacements.put("@className", fullInterfaceName);
replacements.put("@shortClassName", interfaceName);
replacements.put("@gwtUserPath", basePathEnv + gwtUserPath);
replacements.put("@gwtDevPath", basePathEnv + gwtDevPath);
replacements.put("@compileClass", "com.google.gwt.dev.GWTCompiler");
replacements.put("@i18nClass", "com.google.gwt.i18n.tools.I18NSync");
// Add command line arguments to create
// Messages/Constants/ConstantsWithLookup code.
String templateData = null;
if (Messages.class == interfaceToCreate) {
replacements.put("@createMessages", "-createMessages");
templateData = Utility.getFileFromClassPath(PACKAGE_PATH
+ "i18nMessages.propertiessrc");
} else {
if (ConstantsWithLookup.class == interfaceToCreate) {
replacements.put("@createMessages", "-createConstantsWithLookup");
} else if (Constants.class == interfaceToCreate) {
replacements.put("@createMessages", "");
} else {
throw new RuntimeException(
"Internal Error: Unable to create i18n class derived from "
+ interfaceToCreate.getName());
}
// This same template works for both Constants and ConstantsWithLookup
// classes
templateData = Utility.getFileFromClassPath(PACKAGE_PATH
+ "i18nConstants.propertiessrc");
}
// Populate the file from the template
File i18nPropertiesFile = Utility.createNormalFile(clientDir, interfaceName
+ ".properties", overwrite, ignore);
if (i18nPropertiesFile != null && templateData != null) {
Utility.writeTemplateFile(i18nPropertiesFile, templateData, replacements);
}
if (eclipse != null) {
// Create an eclipse localizable creator launch config
replacements.put("@projectName", eclipse);
File updateLaunchConfig = Utility.createNormalFile(outDir, interfaceName
+ "-i18n" + ".launch", overwrite, ignore);
if (updateLaunchConfig != null) {
String out = Utility.getFileFromClassPath(PACKAGE_PATH
+ "I18N-update.launchsrc");
Utility.writeTemplateFile(updateLaunchConfig, out, replacements);
}
}
// create startup files
String extension;
if (isWindows) {
extension = ".cmd";
} else {
extension = "";
}
File gwti18n = Utility.createNormalFile(outDir, interfaceName + "-i18n"
+ extension, overwrite, ignore);
if (gwti18n != null) {
String out = Utility.getFileFromClassPath(PACKAGE_PATH + "gwti18n"
+ extension + "src");
Utility.writeTemplateFile(gwti18n, out, replacements);
if (extension.length() == 0) {
Runtime.getRuntime().exec("chmod u+x " + gwti18n.getAbsolutePath());
}
}
}
private ArgHandlerValueChooser chooser;
private String eclipse = null;
private String fullInterfaceName = null;
private boolean ignore = false;
private File outDir;
private boolean overwrite = false;
protected I18NCreator() {
registerHandler(new ArgHandlerEclipse() {
@Override
public boolean setString(String str) {
eclipse = str;
return true;
}
});
registerHandler(new ArgHandlerOutDir() {
@Override
public void setDir(File dir) {
outDir = dir;
}
});
registerHandler(new ArgHandlerOverwrite() {
@Override
public boolean setFlag(boolean value) {
if (value && ignore) {
System.err.println("-overwrite cannot be used with -ignore.");
return false;
}
overwrite = value;
return true;
}
@Override
public boolean getDefaultValue() {
return overwrite;
}
});
chooser = new ArgHandlerValueChooser();
registerHandler(chooser.getConstantsWithLookupArgHandler());
registerHandler(chooser.getMessagesArgHandler());
registerHandler(new ArgHandlerIgnore() {
@Override
public boolean setFlag(boolean value) {
if (value && overwrite) {
System.err.println("-ignore cannot be used with -overwrite.");
return false;
}
ignore = value;
return true;
}
@Override
public boolean getDefaultValue() {
return ignore;
}
});
registerHandler(new ArgHandlerClassName());
}
protected boolean run() {
try {
createLocalizable(fullInterfaceName, outDir, eclipse, overwrite, ignore,
chooser.getArgValue());
return true;
} catch (IOException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
return false;
}
}
}