/* * 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.hibernate.dep; import java.util.Iterator; import java.util.List; import org.compass.core.CompassSession; import org.compass.gps.CompassGpsException; import org.compass.gps.device.hibernate.HibernateGpsDeviceException; import org.compass.gps.device.support.parallel.AbstractParallelGpsDevice; import org.compass.gps.device.support.parallel.IndexEntitiesIndexer; import org.compass.gps.device.support.parallel.IndexEntity; /** * <p>An abstract hibernate device support. Aimed to provide the base operations * required by both Hiberante 2 and Hibernate 3 - the index operation. * * <p>Extends the abstract parallel gps device providing parallel index execution * support. * * @author kimchy */ public abstract class AbstractHibernateGpsDevice extends AbstractParallelGpsDevice { public static interface HibernateSessionWrapper { void open() throws HibernateGpsDeviceException; void close(); void closeOnError(); } protected int fetchCount = 200; public void setFetchCount(int fetchCount) { this.fetchCount = fetchCount; } protected IndexEntity[] doGetIndexEntities() throws CompassGpsException { return doGetHibernateEntitiesInfo(); } protected IndexEntitiesIndexer doGetIndexEntitiesIndexer() { return new HibernateIndexEntitiesIndexer(); } /** * Returns all the hibernate entity info. Called when the device starts up. * * @return Hibernate class informtion * @throws HibernateGpsDeviceException */ protected abstract HibernateEntityInfo[] doGetHibernateEntitiesInfo() throws HibernateGpsDeviceException; /** * Returns the data that maps to the given class info, paginated with from * and count. */ protected abstract List doGetObjects(HibernateEntityInfo info, int from, int count, HibernateSessionWrapper sessionWrapper) throws HibernateGpsDeviceException; protected abstract HibernateSessionWrapper doGetHibernateSessionWrapper(); private class HibernateIndexEntitiesIndexer implements IndexEntitiesIndexer { public void performIndex(CompassSession session, IndexEntity[] entities) { for (int i = 0; i < entities.length; i++) { HibernateEntityInfo entityInfo = (HibernateEntityInfo) entities[i]; int current = 0; while (true) { if (!isRunning()) { return; } HibernateSessionWrapper sessionWrapper = doGetHibernateSessionWrapper(); try { sessionWrapper.open(); final List values = doGetObjects(entityInfo, current, fetchCount, sessionWrapper); if (log.isDebugEnabled()) { log.debug(buildMessage("Indexing entity [" + entityInfo.getName() + "] range [" + current + "-" + (current + fetchCount) + "]")); } current += fetchCount; for (Iterator it = values.iterator(); it.hasNext();) { session.create(it.next()); } session.evictAll(); sessionWrapper.close(); if (values.size() < fetchCount) { break; } } catch (Exception e) { log.error(buildMessage("Failed to index the database"), e); sessionWrapper.closeOnError(); if (!(e instanceof HibernateGpsDeviceException)) { throw new HibernateGpsDeviceException(buildMessage("Failed to index the database"), e); } throw (HibernateGpsDeviceException) e; } } } } } }