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.hibernate.entities;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.Map;
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.hibernate.HibernateGpsDevice;
027: import org.compass.gps.device.hibernate.HibernateGpsDeviceException;
028: import org.compass.gps.spi.CompassGpsInterfaceDevice;
029: import org.hibernate.EntityMode;
030: import org.hibernate.SessionFactory;
031: import org.hibernate.metadata.ClassMetadata;
032: import org.hibernate.persister.entity.AbstractEntityPersister;
033:
034: /**
035: * A default implemenation that automatically locates entities to index based
036: * on Hibernate current mapped objects and mappings for the objects that exists
037: * with Compass.
038: *
039: * @author kimchy
040: */
041: public class DefaultHibernateEntitiesLocator implements
042: HibernateEntitiesLocator {
043:
044: protected Log log = LogFactory.getLog(getClass());
045:
046: public EntityInformation[] locate(SessionFactory sessionFactory,
047: HibernateGpsDevice device)
048: throws HibernateGpsDeviceException {
049:
050: CompassGpsInterfaceDevice gps = (CompassGpsInterfaceDevice) device
051: .getGps();
052:
053: ArrayList<EntityInformation> entitiesList = new ArrayList<EntityInformation>();
054:
055: Map allClassMetaData = sessionFactory.getAllClassMetadata();
056: for (Iterator it = allClassMetaData.keySet().iterator(); it
057: .hasNext();) {
058: String entityname = (String) it.next();
059: if (!gps.hasMappingForEntityForIndex((entityname))) {
060: if (log.isDebugEnabled()) {
061: log
062: .debug("Entity ["
063: + entityname
064: + "] does not have compass mapping, filtering it out");
065: }
066: continue;
067: }
068:
069: ClassMetadata classMetadata = (ClassMetadata) allClassMetaData
070: .get(entityname);
071: if (shouldFilter(entityname, classMetadata,
072: allClassMetaData, device)) {
073: continue;
074: }
075: Class clazz = classMetadata.getMappedClass(EntityMode.POJO);
076: ResourceMapping resourceMapping = gps
077: .getMappingForEntityForIndex(entityname);
078: EntityInformation entityInformation = new EntityInformation(
079: clazz, entityname, resourceMapping
080: .getSubIndexHash().getSubIndexes());
081: entitiesList.add(entityInformation);
082: if (log.isDebugEnabled()) {
083: log
084: .debug("Entity [" + entityname
085: + "] will be indexed");
086: }
087: }
088: return (EntityInformation[]) entitiesList
089: .toArray(new EntityInformation[entitiesList.size()]);
090: }
091:
092: /**
093: * Returns <code>true</code> if the entity name needs to be filtered.
094: *
095: * <p>Implementation filteres out inherited hibernate mappings, since the select query
096: * for the base class will cover any inherited classes as well.
097: *
098: * <p>Note, that this method is called after it has been verified that the class has
099: * Compass mappings (either directly, or indirectly by an interface or a super class).
100: *
101: * @param entityname The name of the entity
102: * @param classMetadata The Hibernate class meta data.
103: * @param device The Hibernate Gps device
104: * @return <code>true</code> if the entity should be filtered out, <code>false</code> if not.
105: */
106: protected boolean shouldFilter(String entityname,
107: ClassMetadata classMetadata, Map allClassMetaData,
108: HibernateGpsDevice device) {
109: Class clazz = classMetadata.getMappedClass(EntityMode.POJO);
110: // if it is inherited, do not add it to the classes to index, since the "from [entity]"
111: // query for the base class will return results for this class as well
112: if (classMetadata.isInherited()) {
113: String super ClassEntityName = ((AbstractEntityPersister) classMetadata)
114: .getMappedSuperclass();
115: ClassMetadata super ClassMetadata = (ClassMetadata) allClassMetaData
116: .get(super ClassEntityName);
117: Class super Class = super ClassMetadata
118: .getMappedClass(EntityMode.POJO);
119: // only filter out classes that their super class has compass mappings
120: if (super Class != null
121: && ((CompassGpsInterfaceDevice) device.getGps())
122: .hasMappingForEntityForIndex(super Class)) {
123: if (log.isDebugEnabled()) {
124: log
125: .debug("Entity ["
126: + entityname
127: + "] is inherited and super class ["
128: + super Class
129: + "] has compass mapping, filtering it out");
130: }
131: return true;
132: }
133: }
134: return false;
135: }
136: }
|