com.github.shyiko.rook.target.hibernate4.fulltextindex.SynchronizationContext Maven / Gradle / Ivy
/*
* Copyright 2013 Stanley Shyiko
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.shyiko.rook.target.hibernate4.fulltextindex;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
import org.hibernate.property.Getter;
import org.hibernate.search.annotations.ContainedIn;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.indexes.interceptor.DefaultEntityInterceptor;
import org.hibernate.search.indexes.interceptor.EntityIndexingInterceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
/**
* @author Stanley Shyiko
*/
public class SynchronizationContext {
private final String schema;
private final SessionFactory sessionFactory;
private final Map directivesByTable = new HashMap();
private final Map directivesByEntityClass = new HashMap();
public SynchronizationContext(Configuration configuration, SessionFactory sessionFactory) {
this.schema = ((SessionFactoryImplementor) sessionFactory).getJdbcServices().
getExtractedMetaDataSupport().getConnectionCatalogName().toLowerCase();
this.sessionFactory = sessionFactory;
loadIndexingDirectives(configuration);
}
public SessionFactoryImplementor getSessionFactory() {
return (SessionFactoryImplementor) sessionFactory;
}
public Collection getIndexingDirectives(String table) {
IndexingDirective indexingTarget = directivesByTable.get(table.toLowerCase());
return indexingTarget == null ? Collections.emptyList() : Arrays.asList(indexingTarget);
}
public IndexingDirective getIndexingDirective(Class entityClass) {
return directivesByEntityClass.get(entityClass);
}
@SuppressWarnings("unchecked")
private void loadIndexingDirectives(Configuration configuration) {
Map directivesByEntityNameMap = new HashMap();
Collection allContainedInProperties = new ArrayList();
for (Iterator classIterator = configuration.getClassMappings(); classIterator.hasNext(); ) {
PersistentClass persistentClass = classIterator.next();
boolean suppressSelfIndexing = true;
Class mappedClass = persistentClass.getMappedClass();
Indexed indexed = (Indexed) mappedClass.getAnnotation(Indexed.class);
EntityIndexingInterceptor indexingInterceptor = null;
if (indexed != null) {
suppressSelfIndexing = false;
Class extends EntityIndexingInterceptor> interceptorClass = indexed.interceptor();
if (interceptorClass != DefaultEntityInterceptor.class) {
try {
indexingInterceptor = interceptorClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Failed to instantiate " + interceptorClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to instantiate " + interceptorClass, e);
}
}
}
Collection containedInProperties = extractAnnotatedProperties(persistentClass, ContainedIn.class);
if (suppressSelfIndexing && containedInProperties.isEmpty()) {
continue;
}
allContainedInProperties.addAll(containedInProperties);
PrimaryKey primaryKey = new PrimaryKey(persistentClass);
Collection containers = new ArrayList();
for (Property property : containedInProperties) {
containers.add(new Reference(property.getGetter(mappedClass)));
}
IndexingDirective indexingDirective = new IndexingDirective(primaryKey, suppressSelfIndexing,
indexingInterceptor, containers);
Table table = persistentClass.getTable();
directivesByTable.put(schema + "." + table.getName().toLowerCase(), indexingDirective);
directivesByEntityClass.put(mappedClass, indexingDirective);
directivesByEntityNameMap.put(persistentClass.getEntityName(), indexingDirective);
}
loadIndexingDirectivesForJoinTables(allContainedInProperties, directivesByEntityNameMap);
}
@SuppressWarnings("unchecked")
private Collection extractAnnotatedProperties(PersistentClass persistentClass,
Class extends Annotation> annotation) {
Class mappedClass = persistentClass.getMappedClass();
Collection properties = new ArrayList();
for (Iterator propertyIterator = persistentClass.getPropertyIterator();
propertyIterator.hasNext(); ) {
Property property = propertyIterator.next();
Getter getter = property.getGetter(mappedClass);
if (getter == null) {
continue;
}
Member mappedClassMember = getter.getMember();
boolean isRequestedAnnotationPresent = mappedClassMember instanceof AccessibleObject &&
((AccessibleObject) mappedClassMember).isAnnotationPresent(annotation);
if (isRequestedAnnotationPresent) {
properties.add(property);
}
}
return properties;
}
private void loadIndexingDirectivesForJoinTables(Collection allContainedInProperties,
Map directivesByEntityNameMap) {
for (Property property : allContainedInProperties) {
Value value = property.getValue();
if (value instanceof org.hibernate.mapping.Collection) {
org.hibernate.mapping.Collection collection = (org.hibernate.mapping.Collection) value;
Table collectionTable = collection.getCollectionTable();
String tableName = schema + "." + collectionTable.getName().toLowerCase();
if (directivesByTable.containsKey(tableName)) {
continue;
}
PrimaryKey primaryKey = resolveForeignPrimaryKey(collection, directivesByEntityNameMap);
if (primaryKey == null) {
continue;
}
IndexingDirective containerIndexingDirective = directivesByEntityClass.get(primaryKey.getEntityClass());
directivesByTable.put(tableName,
new IndexingDirective(primaryKey, containerIndexingDirective.isSuppressSelfIndexing(),
containerIndexingDirective.getEntityIndexingInterceptor(),
containerIndexingDirective.getContainerReferences()));
}
}
}
@SuppressWarnings("unchecked")
private PrimaryKey resolveForeignPrimaryKey(org.hibernate.mapping.Collection collection,
Map directivesByEntityNameMap) {
Table collectionTable = collection.getCollectionTable();
ToOne element = (ToOne) collection.getElement();
IndexingDirective indexingDirective = directivesByEntityNameMap.get(element.getReferencedEntityName());
if (indexingDirective == null) {
return null;
}
Collection targetPrimaryKeyColumnNames = new HashSet();
for (Iterator columnIterator = element.getColumnIterator(); columnIterator.hasNext(); ) {
Column column = columnIterator.next();
targetPrimaryKeyColumnNames.add(column.getName());
}
Map columnIndexByNameMap = new HashMap();
int index = 0;
for (Iterator columnIterator = collectionTable.getColumnIterator(); columnIterator.hasNext(); ) {
Column column = columnIterator.next();
if (targetPrimaryKeyColumnNames.contains(column.getName())) {
columnIndexByNameMap.put(column.getName(), index);
}
index++;
}
return new PrimaryKey(indexingDirective.getPrimaryKey(), columnIndexByNameMap);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy