001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.gps.device.jpa.entities;
018:
019: import java.util.ArrayList;
020: import java.util.Map;
021: import javax.persistence.EntityManagerFactory;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.compass.core.mapping.ResourceMapping;
026: import org.compass.gps.device.jpa.JpaGpsDevice;
027: import org.compass.gps.device.jpa.JpaGpsDeviceException;
028: import org.compass.gps.spi.CompassGpsInterfaceDevice;
029: import org.eclipse.persistence.descriptors.ClassDescriptor;
030: import org.eclipse.persistence.descriptors.InheritancePolicy;
031: import org.eclipse.persistence.jpa.JpaEntityManager;
032: import org.eclipse.persistence.sessions.Session;
033:
034: /**
035: * A specilized version that works with Eclipse Persistence. This class should be used instead of
036: * {@link DefaultJpaEntitiesLocator} since it works with both xml files and annotatios.
037: *
038: * @author kimchy
039: */
040: public class EclipseLinkJpaEntitiesLocator implements
041: JpaEntitiesLocator {
042:
043: protected Log log = LogFactory.getLog(getClass());
044:
045: public EntityInformation[] locate(
046: EntityManagerFactory entityManagerFactory,
047: JpaGpsDevice device) throws JpaGpsDeviceException {
048:
049: CompassGpsInterfaceDevice gps = (CompassGpsInterfaceDevice) device
050: .getGps();
051:
052: JpaEntityManager entityManager = (JpaEntityManager) entityManagerFactory
053: .createEntityManager();
054: Session session = entityManager.getServerSession();
055: entityManager.close();
056:
057: ArrayList<EntityInformation> entitiesList = new ArrayList<EntityInformation>();
058:
059: Map descriptors = session.getDescriptors();
060: for (Object o : descriptors.values()) {
061: ClassDescriptor classDescriptor = (ClassDescriptor) o;
062: String entityname = classDescriptor.getJavaClassName();
063: if (!gps.hasMappingForEntityForIndex((entityname))) {
064: if (log.isDebugEnabled()) {
065: log
066: .debug("Entity ["
067: + entityname
068: + "] does not have compass mapping, filtering it out");
069: }
070: continue;
071: }
072:
073: if (shouldFilter(entityname, classDescriptor, device)) {
074: continue;
075: }
076: Class<?> clazz = classDescriptor.getJavaClass();
077: ResourceMapping resourceMapping = gps
078: .getMappingForEntityForIndex(entityname);
079: EntityInformation entityInformation = new EntityInformation(
080: clazz, classDescriptor.getAlias(), resourceMapping
081: .getSubIndexHash().getSubIndexes());
082: entitiesList.add(entityInformation);
083: if (log.isDebugEnabled()) {
084: log
085: .debug("Entity [" + entityname
086: + "] will be indexed");
087: }
088: }
089:
090: return entitiesList.toArray(new EntityInformation[entitiesList
091: .size()]);
092: }
093:
094: /**
095: * Returns <code>true</code> if the entity name needs to be filtered.
096: *
097: * <p>Implementation filteres out inherited Eclipse mappings, since the select query
098: * for the base class will cover any inherited classes as well.
099: *
100: * <p>Note, that this method is called after it has been verified that the class has
101: * Compass mappings (either directly, or indirectly by an interface or a super class).
102: *
103: * @param entityname The name of the entity
104: * @param classDescriptor The Eclipse class descriptor
105: * @param device The Jpa Gps device
106: * @return <code>true</code> if the entity should be filtered out, <code>false</code> if not.
107: */
108: protected boolean shouldFilter(String entityname,
109: ClassDescriptor classDescriptor, JpaGpsDevice device) {
110: if (!classDescriptor.hasInheritance()) {
111: return false;
112: }
113: InheritancePolicy inheritancePolicy = classDescriptor
114: .getInheritancePolicy();
115: if (inheritancePolicy == null
116: || inheritancePolicy.getParentClass() == null) {
117: return false;
118: }
119: Class super Class = inheritancePolicy.getParentClass();
120: // only filter out classes that their super class has compass mappings
121: if (super Class != null
122: && ((CompassGpsInterfaceDevice) device.getGps())
123: .hasMappingForEntityForIndex(super Class)) {
124: if (log.isDebugEnabled()) {
125: log.debug("Entity [" + entityname
126: + "] is inherited and super class ["
127: + super Class
128: + "] has compass mapping, filtering it out");
129: }
130: return true;
131: }
132: return false;
133: }
134: }
|