1 package org.hibernate.hql.ast.tree; 3 4 import java.util.Map ; 5 6 import org.hibernate.MappingException; 7 import org.hibernate.engine.JoinSequence; 8 import org.hibernate.hql.CollectionProperties; 9 import org.hibernate.hql.CollectionSubqueryFactory; 10 import org.hibernate.hql.NameGenerator; 11 import org.hibernate.persister.collection.CollectionPropertyMapping; 12 import org.hibernate.persister.collection.QueryableCollection; 13 import org.hibernate.persister.entity.EntityPersister; 14 import org.hibernate.persister.entity.Joinable; 15 import org.hibernate.persister.entity.PropertyMapping; 16 import org.hibernate.persister.entity.Queryable; 17 import org.hibernate.type.EntityType; 18 import org.hibernate.type.Type; 19 import org.hibernate.type.TypeFactory; 20 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 24 29 class FromElementType { 30 private static final Log log = LogFactory.getLog( FromElementType.class ); 31 32 private FromElement fromElement; 33 private EntityType entityType; 34 private EntityPersister persister; 35 private QueryableCollection queryableCollection; 36 private CollectionPropertyMapping collectionPropertyMapping; 37 private JoinSequence joinSequence; 38 39 private String collectionSuffix; 40 41 public FromElementType(FromElement fromElement, EntityPersister persister, EntityType entityType) { 42 this.fromElement = fromElement; 43 this.persister = persister; 44 this.entityType = entityType; 45 if ( persister != null ) { 46 fromElement.setText( ( ( Queryable ) persister ).getTableName() + " " + getTableAlias() ); 47 } 48 } 49 50 private String getTableAlias() { 51 return fromElement.getTableAlias(); 52 } 53 54 private String getCollectionTableAlias() { 55 return fromElement.getCollectionTableAlias(); 56 } 57 58 public String getCollectionSuffix() { 59 return collectionSuffix; 60 } 61 62 public void setCollectionSuffix(String suffix) { 63 collectionSuffix = suffix; 64 } 65 66 public EntityPersister getEntityPersister() { 67 return persister; 68 } 69 70 public Type getDataType() { 71 if ( persister == null ) { 72 if ( queryableCollection == null ) { 73 return null; 74 } 75 return queryableCollection.getType(); 76 } 77 else { 78 return entityType; 79 } 80 } 81 82 public Type getSelectType() { 83 if (entityType==null) return null; 84 boolean shallow = fromElement.getFromClause().getWalker().isShallowQuery(); 85 return TypeFactory.manyToOne( entityType.getAssociatedEntityName(), shallow ); 86 } 87 88 93 public Queryable getQueryable() { 94 return ( persister instanceof Queryable ) ? ( Queryable ) persister : null; 95 } 96 97 103 String renderScalarIdentifierSelect(int i) { 104 checkInitialized(); 105 String [] cols = getPropertyMapping( EntityPersister.ENTITY_ID ).toColumns( getTableAlias(), EntityPersister.ENTITY_ID ); 106 StringBuffer buf = new StringBuffer (); 107 for ( int j = 0; j < cols.length; j++ ) { 109 String column = cols[j]; 110 if ( j > 0 ) { 111 buf.append( ", " ); 112 } 113 buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, j ) ); 114 } 115 return buf.toString(); 116 } 117 118 125 String renderIdentifierSelect(int size, int k) { 126 checkInitialized(); 127 if ( fromElement.getFromClause().isSubQuery() ) { 129 String [] idColumnNames = ( persister != null ) ? 131 ( ( Queryable ) persister ).getIdentifierColumnNames() : new String [0]; 132 StringBuffer buf = new StringBuffer (); 133 for ( int i = 0; i < idColumnNames.length; i++ ) { 134 buf.append( fromElement.getTableAlias() ).append( '.' ).append( idColumnNames[i] ); 135 if ( i != idColumnNames.length - 1 ) buf.append( ", " ); 136 } 137 return buf.toString(); 138 } 139 else { 140 String fragment = ( ( Queryable ) persister ).identifierSelectFragment( getTableAlias(), getSuffix( size, k ) ); 141 return trimLeadingCommaAndSpaces( fragment ); 142 } 143 } 144 145 private String getSuffix(int size, int sequence) { 146 return generateSuffix( size, sequence ); 147 } 148 149 private static String generateSuffix(int size, int k) { 150 String suffix = size == 1 ? "" : Integer.toString( k ) + '_'; 151 return suffix; 152 } 153 154 private void checkInitialized() { 155 fromElement.checkInitialized(); 156 } 157 158 164 String renderPropertySelect(int size, int k, boolean allProperties) { 165 checkInitialized(); 166 if ( persister == null ) { 167 return ""; 168 } 169 else { 170 String fragment = ( ( Queryable ) persister ).propertySelectFragment( 171 getTableAlias(), 172 getSuffix( size, k ), 173 allProperties 174 ); 175 return trimLeadingCommaAndSpaces( fragment ); 176 } 177 } 178 179 String renderCollectionSelectFragment(int size, int k) { 180 if ( queryableCollection == null ) { 181 return ""; 182 } 183 else { 184 if ( collectionSuffix == null ) { 185 collectionSuffix = generateSuffix( size, k ); 186 } 187 String fragment = queryableCollection.selectFragment( getCollectionTableAlias(), collectionSuffix ); 188 return trimLeadingCommaAndSpaces( fragment ); 189 } 190 } 191 192 public String renderValueCollectionSelectFragment(int size, int k) { 193 if ( queryableCollection == null ) { 194 return ""; 195 } 196 else { 197 if ( collectionSuffix == null ) { 198 collectionSuffix = generateSuffix( size, k ); 199 } 200 String fragment = queryableCollection.selectFragment( getTableAlias(), collectionSuffix ); 201 return trimLeadingCommaAndSpaces( fragment ); 202 } 203 } 204 205 212 private static String trimLeadingCommaAndSpaces(String fragment) { 213 if ( fragment.length() > 0 && fragment.charAt( 0 ) == ',' ) { 214 fragment = fragment.substring( 1 ); 215 } 216 fragment = fragment.trim(); 217 return fragment.trim(); 218 } 219 220 public void setJoinSequence(JoinSequence joinSequence) { 221 this.joinSequence = joinSequence; 222 } 223 224 public JoinSequence getJoinSequence() { 225 if ( joinSequence != null ) { 226 return joinSequence; 227 } 228 229 if ( persister instanceof Joinable ) { 231 Joinable joinable = ( Joinable ) persister; 232 return fromElement.getSessionFactoryHelper().createJoinSequence().setRoot( joinable, getTableAlias() ); 233 } 234 else { 235 return null; } 237 } 238 239 public void setQueryableCollection(QueryableCollection queryableCollection) { 240 if ( this.queryableCollection != null ) { 241 throw new IllegalStateException ( "QueryableCollection is already defined for " + this + "!" ); 242 } 243 this.queryableCollection = queryableCollection; 244 if ( !queryableCollection.isOneToMany() ) { 245 fromElement.setText( queryableCollection.getTableName() + " " + getTableAlias() ); 247 } 248 } 249 250 public QueryableCollection getQueryableCollection() { 251 return queryableCollection; 252 } 253 254 261 public Type getPropertyType(String propertyName, String propertyPath) { 262 checkInitialized(); 263 Type type = null; 264 if ( persister != null && propertyName.equals( propertyPath ) && propertyName.equals( persister.getIdentifierPropertyName() ) ) { 270 type = persister.getIdentifierType(); 271 } 272 else { PropertyMapping mapping = getPropertyMapping( propertyName ); 274 type = mapping.toType( propertyPath ); 275 } 276 if ( type == null ) { 277 throw new MappingException( "Property " + propertyName + " does not exist in " + 278 ( ( queryableCollection == null ) ? "class" : "collection" ) + " " 279 + ( ( queryableCollection == null ) ? fromElement.getClassName() : queryableCollection.getRole() ) ); 280 } 281 return type; 282 } 283 284 String [] toColumns(String tableAlias, String path, boolean inSelect) { 285 checkInitialized(); 286 PropertyMapping propertyMapping = getPropertyMapping( path ); 287 if ( !inSelect && queryableCollection != null && CollectionProperties.isCollectionProperty( path ) ) { 290 Map enabledFilters = fromElement.getWalker().getEnabledFilters(); 291 String subquery = CollectionSubqueryFactory.createCollectionSubquery( joinSequence, enabledFilters, 292 propertyMapping.toColumns( tableAlias, path ) ); 293 if ( log.isDebugEnabled() ) { 294 log.debug( "toColumns(" + tableAlias + "," + path + ") : subquery = " + subquery ); 295 } 296 return new String []{"(" + subquery + ")"}; 297 } 298 else { 299 if ( fromElement.getWalker().isSelectStatement() ) { 300 return propertyMapping.toColumns( tableAlias, path ); 301 } 302 else { 303 return propertyMapping.toColumns( path ); 304 } 305 } 306 } 307 308 PropertyMapping getPropertyMapping(String propertyName) { 309 checkInitialized(); 310 if ( queryableCollection == null ) { return ( PropertyMapping ) persister; } 313 if ( CollectionProperties.isCollectionProperty( propertyName ) ) { 315 if ( collectionPropertyMapping == null ) { 316 collectionPropertyMapping = new CollectionPropertyMapping( queryableCollection ); 317 } 318 return collectionPropertyMapping; 319 } 320 if ( queryableCollection.getElementType().isComponentType() ) { if ( propertyName.equals( EntityPersister.ENTITY_ID ) ) { 322 return ( PropertyMapping ) queryableCollection.getOwnerEntityPersister(); 323 } 324 } 325 return queryableCollection; 326 } 327 328 public boolean isCollectionOfValuesOrComponents() { 329 if ( persister == null ) { 330 if ( queryableCollection == null ) { 331 return false; 332 } 333 else { 334 return !queryableCollection.getElementType().isEntityType(); 335 } 336 } 337 else { 338 return false; 339 } 340 } 341 342 public boolean isEntity() { 343 return persister != null; 344 } 345 } 346 | Popular Tags |