All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.shyiko.rook.target.hibernate4.fulltextindex.SynchronizationContext Maven / Gradle / Ivy

There is a newer version: 0.1.3
Show newest version
/*
 * 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 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 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