/*
* 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);
}
}