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

org.compass.gps.device.jpa.entities.DefaultJpaEntitiesLocator Maven / Gradle / Ivy

There is a newer version: 2.2.2-ldh
Show newest version
/*
 * Copyright 2004-2009 the original author or authors.
 *
 * 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 org.compass.gps.device.jpa.entities;

import java.util.ArrayList;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Inheritance;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.compass.core.mapping.ResourceMapping;
import org.compass.core.mapping.osem.ClassMapping;
import org.compass.core.spi.InternalCompass;
import org.compass.core.util.ClassUtils;
import org.compass.core.util.StringUtils;
import org.compass.gps.device.jpa.JpaGpsDevice;
import org.compass.gps.device.jpa.JpaGpsDeviceException;
import org.compass.gps.spi.CompassGpsInterfaceDevice;

/**
 * The default {@link JpaEntitiesLocator} implementations. Should work with all different
 * JPA implementations, with the only caveat that it is based on Annotations only. So, any
 * applications that uses a combination of both annotations and xml definitions (or any other
 * type), will probably loose some information during the index process (providing that the
 * xml definitions are ones that collide with Compass definitions). Please check if a
 * JPA actual implementation is provided with compass in such cases, and if not, writing
 * one should be simple (and should probably use the actual JPA implementation APIs).
 *
 * @author kimchy
 */
public class DefaultJpaEntitiesLocator implements JpaEntitiesLocator {

    protected Log log = LogFactory.getLog(getClass());

    public EntityInformation[] locate(EntityManagerFactory entityManagerFactory, JpaGpsDevice device) throws JpaGpsDeviceException {
        CompassGpsInterfaceDevice gps = (CompassGpsInterfaceDevice) device.getGps();
        final ResourceMapping[] resourceMappings =
                ((InternalCompass) gps.getIndexCompass()).getMapping().getRootMappings();

        ArrayList entitiesList = new ArrayList(resourceMappings.length);
        for (ResourceMapping resourceMapping : resourceMappings) {
            if (!(resourceMapping instanceof ClassMapping)) {
                continue;
            }
            ClassMapping classMapping = (ClassMapping) resourceMapping;
            if (!classMapping.isRoot()) {
                continue;
            }
            EntityInformation entityInformation = createEntityInformation(classMapping.getClazz(), resourceMapping);
            if (entityInformation == null) {
                continue;
            }
            if (shouldFilter(entityInformation, device)) {
                continue;
            }
            entitiesList.add(entityInformation);
        }
        return entitiesList.toArray(new EntityInformation[entitiesList.size()]);
    }

    /**
     * Creates the {@link EntityInformation} for a given class. If return null
     * the class will be filtered out.
     * 

* Implementation filters out classes that do not have the {@link Entity} annotation (i.e. * return null for such a case). * * @param clazz The class to create the {@link EntityInformation} for * @param resourceMapping The Compass resource mapping (used for sub indexes extraction) * @return The entity information, or null to filter it out * @throws JpaGpsDeviceException */ protected EntityInformation createEntityInformation(Class clazz, ResourceMapping resourceMapping) throws JpaGpsDeviceException { Entity entity = clazz.getAnnotation(Entity.class); if (entity == null) { return null; } String name; if (StringUtils.hasLength(entity.name())) { name = entity.name(); } else { name = ClassUtils.getShortName(clazz); } return new EntityInformation(clazz, name, resourceMapping.getSubIndexHash().getSubIndexes()); } /** * Return true if the entity should be filtered out from the index operation. *

* Implementation filters out classes that one of the super classes has the {@link Inheritance} * annotation and the super class has compass mappings. * * @param entityInformation The entity information to check if it should be filtered * @param device The Jpa gps device * @return true if the entity should be filtered from the index process */ protected boolean shouldFilter(EntityInformation entityInformation, JpaGpsDevice device) { Class clazz = entityInformation.getEntityClass().getSuperclass(); while (true) { if (clazz == null || clazz.equals(Object.class)) { break; } if (clazz.isAnnotationPresent(Inheritance.class) && ((CompassGpsInterfaceDevice) device.getGps()).hasMappingForEntityForIndex(clazz)) { if (log.isDebugEnabled()) { log.debug("Entity [" + entityInformation.getName() + "] is inherited and super class [" + clazz + "] has compass mapping, filtering it out"); } return true; } clazz = clazz.getSuperclass(); } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy