/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.mantle.rebind;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import org.pentaho.mantle.client.commands.CommandExec;
import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel;
import java.io.PrintWriter;
import java.util.ArrayList;
public class CommandExecGenerator extends Generator {
private String packageName;
private String className;
private TypeOracle typeOracle;
private TreeLogger logger;
@Override
public String generate( TreeLogger logger, GeneratorContext context, String typeName )
throws UnableToCompleteException {
this.logger = logger;
typeOracle = context.getTypeOracle();
try {
// get classType and save instance variables
JClassType classType = typeOracle.getType( typeName );
packageName = classType.getPackage().getName();
className = classType.getSimpleSourceName() + "Impl";
// Generate class source code
generateClass( logger, context );
} catch ( Exception e ) {
// record to logger that Map generation threw an exception
logger.log( TreeLogger.ERROR, "PropertyMap ERROR!!!", e );
}
// return the fully qualified name of the class generated
return packageName + "." + className;
}
private void generateClass( TreeLogger logger, GeneratorContext context ) {
// get print writer that receives the source code
PrintWriter printWriter = null;
printWriter = context.tryCreate( logger, packageName, className );
// print writer if null, source code has ALREADY been generated, return
if ( printWriter == null ) {
return;
}
// init composer, set class properties, create source writer
ClassSourceFileComposerFactory composer = null;
composer = new ClassSourceFileComposerFactory( packageName, className );
composer.addImplementedInterface( CommandExec.class.getName() );
composer.addImport( SolutionBrowserPanel.class.getName() );
composer.addImport( JavaScriptObject.class.getName() );
composer.addImport( Command.class.getName() );
SourceWriter sourceWriter = null;
sourceWriter = composer.createSourceWriter( context, printWriter );
sourceWriter.indent();
// generator constructor source code
generateConstructor( sourceWriter );
generateMethods( sourceWriter );
// close generated class
sourceWriter.outdent();
sourceWriter.println( "}" );
// commit generated class
context.commit( logger, printWriter );
}
private void generateMethods( SourceWriter sourceWriter ) {
sourceWriter.println();
sourceWriter
.println(
"public native String getParameterString(final String paramName, final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println(
"public native Integer getParameterInteger(final String paramName, final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println(
"public native Boolean getParameterBoolean(final String paramName, final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println( "public native Float getParameterFloat(final String paramName,"
+ "final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println(
"public native Double getParameterDouble(final String paramName, "
+ "final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println( "public native Long getParameterLong(final String paramName, final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter
.println( "public native Short getParameterShort(final String paramName,"
+ "final JavaScriptObject parameterMap)" );
sourceWriter.println( "/*-{" );
sourceWriter.indent();
sourceWriter.println( "return parameterMap[paramName];" );
sourceWriter.outdent();
sourceWriter.println( "}-*/;" );
sourceWriter.println();
sourceWriter.println( "public void execute(final String commandName, final JavaScriptObject parameterMap) { " );
sourceWriter.indent();
try {
// find Command implementors
ArrayList<JClassType> implementingTypes = new ArrayList<JClassType>();
JPackage pack = typeOracle.getPackage( CommandExec.class.getPackage().getName() );
JClassType commandSourceType = typeOracle.getType( Command.class.getName() );
for ( JClassType type : pack.getTypes() ) {
if ( type.isAssignableTo( commandSourceType ) ) {
implementingTypes.add( type );
}
}
sourceWriter.println( "if(false){}" ); // placeholder
for ( JClassType implementingType : implementingTypes ) {
if ( implementingType.isAbstract() ) {
continue;
}
sourceWriter.println( "else if(commandName.equals(\"" + implementingType.getSimpleSourceName() + "\")){" );
sourceWriter.indent();
sourceWriter.println( implementingType.getName() + " command = new " + implementingType.getName() + "();" );
for ( JMethod eventMethod : implementingType.getMethods() ) {
if ( eventMethod.isPublic() && !eventMethod.isStatic() && eventMethod.isConstructor() == null
&& eventMethod.getName().startsWith( "set" ) ) {
String propertyName = eventMethod.getName().substring( 3 );
propertyName = propertyName.substring( 0, 1 ).toLowerCase() + propertyName.substring( 1 );
String simpleType = implementingType.getField( propertyName ).getType().getSimpleSourceName();
if ( "string".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterString(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "integer".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterInteger(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "float".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterFloat(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "double".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterDouble(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "long".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterLong(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "short".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterShort(\"" + propertyName
+ "\", parameterMap));" );
} else if ( "boolean".equalsIgnoreCase( simpleType ) ) {
sourceWriter.println( "command." + eventMethod.getName() + "(getParameterBoolean(\"" + propertyName
+ "\", parameterMap));" );
}
}
}
sourceWriter.println( "command.execute();" );
sourceWriter.outdent();
sourceWriter.println( "}" );
}
} catch ( Exception e ) {
// record to logger that Map generation threw an exception
logger.log( TreeLogger.ERROR, "Error generating BindingContext!!!", e );
}
sourceWriter.outdent();
sourceWriter.println( "}" );
}
private void generateConstructor( SourceWriter sourceWriter ) {
// start constructor source generation
sourceWriter.println( "public " + className + "() { " );
sourceWriter.indent();
sourceWriter.println( "super();" );
sourceWriter.outdent();
sourceWriter.println( "}" );
}
@SuppressWarnings( "unused" )
private String boxPrimative( JType type ) {
if ( type.isPrimitive() != null ) {
JPrimitiveType primative = type.isPrimitive();
return primative.getQualifiedBoxedSourceName();
} else {
return type.getQualifiedSourceName();
}
}
}