package org.hibernate.tool.hbm2x.pojo; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hibernate.cfg.reveng.ReverseEngineeringStrategyUtil; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Array; import org.hibernate.mapping.Bag; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; import org.hibernate.mapping.IdentifierBag; import org.hibernate.mapping.MetaAttributable; import org.hibernate.mapping.MetaAttribute; import org.hibernate.mapping.PrimitiveArray; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; import org.hibernate.mapping.Set; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Value; import org.hibernate.tool.hbm2x.Cfg2JavaTool; import org.hibernate.tool.hbm2x.MetaAttributeConstants; import org.hibernate.tool.hbm2x.MetaAttributeHelper; import org.hibernate.tool.hbm2x.visitor.DefaultValueVisitor; import org.hibernate.tuple.GenerationTiming; /** * Abstract implementation of POJOClass. To be extended by ComponentPOJO and EntityPOJO * @author max * @author <a href="mailto:abhayani@jboss.org">Amit Bhayani</a> * */ abstract public class BasicPOJOClass implements POJOClass, MetaAttributeConstants { protected ImportContext importContext; protected MetaAttributable meta; protected final Cfg2JavaTool c2j; public BasicPOJOClass(MetaAttributable ma, Cfg2JavaTool c2j) { this.meta = ma; this.c2j = c2j; if(this.meta==null) { throw new IllegalArgumentException("class Argument must be not null"); } if(this.c2j==null) throw new IllegalArgumentException("c2j must be not null"); } // called by subclasses protected void init() { importContext = new ImportContextImpl(getPackageName()); MetaAttribute metaAttribute = meta.getMetaAttribute("extra-import"); if(metaAttribute!=null) { Iterator<?> values = metaAttribute.getValues().iterator(); while ( values.hasNext() ) { String element = (String) values.next(); importContext.importType(element); } } } protected String getPackageDeclaration(String pkgName) { if (pkgName!=null && pkgName.trim().length()!=0 ) { return "package " + pkgName + ";"; } else { return "// default package"; } } public String getPackageDeclaration() { String pkgName = getPackageName(); return getPackageDeclaration(pkgName); } /** Return package name. Note: Does not handle inner classes */ public String getPackageName() { String generatedClass = getGeneratedClassName(); return StringHelper.qualifier(generatedClass.trim()); } public String getShortName() { return qualifyInnerClass(StringHelper.unqualify(getMappedClassName())); } public String getQualifiedDeclarationName() { String generatedName = qualifyInnerClass(getGeneratedClassName()); String qualifier = StringHelper.qualifier( getMappedClassName() ); if ( "".equals( qualifier ) ) { return qualifier + "." + generatedName; } else { return generatedName; } } /** * @return unqualified classname for this class (can be changed by meta attribute "generated-class") */ public String getDeclarationName() { return qualifyInnerClass(StringHelper.unqualify( getGeneratedClassName() )); } protected String getGeneratedClassName() { String generatedClass = getMetaAsString(MetaAttributeConstants.GENERATED_CLASS).trim(); if(StringHelper.isEmpty(generatedClass) ) { generatedClass = getMappedClassName(); } if(generatedClass==null) return ""; // will occur for <dynamic-component> return generatedClass; } protected String qualifyInnerClass(String className) { return className.replace('$', '.'); } protected abstract String getMappedClassName(); public String getMetaAsString(String attribute) { MetaAttribute c = meta.getMetaAttribute( attribute ); return MetaAttributeHelper.getMetaAsString( c ); } public boolean hasMetaAttribute(String attribute) { return meta.getMetaAttribute( attribute ) != null; } public String getMetaAsString(String attribute, String seperator) { return MetaAttributeHelper.getMetaAsString( meta.getMetaAttribute( attribute ), seperator ); } public boolean getMetaAsBool(String attribute) { return getMetaAsBool( attribute, false ); } public boolean getMetaAsBool(String attribute, boolean defaultValue) { return MetaAttributeHelper.getMetaAsBool( meta.getMetaAttribute( attribute ), defaultValue ); } public String getClassJavaDoc(String fallback, int indent) { MetaAttribute c = meta.getMetaAttribute( CLASS_DESCRIPTION ); if ( c == null ) { return c2j.toJavaDoc( fallback, indent ); } else { return c2j.toJavaDoc( getMetaAsString( CLASS_DESCRIPTION ), indent ); } } public String getClassModifiers() { String classModifiers = null; // Get scope (backwards compatibility) if ( meta.getMetaAttribute( SCOPE_CLASS ) != null ) { classModifiers = getMetaAsString( SCOPE_CLASS ).trim(); } // Get modifiers if ( meta.getMetaAttribute( CLASS_MODIFIER ) != null ) { classModifiers = getMetaAsString( CLASS_MODIFIER ).trim(); } return classModifiers == null ? "public" : classModifiers; } public String getDeclarationType() { boolean isInterface = isInterface(); if ( isInterface ) { return INTERFACE; } else { return "class"; } } public boolean isInterface() { return getMetaAsBool( INTERFACE ); } public String getExtendsDeclaration() { String extendz = getExtends(); if ( extendz == null || extendz.trim().length() == 0 ) { return ""; } else { return "extends " + extendz; } } public String getImplementsDeclaration() { String implementz = getImplements(); if ( implementz == null || implementz.trim().length() == 0 ) { return ""; } else { return "implements " + implementz; } } public String generateEquals(String thisName, String otherName, boolean useGenerics) { Iterator<Property> allPropertiesIterator = getEqualsHashCodePropertiesIterator(); return generateEquals( thisName, otherName, allPropertiesIterator, useGenerics ); } /** returns the properties that would be visible on this entity as a pojo. This does not return *all* properties since hibernate has certain properties that are only relevant in context of persistence. */ public abstract Iterator<Property> getAllPropertiesIterator(); protected String generateEquals(String thisName, String otherName, Iterator<Property> allPropertiesIterator, boolean useGenerics) { StringBuffer buf = new StringBuffer(); while ( allPropertiesIterator.hasNext() ) { Property property = (Property) allPropertiesIterator.next(); if ( buf.length() > 0 ) buf.append( "\n && " ); String javaTypeName = c2j.getJavaTypeName( property, useGenerics, this ); buf.append( internalgenerateEquals( javaTypeName, thisName + "." + getGetterSignature( property ) + "()", otherName + "." + getGetterSignature( property ) + "()") ); } if ( buf.length() == 0 ) { return "false"; } else { return buf.toString(); } } private boolean usePropertyInEquals(Property property) { boolean hasEqualsMetaAttribute = c2j.hasMetaAttribute(property, "use-in-equals"); boolean useInEquals = c2j.getMetaAsBool( property, "use-in-equals" ); if(property.isNaturalIdentifier()) { if(hasEqualsMetaAttribute && !useInEquals) { return false; } else { return true; } } return useInEquals; } private boolean useCompareTo(String javaTypeName) { // Fix for HBX-400 if ("java.math.BigDecimal".equals(javaTypeName)) { return true; } else { return false; } } private String internalgenerateEquals(String typeName, String lh, String rh) { if ( c2j.isPrimitive( typeName ) ) { return "(" + lh + "==" + rh + ")"; } else { if(useCompareTo( typeName )) { return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".compareTo(" + rh + ")==0 ) )"; } else { if(typeName.endsWith("[]")) { return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + importType("java.util.Arrays") + ".equals(" + lh + ", " + rh + ") ) )"; } else { return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".equals(" + rh + ") ) )"; } } } } public String getExtraClassCode() { return getMetaAsString( "class-code", "\n" ); } private boolean needsEqualsHashCode(Iterator<?> iter) { while ( iter.hasNext() ) { Property element = (Property) iter.next(); if ( usePropertyInEquals( element ) ) { return true; } } return false; } public boolean needsEqualsHashCode() { Iterator<Property> iter = getAllPropertiesIterator(); return needsEqualsHashCode( iter ); } public abstract String getExtends(); public abstract String getImplements(); public String importType(String fqcn) { return importContext.importType(fqcn); } public String generateImports() { return importContext.generateImports(); } public String staticImport(String fqcn, String member) { return importContext.staticImport(fqcn, member); } public String generateBasicAnnotation(Property property) { StringBuffer annotations = new StringBuffer( " " ); if(property.getValue() instanceof SimpleValue) { if (hasVersionProperty()) if (property.equals(getVersionProperty())) buildVersionAnnotation(annotations); String typeName = ((SimpleValue)property.getValue()).getTypeName(); if("date".equals(typeName) || "java.sql.Date".equals(typeName)) { buildTemporalAnnotation( annotations, "DATE" ); } else if ("timestamp".equals(typeName) || "java.sql.Timestamp".equals(typeName)) { buildTemporalAnnotation( annotations, "TIMESTAMP" ); } else if ("time".equals(typeName) || "java.sql.Time".equals(typeName)) { buildTemporalAnnotation(annotations, "TIME"); } //TODO: calendar etc. ? } return annotations.toString(); } private StringBuffer buildTemporalAnnotation(StringBuffer annotations, String temporalTypeValue) { String temporal = importType("javax.persistence.Temporal"); String temporalType = importType("javax.persistence.TemporalType"); return annotations.append( "@" + temporal +"(" + temporalType + "." + temporalTypeValue + ")"); } private StringBuffer buildVersionAnnotation(StringBuffer annotations) { String version = importType("javax.persistence.Version"); return annotations.append( "@" + version ); } public String generateAnnColumnAnnotation(Property property) { StringBuffer annotations = new StringBuffer( " " ); boolean insertable = property.isInsertable(); boolean updatable = property.isUpdateable(); if ( property.isComposite() ) { annotations.append( "@" + importType("javax.persistence.AttributeOverrides") +"( {" ); Component component = (Component) property.getValue(); Iterator<?> subElements = component.getPropertyIterator(); buildRecursiveAttributeOverride( subElements, null, property, annotations ); annotations.setLength( annotations.length() - 2 ); annotations.append( " } )" ); } else { if ( property.getColumnSpan() == 1 ) { Selectable selectable = (Selectable) property.getColumnIterator().next(); buildColumnAnnotation( selectable, annotations, insertable, updatable ); } else { Iterator<?> columns = property.getColumnIterator(); annotations.append("@").append( importType("org.hibernate.annotations.Columns") ).append("( { " ); while ( columns.hasNext() ) { Selectable selectable = (Selectable) columns.next(); if ( selectable.isFormula() ) { //TODO formula in multicolumns not supported by annotations //annotations.append("/* TODO formula in multicolumns not supported by annotations */"); } else { annotations.append( "\n " ); buildColumnAnnotation( selectable, annotations, insertable, updatable ); annotations.append( ", " ); } } annotations.setLength( annotations.length() - 2 ); annotations.append( " } )" ); } } return annotations.toString(); } private void buildRecursiveAttributeOverride(Iterator<?> subElements, String path, Property property, StringBuffer annotations) { while ( subElements.hasNext() ) { Property subProperty = (Property) subElements.next(); if ( subProperty.isComposite() ) { if ( path != null ) { path = path + "."; } else { path = ""; } path = path + subProperty.getName(); Component component = (Component) subProperty.getValue(); buildRecursiveAttributeOverride( component.getPropertyIterator(), path, subProperty, annotations ); } else { Iterator<?> columns = subProperty.getColumnIterator(); Selectable selectable = (Selectable) columns.next(); if ( selectable.isFormula() ) { //TODO formula in multicolumns not supported by annotations } else { annotations.append( "\n " ).append("@") .append( importType("javax.persistence.AttributeOverride") ).append("(name=\"" ); if ( path != null ) { annotations.append( path ).append( "." ); } annotations.append( subProperty.getName() ).append( "\"" ) .append( ", column=" ); buildColumnAnnotation( selectable, annotations, subProperty.isInsertable(), subProperty.isUpdateable() ); annotations.append( " ), " ); } } } } private void buildColumnAnnotation(Selectable selectable, StringBuffer annotations, boolean insertable, boolean updatable) { if ( selectable.isFormula() ) { annotations.append("@").append( importType("org.hibernate.annotations.Formula") ) .append("(value=\"" ).append( selectable.getText() ).append( "\")" ); } else { Column column = (Column) selectable; annotations.append( "@" + importType("javax.persistence.Column") + "(name=\"" ).append( column.getName() ).append( "\"" ); appendCommonColumnInfo( annotations, column, insertable, updatable ); if (column.getPrecision() != Column.DEFAULT_PRECISION) { // the default is actually 0 in spec annotations.append( ", precision=" ).append( column.getPrecision() ); } if (column.getScale() != Column.DEFAULT_SCALE) { // default is actually 0 in spec annotations.append( ", scale=" ).append( column.getScale() ); } else if (column.getLength() != 255){ annotations.append( ", length=" ).append( column.getLength() ); } //TODO support secondary table annotations.append( ")" ); } } protected void appendCommonColumnInfo(StringBuffer annotations, Column column, boolean insertable, boolean updatable) { if(column.isUnique()) { annotations.append( ", unique=" ).append( column.isUnique() ); } if(!column.isNullable()) { annotations.append( ", nullable=" ).append( column.isNullable() ); } if(!insertable) { annotations.append( ", insertable=" ).append( insertable ); } if(!updatable) { annotations.append( ", updatable=" ).append( updatable ); } String sqlType = column.getSqlType(); if ( StringHelper.isNotEmpty( sqlType ) ) { annotations.append( ", columnDefinition=\"" ).append( sqlType ).append( "\"" ); } } public Iterator<Property> getToStringPropertiesIterator() { Iterator<Property> iter = getAllPropertiesIterator(); return getToStringPropertiesIterator( iter ); } private Iterator<Property> getToStringPropertiesIterator(Iterator<Property> iter) { List<Property> properties = new ArrayList<Property>(); while ( iter.hasNext() ) { Property element = (Property) iter.next(); if ( c2j.getMetaAsBool( element, "use-in-tostring" ) ) { properties.add( element ); } } return properties.iterator(); } public Iterator<Property> getEqualsHashCodePropertiesIterator() { Iterator<Property> iter = getAllPropertiesIterator(); return getEqualsHashCodePropertiesIterator(iter); } private Iterator<Property> getEqualsHashCodePropertiesIterator(Iterator<Property> iter) { List<Property> properties = new ArrayList<Property>(); while ( iter.hasNext() ) { Property element = (Property) iter.next(); if ( usePropertyInEquals(element) ) { properties.add( element ); } } return properties.iterator(); } public boolean needsToString() { Iterator<Property> iter = getAllPropertiesIterator(); return needsToString( iter ); } private boolean needsToString(Iterator<Property> iter) { while ( iter.hasNext() ) { Property element = (Property) iter.next(); if ( c2j.getMetaAsBool( element, "use-in-tostring" ) ) { return true; } } return false; } public boolean hasMetaAttribute(MetaAttributable pc, String attribute) { return pc.getMetaAttribute( attribute ) != null; } public boolean getMetaAttribAsBool(MetaAttributable pc, String attribute, boolean defaultValue) { return MetaAttributeHelper.getMetaAsBool( pc.getMetaAttribute( attribute ), defaultValue ); } public boolean hasFieldJavaDoc(Property property) { return property.getMetaAttribute("field-description")!=null; } public String getFieldJavaDoc(Property property, int indent) { MetaAttribute c = property.getMetaAttribute( "field-description" ); if ( c == null ) { return c2j.toJavaDoc( "", indent ); } else { return c2j.toJavaDoc( c2j.getMetaAsString( property, "field-description" ), indent ); } } public String getFieldDescription(Property property){ MetaAttribute c = property.getMetaAttribute( "field-description" ); if ( c == null ) { return ""; } else { return c2j.getMetaAsString( property, "field-description" ); } } /** * Method getGetterSignature. * * @return String */ public String getGetterSignature(Property p) { String prefix = c2j.getJavaTypeName( p, false).equals( "boolean" ) ? "is" : "get"; return prefix + beanCapitalize( p.getName() ); } /** * @param p * @return foo -> Foo, FOo -> FOo */ public String getPropertyName(Property p) { return beanCapitalize( p.getName() ); } // get the "opposite" collectionnae for a property. Currently a "hack" that just uses the same naming algorithm as in reveng, will fail on more general models! public String getCollectionNameFor(Property property) { String str = getPropertyName(property); return ReverseEngineeringStrategyUtil.simplePluralize(str); } /** * foo -> Foo * FOo -> FOo */ static public String beanCapitalize(String fieldname) { if ( fieldname == null || fieldname.length() == 0 ) { return fieldname; } if ( fieldname.length() > 1 && Character.isUpperCase( fieldname.charAt( 1 ) ) ) { return fieldname; } char chars[] = fieldname.toCharArray(); chars[0] = Character.toUpperCase( chars[0] ); return new String( chars ); } public boolean isComponent(Property property) { Value value = property.getValue(); if ( value != null && value instanceof Component ) { return true; } else { return false; } } public String generateHashCode(Property property, String result, String thisName, boolean jdk5) { StringBuffer buf = new StringBuffer(); if ( c2j.getMetaAsBool( property, "use-in-equals" ) ) { String javaTypeName = c2j.getJavaTypeName( property, jdk5, this ); boolean isPrimitive = c2j.isPrimitive( javaTypeName ); if ( isPrimitive ) { buf.append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ); String thisValue = thisName + "." + getGetterSignature( property ) + "()"; if("char".equals(javaTypeName)||"int".equals(javaTypeName)||"short".equals(javaTypeName)||"byte".equals(javaTypeName)) { buf.append( thisValue ); } else if("boolean".equals(javaTypeName)) { buf.append("(" + thisValue + "?1:0)"); } else { buf.append( "(int) "); buf.append( thisValue ); } buf.append(";"); } else { if(javaTypeName.endsWith("[]")) { if(jdk5) { buf.append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ); buf.append( "( " ) .append( getGetterSignature( property ) ) .append( "() == null ? 0 : " + importType("java.util.Arrays") + ".hashCode(" ) .append( thisName ) .append( "." ) .append( getGetterSignature( property ) ) .append( "())" ) .append( " )" ) .append(";"); } else { buf.append(internalGenerateArrayHashcode(property, javaTypeName, result, thisName)); } } else { buf.append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ); buf.append( "( " ) .append( getGetterSignature( property ) ) .append( "() == null ? 0 : " ) .append( thisName ) .append( "." ) .append( getGetterSignature( property ) ) .append( "()" ) .append( ".hashCode()" ) .append( " )" ) .append(";"); } } } return buf.toString(); } private String internalGenerateArrayHashcode(Property property, String javaTypeName, String result, String thisName) { StringBuffer buf = new StringBuffer(); String propertyHashVarName = property.getName() + "Hashcode"; String propertyArrayName = property.getName() + "Property"; // int propertyHash = 0; buf.append( "int ") .append( propertyHashVarName ) .append( " = 0;\n" ); // type[] proterty = getProperty(); buf.append( " " ) .append( javaTypeName ) .append( " " ) .append( propertyArrayName ) .append( " = " ) .append( thisName ) .append( "." ) .append( getGetterSignature( property ) ) .append( "();\n"); // if(property != null) { buf.append( " if(" ) .append( propertyArrayName ) .append( " != null) {\n" ); // propertyHash = 1; buf.append( " " ) .append( propertyHashVarName ) .append( " = 1;\n" ); // for (int i=0; i<property.length; i++) javaTypeName.replaceAll("\\[\\]", ""); buf.append( " for (int i=0; i<" ) .append( propertyArrayName ) .append( ".length; i++) {\n" ); if(javaTypeName.startsWith("long")) { // int elementHash = (int)(propertyArray[i] ^ (propertyArray[i] >>> 32)); buf.append( " int elementHash = (int)(" ) .append( propertyArrayName ) .append( "[i] ^ (" ) .append( propertyArrayName ) .append( "[i] >>> 32));\n" ); // propertyHash = 37 * propertyHash + elementHash; buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + elementHash;\n" ); } else if(javaTypeName.startsWith("boolean")) { // propertyHash = 37 * propertyHash + (propertyArray[i] ? 1231 : 1237); buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + (" ) .append( propertyArrayName ) .append( "[i] ? 1231 : 1237);\n" ); } else if(javaTypeName.startsWith("float")) { // propertyHash = 37 * propertyHash + Float.floatToIntBits(propertyArray[i]); buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + Float.floatToIntBits(" ) .append( propertyArrayName ) .append( "[i]);\n" ); } else if(javaTypeName.startsWith("double")) { // long bits = Double.doubleToLongBits(propertyArray[i]); buf.append( " long bits = Double.doubleToLongBits(" ) .append( propertyArrayName ) .append( "[i]);\n" ); // propertyHash = 37 * propertyHash + (int)(bits ^ (bits >>> 32)); buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + (int)(bits ^ (bits >>> 32));\n" ); } else if(javaTypeName.startsWith("int") || javaTypeName.startsWith("short") || javaTypeName.startsWith("char") || javaTypeName.startsWith("byte")) { // propertyHash = 37 * propertyHash + propertyArray[i]; buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + " ) .append( propertyArrayName ) .append( "[i];\n" ); } else {// Object[] // propertyHash = 37 * propertyHash + propertyArray[i].hashCode(); buf.append( " " ) .append( propertyHashVarName ) .append( " = 37 * " ) .append( propertyHashVarName ) .append( " + " ) .append( propertyArrayName ) .append( "[i].hashCode();\n" ); } buf.append( " }\n" ); buf.append( " }\n\n" ); // result = 37 * result + arrayHashcode; buf.append( " " ) .append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ) .append( propertyHashVarName ) .append( ";\n" ); return buf.toString(); } public String getFieldModifiers(Property property) { return getModifiers( property, "scope-field", "private" ); } public String getPropertyGetModifiers(Property property) { return getModifiers( property, "scope-get", "public" ); } public String getPropertySetModifiers(Property property) { return getModifiers( property, "scope-set", "public" ); } //TODO defaultModifiers private String getModifiers(Property property, String modifiername, String defaultModifiers) { MetaAttribute override = property.getMetaAttribute( modifiername ); if ( override != null ) { return MetaAttributeHelper.getMetaAsString( override ); } else { return defaultModifiers; } } protected boolean isRequiredInConstructor(Property field) { if(hasMetaAttribute(field, "default-value")) { return false; } if(field.getValue()!=null) { if (!field.isOptional() && (field.getValueGenerationStrategy() == null || field.getValueGenerationStrategy().getGenerationTiming().equals(GenerationTiming.NEVER))) { return true; } else if (field.getValue() instanceof Component) { Component c = (Component) field.getValue(); Iterator<?> it = c.getPropertyIterator(); while ( it.hasNext() ) { Property prop = (Property) it.next(); if(isRequiredInConstructor(prop)) { return true; } } } } return false; } public boolean needsMinimalConstructor() { List<Property> propClosure = getPropertyClosureForMinimalConstructor(); if(propClosure.isEmpty()) return false; // minimal=default if(propClosure.equals(getPropertyClosureForFullConstructor())) return false; // minimal=full return true; } public boolean needsFullConstructor() { return !getPropertyClosureForFullConstructor().isEmpty(); } public String getJavaTypeName(Property p, boolean useGenerics) { return c2j.getJavaTypeName(p, useGenerics, this); } static private class DefaultInitializor { private final String type; private final boolean initToZero; public DefaultInitializor(String type, boolean initToZero) { this.type = type; this.initToZero = initToZero; } public String getDefaultValue(String comparator, String genericDeclaration, ImportContext importContext) { StringBuffer val = new StringBuffer("new " + importContext.importType(type)); if(genericDeclaration!=null) { val.append(genericDeclaration); } val.append("("); if(comparator!=null) { val.append("new "); val.append(importContext.importType(comparator)); val.append("()"); if(initToZero) val.append(","); } if(initToZero) { val.append("0"); } val.append(")"); return val.toString(); } } static Map<String, DefaultInitializor> defaultInitializors = new HashMap<String, DefaultInitializor>(); static { defaultInitializors.put("java.util.List", new DefaultInitializor("java.util.ArrayList", true)); defaultInitializors.put("java.util.Map", new DefaultInitializor("java.util.HashMap", true)); defaultInitializors.put("java.util.Set", new DefaultInitializor("java.util.HashSet",true)); defaultInitializors.put("java.util.SortedSet", new DefaultInitializor("java.util.TreeSet", false)); defaultInitializors.put("java.util.SortedMap", new DefaultInitializor("java.util.TreeMap", false)); } public boolean hasFieldInitializor(Property p, boolean useGenerics) { return getFieldInitialization(p, useGenerics)!=null; } public String getFieldInitialization(Property p, boolean useGenerics) { if(hasMetaAttribute(p, "default-value")) { return MetaAttributeHelper.getMetaAsString( p.getMetaAttribute( "default-value" ) ); } if(c2j.getJavaTypeName(p, false)==null) { throw new IllegalArgumentException(); } else if (p.getValue() instanceof Collection) { Collection col = (Collection) p.getValue(); DefaultInitializor initialization = (DefaultInitializor) col.accept(new DefaultValueVisitor(true) { public Object accept(Bag o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(org.hibernate.mapping.List o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(org.hibernate.mapping.Map o) { if(o.isSorted()) { return new DefaultInitializor("java.util.TreeMap", false); } else { return new DefaultInitializor("java.util.HashMap", true); } } public Object accept(IdentifierBag o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(Set o) { if(o.isSorted()) { return new DefaultInitializor("java.util.TreeSet", false); } else { return new DefaultInitializor("java.util.HashSet", true); } } public Object accept(PrimitiveArray o) { return null; // TODO: default init for arrays ? } public Object accept(Array o) { return null;// TODO: default init for arrays ? } }); if(initialization!=null) { String comparator = null; String decl = null; if(col.isSorted()) { comparator = col.getComparatorClassName(); } if(useGenerics) { decl = c2j.getGenericCollectionDeclaration((Collection) p.getValue(), true, importContext); } return initialization.getDefaultValue(comparator, decl, this); } else { return null; } } else { return null; } } }