/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */ package com.caucho.amber.gen; import com.caucho.VersionFactory; import com.caucho.amber.field.*; import com.caucho.amber.type.EmbeddableType; import com.caucho.bytecode.*; import com.caucho.java.JavaWriter; import com.caucho.java.gen.ClassComponent; import com.caucho.util.L10N; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.ArrayList; /** * Generates the Java code for the wrapped object. */ public class EmbeddableComponent extends ClassComponent { private static final L10N L = new L10N(EmbeddableComponent.class); private String _baseClassName; private String _extClassName; private EmbeddableType _embeddableType; public EmbeddableComponent() { } /** * Sets the bean info for the generator */ public void setEmbeddableType(EmbeddableType embeddableType) { _embeddableType = embeddableType; } /** * Sets the base class name */ public void setBaseClassName(String baseClassName) { _baseClassName = baseClassName; } /** * Gets the base class name */ public String getBaseClassName() { return _baseClassName; } /** * Sets the ext class name */ public void setExtClassName(String extClassName) { _extClassName = extClassName; } /** * Sets the ext class name */ public String getClassName() { return _extClassName; } /** * Get bean class name. */ public String getBeanClassName() { return _baseClassName; } /** * Starts generation of the Java code */ @Override public void generate(JavaWriter out) throws IOException { try { generateHeader(out); generateInit(out); generateMake(out); generateMakeFromLoad(out); // jpa/0u21 generateGetField(out); // generateFields(out); generateLoad(out); } catch (IOException e) { throw e; } } /** * Generates the class header for the generated code. */ private void generateHeader(JavaWriter out) throws IOException { out.println("/*"); out.println(" * Generated by Resin Amber"); out.println(" * " + VersionFactory.getVersion()); out.println(" */"); out.println("private static final java.util.logging.Logger __caucho_log"); out.println(" = java.util.logging.Logger.getLogger(\"" + getBeanClassName() + "\");"); } /** * Generates the initialization. */ private void generateInit(JavaWriter out) throws IOException { String className = getClassName(); int p = className.lastIndexOf('.'); if (p > 0) className = className.substring(p + 1); ArrayList<AmberField> fields = _embeddableType.getFields(); for (Constructor ctor : _embeddableType.getBeanClass().getConstructors()) { out.println(); // XXX: s/b actual access type? out.print("public "); out.print(className); out.print("("); Class []args = ctor.getParameterTypes(); for (int i = 0; i < args.length; i++) { if (i != 0) out.print(", "); out.printClass(args[i]); out.print(" a" + i); } out.println(")"); out.println("{"); out.pushDepth(); out.print("super("); for (int i = 0; i < args.length; i++) { if (i != 0) out.print(", "); out.print("a" + i); } out.println(");"); for (AmberField field : fields) { field.generatePostConstructor(out); } out.popDepth(); out.println("}"); } } /** * Generates the fields. */ /* private void generateFields(JavaWriter out) throws IOException { // jpa/0u22 if (_embeddableType.isIdClass() && ! _embeddableType.isFieldAccess()) return; ArrayList<AmberField> fields = _embeddableType.getFields(); for (int i = 0; i < fields.size(); i++) { AmberField prop = fields.get(i); prop.generatePrologue(out, null); prop.generateSuperGetterMethod(out); prop.generateGetterMethod(out); prop.generateSuperSetterMethod(out); prop.generateSetterMethod(out); } } */ /** * Generates the make method. */ private void generateMake(JavaWriter out) throws IOException { ArrayList<AmberField> fields = _embeddableType.getFields(); out.println(); out.println("public static " + getClassName() + " __caucho_make("); for (int i = 0; i < fields.size(); i++) { AmberField prop = fields.get(i); out.print(" " + prop.getJavaTypeName() + " a" + i); if (i + 1 < fields.size()) out.println(","); } out.println(")"); out.println("{"); out.pushDepth(); out.println(getClassName() + " bean = new " + getClassName() + "();"); for (int i = 0; i < fields.size(); i++) { AmberField prop = fields.get(i); out.println(prop.generateSuperSetter("bean", "a" + i) + ";"); } out.println("return bean;"); out.popDepth(); out.println("}"); } /** * Generates the make method. */ private void generateMakeFromLoad(JavaWriter out) throws IOException { ArrayList<AmberField> fields = _embeddableType.getFields(); out.println(); out.println("public static " + getClassName() + " __caucho_make("); out.println(" com.caucho.amber.manager.AmberConnection aConn,"); out.println(" java.sql.ResultSet rs,"); out.println(" int index)"); out.println(" throws java.sql.SQLException"); out.println("{"); out.pushDepth(); out.println(getClassName() + " bean = new " + getClassName() + "();"); out.println("bean.__caucho_load(aConn, rs, index);"); out.println("return bean;"); out.popDepth(); out.println("}"); } /** * Generates the get field method. */ private void generateGetField(JavaWriter out) throws IOException { out.println(); out.println("public Object __caucho_get_field(int index)"); out.println("{"); out.pushDepth(); out.println("switch (index) {"); out.pushDepth(); ArrayList<AmberField> fields = _embeddableType.getFields(); for (int i = 0; i < fields.size(); i++) { AmberField prop = fields.get(i); if (! (prop instanceof PropertyField)) break; out.println("case " + i + ":"); out.println(" return " + prop.generateSuperGetter("this") + ";"); out.println(); } out.println("default:"); out.println(" throw new IllegalStateException(\"invalid index: \" + index);"); out.popDepth(); out.println("}"); out.popDepth(); out.println("}"); } /** * Generates the load. */ private void generateLoad(JavaWriter out) throws IOException { out.println(); out.println("public int __caucho_load(com.caucho.amber.manager.AmberConnection aConn,"); out.println(" java.sql.ResultSet rs,"); out.println(" int index)"); out.println(" throws java.sql.SQLException"); out.println("{"); out.pushDepth(); if (_embeddableType.isIdClass()) { out.println("return 0;"); } else { _embeddableType.generateLoad(out, "rs", "index", 0, -1); out.println("return index;"); } out.popDepth(); out.println("}"); } }