/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat, Inc. and/or its affiliates or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.search.spi.internals;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.search.util.logging.impl.Log;
import org.hibernate.search.util.logging.impl.LoggerFactory;
/**
* Helper class which keeps track of all super classes and interfaces of the indexed entities.
*/
//FIXME make it immutable (builder pattern)
public class PolymorphicIndexHierarchy {
private static final Log log = LoggerFactory.make();
private Map<Class<?>, Set<Class<?>>> classToIndexedClass;
public PolymorphicIndexHierarchy() {
classToIndexedClass = new HashMap<Class<?>, Set<Class<?>>>();
}
public void addIndexedClass(Class<?> indexedClass) {
addClass( indexedClass, indexedClass );
Class<?> superClass = indexedClass.getSuperclass();
while ( superClass != null ) {
addClass( superClass, indexedClass );
superClass = superClass.getSuperclass();
}
for ( Class<?> clazz : indexedClass.getInterfaces() ) {
addClass( clazz, indexedClass );
}
}
private void addClass(Class<?> superclass, Class<?> indexedClass) {
Set<Class<?>> classesSet = classToIndexedClass.get( superclass );
if ( classesSet == null ) {
classesSet = new HashSet<Class<?>>();
classToIndexedClass.put( superclass, classesSet );
}
classesSet.add( indexedClass );
}
public Set<Class<?>> getIndexedClasses(Class<?>[] classes) {
Set<Class<?>> indexedClasses = new HashSet<Class<?>>();
for ( Class<?> clazz : classes ) {
Set<Class<?>> set = classToIndexedClass.get( clazz );
if ( set != null ) {
// at this point we don't have to care about including indexed subclasses of a indexed class
// MultiClassesQueryLoader will take care of this later and optimise the queries
indexedClasses.addAll( set );
}
}
if ( log.isTraceEnabled() ) {
log.tracef( "Targeted indexed classes for %s: %s", Arrays.toString( classes ), indexedClasses );
}
return indexedClasses;
}
}