/* * Copyright 2008 Filip Hianik, Vanja Culafic * * 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 org.exolab.castor.builder.descriptors; import java.util.List; import org.castor.core.constants.cpa.JDOConstants; import org.exolab.castor.builder.BuilderConfiguration; import org.exolab.castor.builder.info.ClassInfo; import org.exolab.castor.builder.info.FieldInfo; import org.exolab.castor.builder.info.nature.JDOClassInfoNature; import org.exolab.castor.builder.info.nature.JDOFieldInfoNature; import org.exolab.castor.builder.info.nature.XMLInfoNature; import org.exolab.castor.builder.info.nature.relation.JDOOneToManyNature; import org.exolab.castor.builder.info.nature.relation.JDOOneToOneNature; import org.exolab.castor.builder.types.XSList; import org.exolab.castor.builder.types.XSType; import org.exolab.javasource.JClass; import org.exolab.javasource.JConstructor; import org.exolab.javasource.JNaming; import org.exolab.javasource.JPrimitiveType; import org.exolab.javasource.JSourceCode; import org.exolab.javasource.JType; /** * A class for creating the source code of JDO-specific descriptor classes. * * @author Filip Hianik * @author Vanja Culafic * @since 1.2.1 * * @see DescriptorSourceFactory * @see JDODescriptorJClass * */ public final class JDOClassDescriptorFactory { /** * The BuilderConfiguration instance. */ private final BuilderConfiguration _config; /** * Contains all fields exclusive identities. */ private String _fields = null; /** * Contains all identities. */ private String _identities = null; /** * Creates a new {@link JDOClassDescriptorFactory} with the given * configuration. * * @param config * A {@link BuilderConfiguration} instance */ public JDOClassDescriptorFactory(final BuilderConfiguration config) { if (config == null) { String err = "The argument 'config' must not be null."; throw new IllegalArgumentException(err); } _config = config; } /** * Creates the Source code of a ClassInfo for a given XML Schema element * declaration. * * @param classInfo * the XML Schema element declaration * @return the JClass representing the ClassInfo source code */ public JClass createSource(final ClassInfo classInfo) { if (!checkClassInfoNature(classInfo)) { return null; } JClass jClass = classInfo.getJClass(); String descriptorClassName = getQualifiedJDODescriptorClassName(jClass.getName()); JDODescriptorJClass classDesc = new JDODescriptorJClass(_config, descriptorClassName, jClass); JDOClassInfoNature cNature = new JDOClassInfoNature(classInfo); //-- get handle to default constructor JConstructor ctor = classDesc.getConstructor(0); JSourceCode jsc = ctor.getSourceCode(); jsc = createClassInfoPart(classInfo, jsc); //================= // FieldDescriptors //================= for (int i = 0; i < classInfo.getElementFields().length; i++) { FieldInfo fInfo = classInfo.getElementFields()[i]; if (checkFieldInfoNatures(fInfo)) { if (fInfo.hasNature(JDOOneToOneNature.class.getName())) { jsc = createOneToOneFieldInfoPart(fInfo, jsc); } else if (fInfo.hasNature(JDOOneToManyNature.class.getName())) { jsc = createOneToManyFieldInfoPart(fInfo, jsc); } else { jsc = createEntityFieldInfoPart(fInfo, jsc); } } } _fields = setFields(classInfo.getElementFields()); _identities = setIdentities(cNature.getPrimaryKeys()); jsc.add(""); jsc.add("setFields(new FieldDescriptor[] {" + _fields + "});"); jsc.add("setIdentities(new FieldDescriptor[] {" + _identities + "});"); return classDesc; } /** * Returns the fully-qualified class name of the JDODescriptor to create. * Given the fully-qualified class name of the class we are creating a * JDODescriptor for, return the correct fully-qualified name for the * JDODescriptor. * * @param name * fully-qualified class name of the class we are describing * @return the fully-qualified class name of the JDODescriptor to create */ private String getQualifiedJDODescriptorClassName(final String name) { String descPackage = JNaming.getPackageFromClassName(name); String descClassName = JNaming.getLocalNameFromClassName(name); if (descPackage != null && descPackage.length() > 0) { descPackage = descPackage + "." + JDOConstants.JDO_DESCRIPTOR_PACKAGE + "."; } else { descPackage = ""; } // TODO integrate XMLConstants.JDO_DESCRIPTOR_SUFFIX; return descPackage + descClassName + "JDODescriptor"; } /** * Returns the modified string with the first letter upperCase. * @param string String to upper case * @return the string with first letter upperCase */ private static String toUpperCaseFirstLetter(final String string) { return string.substring(0, 1).toUpperCase() + string.substring(1); } /** * Returns the string which contains names of all FieldDescriptors * for Fields that are not identities. Names are separated by comma. * @param fInfos Array of FieldInfos * @return names of all FieldDescriptors as one String (separated by comma) */ private String setFields(final FieldInfo[] fInfos) { String str = ""; FieldInfo fInfo; ClassInfo cInfo; for (int i = 0; i < fInfos.length; i++) { fInfo = fInfos[i]; cInfo = fInfo.getDeclaringClassInfo(); JDOClassInfoNature cNature = new JDOClassInfoNature(cInfo); if (cNature.getPrimaryKeys() != null) { if (cNature.getPrimaryKeys().contains(new XMLInfoNature(fInfo).getNodeName())) { continue; } } if (str.equals("")) { str = str + new XMLInfoNature(fInfo).getNodeName() + "FieldDescr"; } else { str = str + "," + new XMLInfoNature(fInfo).getNodeName() + "FieldDescr"; } } return str; } /** * Returns the string which contains names of all FieldDescriptors * for Fields that are identities. Names are separated by comma. * @param primaryKeys Array of primary keys. * @return names of all FieldDescriptors as one String (separated by comma) */ private String setIdentities(final List<?> primaryKeys) { String identities = ""; Object[] pkArray = null; if (primaryKeys != null) { pkArray = primaryKeys.toArray(); for (int i = 0; i < pkArray.length; i++) { if (identities.equals("")) { identities = identities + pkArray[i] + "FieldDescr"; } else { identities = identities + "," + pkArray[i] + "FieldDescr"; } } } return identities; } /** * Checks if ClassInfo has the JDOClassNature and if their required * attributes are properly set. * @param cInfo the ClassInfo object * @return true when ClassInfo has a JDOClassNature with all required * attributes properly set, false otherwise */ private boolean checkClassInfoNature(final ClassInfo cInfo) { if (cInfo.hasNature(JDOClassInfoNature.class.getName())) { JDOClassInfoNature cNature = new JDOClassInfoNature(cInfo); if (cNature.getAccessMode() == null || cNature.getPrimaryKeys() == null || cNature.getPrimaryKeys().isEmpty() || cNature.getTableName() == null || cNature.getTableName().length() == 0) { return false; } return true; } return false; } /** * Checks if FieldInfo has the XMLInfoNature and JDOFieldNature and if * their required attributes are properly set. * @param fInfo the FieldInfo object * @return true when FieldInfo has a XMLInfoNature and JDOFieldNature * with all required attributes properly set, false otherwise */ private boolean checkFieldInfoNatures(final FieldInfo fInfo) { if (!fInfo.hasNature(XMLInfoNature.class.getName())) { return false; } if (fInfo.hasNature(JDOFieldInfoNature.class.getName())) { JDOFieldInfoNature fNature = new JDOFieldInfoNature(fInfo); if (fNature.getColumnName() == null || fNature.getColumnName().length() == 0 || fNature.getColumnType() == null) { return false; } return true; } if (fInfo.hasNature(JDOOneToOneNature.class.getName())) { JDOOneToOneNature oneNature = new JDOOneToOneNature(fInfo); if (oneNature.getForeignKeys().size() != 1) { return false; } return true; } if (fInfo.hasNature(JDOOneToManyNature.class.getName())) { JDOOneToManyNature manyNature = new JDOOneToManyNature(fInfo); if (manyNature.getForeignKeys().size() != 1) { return false; } return true; } return false; } /** * Creates the ClassInfo part of the JDOClassDescriptor. * @param classInfo ClassInfo object * @param jsc JSourceCode * @return JSourceCode created in this method */ private JSourceCode createClassInfoPart(final ClassInfo classInfo, final JSourceCode jsc) { JDOClassInfoNature cNature = new JDOClassInfoNature(classInfo); jsc.add(""); jsc.add("addNature(ClassDescriptorJDONature.class.getName());"); jsc.add("ClassDescriptorJDONature jdoNature = new ClassDescriptorJDONature(this);"); //-- set table name String tableName = cNature.getTableName(); jsc.add("jdoNature.setTableName(\"" + tableName + "\");"); //-- set corresponding Java class // TODO IS THERE A NEED TO CHECK THIS?! String className = classInfo.getJClass().getLocalName(); if ((className != null) && (className.length() > 0)) { jsc.add("setJavaClass("); jsc.append(className); jsc.append(".class);"); } //-- set access mode String accessMode = cNature.getAccessMode().getName(); jsc.add("jdoNature.setAccessMode(AccessMode.valueOf(\"" + accessMode + "\"));"); //-- set cache key // TODO IS THERE A NEED TO CHECK THIS?! String fullName = classInfo.getJClass().getName(); if ((fullName != null) && (fullName.length() > 0)) { jsc.add("jdoNature.addCacheParam(\"name\", \""); jsc.append(fullName); jsc.append("\");"); } jsc.add(""); //-- Configure class mapping jsc.add("mapping.setAccess(ClassMappingAccessType.fromValue(\""); jsc.append(accessMode); jsc.append("\"));"); jsc.add("mapping.setAutoComplete(true);"); // TODO IS THERE A NEED TO CHECK THIS?! if ((fullName != null) && (fullName.length() > 0)) { jsc.add("mapping.setName(\""); jsc.append(fullName); jsc.append("\");"); } //-- set class choice jsc.add("mapping.setClassChoice(choice);"); //-- set table String table = cNature.getTableName(); jsc.add("mapTo.setTable(\"" + table + "\");"); //-- set table mapping jsc.add("mapping.setMapTo(mapTo);"); //-- set mapping jsc.add("setMapping(mapping);"); return jsc; } /** * Creates the source code of the FieldInfo part appeding it to * the source code generated till now. * @param fInfo FieldInfo object * @param jsc JSourceCode created till now * @return JSourceCode created in this method */ private JSourceCode createEntityFieldInfoPart(final FieldInfo fInfo, final JSourceCode jsc) { JDOFieldInfoNature fNature = new JDOFieldInfoNature(fInfo); JDOClassInfoNature cNature = new JDOClassInfoNature(fInfo.getDeclaringClassInfo()); XMLInfoNature xmlNature = new XMLInfoNature(fInfo); //-- set name String name = xmlNature.getNodeName(); jsc.add(""); jsc.add("//" + name + " field"); jsc.add("String " + name + "FieldName = \"" + name + "\";"); //-- initialize objects jsc.add("FieldDescriptorImpl " + name + "FieldDescr;"); jsc.add("FieldMapping " + name + "FM = new FieldMapping();"); //-- set typeInfo String type = null; XSType schemaType; schemaType = xmlNature.getSchemaType(); JType javaType = schemaType.getJType(); type = javaType.toString(); String wrapperType = null; if (javaType instanceof JPrimitiveType) { wrapperType = ((JPrimitiveType) javaType).getWrapperName(); } else { wrapperType = type; } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.add("TypeInfo " + name + "Type = new TypeInfo(" + wrapperType + ".class);"); } jsc.add("// Set columns required (= not null)"); jsc.add(name + "Type.setRequired(" + Boolean.toString(xmlNature.isRequired()) + ");"); jsc.add(""); jsc.add("FieldHandler " + name + "Handler;"); jsc.add("try {"); //-- get/set methods jsc.indent(); String className = fInfo.getDeclaringClassInfo().getJClass().getLocalName(); // TODO IS THERE A NEED TO CHECK THIS?! if ((className != null) && (className.length() > 0)) { jsc.add("Method " + name + "GetMethod = " + className + ".class.getMethod(\"get" + toUpperCaseFirstLetter(name) + "\", null);"); jsc.add("Method " + name + "SetMethod = " + className + ".class.getMethod(\"set" + toUpperCaseFirstLetter(name) + "\", new Class[]{"); } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.addIndented(type + ".class});"); } jsc.add(""); jsc.add(name + "Handler = new FieldHandlerImpl(" + name + "FieldName, "); jsc.append("null, null,"); jsc.addIndented(name + "GetMethod, " + name + "SetMethod, " + name + "Type);"); jsc.unindent(); jsc.add(""); //-- Catch of exceptions jsc.add("} catch (SecurityException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (MappingException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (NoSuchMethodException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("}"); // //-- JDOFieldDescriptorImpl constructor // jsc.add("// Instantiate " + name + " field descriptor"); // jsc.add(name + "FieldDescr = new JDOFieldDescriptorImpl("); // jsc.append(name + "FieldName, " + name + "Type,"); // jsc.indent(); // jsc.add(name + "Handler, "); // jsc.append(Boolean.toString(fInfo.isTransient()) + ", "); // String sqlName = new JDOFieldInfoNature(fInfo).getColumnName(); // jsc.append("new String[] { \"" + sqlName + "\" },"); // jsc.add("new int[] {SQLTypeInfos"); // jsc.indent(); // jsc.add(".javaType2sqlTypeNum("); // // // TODO IS THERE NEED TO CHECK THIS?! // if ((type != null) && (type.length() > 0)) { // jsc.append(wrapperType + ".class) },"); // } // // jsc.unindent(); // jsc.add("null, new String[] {}, "); // jsc.append(Boolean.toString(fNature.isDirty()) + ", "); // jsc.append(Boolean.toString(fNature.isReadOnly()) + ");"); // jsc.unindent(); //-- invoke FieldDescriptorImpl constructor jsc.add("// Instantiate " + name + " field descriptor"); jsc.add(name + "FieldDescr = new FieldDescriptorImpl("); jsc.append(name + "FieldName, " + name + "Type,"); jsc.append(name + "Handler, "); jsc.append(Boolean.toString(fInfo.isTransient()) + ");"); jsc.add(name + "FieldDescr.addNature(FieldDescriptorJDONature.class.getName());"); jsc.add("FieldDescriptorJDONature " + name + "FieldJdoNature = new FieldDescriptorJDONature(" + name + "FieldDescr);"); String sqlName = new JDOFieldInfoNature(fInfo).getColumnName(); jsc.add(name + "FieldJdoNature.setSQLName(new String[] { \"" + sqlName + "\" });"); jsc.add(name + "FieldJdoNature.setSQLType(new int[] {SQLTypeInfos"); jsc.append(".javaType2sqlTypeNum("); // TODO IS THERE NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.append(wrapperType + ".class) });"); } // jsc.add("null, new String[] {}, "); jsc.add(name + "FieldJdoNature.setManyTable(null);"); jsc.add(name + "FieldJdoNature.setManyKey(new String[] {});"); jsc.add(name + "FieldJdoNature.setDirtyCheck(" + Boolean.toString(fNature.isDirty()) + ");"); jsc.add(name + "FieldJdoNature.setReadOnly(" + Boolean.toString(fNature.isReadOnly()) + ");"); jsc.add(""); jsc.add(name + "FieldDescr.setDirect(false);"); jsc.add(name + "FieldDescr.setRequired(" + xmlNature.isRequired() + ");"); jsc.add(name + "FieldDescr.setSetMethod(\"set" + toUpperCaseFirstLetter(name) + "\");"); jsc.add(name + "FieldDescr.setGetMethod(\"get" + toUpperCaseFirstLetter(name) + "\");"); jsc.add(""); //-- parent class descriptor jsc.add(name + "FieldDescr.setContainingClassDescriptor(this);"); boolean isPrimaryKey = false; if (cNature.getPrimaryKeys() != null) { isPrimaryKey = (cNature.getPrimaryKeys().contains(xmlNature.getNodeName())); } jsc.add(name + "FieldDescr.setIdentity(" + Boolean.toString(isPrimaryKey) + ");"); //-- fieldmapping jsc.add(name + "FM.setIdentity(" + Boolean.toString(isPrimaryKey) + ");"); jsc.add(name + "FM.setDirect(false);"); jsc.add(name + "FM.setName(\"" + name + "\");"); jsc.add(name + "FM.setRequired(" + xmlNature.isRequired() + ");"); jsc.add(name + "FM.setSetMethod(\"set" + toUpperCaseFirstLetter(name) + "\");"); jsc.add(name + "FM.setGetMethod(\"get" + toUpperCaseFirstLetter(name) + "\");"); //-- sql part jsc.add("Sql " + name + "Sql = new Sql();"); jsc.add(name + "Sql.addName(\"" + name + "\");"); String sqlType = fNature.getColumnType(); if ((sqlType != null) && (sqlType.length() > 0)) { jsc.add(name + "Sql.setType(\"" + sqlType + "\");"); } jsc.add(name + "FM.setSql(" + name + "Sql);"); if ((type != null) && (type.length() > 0)) { jsc.add(name + "FM.setType(\"" + type + "\");"); } jsc.add("choice.addFieldMapping(" + name + "FM);"); return jsc; } /** * Creates the source code of the FieldInfo part with * one-to-one relation appeding it to * the source code generated till now. * @param fInfo FieldInfo object * @param jsc JSourceCode created till now * @return JSourceCode created in this method */ private JSourceCode createOneToOneFieldInfoPart(final FieldInfo fInfo, final JSourceCode jsc) { // JDOFieldInfoNature fNature = new JDOFieldInfoNature(fInfo); JDOClassInfoNature cNature = new JDOClassInfoNature(fInfo.getDeclaringClassInfo()); JDOOneToOneNature oneNature = new JDOOneToOneNature(fInfo); XMLInfoNature xmlNature = new XMLInfoNature(fInfo); //-- set name String name = xmlNature.getNodeName(); jsc.add(""); jsc.add("//" + name + " field"); jsc.add("String " + name + "FieldName = \"" + name + "\";"); String sqlName = oneNature.getForeignKeys().get(0).toString(); jsc.add("String " + name + "SqlName = \"" + sqlName + "\";"); //-- initialize objects jsc.add("FieldDescriptorImpl " + name + "FieldDescr;"); jsc.add("FieldMapping " + name + "FM = new FieldMapping();"); //-- set typeInfo String type = null; XSType schemaType; schemaType = xmlNature.getSchemaType(); JType javaType = schemaType.getJType(); type = javaType.toString(); String wrapperType = null; if (javaType instanceof JPrimitiveType) { wrapperType = ((JPrimitiveType) javaType).getWrapperName(); } else { wrapperType = type; } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.add("TypeInfo " + name + "Type = new TypeInfo(" + type + ".class);"); } jsc.add("// Set columns required (= not null)"); jsc.add(name + "Type.setRequired(" + Boolean.toString(xmlNature.isRequired()) + ");"); jsc.add(""); jsc.add("FieldHandler " + name + "Handler;"); jsc.add("try {"); //-- get/set methods jsc.indent(); // TODO HOW ABOUT GETTING THE NAME FROM NATURE? String className = fInfo.getDeclaringClassInfo().getJClass().getLocalName(); // TODO IS THERE A NEED TO CHECK THIS?! if ((className != null) && (className.length() > 0)) { jsc.add("Method " + name + "GetMethod = " + className + ".class.getMethod(\"get" + toUpperCaseFirstLetter(name) + "\", null);"); jsc.add("Method " + name + "SetMethod = " + className + ".class.getMethod(\"set" + toUpperCaseFirstLetter(name) + "\", new Class[]{"); } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.addIndented(type + ".class});"); } jsc.add(""); jsc.add(name + "Handler = new FieldHandlerImpl(" + name + "FieldName, "); jsc.append("null, null,"); jsc.addIndented(name + "GetMethod, " + name + "SetMethod, " + name + "Type);"); jsc.unindent(); jsc.add(""); //-- Catch of exceptions jsc.add("} catch (SecurityException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (MappingException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (NoSuchMethodException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("}"); // //-- JDOFieldDescriptorImpl constructor // jsc.add("// Instantiate " + name + " field descriptor"); // jsc.add(name + "FieldDescr = new JDOFieldDescriptorImpl("); // jsc.append(name + "FieldName, " + name + "Type,"); // jsc.indent(); // jsc.add(name + "Handler, "); // jsc.append(Boolean.toString(fInfo.isTransient()) + ", "); // jsc.append("new String[] { " + name + "SqlName },"); // jsc.add("new int[] {SQLTypeInfos"); // jsc.indent(); // jsc.add(".javaType2sqlTypeNum("); // // // TODO IS THERE NEED TO CHECK THIS?! // if ((type != null) && (type.length() > 0)) { // jsc.append(wrapperType + ".class) },"); // } // // jsc.unindent(); // jsc.add("null, new String[] { " + name + "SqlName }, "); // jsc.append(Boolean.toString(oneNature.isDirty()) + ", "); // jsc.append(Boolean.toString(oneNature.isReadOnly()) + ");"); // jsc.unindent(); //-- invoke FieldDescriptorImpl constructor jsc.add("// Instantiate " + name + " field descriptor"); jsc.add(name + "FieldDescr = new FieldDescriptorImpl("); jsc.append(name + "FieldName, " + name + "Type,"); jsc.append(name + "Handler, "); jsc.append(Boolean.toString(fInfo.isTransient()) + ");"); jsc.add(name + "FieldDescr.addNature(FieldDescriptorJDONature.class.getName());"); jsc.add("FieldDescriptorJDONature " + name + "FieldJdoNature = new FieldDescriptorJDONature(" + name + "FieldDescr);"); jsc.add(name + "FieldJdoNature.setSQLName(new String[] { " + name + "SqlName });"); jsc.add(name + "FieldJdoNature.setSQLType(new int[] {SQLTypeInfos"); jsc.append(".javaType2sqlTypeNum("); // TODO IS THERE NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.append(wrapperType + ".class) });"); } // jsc.add(name + "FieldJdoNature.setManyTable(null);"); jsc.add(name + "FieldJdoNature.setManyKey(new String[] { " + name + "SqlName });"); jsc.add(name + "FieldJdoNature.setDirtyCheck(" + Boolean.toString(oneNature.isDirty()) + ");"); jsc.add(name + "FieldJdoNature.setReadOnly(" + Boolean.toString(oneNature.isReadOnly()) + ");"); jsc.add(""); //-- parent class descriptor jsc.add(name + "FieldDescr.setContainingClassDescriptor(this);"); jsc.add(name + "FieldDescr.setClassDescriptor(new " + getLocalName(type) + "JDODescriptor());"); boolean isPrimaryKey = false; if (cNature.getPrimaryKeys() != null) { isPrimaryKey = (cNature.getPrimaryKeys().contains(xmlNature.getNodeName())); } //-- fieldmapping jsc.add(name + "FM.setIdentity(" + Boolean.toString(isPrimaryKey) + ");"); jsc.add(name + "FM.setDirect(false);"); jsc.add(name + "FM.setName(\"" + name + "\");"); jsc.add(name + "FM.setRequired(" + xmlNature.isRequired() + ");"); jsc.add(name + "FM.setSetMethod(\"set" + toUpperCaseFirstLetter(name) + "\");"); jsc.add(name + "FM.setGetMethod(\"get" + toUpperCaseFirstLetter(name) + "\");"); //-- sql part jsc.add("Sql " + name + "Sql = new Sql();"); jsc.add(name + "Sql.addName(\"" + sqlName + "\");"); jsc.add(name + "Sql.setManyKey(new String[] {\"" + sqlName + "\"});"); jsc.add(name + "FM.setSql(" + name + "Sql);"); if ((type != null) && (type.length() > 0)) { jsc.add(name + "FM.setType(\"" + type + "\");"); } jsc.add("choice.addFieldMapping(" + name + "FM);"); return jsc; } /** * Creates the source code of the FieldInfo part with * one-to-one relation appeding it to * the source code generated till now. * @param fInfo FieldInfo object * @param jsc JSourceCode created till now * @return JSourceCode created in this method */ private JSourceCode createOneToManyFieldInfoPart(final FieldInfo fInfo, final JSourceCode jsc) { //JDOFieldInfoNature fNature = new JDOFieldInfoNature(fInfo); JDOClassInfoNature cNature = new JDOClassInfoNature(fInfo.getDeclaringClassInfo()); JDOOneToManyNature manyNature = new JDOOneToManyNature(fInfo); XMLInfoNature xmlNature = new XMLInfoNature(fInfo); //-- set name String name = xmlNature.getNodeName(); jsc.add(""); jsc.add("//" + name + " field"); jsc.add("String " + name + "FieldName = \"" + name + "\";"); String sqlName = manyNature.getForeignKeys().get(0).toString(); jsc.add("String " + name + "SqlName = \"" + sqlName + "\";"); //-- initialize objects jsc.add("FieldDescriptorImpl " + name + "FieldDescr;"); jsc.add("FieldMapping " + name + "FM = new FieldMapping();"); //-- set typeInfo String type = null; XSList schemaType; schemaType = (XSList) xmlNature.getSchemaType(); JType javaType = schemaType.getContentType().getJType(); type = javaType.toString(); String wrapperType = null; if (javaType instanceof JPrimitiveType) { wrapperType = ((JPrimitiveType) javaType).getWrapperName(); } else { wrapperType = type; } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.add("TypeInfo " + name + "Type = new TypeInfo(" + type + ".class);"); } jsc.add("// Set columns required (= not null)"); jsc.add(name + "Type.setRequired(" + Boolean.toString(xmlNature.isRequired()) + ");"); jsc.add(""); jsc.add("FieldHandler " + name + "Handler;"); jsc.add("try {"); //-- get/set methods jsc.indent(); // TODO HOW ABOUT GETTING THE NAME FROM NATURE? String className = fInfo.getDeclaringClassInfo().getJClass().getLocalName(); // TODO IS THERE A NEED TO CHECK THIS?! if ((className != null) && (className.length() > 0)) { jsc.add("Method " + name + "GetMethod = " + className + ".class.getMethod(\"get" + toUpperCaseFirstLetter(name) + "\", null);"); jsc.add("Method " + name + "SetMethod = " + className + ".class.getMethod(\"set" + toUpperCaseFirstLetter(name) + "\", new Class[]{"); } // TODO IS THERE A NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.addIndented(type + "[].class});"); } jsc.add(""); jsc.add(name + "Handler = new FieldHandlerImpl(" + name + "FieldName, "); jsc.append("null, null,"); jsc.addIndented(name + "GetMethod, " + name + "SetMethod, " + name + "Type);"); jsc.unindent(); jsc.add(""); //-- Catch of exceptions jsc.add("} catch (SecurityException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (MappingException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("} catch (NoSuchMethodException e1) {"); jsc.indent(); jsc.add("throw new RuntimeException(e1.getMessage());"); jsc.unindent(); jsc.add("}"); // //-- JDOFieldDescriptorImpl constructor // jsc.add("// Instantiate " + name + " field descriptor"); // jsc.add(name + "FieldDescr = new JDOFieldDescriptorImpl("); // jsc.append(name + "FieldName, " + name + "Type,"); // jsc.indent(); // jsc.add(name + "Handler, "); // jsc.append(Boolean.toString(fInfo.isTransient()) + ", "); // jsc.append("new String[] { },"); // jsc.add("new int[] {SQLTypeInfos"); // jsc.indent(); // jsc.add(".javaType2sqlTypeNum("); // // // TODO IS THERE NEED TO CHECK THIS?! // if ((type != null) && (type.length() > 0)) { // jsc.append(wrapperType + ".class) },"); // } // // jsc.unindent(); // jsc.add("null, new String[] { " + name + "SqlName }, "); // jsc.append(Boolean.toString(manyNature.isDirty()) + ", "); // jsc.append(Boolean.toString(manyNature.isReadOnly()) + ");"); // jsc.unindent(); //-- invoke FieldDescriptorImpl constructor jsc.add("// Instantiate " + name + " field descriptor"); jsc.add(name + "FieldDescr = new FieldDescriptorImpl("); jsc.append(name + "FieldName, " + name + "Type,"); jsc.append(name + "Handler, "); jsc.append(Boolean.toString(fInfo.isTransient()) + ");"); jsc.add(name + "FieldDescr.addNature(FieldDescriptorJDONature.class.getName());"); jsc.add("FieldDescriptorJDONature " + name + "FieldJdoNature = new FieldDescriptorJDONature(" + name + "FieldDescr);"); jsc.add(name + "FieldJdoNature.setSQLName(null);"); jsc.add(name + "FieldJdoNature.setSQLType(new int[] {SQLTypeInfos"); jsc.append(".javaType2sqlTypeNum("); // TODO IS THERE NEED TO CHECK THIS?! if ((type != null) && (type.length() > 0)) { jsc.append(wrapperType + ".class) });"); } jsc.add(name + "FieldJdoNature.setManyKey(new String[] { " + name + "SqlName });"); jsc.add(name + "FieldJdoNature.setDirtyCheck(" + Boolean.toString(manyNature.isDirty()) + ");"); jsc.add(name + "FieldJdoNature.setReadOnly(" + Boolean.toString(manyNature.isReadOnly()) + ");"); jsc.add(""); jsc.add(name + "FieldDescr.setDirect(false);"); jsc.add(name + "FieldDescr.setName(\"" + name + "\");"); jsc.add(name + "FieldDescr.setRequired(" + xmlNature.isRequired() + ");"); // TODO support of other collection types jsc.add(name + "FieldDescr.setCollection(FieldMappingCollectionType.ARRAY);"); jsc.add(""); //-- parent class descriptor jsc.add(name + "FieldDescr.setContainingClassDescriptor(this);"); jsc.add(name + "FieldDescr.setClassDescriptor(new " + getLocalName(type) + "JDODescriptor());"); jsc.add(name + "FieldDescr.setMultivalued(true);"); boolean isPrimaryKey = false; if (cNature.getPrimaryKeys() != null) { isPrimaryKey = (cNature.getPrimaryKeys().contains(xmlNature.getNodeName())); } //-- fieldmapping jsc.add(name + "FM.setIdentity(" + Boolean.toString(isPrimaryKey) + ");"); jsc.add(name + "FM.setDirect(false);"); jsc.add(name + "FM.setName(\"" + name + "\");"); jsc.add(name + "FM.setRequired(" + xmlNature.isRequired() + ");"); // TODO support of other collection types jsc.add(name + "FM.setCollection(FieldMappingCollectionType.ARRAY);"); //-- sql part jsc.add("Sql " + name + "Sql = new Sql();"); jsc.add(name + "Sql.addName(\"" + sqlName + "\");"); jsc.add(name + "Sql.setManyKey(new String[] {\"" + sqlName + "\"});"); jsc.add(name + "FM.setSql(" + name + "Sql);"); if ((type != null) && (type.length() > 0)) { jsc.add(name + "FM.setType(\"" + type + "\");"); } jsc.add("choice.addFieldMapping(" + name + "FM);"); return jsc; } /** * Returns the unqualified Java type name (i.e. without package). * * @param name the qualified Java type name. * @return The unqualified Java type name. */ private String getLocalName(final String name) { // -- use getName method in case it's been overloaded return JNaming.getLocalNameFromClassName(name); } }