/* * Copyright 2010 Zhihua (Dennis) Jiang * * 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.gwtmobile.persistence.rebind; import java.util.List; import com.google.gwt.core.ext.typeinfo.JMethod; public class EntityGenerator implements ClassGenerator { final GenUtils utils; final String requestedClassName; final String generatedClassName; final List<JMethod> getters; final List<JMethod> hasManyRels; final List<JMethod> hasOneRels; public EntityGenerator(GenUtils utils, String requestedClassName, String generatedClassName, List<JMethod> getters, List<JMethod> hasManyRels, List<JMethod> hasOneRels) { this.utils = utils; this.requestedClassName = requestedClassName; this.generatedClassName = generatedClassName; this.getters = getters; this.hasManyRels = hasManyRels; this.hasOneRels = hasOneRels; } @Override public void classSetup() { AddImports(); setSuperClass(); } private void AddImports() { utils.factory().addImport("java.util.HashMap"); utils.factory().addImport("java.util.Date"); utils.factory().addImport("com.google.gwt.core.client.JavaScriptObject"); utils.factory().addImport("com.google.gwt.core.client.JsArrayString"); utils.factory().addImport("com.google.gwt.core.client.GWT"); utils.factory().addImport("com.google.gwt.json.client.*"); utils.factory().addImport("com.gwtmobile.persistence.client.*"); } private void setSuperClass() { utils.factory().setSuperclass("EntityInternal<" + requestedClassName + ">"); } private void AddVariables() { StringBuilder sb = new StringBuilder(); sb.append(String.format("Persistence.define(\"%s\", new HashMap<String, String> () {{\n", requestedClassName)); for (JMethod getter : getters) { String propertyName = getter.getName().substring(3); String propertyType = utils.getSQLiteType(getter.getReturnType()); sb.append(String.format("\tput(\"%s\", \"%s\");\n", propertyName, propertyType)); } sb.append("}});"); utils.addVariable("private static", "JavaScriptObject", "nativeEntity", sb.toString()); for (JMethod hasManyRel : hasManyRels) { String hasManyRelName = hasManyRel.getName().substring(3); String hasManyRelEntity = utils.getGenericTypeShortName(hasManyRel.getReturnType().getParameterizedQualifiedSourceName()); utils.addVariable("private static", "EntityInternal<" + hasManyRelEntity + ">", "hasMany" + hasManyRelName, "GWT.create(" + hasManyRelEntity + ".class)"); } for (JMethod hasOneRel : hasOneRels) { String hasOneRelColName = hasOneRel.getName().substring(3); String hasOneRelEntity = hasOneRel.getReturnType().getSimpleSourceName(); utils.addVariable("private static", "EntityInternal<" + hasOneRelEntity + ">", "hasOne" + hasOneRelColName, "GWT.create(" + hasOneRelEntity + ".class)"); } } @Override public void generateClass() { AddVariables(); utils.genrateStaticConstructor(new MethodGenerator() { @Override public void generateMethod() { for (JMethod hasManyRel : hasManyRels) { String hasManyRelName = hasManyRel.getName().substring(3); utils.println("hasMany(nativeEntity, \"%s\", hasMany%s.getNativeObject(), hasMany%s.getInverseRelationName(\"%s\"));", hasManyRelName, hasManyRelName, hasManyRelName, requestedClassName); } for (JMethod hasOneRel : hasOneRels) { String hasOneRelColName = hasOneRel.getName().substring(3); utils.println("hasOne(nativeEntity, \"%s\", hasOne%s.getNativeObject());", hasOneRelColName, hasOneRelColName); } } }); utils.generateMethod("public", "JavaScriptObject", "getNativeObject", null, new MethodGenerator() { @Override public void generateMethod() { utils.println("return nativeEntity;"); } }); utils.generateMethod("public", requestedClassName, "newInstance", new String[][] {{"JavaScriptObject", "nativeObject"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("return new %sImpl(nativeObject);", requestedClassName); } }); utils.generateMethod("public", requestedClassName, "newInstance", null, new MethodGenerator() { @Override public void generateMethod() { utils.println("JavaScriptObject nativeObject = %s.newInstanceNative(nativeEntity, Persistence.getAutoAdd());", generatedClassName); utils.println("return new %sImpl(nativeObject);", requestedClassName); } }); utils.generateMethod("public", requestedClassName + "[]", "newInstanceArray", new String[][] {{"int", "size"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("return new %s[size];", requestedClassName); } }); utils.generateMethod("public", "Collection<" + requestedClassName + ">", "all", null, new MethodGenerator() { @Override public void generateMethod() { utils.println("JavaScriptObject nativeObject = %s.all(nativeEntity);", generatedClassName); utils.println("return new CollectionImpl(nativeObject, this);"); } }); utils.generateMethod("public", "Collection<" + requestedClassName + ">", "newCollection", new String[][] {{"JavaScriptObject", "nativeObject"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("return new CollectionImpl(nativeObject, this);", requestedClassName); } }); utils.generateMethod("public", "String", "getInverseRelationName", new String[][] {{"String", "rel"}}, new MethodGenerator(){ @Override public void generateMethod() { for (JMethod hasManyRel : hasManyRels) { String hasManyRelName = hasManyRel.getName().substring(3); String hasManyRelEntity = utils.getGenericTypeShortName(hasManyRel.getReturnType().getParameterizedQualifiedSourceName()); utils.println("if (rel.equals(\"%s\")) {", hasManyRelEntity); utils.sw().indent(); utils.println("return \"%s\";", hasManyRelName); utils.sw().outdent(); utils.println("}"); } for (JMethod hasOneRel : hasOneRels) { String hasOneRelationName = hasOneRel.getName().substring(3); String hasOneRelationEntity = hasOneRel.getName().substring(3); utils.println("if (rel.equals(\"%s\")) {", hasOneRelationEntity); utils.sw().indent(); utils.println("return \"%s\";", hasOneRelationName); utils.sw().outdent(); utils.println("}"); } utils.println("return null;"); }}); utils.generateMethod("public", "String", "getEntityName", null, new MethodGenerator() { @Override public void generateMethod() { utils.println("return \"%s\";", requestedClassName); } }); utils.generateNativeMethod("private static", "JavaScriptObject", "newInstanceNative", new String[][] { {"JavaScriptObject", "nativeEntity"}, {"Boolean", "autoAdd"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("var instance = new nativeEntity();"); utils.println("if (autoAdd) {"); utils.println("\t$wnd.persistence.add(instance);"); utils.println("}"); utils.println("return instance;"); } }); utils.generateNativeMethod("private static", "JavaScriptObject", "all", new String[][] {{"JavaScriptObject", "nativeEntity"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("return nativeEntity.all();"); } }); utils.generateNativeMethod("private static", "void", "hasMany", new String[][] { {"JavaScriptObject", "nativeEntity"}, {"String", "collName"}, {"JavaScriptObject", "otherEntity"}, {"String", "invRel"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("nativeEntity.hasMany(collName, otherEntity, invRel);"); } }); utils.generateNativeMethod("private static", "void", "hasOne", new String[][] { {"JavaScriptObject", "nativeEntity"}, {"String", "collName"}, {"JavaScriptObject", "otherEntity"}}, new MethodGenerator() { @Override public void generateMethod() { utils.println("nativeEntity.hasOne(collName, otherEntity);"); } }); String superClass = null; String[] interfaces = null; if (utils.isInterface(requestedClassName)) { interfaces = new String[]{"PersistableInternal", requestedClassName}; } else { superClass = requestedClassName; interfaces = new String[]{"PersistableInternal"}; } utils.generateInnerClass("private", requestedClassName + "Impl", superClass, interfaces, new InstanceGenerator(utils, requestedClassName, generatedClassName, getters, hasManyRels, hasOneRels)); } }