1 package org.hibernate.cfg; 3 4 import java.util.ArrayList ; 5 import java.util.HashMap ; 6 import java.util.HashSet ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 import java.util.Set ; 11 import java.util.StringTokenizer ; 12 13 import org.hibernate.AnnotationException; 14 import org.hibernate.AssertionFailure; 15 import org.hibernate.MappingException; 16 import org.hibernate.cfg.annotations.TableBinder; 17 import org.hibernate.mapping.Collection; 18 import org.hibernate.mapping.Column; 19 import org.hibernate.mapping.Component; 20 import org.hibernate.mapping.PersistentClass; 21 import org.hibernate.mapping.Property; 22 import org.hibernate.mapping.ToOne; 23 import org.hibernate.mapping.Value; 24 import org.hibernate.util.StringHelper; 25 26 29 public class BinderHelper { 30 private BinderHelper() {} 31 32 35 public static Property shallowCopy(Property property) { 36 Property clone = new Property(); 37 clone.setCascade( property.getCascade() ); 38 clone.setInsertable( property.isInsertable() ); 39 clone.setLazy( property.isLazy() ); 40 clone.setName( property.getName() ); 41 clone.setNaturalIdentifier( property.isNaturalIdentifier() ); 42 clone.setOptimisticLocked( property.isOptimisticLocked() ); 43 clone.setOptional( property.isOptional() ); 44 clone.setPersistentClass( property.getPersistentClass() ); 45 clone.setPropertyAccessorName( property.getPropertyAccessorName() ); 46 clone.setSelectable( property.isSelectable() ); 47 clone.setUpdateable( property.isUpdateable() ); 48 clone.setValue( property.getValue() ); 49 return clone; 50 } 51 52 public static void createSyntheticPropertyReference( 53 Ejb3JoinColumn[] columns, 54 PersistentClass referencedEntity, 55 Value value, 56 ExtendedMappings mappings) { 57 if ( columns[0].isImplicit() || StringHelper.isNotEmpty( columns[0].getMappedBy() ) ) return; 58 int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, referencedEntity); 59 PersistentClass associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass(); 60 if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) { 61 68 69 String syntheticPropertyName = new StringBuffer ("_") 70 .append( referencedEntity.getEntityName().replace( '.', '_') ) 71 .append("_") 72 .append( columns[0].getPropertyName() ).toString(); 73 List <Property> properties = findPropertiesByColumns(referencedEntity, columns); 75 Property synthProp = null; 77 if (properties != null) { 78 Component embeddedComp = new Component( referencedEntity ); 79 embeddedComp.setEmbedded( true ); 80 embeddedComp.setComponentClassName( embeddedComp.getOwner().getClassName() ); 81 for (Property property : properties) { 82 Property clone = BinderHelper.shallowCopy(property); 83 clone.setInsertable( false ); 84 clone.setUpdateable( false ); 85 clone.setNaturalIdentifier( false ); 86 embeddedComp.addProperty( clone ); 87 } 88 synthProp = new Property(); 89 synthProp.setName(syntheticPropertyName); 90 synthProp.setPersistentClass( referencedEntity ); 92 synthProp.setUpdateable(false); 93 synthProp.setInsertable(false); 94 synthProp.setValue(embeddedComp); 95 synthProp.setPropertyAccessorName( "embedded" ); 96 referencedEntity.addProperty(synthProp); 97 TableBinder.createUniqueConstraint( embeddedComp ); 99 } 100 else { 101 StringBuffer columnsList = new StringBuffer (); 103 for(Ejb3JoinColumn column : columns) { 104 columnsList.append( column.getReferencedColumn() ).append(", "); 105 } 106 throw new AnnotationException("referencedColumnName not mapped to a property is not supported: " 107 + columnsList.toString() ); 108 } 109 110 113 if (value instanceof ToOne) { 114 ( (ToOne) value).setReferencedPropertyName(syntheticPropertyName); 115 mappings.addUniquePropertyReference(referencedEntity.getEntityName(), syntheticPropertyName); 116 } 117 else if (value instanceof Collection) { 118 ( (Collection) value).setReferencedPropertyName( syntheticPropertyName ); 120 mappings.addPropertyReference(referencedEntity.getEntityName(), syntheticPropertyName); 122 } 123 else { 124 throw new AssertionFailure("Do a property ref on an unexpected Value type: " 125 + value.getClass().getName() ); 126 } 127 mappings.addPropertyReferencedAssociation( 128 associatedClass.getEntityName(), 129 columns[0].getPropertyName(), 130 syntheticPropertyName 131 ); 132 } 133 } 134 135 136 private static List <Property> findPropertiesByColumns(PersistentClass referencedEntity, Ejb3JoinColumn[] columns) { 137 Map <Column,Set <Property>> columnsToProperty = new HashMap <Column,Set <Property>>(); 138 List <Column> orderedColumns = new ArrayList <Column>(); 139 for(int index = 0 ; index < columns.length ; index++) { 140 Column column = new Column( columns[index].getReferencedColumn() ); 141 orderedColumns.add( column ); 142 columnsToProperty.put( column, new HashSet <Property>() ); 143 } 144 Iterator it = referencedEntity.getPropertyIterator(); 145 while ( it.hasNext() ) { 146 Property property = (Property) it.next(); 147 Iterator columnIt = property.getColumnIterator(); 148 while ( columnIt.hasNext() ) { 149 Column column = (Column) columnIt.next(); 150 if ( columnsToProperty.containsKey( column ) ) { 151 columnsToProperty.get( column ).add( property ); 152 } 153 } 154 } 155 List <Property> orderedProperties = new ArrayList <Property>(); 159 for (Column column : orderedColumns) { 160 boolean found = false; 161 for (Property property : columnsToProperty.get( column ) ) { 162 if (property.getColumnSpan() == 1) { 163 orderedProperties.add(property); 164 found = true; 165 break; 166 } 167 } 168 if (!found) return null; } 170 return orderedProperties; 171 } 172 173 public static Property findPropertyByName(PersistentClass associatedClass, String propertyName) { 174 Property property = null; 175 Property idProperty = associatedClass.getIdentifierProperty(); 176 String idName = idProperty != null ? idProperty.getName() : null; 177 try { 178 if ( propertyName == null 179 || propertyName.equals( "" ) 180 || propertyName.equals( idName ) ) { 181 property = idProperty; 183 } 184 else { 185 if ( propertyName.indexOf( idName + "." ) == 0 ) { 186 property = idProperty; 187 propertyName = propertyName.substring( idName.length() + 1 ); 188 } 189 StringTokenizer st = new StringTokenizer ( propertyName, ".", false); 190 while ( st.hasMoreElements() ) { 191 String element = (String ) st.nextElement(); 192 if (property == null) { 193 property = associatedClass.getProperty( element ); 194 } 195 else { 196 if ( ! property.isComposite() ) return null; 197 property = ( (Component) property.getValue() ).getProperty(element); 198 } 199 } 200 } 201 } 202 catch (MappingException e) { 203 return null; 204 } 205 return property; 206 } 207 } 208 | Popular Tags |