Skip to content

Commit

Permalink
HHH-2394 Implemented @SqlFragmentAlias
Browse files Browse the repository at this point in the history
  • Loading branch information
rworsnop authored and stliu committed Jul 12, 2012
1 parent cfe7db0 commit 05dcc20
Show file tree
Hide file tree
Showing 17 changed files with 184 additions and 139 deletions.
Expand Up @@ -42,6 +42,7 @@
@Retention(RUNTIME)
public @interface Filter {
String name();
String table() default "";
String condition() default "";
boolean deduceAliasInjectionPoints() default true;
SqlFragmentAlias[] aliases() default {};
}
Expand Up @@ -33,11 +33,13 @@
* Add filters to a join table collection
*
* @author Emmanuel Bernard
* @author Rob Worsnop
*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FilterJoinTable {
String name();

String condition() default "";
boolean deduceAliasInjectionPoints() default true;
SqlFragmentAlias[] aliases() default {};
}
Expand Up @@ -21,25 +21,22 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.internal;
package org.hibernate.annotations;

import org.hibernate.engine.spi.SessionFactoryImplementor;
/**
*
* @author Rob Worsnop
*/
public class QualifiedTableNameFilterConfiguration extends FilterConfiguration {

private final String tableName;

public QualifiedTableNameFilterConfiguration(String name, String tableName, String condition) {
super(name, condition);
this.tableName = tableName;
}
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Override
public String getQualifiedTableName(SessionFactoryImplementor factory) {
return tableName;
}

}
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Describe aliases for filters
*
* @author Rob Worsnop
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface SqlFragmentAlias {
String alias();
String table();
}
Expand Up @@ -1205,13 +1205,13 @@ private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder
Filters filtersAnn = annotatedElement.getAnnotation( Filters.class );
if ( filtersAnn != null ) {
for ( Filter filter : filtersAnn.value() ) {
entityBinder.addFilter( filter.name(), filter.condition() );
entityBinder.addFilter(filter);
}
}

Filter filterAnn = annotatedElement.getAnnotation( Filter.class );
if ( filterAnn != null ) {
entityBinder.addFilter( filterAnn.name(), filterAnn.condition() );
entityBinder.addFilter(filterAnn);
}
}

