org.compass.gps.device.jpa.entities.DefaultJpaEntitiesLocator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compass Show documentation
Show all versions of compass Show documentation
Compass Search Engine Framework
/*
* 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