blob: 8ff8d9cfd0d87d9bd497691430d17072f4bfc174 [file] [log] [blame]
package org.apache.flex.runtimelocale.command {
import flash.events.Event;
import mx.controls.Alert;
import org.antlr.runtime.TokenConstants;
import org.apache.flex.runtimelocale.event.ApplicationStatusEvent;
import org.apache.flex.runtimelocale.event.LocaleEvent;
import org.apache.flex.runtimelocale.model.locale.LocaleDataVO;
import org.apache.flex.runtimelocale.model.locale.LocaleItemDataVO;
import org.as3commons.asblocks.dom.IASMethod;
import org.as3commons.asblocks.dom.IASStatement;
import org.as3commons.asblocks.dom.Visibility;
import org.as3commons.asblocks.impl.AS3FragmentParser;
import org.as3commons.asblocks.impl.ASTASClassType;
import org.as3commons.asblocks.impl.ASTASExpressionStatement;
import org.as3commons.asblocks.impl.ASTASField;
import org.as3commons.asblocks.impl.ASTASMethod;
import org.as3commons.asblocks.impl.ASTASStringLiteral;
import org.as3commons.asblocks.impl.ASTScriptElement;
import org.as3commons.asblocks.impl.ContainerDelegate;
import org.as3commons.asblocks.impl.TokenBuilder;
import org.as3commons.asblocks.parser.antlr.LinkedListToken;
import org.as3commons.asblocks.parser.antlr.LinkedListTree;
import org.as3commons.asblocks.parser.antlr.as3.AS3Parser;
import org.as3commons.collections.ArrayList;
import org.as3commons.collections.framework.IIterator;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
public class CreateLocaleRequestCommand extends AbstractApplicationModelAwareBaseCommand {
private static const INSTALL_METHOD_PREFIX:String = "install_";
private static const logger:ILogger = getClassLogger(CreateLocaleRequestCommand);
public function CreateLocaleRequestCommand(event:Event) {
super(event);
}
override public function execute():* {
var localeEvent:LocaleEvent = event as LocaleEvent;
if (localeEvent) {
if (applicationModel.availableLocales.getItemIndex(localeEvent.localeName) > -1) {
event.preventDefault();
logger.info("'{0}' already exists, aborting CreateLocaleRequestCommand", [localeEvent.localeName]);
Alert.show(localeEvent.localeName + " already exists");
} else {
createLocale(localeEvent.localeName);
}
}
}
private function addContentStatements(method:IASMethod):void {
for each (var localeItem:LocaleItemDataVO in applicationModel.referenceLocale.content) {
addKey(localeItem.key, method);
}
}
private function addField(type:ASTASClassType, localeName:String):void {
var field:ASTASField = type.newField(localeName.toUpperCase(), Visibility.PUBLIC, "String") as ASTASField;
field.setStatic(true);
field.setConstant(true);
var literal:ASTASStringLiteral = new ASTASStringLiteral(AS3FragmentParser.parseExpression('"' + localeName + '"'));
field.setInitializer(literal);
logger.info("Added static constant field to .as file: {0}", [field.toString()]);
}
private function addKey(key:String, method:IASMethod):void {
var newStatement:ASTASExpressionStatement = new ASTASExpressionStatement(AS3FragmentParser.parseExprStatement(' content[' + key + ']="";'));
method.addStatement(newStatement);
}
private function addMethod(type:ASTASClassType, localeName:String):ASTASMethod {
var method:ASTASMethod = type.newMethod(INSTALL_METHOD_PREFIX + localeName, Visibility.PRIVATE, "void") as ASTASMethod;
var ast:LinkedListTree = AS3FragmentParser.parseStatement("var locale:String = " + localeName.toUpperCase() + ";");
method.addStatement(new ASTASExpressionStatement(ast));
ast = AS3FragmentParser.parseStatement("var resource:ResourceBundle = new ResourceBundle(locale, ViewResourceConstants.BUNDLE_NAME);");
method.addStatement(new ASTASExpressionStatement(ast));
ast = AS3FragmentParser.parseStatement("var content:Object = resource.content;");
method.addStatement(new ASTASExpressionStatement(ast));
addContentStatements(method);
ast = AS3FragmentParser.parseStatement("_resourceManager.addResourceBundle(resource);");
method.addStatement(new ASTASExpressionStatement(ast));
logger.info("Added method to .as file: {0}()", [INSTALL_METHOD_PREFIX + localeName]);
return method;
}
private function addMethodInvocation(type:ASTASClassType, localeName:String):void {
var method:ASTASMethod = type.getMethod("installResources") as ASTASMethod;
var newAST:LinkedListTree = AS3FragmentParser.parseStatement(INSTALL_METHOD_PREFIX + localeName + "();");
for (var i:int = 0; i < 4; ++i) {
var tab:LinkedListToken = TokenBuilder.newToken(AS3Parser.WS, "\t");
tab.channel = TokenConstants.HIDDEN_CHANNEL;
newAST.addToken(0, tab);
}
newAST.addToken(0, TokenBuilder.newNewline());
insertInvocation(method.getStatements() as ArrayList, method, newAST);
logger.info("Added invocation of method '{0}'() to method '{1}' to .as file", [INSTALL_METHOD_PREFIX + localeName, "installResources()"]);
}
private function createLocale(localeName:String):void {
logger.info("Creating new locale '{0}', using '{1}' as the reference locale", [localeName, applicationModel.referenceLocale.name]);
var type:ASTASClassType = applicationModel.localeCompilationUnit.getType() as ASTASClassType;
addField(type, localeName);
var method:ASTASMethod = addMethod(type, localeName);
var data:LocaleDataVO = new LocaleDataVO(method, localeName);
applicationModel.localeData[applicationModel.localeData.length] = data;
addMethodInvocation(type, localeName);
dispatchEvent(new LocaleEvent(LocaleEvent.LOCALE_CREATED, null, data));
logger.info("Finished creating locale '{0}'", [localeName]);
dispatchEvent(new ApplicationStatusEvent(ApplicationStatusEvent.APPLICATION_INFO_STATUS, "New locale '" + localeName + "' created succesfully!"));
}
private function insertInvocation(statements:ArrayList, container:ASTScriptElement, newAST:LinkedListTree):void {
var iterator:IIterator = statements.iterator();
var idx:int = 0;
while (iterator.hasNext()) {
var statement:IASStatement = iterator.next();
if (statement is ContainerDelegate) {
insertInvocation((statement as ContainerDelegate).getStatements() as ArrayList, statement as ASTScriptElement, newAST);
} else {
if (statement is ASTASExpressionStatement) {
var expr:ASTASExpressionStatement = statement as ASTASExpressionStatement;
if (expr.toString().substr(0, INSTALL_METHOD_PREFIX.length) == INSTALL_METHOD_PREFIX) {
var containerAST:LinkedListTree = container.getAST();
containerAST = containerAST.getChild(containerAST.childCount - 1) as LinkedListTree;
containerAST.addChildAtWithTokens(idx + 1, newAST);
break;
}
}
}
idx++;
}
}
}
}