Expand Down
22 changes: 18 additions & 4 deletions hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
Expand Up @@ -2614,7 +2614,6 @@ private static void bindManyToManySubelements(
while ( filters.hasNext() ) {
final Element filterElement = ( Element ) filters.next();
final String name = filterElement.attributeValue( "name" );
final String tableName = filterElement.attributeValue("table");
String condition = filterElement.getTextTrim();
if ( StringHelper.isEmpty(condition) ) condition = filterElement.attributeValue( "condition" );
if ( StringHelper.isEmpty(condition) ) {
Expand All @@ -2623,10 +2622,18 @@ private static void bindManyToManySubelements(
if ( condition==null) {
throw new MappingException("no filter condition found for filter: " + name);
}
Iterator aliasesIterator = filterElement.elementIterator("aliases");
java.util.Map<String, String> aliasTables = new HashMap<String, String>();
while (aliasesIterator.hasNext()){
Element alias = (Element) aliasesIterator.next();
aliasTables.put(alias.attributeValue("alias"), alias.attributeValue("table"));
}
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Applying many-to-many filter [%s] as [%s] to role [%s]", name, condition, collection.getRole() );
}
collection.addManyToManyFilter( name, tableName, condition );
String autoAliasInjectionText = filterElement.attributeValue("autoAliasInjection");
boolean autoAliasInjection = StringHelper.isEmpty(autoAliasInjectionText) ? true : Boolean.parseBoolean(autoAliasInjectionText);
collection.addManyToManyFilter(name, condition, autoAliasInjection, aliasTables);
}
}

Expand Down Expand Up @@ -3015,7 +3022,6 @@ private static void parseFilterDef(Element element, Mappings mappings) {

private static void parseFilter(Element filterElement, Filterable filterable, Mappings model) {
final String name = filterElement.attributeValue( "name" );
final String tableName = filterElement.attributeValue("table");
String condition = filterElement.getTextTrim();
if ( StringHelper.isEmpty(condition) ) {
condition = filterElement.attributeValue( "condition" );
Expand All @@ -3032,8 +3038,16 @@ private static void parseFilter(Element filterElement, Filterable filterable, Ma
if ( condition==null) {
throw new MappingException("no filter condition found for filter: " + name);
}
Iterator aliasesIterator = filterElement.elementIterator("aliases");
java.util.Map<String, String> aliasTables = new HashMap<String, String>();
while (aliasesIterator.hasNext()){
Element alias = (Element) aliasesIterator.next();
aliasTables.put(alias.attributeValue("alias"), alias.attributeValue("table"));
}
LOG.debugf( "Applying filter [%s] as [%s]", name, condition );
filterable.addFilter( name, tableName, condition );
String autoAliasInjectionText = filterElement.attributeValue("autoAliasInjection");
boolean autoAliasInjection = StringHelper.isEmpty(autoAliasInjectionText) ? true : Boolean.parseBoolean(autoAliasInjectionText);
filterable.addFilter(name, condition, autoAliasInjection, aliasTables);
}

private static void parseFetchProfile(Element element, Mappings mappings, String containingEntityName) {
Expand Down
Expand Up @@ -71,6 +71,7 @@
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import org.hibernate.annotations.SqlFragmentAlias;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.WhereJoinTable;
import org.hibernate.annotations.common.AssertionFailure;
Expand Down Expand Up @@ -810,28 +811,33 @@ private void bindFilters(boolean hasAssociationTable) {
//if ( StringHelper.isNotEmpty( where ) ) collection.setWhere( where );
if ( simpleFilter != null ) {
if ( hasAssociationTable ) {
collection.addManyToManyFilter( simpleFilter.name(), getTableName(simpleFilter), getCondition( simpleFilter ) );
collection.addManyToManyFilter(simpleFilter.name(), getCondition(simpleFilter), simpleFilter.deduceAliasInjectionPoints(),
toTableAliasMap(simpleFilter.aliases()));
}
else {
collection.addFilter( simpleFilter.name(), getTableName(simpleFilter), getCondition( simpleFilter ) );
collection.addFilter(simpleFilter.name(), getCondition(simpleFilter), simpleFilter.deduceAliasInjectionPoints(),
toTableAliasMap(simpleFilter.aliases()));
}
}
Filters filters = property.getAnnotation( Filters.class );
if ( filters != null ) {
for (Filter filter : filters.value()) {
if ( hasAssociationTable ) {
collection.addManyToManyFilter( filter.name(), getTableName(simpleFilter), getCondition( filter ) );
collection.addManyToManyFilter( filter.name(), getCondition(filter), filter.deduceAliasInjectionPoints(),
toTableAliasMap(filter.aliases()));
}
else {
collection.addFilter( filter.name(), getTableName(filter), getCondition( filter ) );
collection.addFilter(filter.name(), getCondition(filter), filter.deduceAliasInjectionPoints(),
toTableAliasMap(filter.aliases()));
}
}
}
FilterJoinTable simpleFilterJoinTable = property.getAnnotation( FilterJoinTable.class );
if ( simpleFilterJoinTable != null ) {
if ( hasAssociationTable ) {
collection.addFilter( simpleFilterJoinTable.name(), null, getCondition( simpleFilterJoinTable ) );
}
collection.addFilter(simpleFilterJoinTable.name(), simpleFilterJoinTable.condition(),
simpleFilterJoinTable.deduceAliasInjectionPoints(), toTableAliasMap(simpleFilterJoinTable.aliases()));
}
else {
throw new AnnotationException(
"Illegal use of @FilterJoinTable on an association without join table:"
Expand All @@ -843,7 +849,8 @@ private void bindFilters(boolean hasAssociationTable) {
if ( filterJoinTables != null ) {
for (FilterJoinTable filter : filterJoinTables.value()) {
if ( hasAssociationTable ) {
collection.addFilter( filter.name(), null, getCondition( filter ) );
collection.addFilter(filter.name(), filter.condition(),
filter.deduceAliasInjectionPoints(), toTableAliasMap(filter.aliases()));
}
else {
throw new AnnotationException(
Expand Down Expand Up @@ -888,18 +895,21 @@ private void bindFilters(boolean hasAssociationTable) {
// );
// }
}

private static Map<String,String> toTableAliasMap(SqlFragmentAlias[] aliases){
Map<String,String> ret = new HashMap<String,String>();
for (int i = 0; i < aliases.length; i++){
ret.put(aliases[i].alias(), aliases[i].table());
}
return ret;
}

private String getCondition(FilterJoinTable filter) {
//set filtering
String name = filter.name();
String cond = filter.condition();
return getCondition( cond, name );
}

private String getTableName(Filter filter){
return BinderHelper.isEmptyAnnotationValue(filter.table())? null : filter.table();
}

private String getCondition(Filter filter) {
//set filtering
String name = filter.name();
Expand Down
Expand Up @@ -23,6 +23,7 @@
*/
package org.hibernate.cfg.annotations;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
Expand All @@ -47,6 +48,7 @@
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.NaturalIdCache;
Expand All @@ -62,6 +64,7 @@
import org.hibernate.annotations.SQLInsert;
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;
import org.hibernate.annotations.SqlFragmentAlias;
import org.hibernate.annotations.Subselect;
import org.hibernate.annotations.Synchronize;
import org.hibernate.annotations.Tables;
Expand Down Expand Up @@ -96,6 +99,7 @@
import org.hibernate.mapping.TableOwner;
import org.hibernate.mapping.Value;


/**
* Stateful holder and processor for binding Entity information
*
Expand Down Expand Up @@ -127,7 +131,7 @@ public class EntityBinder {
private String cacheConcurrentStrategy;
private String cacheRegion;
private String naturalIdCacheRegion;
private java.util.Map<String, String> filters = new HashMap<String, String>();
private List<Filter> filters = new ArrayList<Filter>();
private InheritanceState inheritanceState;
private boolean ignoreIdAnnotations;
private boolean cacheLazyProperty;
Expand Down Expand Up @@ -371,9 +375,9 @@ public void bindEntity() {
persistentClass.addTuplizer( mode, tuplizer.impl().getName() );
}

for ( Map.Entry<String, String> filter : filters.entrySet() ) {
String filterName = filter.getKey();
String cond = filter.getValue();
for ( Filter filter : filters ) {
String filterName = filter.name();
String cond = filter.condition();
if ( BinderHelper.isEmptyAnnotationValue( cond ) ) {
FilterDefinition definition = mappings.getFilterDefinition( filterName );
cond = definition == null ? null : definition.getDefaultFilterCondition();
Expand All @@ -383,7 +387,7 @@ public void bindEntity() {
);
}
}
persistentClass.addFilter( filterName, null, cond );
persistentClass.addFilter(filterName, cond, filter.deduceAliasInjectionPoints(), toTableAliasMap(filter.aliases()));
}
LOG.debugf( "Import with entity name %s", name );
try {
Expand All @@ -397,6 +401,14 @@ public void bindEntity() {
throw new AnnotationException( "Use of the same entity name twice: " + name, me );
}
}

private static Map<String,String> toTableAliasMap(SqlFragmentAlias[] aliases){
Map<String,String> ret = new HashMap<String,String>();
for (int i = 0; i < aliases.length; i++){
ret.put(aliases[i].alias(), aliases[i].table());
}
return ret;
}

public void bindDiscriminatorValue() {
if ( StringHelper.isEmpty( discriminatorValue ) ) {
Expand Down Expand Up @@ -884,8 +896,8 @@ public static String getCacheConcurrencyStrategy(CacheConcurrencyStrategy strate
return accessType == null ? null : accessType.getExternalName();
}

public void addFilter(String name, String condition) {
filters.put( name, condition );
public void addFilter(Filter filter) {
filters.add(filter);
}

public void setInheritanceState(InheritanceState inheritanceState) {
Expand Down
Expand Up @@ -23,26 +23,55 @@
*/
package org.hibernate.internal;

import java.util.Collections;
import java.util.Map;

import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.PersistentClass;

/**
*
* @author Rob Worsnop
*/
public abstract class FilterConfiguration {
public class FilterConfiguration {
private final String name;
private final String condition;
private final boolean autoAliasInjection;
private final Map<String, String> aliasTableMap;
private final PersistentClass persistentClass;

protected FilterConfiguration(String name, String condition) {
public FilterConfiguration(String name, String condition, boolean autoAliasInjection, Map<String, String> aliasTableMap, PersistentClass persistentClass) {
this.name = name;
this.condition = condition;
this.autoAliasInjection = autoAliasInjection;
this.aliasTableMap = aliasTableMap;
this.persistentClass = persistentClass;
}

public String getName() {
return name;
}

public String getCondition() {
return condition;
}
public abstract String getQualifiedTableName(SessionFactoryImplementor factory);


public boolean useAutoAliasInjection() {
return autoAliasInjection;
}

public Map<String, String> getAliasTableMap(SessionFactoryImplementor factory) {
if (!CollectionHelper.isEmpty(aliasTableMap)){
return aliasTableMap;
} else if (persistentClass != null){
String table = persistentClass.getTable().getQualifiedName(factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName());
return Collections.singletonMap(null, table);
} else{
return Collections.emptyMap();
}

}
}

0 comments on commit 05dcc20

Please sign in to comment.