1 package org.hibernate.loader.custom; 3 4 import java.util.ArrayList ; 5 import java.util.HashMap ; 6 import java.util.Iterator ; 7 import java.util.List ; 8 import java.util.Map ; 9 10 import org.hibernate.HibernateException; 11 import org.hibernate.LockMode; 12 import org.hibernate.MappingException; 13 import org.hibernate.engine.SessionFactoryImplementor; 14 import org.hibernate.persister.collection.QueryableCollection; 15 import org.hibernate.persister.entity.EntityPersister; 16 import org.hibernate.persister.entity.SQLLoadable; 17 import org.hibernate.type.EntityType; 18 import org.hibernate.type.Type; 19 20 23 public class SQLQueryReturnProcessor { 24 25 private SQLQueryReturn[] queryReturns; 26 private SQLQueryScalarReturn[] scalarQueryReturns; 27 28 private final List aliases = new ArrayList (); 29 private final List persisters = new ArrayList (); 30 private final List propertyResults = new ArrayList (); 31 private final List lockModes = new ArrayList (); 32 private final Map alias2Persister = new HashMap (); 33 private final Map alias2Return = new HashMap (); 34 private final Map alias2OwnerAlias = new HashMap (); 35 36 private final List scalarTypes = new ArrayList (); 37 private final List scalarColumnAliases = new ArrayList (); 38 39 private final SessionFactoryImplementor factory; 40 41 private List collectionOwnerAliases = new ArrayList (); 42 private List collectionAliases = new ArrayList (); 43 private List collectionPersisters = new ArrayList (); 44 private List collectionResults = new ArrayList (); 45 46 47 48 private SessionFactoryImplementor getFactory() { 49 return factory; 50 } 51 52 private SQLLoadable getSQLLoadable(String entityName) throws MappingException { 53 EntityPersister persister = getFactory().getEntityPersister( entityName ); 54 if ( !(persister instanceof SQLLoadable) ) { 55 throw new MappingException( "class persister is not SQLLoadable: " + entityName ); 56 } 57 return (SQLLoadable) persister; 58 } 59 60 public SQLQueryReturnProcessor( 61 SQLQueryReturn[] queryReturns, 62 SQLQueryScalarReturn[] scalarQueryReturns, 63 SessionFactoryImplementor factory 64 ) { 65 this.queryReturns = queryReturns; 66 this.scalarQueryReturns = scalarQueryReturns; 67 this.factory = factory; 68 } 69 70 public void process() { 71 72 for (int i=0; i<queryReturns.length; i++) { 75 alias2Return.put( queryReturns[i].getAlias(), queryReturns[i] ); 76 if (queryReturns[i] instanceof SQLQueryJoinReturn) { 77 SQLQueryJoinReturn roleReturn = (SQLQueryJoinReturn) queryReturns[i]; 78 alias2OwnerAlias.put( roleReturn.getAlias(), roleReturn.getOwnerAlias() ); 79 } 80 else if (queryReturns[i] instanceof SQLQueryCollectionReturn) { 81 } 83 } 84 85 for (int i=0; i<queryReturns.length; i++) { 87 processReturn( queryReturns[i] ); 88 } 89 if (scalarQueryReturns!=null) { 90 for (int i=0; i<scalarQueryReturns.length; i++) { 91 processScalarReturn( scalarQueryReturns[i] ); 92 } 93 } 94 } 95 96 private void processReturn(SQLQueryReturn rtn) { 97 if (rtn instanceof SQLQueryRootReturn) { 98 processRootReturn( (SQLQueryRootReturn) rtn ); 99 } 100 else if (rtn instanceof SQLQueryCollectionReturn) { 101 processCollectionReturn( (SQLQueryCollectionReturn) rtn ); 102 } 103 else { 104 processJoinReturn( (SQLQueryJoinReturn) rtn ); 105 } 106 } 107 108 private void processScalarReturn(SQLQueryScalarReturn typeReturn) { 109 scalarColumnAliases.add( typeReturn.getColumnAlias() ); 110 scalarTypes.add( typeReturn.getType() ); 111 } 112 113 private void processRootReturn(SQLQueryRootReturn rootReturn) { 114 if ( alias2Persister.containsKey( rootReturn.getAlias() ) ) { 115 return; 117 } 118 119 SQLLoadable persister = getSQLLoadable( rootReturn.getReturnEntityName() ); 120 aliases.add( rootReturn.getAlias() ); 121 addPersister(rootReturn.getPropertyResultsMap(), persister); 122 alias2Persister.put( rootReturn.getAlias(), persister ); 123 lockModes.add( rootReturn.getLockMode() ); 124 } 125 126 130 private void addPersister(Map propertyResult, SQLLoadable persister) { 131 this.persisters.add(persister); 132 this.propertyResults.add(propertyResult); 133 } 134 135 private void addCollection(String role, String alias, Map propertyResults, LockMode lockMode) { 136 QueryableCollection collectionPersister = (QueryableCollection) getFactory().getCollectionPersister(role); 137 collectionPersisters.add( collectionPersister ); 138 collectionAliases.add(alias); 139 this.collectionResults.add(propertyResults); 140 141 if ( collectionPersister.isOneToMany() ) { 142 SQLLoadable persister = (SQLLoadable) collectionPersister.getElementPersister(); 143 aliases.add(alias); 144 addPersister(filter(propertyResults), persister); 145 lockModes.add(lockMode); 146 alias2Persister.put(alias, persister); 147 } 148 } 149 150 private Map filter(Map propertyResults) { 151 Map result = new HashMap (propertyResults.size() ); 152 153 String keyPrefix = "element."; 154 155 Iterator iter = propertyResults.entrySet().iterator(); 156 while ( iter.hasNext() ) { 157 Map.Entry element = (Map.Entry ) iter.next(); 158 String path = (String ) element.getKey(); 159 if( path.startsWith(keyPrefix) ) { 160 result.put(path.substring(keyPrefix.length() ), element.getValue() ); 161 } 162 } 163 164 return result; 165 } 166 167 private void processCollectionReturn(SQLQueryCollectionReturn collectionReturn) { 168 collectionOwnerAliases.add(null); 171 String role = collectionReturn.getOwnerEntityName() + '.' + collectionReturn.getOwnerProperty(); 172 addCollection( 173 role, 174 collectionReturn.getAlias(), 175 collectionReturn.getPropertyResultsMap(), 176 collectionReturn.getLockMode() 177 ); 178 } 179 180 private void processJoinReturn(SQLQueryJoinReturn roleReturn) { 181 String alias = roleReturn.getAlias(); 182 if ( alias2Persister.containsKey(alias) || collectionAliases.contains(alias) ) { 183 return; 185 } 186 187 String ownerAlias = roleReturn.getOwnerAlias(); 188 189 if ( !alias2Return.containsKey(ownerAlias) ) { 191 throw new HibernateException( 192 "Owner alias [" + ownerAlias + "] is unknown for alias [" + 193 alias + "]" 194 ); 195 } 196 197 if ( !alias2Persister.containsKey(ownerAlias) ) { 199 SQLQueryReturn ownerReturn = (SQLQueryReturn) alias2Return.get(ownerAlias); 200 processReturn(ownerReturn); 201 } 202 203 SQLLoadable ownerPersister = (SQLLoadable) alias2Persister.get(ownerAlias); 204 Type returnType = ownerPersister.getPropertyType( roleReturn.getOwnerProperty() ); 205 206 if ( returnType.isCollectionType() ) { 207 String role = ownerPersister.getEntityName() + '.' + roleReturn.getOwnerProperty(); 208 addCollection( role, alias, roleReturn.getPropertyResultsMap(), roleReturn.getLockMode() ); 209 collectionOwnerAliases.add(ownerAlias); 210 } 211 else if ( returnType.isEntityType() ) { 212 EntityType eType = (EntityType) returnType; 213 String returnEntityName = eType.getAssociatedEntityName(); 214 SQLLoadable persister = getSQLLoadable(returnEntityName); 215 aliases.add( alias ); 216 addPersister(roleReturn.getPropertyResultsMap(), persister); 217 lockModes.add( roleReturn.getLockMode() ); 218 alias2Persister.put( alias, persister ); 219 } 220 221 } 222 223 public List getCollectionAliases() { 224 return collectionAliases; 225 } 226 227 230 231 public List getCollectionOwnerAliases() { 232 return collectionOwnerAliases; 233 } 234 235 public List getCollectionPersisters() { 236 return collectionPersisters; 237 } 238 239 public Map getAlias2Persister() { 240 return alias2Persister; 241 } 242 243 public List getAliases() { 244 return aliases; 245 } 246 247 250 251 public List getLockModes() { 252 return lockModes; 253 } 254 255 public List getPersisters() { 256 return persisters; 257 } 258 259 public Map getAlias2OwnerAlias() { 260 return alias2OwnerAlias; 261 } 262 263 public List getScalarTypes() { 264 return scalarTypes; 265 } 266 public List getScalarColumnAliases() { 267 return scalarColumnAliases; 268 } 269 270 public List getPropertyResults() { 271 return propertyResults; 272 } 273 274 public List getCollectionPropertyResults() { 275 return collectionResults; 276 } 277 278 279 public Map getAlias2Return() { 280 return alias2Return; 281 } 282 283 284 285 286 } 287 | Popular Tags |