Methods Summary |
---|
private static org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn | bindLoadCollection(org.dom4j.Element returnElem, Mappings mappings)
String alias = returnElem.attributeValue( "alias" );
String collectionAttribute = returnElem.attributeValue( "role" );
LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
int dot = collectionAttribute.lastIndexOf( '." );
if ( dot == -1 ) {
throw new MappingException(
"Collection attribute for sql query return [alias=" + alias +
"] not formatted correctly {OwnerClassName.propertyName}"
);
}
String ownerClassName = HbmBinder.getClassName( collectionAttribute.substring( 0, dot ), mappings );
String ownerPropertyName = collectionAttribute.substring( dot + 1 );
//FIXME: get the PersistentClass
java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
return new NativeSQLQueryCollectionReturn(
alias,
ownerClassName,
ownerPropertyName,
propertyResults,
lockMode
);
|
private static java.util.Map | bindPropertyResults(java.lang.String alias, org.dom4j.Element returnElement, org.hibernate.mapping.PersistentClass pc, Mappings mappings)
HashMap propertyresults = new HashMap(); // maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment
Element discriminatorResult = returnElement.element("return-discriminator");
if(discriminatorResult!=null) {
ArrayList resultColumns = getResultColumns(discriminatorResult);
propertyresults.put("class", ArrayHelper.toStringArray(resultColumns) );
}
Iterator iterator = returnElement.elementIterator("return-property");
List properties = new ArrayList();
List propertyNames = new ArrayList();
while ( iterator.hasNext() ) {
Element propertyresult = (Element) iterator.next();
String name = propertyresult.attributeValue("name");
if ( pc == null || name.indexOf( '.") == -1) { //if dotted and not load-collection nor return-join
//regular property
properties.add(propertyresult);
propertyNames.add(name);
}
else {
/**
* Reorder properties
* 1. get the parent property
* 2. list all the properties following the expected one in the parent property
* 3. calculate the lowest index and insert the property
*/
if (pc == null)
throw new MappingException("dotted notation in <return-join> or <load_collection> not yet supported");
int dotIndex = name.lastIndexOf( '." );
String reducedName = name.substring( 0, dotIndex );
Value value = pc.getRecursiveProperty( reducedName ).getValue();
Iterator parentPropIter;
if ( value instanceof Component ) {
Component comp = (Component) value;
parentPropIter = comp.getPropertyIterator();
}
else if ( value instanceof ToOne ) {
ToOne toOne = (ToOne) value;
PersistentClass referencedPc = mappings.getClass( toOne.getReferencedEntityName() );
if ( toOne.getReferencedPropertyName() != null ) {
try {
parentPropIter = ( (Component) referencedPc.getRecursiveProperty( toOne.getReferencedPropertyName() ).getValue() ).getPropertyIterator();
} catch (ClassCastException e) {
throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
}
}
else {
try {
if ( referencedPc.getIdentifierMapper() == null ) {
parentPropIter = ( (Component) referencedPc.getIdentifierProperty().getValue() ).getPropertyIterator();
}
else {
parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator();
}
}
catch (ClassCastException e) {
throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
}
}
}
else {
throw new MappingException("dotted notation reference neither a component nor a many/one to one");
}
boolean hasFollowers = false;
List followers = new ArrayList();
while ( parentPropIter.hasNext() ) {
String currentPropertyName = ( (Property) parentPropIter.next() ).getName();
String currentName = reducedName + '." + currentPropertyName;
if (hasFollowers) {
followers.add( currentName );
}
if ( name.equals( currentName ) ) hasFollowers = true;
}
int index = propertyNames.size();
int followersSize = followers.size();
for (int loop = 0 ; loop < followersSize ; loop++) {
String follower = (String) followers.get(loop);
int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
propertyNames.add(index, name);
properties.add(index, propertyresult);
}
}
Set uniqueReturnProperty = new HashSet();
iterator = properties.iterator();
while ( iterator.hasNext() ) {
Element propertyresult = (Element) iterator.next();
String name = propertyresult.attributeValue("name");
if ( "class".equals(name) ) {
throw new MappingException(
"class is not a valid property name to use in a <return-property>, use <return-discriminator> instead"
);
}
//TODO: validate existing of property with the chosen name. (secondpass )
ArrayList allResultColumns = getResultColumns(propertyresult);
if ( allResultColumns.isEmpty() ) {
throw new MappingException(
"return-property for alias " + alias +
" must specify at least one column or return-column name"
);
}
if ( uniqueReturnProperty.contains( name ) ) {
throw new MappingException(
"duplicate return-property for property " + name +
" on alias " + alias
);
}
uniqueReturnProperty.add(name);
// the issue here is that for <return-join/> representing an entity collection,
// the collection element values (the property values of the associated entity)
// are represented as 'element.{propertyname}'. Thus the StringHelper.root()
// here puts everything under 'element' (which additionally has significant
// meaning). Probably what we need to do is to something like this instead:
// String root = StringHelper.root( name );
// String key = root; // by default
// if ( !root.equals( name ) ) {
// // we had a dot
// if ( !root.equals( alias ) {
// // the root does not apply to the specific alias
// if ( "elements".equals( root ) {
// // we specifically have a <return-join/> representing an entity collection
// // and this <return-property/> is one of that entity's properties
// key = name;
// }
// }
// }
// but I am not clear enough on the intended purpose of this code block, especially
// in relation to the "Reorder properties" code block above...
// String key = StringHelper.root( name );
String key = name;
ArrayList intermediateResults = (ArrayList) propertyresults.get( key );
if (intermediateResults == null) {
propertyresults.put( key, allResultColumns );
}
else {
intermediateResults.addAll( allResultColumns );
}
}
Iterator entries = propertyresults.entrySet().iterator();
while ( entries.hasNext() ) {
Map.Entry entry = (Map.Entry) entries.next();
if (entry.getValue() instanceof ArrayList) {
ArrayList list = (ArrayList) entry.getValue();
entry.setValue( list.toArray( new String[ list.size() ] ) );
}
}
return propertyresults.isEmpty() ? CollectionHelper.EMPTY_MAP : propertyresults;
|
private static org.hibernate.engine.query.sql.NativeSQLQueryRootReturn | bindReturn(org.dom4j.Element returnElem, Mappings mappings, int elementCount)
String alias = returnElem.attributeValue( "alias" );
if( StringHelper.isEmpty(alias)) {
alias = "alias_" + elementCount; // hack/workaround as sqlquery impl depend on having a key.
}
String entityName = HbmBinder.getEntityName(returnElem, mappings);
if(entityName==null) {
throw new MappingException( "<return alias='" + alias + "'> must specify either a class or entity-name");
}
LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
PersistentClass pc = mappings.getClass( entityName );
java.util.Map propertyResults = bindPropertyResults(alias, returnElem, pc, mappings );
return new NativeSQLQueryRootReturn(
alias,
entityName,
propertyResults,
lockMode
);
|
private static org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn | bindReturnJoin(org.dom4j.Element returnElem, Mappings mappings)
String alias = returnElem.attributeValue( "alias" );
String roleAttribute = returnElem.attributeValue( "property" );
LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
int dot = roleAttribute.lastIndexOf( '." );
if ( dot == -1 ) {
throw new MappingException(
"Role attribute for sql query return [alias=" + alias +
"] not formatted correctly {owningAlias.propertyName}"
);
}
String roleOwnerAlias = roleAttribute.substring( 0, dot );
String roleProperty = roleAttribute.substring( dot + 1 );
//FIXME: get the PersistentClass
java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
return new NativeSQLQueryJoinReturn(
alias,
roleOwnerAlias,
roleProperty,
propertyResults, // TODO: bindpropertyresults(alias, returnElem)
lockMode
);
|
protected static org.hibernate.engine.ResultSetMappingDefinition | buildResultSetMappingDefinition(org.dom4j.Element resultSetElem, java.lang.String path, Mappings mappings)Build a ResultSetMappingDefinition given a containing element for the "return-XXX" elements
String resultSetName = resultSetElem.attribute( "name" ).getValue();
if ( path != null ) {
resultSetName = path + '." + resultSetName;
}
ResultSetMappingDefinition definition = new ResultSetMappingDefinition( resultSetName );
int cnt = 0;
Iterator returns = resultSetElem.elementIterator();
while ( returns.hasNext() ) {
cnt++;
Element returnElem = (Element) returns.next();
String name = returnElem.getName();
if ( "return-scalar".equals( name ) ) {
String column = returnElem.attributeValue( "column" );
String typeFromXML = HbmBinder.getTypeFromXML( returnElem );
Type type = null;
if(typeFromXML!=null) {
type = TypeFactory.heuristicType( typeFromXML );
if ( type == null ) {
throw new MappingException( "could not determine type " + type );
}
}
definition.addQueryReturn( new NativeSQLQueryScalarReturn( column, type ) );
}
else if ( "return".equals( name ) ) {
definition.addQueryReturn( bindReturn( returnElem, mappings, cnt ) );
}
else if ( "return-join".equals( name ) ) {
definition.addQueryReturn( bindReturnJoin( returnElem, mappings ) );
}
else if ( "load-collection".equals( name ) ) {
definition.addQueryReturn( bindLoadCollection( returnElem, mappings ) );
}
}
return definition;
|
private static int | getIndexOfFirstMatchingProperty(java.util.List propertyNames, java.lang.String follower)
int propertySize = propertyNames.size();
for (int propIndex = 0 ; propIndex < propertySize ; propIndex++) {
if ( ( (String) propertyNames.get(propIndex) ).startsWith( follower ) ) {
return propIndex;
}
}
return -1;
|
private static org.hibernate.LockMode | getLockMode(java.lang.String lockMode)
if ( lockMode == null || "read".equals( lockMode ) ) {
return LockMode.READ;
}
else if ( "none".equals( lockMode ) ) {
return LockMode.NONE;
}
else if ( "upgrade".equals( lockMode ) ) {
return LockMode.UPGRADE;
}
else if ( "upgrade-nowait".equals( lockMode ) ) {
return LockMode.UPGRADE_NOWAIT;
}
else if ( "write".equals( lockMode ) ) {
return LockMode.WRITE;
}
else if ( "force".equals( lockMode ) ) {
return LockMode.FORCE;
}
else {
throw new MappingException( "unknown lockmode" );
}
|
private static java.util.ArrayList | getResultColumns(org.dom4j.Element propertyresult)
String column = unquote(propertyresult.attributeValue("column"));
ArrayList allResultColumns = new ArrayList();
if(column!=null) allResultColumns.add(column);
Iterator resultColumns = propertyresult.elementIterator("return-column");
while ( resultColumns.hasNext() ) {
Element element = (Element) resultColumns.next();
allResultColumns.add( unquote(element.attributeValue("name")) );
}
return allResultColumns;
|
private static java.lang.String | unquote(java.lang.String name)
if (name!=null && name.charAt(0)=='`") {
name=name.substring( 1, name.length()-1 );
}
return name;
|