|
From: <one...@us...> - 2002-11-16 13:12:26
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/tools/codegen
In directory usw-pr-cvs1:/tmp/cvs-serv31226/cirrus/hibernate/tools/codegen
Modified Files:
ClassMapping.java
Log Message:
Tom Cellucci's patch allowing correct composite-id generation
Index: ClassMapping.java
===================================================================
RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/tools/codegen/ClassMapping.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** ClassMapping.java 10 Nov 2002 15:19:48 -0000 1.13
--- ClassMapping.java 16 Nov 2002 13:12:22 -0000 1.14
***************
*** 13,17 ****
import cirrus.hibernate.type.Type;
- import org.apache.commons.lang.StringUtils;
import org.jdom.Attribute;
import org.jdom.Element;
--- 13,16 ----
***************
*** 19,175 ****
public class ClassMapping {
! private ClassName name = null;
! private String superClass = null;
! private String proxyClass = null;
! private List fields = new ArrayList();
! private TreeSet imports = new TreeSet();
! private List subclasses = new ArrayList();
! private static final Map components = new HashMap();
!
!
! public ClassMapping(ClassName superClass, Element classElement) throws Exception {
! this(classElement);
!
! this.superClass = superClass.getName();
! addImport(superClass);
! }
!
! public ClassMapping(Element classElement) throws Exception {
! this(classElement, false);
! }
!
! public ClassMapping(Element classElement, boolean component) throws Exception {
! String fullyQualifiedName = classElement.getAttributeValue(component?"class":"name");
!
! System.out.println("processing mapping for class: " + fullyQualifiedName);
!
! // class & package names
! name = new ClassName();
! name.setFullyQualifiedName(fullyQualifiedName);
!
! // get the properties defined for this class
! List propertyList = new ArrayList();
!
! propertyList.addAll( classElement.getChildren("property") );
!
! Attribute att = classElement.getAttribute("proxy");
! if (att!=null) proxyClass = att.getValue();
!
! Element id = classElement.getChild("id");
!
! if (id != null) propertyList.add(0, id);
!
! // derive the class imports and fields from the properties
! for (Iterator properties = propertyList.iterator(); properties.hasNext();) {
! Element property = (Element) properties.next();
!
! String name = property.getAttributeValue("name");
! if ( name == null || name.trim().equals("") ) {
! continue; //since an id doesn't necessarily need a name
! }
!
! // ensure that the type is specified
! String type = property.getAttributeValue("type");
! if (StringUtils.isEmpty(type)) {
! System.out.println("property \"" + name + "\" in class " + getName() + " is missing a type attribute");
! continue;
! }
!
! // handle in a different way id and properties...
! // ids may be generated and may need to be of object type in order to support
! // the unsaved-value "null" value.
! // Properties may be nullable (whilst ids can not)
! if(property == id) {
! Element generator = property.getChild("generator");
! String unsavedValue = property.getAttributeValue("unsaved-value");
! boolean needObject = (unsavedValue != null && unsavedValue.equals("null"));
! boolean generated = !generator.getAttributeValue("class").equals("assigned");
! Field idField = new Field(name, getFieldType(type, needObject), true, generated);
! fields.add(idField);
! } else {
! String notnull = property.getAttributeValue("not-null");
! // if not-null property is missing lets see if it has been
! // defined at column level
! if(notnull == null) {
! Element column = property.getChild("column");
! if(column != null)
! notnull = column.getAttributeValue("not-null");
! }
! boolean nullable = (notnull == null || notnull.equals("false"));
! fields.add(new Field(name, getFieldType(type), nullable));
! }
! }
!
! List onetooneList = classElement.getChildren("one-to-one");
! for (Iterator onetoones = onetooneList.iterator(); onetoones.hasNext();) {
! Element onetoone = (Element) onetoones.next();
!
! String name = onetoone.getAttributeValue("name");
!
! // ensure that the class is specified
! String clazz = onetoone.getAttributeValue("class");
! if(StringUtils.isEmpty(clazz)) {
! System.out.println("one-to-one \"" + name + "\" in class " + getName() + " is missing a class attribute");
! continue;
! }
!
! fields.add(new Field(name, getFieldType(clazz), true));
!
! }
!
!
! // many to ones - TODO: consolidate with code above
! for (Iterator manytoOnes = classElement.getChildren("many-to-one").iterator(); manytoOnes.hasNext();) {
! Element manyToOne = (Element) manytoOnes.next();
!
! String name = manyToOne.getAttributeValue("name");
!
! // ensure that the type is specified
! String type = manyToOne.getAttributeValue("class");
! if ( type == null || type.trim().equals("") ) {
! System.out.println("many-to-one \"" + name + "\" in class " + getName() + " is missing a class attribute");
! continue;
! }
! ClassName classType = new ClassName();
! classType.setFullyQualifiedName(type);
!
! // is it nullable?
! String notnull = manyToOne.getAttributeValue("not-null");
! boolean nullable = (notnull == null || notnull.equals("false"));
!
! // add an import and field for this property
! addImport(classType);
! Field f = new Field( name, classType.getName(), nullable );
! f.setClassType(classType);
! fields.add(f);
! }
!
! // collections
! doCollections(classElement, "list", "java.util.List", "java.util.ArrayList");
! doCollections(classElement, "map", "java.util.Map", "java.util.HashMap");
! doCollections(classElement, "set", "java.util.Set", "java.util.HashSet");
! doArrays(classElement, "array");
! doArrays(classElement, "primitive-array");
!
!
! // subclasses
!
! for ( Iterator iter = classElement.getChildren("subclass").iterator(); iter.hasNext(); ) {
! Element subclass = (Element) iter.next();
! ClassMapping subclassMapping = new ClassMapping(name, subclass);
! subclasses.add(subclassMapping);
! }
!
! //components
!
! for ( Iterator iter = classElement.getChildren("component").iterator(); iter.hasNext(); ) {
! Element cmpe = (Element) iter.next();
! String cmpname = cmpe.getAttributeValue("name");
! String cmpclass = cmpe.getAttributeValue("class");
! if ( cmpclass==null || cmpclass.equals("") ) {
! System.out.println("component \"" + cmpname + "\" in class " + getName() + " does not specify a class");
! continue;
! }
! ClassMapping mapping = new ClassMapping(cmpe, true);
ClassName classType = new ClassName();
--- 18,73 ----
public class ClassMapping {
! private ClassName name = null;
! private String superClass = null;
! private String proxyClass = null;
! private List fields = new ArrayList();
! private TreeSet imports = new TreeSet();
! private List subclasses = new ArrayList();
! private static final Map components = new HashMap();
!
!
! public ClassMapping(ClassName superClass, Element classElement) throws Exception {
! this(classElement);
!
! this.superClass = superClass.getName();
! addImport(superClass);
! }
!
! public ClassMapping(Element classElement) throws Exception {
! this(classElement, false);
! }
!
! public ClassMapping(Element classElement, boolean component) throws Exception {
! String fullyQualifiedName = classElement.getAttributeValue(component?"class":"name");
!
! System.out.println("processing mapping for class: " + fullyQualifiedName);
!
! // class & package names
! name = new ClassName();
! name.setFullyQualifiedName(fullyQualifiedName);
!
! // get the properties defined for this class
! List propertyList = new ArrayList();
!
! propertyList.addAll( classElement.getChildren("property") );
!
! Attribute att = classElement.getAttribute("proxy");
! if (att!=null) proxyClass = att.getValue();
!
! Element id = classElement.getChild("id");
!
! if (id != null) propertyList.add(0, id);
! //
! // composite id
!
! Element cmpid = classElement.getChild("composite-id");
! if (cmpid != null) {
! String cmpname = cmpid.getAttributeValue("name");
! String cmpclass = cmpid.getAttributeValue("class");
! if ( cmpclass==null || cmpclass.equals("") ) {
! propertyList.addAll(cmpid.getChildren("key-property"));
! }
! else {
! ClassMapping mapping = new ClassMapping(cmpid, true);
ClassName classType = new ClassName();
***************
*** 179,331 ****
fields.add(new Field(cmpname, classType.getName(), false));
components.put( mapping.getCanonicalName(), mapping );
! }
! }
!
! public List getFields() {
! return fields;
! }
!
! public TreeSet getImports() {
! return imports;
! }
!
! public String getCanonicalName() {
! return name.getFullyQualifiedName();
! }
!
! public String getName() {
! return name.getName();
! }
!
! public String getProxy() {
! return proxyClass;
! }
!
! public String getPackageName() {
! return name.getPackageName();
! }
!
! public List getSubclasses() {
! return subclasses;
! }
!
! public String getSuperClass() {
! return superClass;
! }
!
!
! // We need a minimal constructor only if it's different from
! // the full constructor or the no-arg constructor.
! // A minimal construtor is one that lets
! // you specify only the required fields.
! public boolean needsMinimalConstructor() {
! boolean generatedId = true;
! boolean missingId = true;
! int countNull = 0;
! for(Iterator it = fields.iterator(); it.hasNext(); ) {
! Field f = (Field) it.next();
! if(f.isIdentifier()) {
! generatedId = f.isGenerated();
! missingId = false;
! }
! else
! if(f.isNullable()) countNull++;
! }
!
! return !(countNull == 0 ||
! ((countNull == (fields.size() - 1)) && generatedId) ||
! ((countNull == (fields.size()) && missingId)));
!
! }
!
! private void addImport(ClassName className) {
! // if the package is java.lang or our own package don't add
! if ( !className.inJavaLang() && !className.inSamePackage(name) ) {
! imports.add( className.getFullyQualifiedName() );
! }
! }
!
! public static Iterator getComponents() {
! return components.values().iterator();
! }
!
! private void doCollections(Element classElement, String xmlName, String interfaceClass, String implementingClass) {
!
! ClassName interfaceClassName = new ClassName();
! ClassName implementingClassName = new ClassName();
!
! interfaceClassName.setFullyQualifiedName(interfaceClass);
! implementingClassName.setFullyQualifiedName(implementingClass);
!
! for (Iterator collections = classElement.getChildren(xmlName).iterator(); collections.hasNext();) {
! Element collection = (Element) collections.next();
!
! String name = collection.getAttributeValue("role");
!
! // add an import and field for this collection
! addImport(interfaceClassName);
! addImport(implementingClassName);
!
! fields.add(new Field(name, interfaceClassName.getName(), "new " + implementingClassName.getName() + "()", false) );
! }
! }
!
! private void doArrays(Element classElement, String type) {
! for (Iterator arrays = classElement.getChildren(type).iterator(); arrays.hasNext();) {
! Element array = (Element) arrays.next();
! String role = array.getAttributeValue("role");
! String elementClass = array.getAttributeValue("element-class");
! if (elementClass==null) {
! Element elt = array.getChild("element");
! if (elt==null) elt = array.getChild("one-to-many");
! if (elt==null) elt = array.getChild("many-to-many");
! if (elt==null) elt = array.getChild("composite-element");
! if (elt==null) {
! System.out.println("skipping collection with subcollections");
! continue;
! }
! elementClass = elt.getAttributeValue("type");
! if (elementClass==null) elementClass=elt.getAttributeValue("class");
}
! fields.add( new Field( role, getFieldType(elementClass) + "[]", false ) );
! }
! }
!
! private String getFieldType(String hibernateType) {
! return getFieldType(hibernateType, false);
! }
!
! private String getFieldType(String hibernateType, boolean needObject) {
! // deal with hibernate binary type
! if ( hibernateType.equals("binary") ) {
! return "byte[]";
! }
! else {
! Type basicType = TypeFactory.basic(hibernateType);
! if ( basicType!=null ) {
!
! if (
! (basicType instanceof PrimitiveType) &&
! !hibernateType.trim().equals( basicType.returnedClass().getName()) &&
! !needObject
! ) {
! return ( (PrimitiveType) basicType ).primitiveClass().getName();
! }
! else {
! return basicType.returnedClass().getName();
! }
!
}
else {
! ClassName classType = new ClassName();
! classType.setFullyQualifiedName(hibernateType);
! // add an import and field for this property
! addImport(classType);
! return classType.getName();
}
! }
! }
!
!
!
}
--- 77,333 ----
fields.add(new Field(cmpname, classType.getName(), false));
components.put( mapping.getCanonicalName(), mapping );
! }
! }
!
! // derive the class imports and fields from the properties
! for (Iterator properties = propertyList.iterator(); properties.hasNext();) {
! Element property = (Element) properties.next();
!
! String name = property.getAttributeValue("name");
! if ( name == null || name.trim().equals("") ) {
! continue; //since an id doesn't necessarily need a name
! }
!
! // ensure that the type is specified
! String type = property.getAttributeValue("type");
! if ( type == null || type.trim().equals("") ) {
! System.out.println("property \"" + name + "\" in class " + getName() + " is missing a type attribute");
! continue;
! }
!
! // handle in a different way id and properties...
! // ids may be generated and may need to be of object type in order to support
! // the unsaved-value "null" value.
! // Properties may be nullable (whilst ids can not)
! if(property == id) {
! Element generator = property.getChild("generator");
! String unsavedValue = property.getAttributeValue("unsaved-value");
! boolean needObject = (unsavedValue != null && unsavedValue.equals("null"));
! boolean generated = !generator.getAttributeValue("class").equals("assigned");
! Field idField = new Field(name, getFieldType(type, needObject), true, generated);
! fields.add(idField);
! } else {
! String notnull = property.getAttributeValue("not-null");
! // if not-null property is missing lets see if it has been
! // defined at column level
! if(notnull == null) {
! Element column = property.getChild("column");
! if(column != null)
! notnull = column.getAttributeValue("not-null");
}
! boolean nullable = (notnull == null || notnull.equals("false"));
! fields.add(new Field(name, getFieldType(type), nullable));
! }
! }
!
! // many to ones - TODO: consolidate with code above
! for (Iterator manytoOnes = classElement.getChildren("many-to-one").iterator(); manytoOnes.hasNext();) {
! Element manyToOne = (Element) manytoOnes.next();
!
! String name = manyToOne.getAttributeValue("name");
!
! // ensure that the type is specified
! String type = manyToOne.getAttributeValue("class");
! if ( type == null || type.trim().equals("") ) {
! System.out.println("many-to-one \"" + name + "\" in class " + getName() + " is missing a class attribute");
! continue;
! }
! ClassName classType = new ClassName();
! classType.setFullyQualifiedName(type);
!
! // is it nullable?
! String notnull = manyToOne.getAttributeValue("not-null");
! boolean nullable = (notnull == null || notnull.equals("false"));
!
! // add an import and field for this property
! addImport(classType);
! Field f = new Field( name, classType.getName(), nullable );
! f.setClassType(classType);
! fields.add(f);
! }
!
! // collections
! doCollections(classElement, "list", "java.util.List", "java.util.ArrayList");
! doCollections(classElement, "map", "java.util.Map", "java.util.HashMap");
! doCollections(classElement, "set", "java.util.Set", "java.util.HashSet");
! doArrays(classElement, "array");
! doArrays(classElement, "primitive-array");
!
!
! // subclasses
!
! for ( Iterator iter = classElement.getChildren("subclass").iterator(); iter.hasNext(); ) {
! Element subclass = (Element) iter.next();
! ClassMapping subclassMapping = new ClassMapping(name, subclass);
! subclasses.add(subclassMapping);
! }
!
! //components
!
! for ( Iterator iter = classElement.getChildren("component").iterator(); iter.hasNext(); ) {
! Element cmpe = (Element) iter.next();
! String cmpname = cmpe.getAttributeValue("name");
! String cmpclass = cmpe.getAttributeValue("class");
! if ( cmpclass==null || cmpclass.equals("") ) {
! System.out.println("component \"" + cmpname + "\" in class " + getName() + " does not specify a class");
! continue;
! }
! ClassMapping mapping = new ClassMapping(cmpe, true);
!
! ClassName classType = new ClassName();
! classType.setFullyQualifiedName(cmpclass);
! // add an import and field for this property
! addImport(classType);
! fields.add(new Field(cmpname, classType.getName(), false));
! components.put( mapping.getCanonicalName(), mapping );
! }
! }
!
! public List getFields() {
! return fields;
! }
!
! public TreeSet getImports() {
! return imports;
! }
!
! public String getCanonicalName() {
! return name.getFullyQualifiedName();
! }
!
! public String getName() {
! return name.getName();
! }
!
! public String getProxy() {
! return proxyClass;
! }
!
! public String getPackageName() {
! return name.getPackageName();
! }
!
! public List getSubclasses() {
! return subclasses;
! }
!
! public String getSuperClass() {
! return superClass;
! }
!
!
! // We need a minimal constructor only if it's different from
! // the full constructor or the no-arg constructor.
! // A minimal construtor is one that lets
! // you specify only the required fields.
! public boolean needsMinimalConstructor() {
! boolean generatedId = true;
! boolean missingId = true;
! int countNull = 0;
! for(Iterator it = fields.iterator(); it.hasNext(); ) {
! Field f = (Field) it.next();
! if(f.isIdentifier()) {
! generatedId = f.isGenerated();
! missingId = false;
! }
! else
! if(f.isNullable()) countNull++;
! }
!
! return !(countNull == 0 ||
! ((countNull == (fields.size() - 1)) && generatedId) ||
! ((countNull == (fields.size()) && missingId)));
!
! }
!
! private void addImport(ClassName className) {
! // if the package is java.lang or our own package don't add
! if ( !className.inJavaLang() && !className.inSamePackage(name) ) {
! imports.add( className.getFullyQualifiedName() );
! }
! }
!
! public static Iterator getComponents() {
! return components.values().iterator();
! }
!
! private void doCollections(Element classElement, String xmlName, String interfaceClass, String implementingClass) {
!
! ClassName interfaceClassName = new ClassName();
! ClassName implementingClassName = new ClassName();
!
! interfaceClassName.setFullyQualifiedName(interfaceClass);
! implementingClassName.setFullyQualifiedName(implementingClass);
!
! for (Iterator collections = classElement.getChildren(xmlName).iterator(); collections.hasNext();) {
! Element collection = (Element) collections.next();
!
! String name = collection.getAttributeValue("role");
!
! // add an import and field for this collection
! addImport(interfaceClassName);
! addImport(implementingClassName);
!
! fields.add(new Field(name, interfaceClassName.getName(), "new " + implementingClassName.getName() + "()", false) );
! }
! }
!
! private void doArrays(Element classElement, String type) {
! for (Iterator arrays = classElement.getChildren(type).iterator(); arrays.hasNext();) {
! Element array = (Element) arrays.next();
! String role = array.getAttributeValue("role");
! String elementClass = array.getAttributeValue("element-class");
! if (elementClass==null) {
! Element elt = array.getChild("element");
! if (elt==null) elt = array.getChild("one-to-many");
! if (elt==null) elt = array.getChild("many-to-many");
! if (elt==null) elt = array.getChild("composite-element");
! if (elt==null) {
! System.out.println("skipping collection with subcollections");
! continue;
! }
! elementClass = elt.getAttributeValue("type");
! if (elementClass==null) elementClass=elt.getAttributeValue("class");
! }
! fields.add( new Field( role, getFieldType(elementClass) + "[]", false ) );
! }
! }
!
! private String getFieldType(String hibernateType) {
! return getFieldType(hibernateType, false);
! }
!
! private String getFieldType(String hibernateType, boolean needObject) {
! // deal with hibernate binary type
! if ( hibernateType.equals("binary") ) {
! return "byte[]";
! }
! else {
! Type basicType = TypeFactory.basic(hibernateType);
! if ( basicType!=null ) {
!
! if (
! (basicType instanceof PrimitiveType) &&
! !hibernateType.trim().equals( basicType.returnedClass().getName()) &&
! !needObject
! ) {
! return ( (PrimitiveType) basicType ).primitiveClass().getName();
}
else {
! return basicType.returnedClass().getName();
}
!
! }
! else {
! ClassName classType = new ClassName();
! classType.setFullyQualifiedName(hibernateType);
! // add an import and field for this property
! addImport(classType);
! return classType.getName();
! }
! }
! }
!
!
!
}
|