/* * 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; import java.util.HashSet; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.compass.core.CompassCallbackWithoutResult; import org.compass.core.CompassException; import org.compass.core.CompassSession; import org.compass.gps.CompassGps; import org.compass.gps.CompassGpsDevice; import org.compass.gps.CompassGpsException; import org.compass.gps.IndexPlan; import org.compass.gps.MirrorDataChangesGpsDevice; import org.compass.gps.spi.CompassGpsInterfaceDevice; /** * A general abstract device which can be used by all types of devices. * <p/> * Provides support for device name, state management * {@link AbstractGpsDevice#isRunning()}, as well as general helper methods. * * @author kimchy */ public abstract class AbstractGpsDevice implements CompassGpsDevice { protected Log log = LogFactory.getLog(getClass()); private String name; protected CompassGpsInterfaceDevice compassGps; private volatile boolean started = false; private boolean internalMirrorDataChanges = false; private String[] filteredEntitiesForIndex; private Set filteredEntitiesLookupForIndex; public String getName() { return name; } public void setName(String name) { this.name = name; } public CompassGps getGps() { return compassGps; } public void injectGps(CompassGps compassGps) { this.compassGps = (CompassGpsInterfaceDevice) compassGps; } public void setFilteredEntitiesForIndex(String[] filteredEntitiesForIndex) { this.filteredEntitiesForIndex = filteredEntitiesForIndex; } public String buildMessage(String message) { return "{" + name + "}: " + message; } public boolean isFilteredForIndex(String entity) { return (filteredEntitiesLookupForIndex != null && filteredEntitiesLookupForIndex.contains(entity)); } public synchronized void index(final IndexPlan indexPlan) throws CompassGpsException { if (!isRunning()) { throw new IllegalStateException( buildMessage("must be running in order to perform the index operation")); } compassGps.executeForIndex(new CompassCallbackWithoutResult() { protected void doInCompassWithoutResult(CompassSession session) throws CompassException { doIndex(session, indexPlan); session.flush(); } }); } /** * Derived devices must implement the method to perform the actual indexing * operation. */ protected abstract void doIndex(CompassSession session, IndexPlan indexPlan) throws CompassGpsException; public synchronized void start() throws CompassGpsException { if (name == null) { throw new IllegalArgumentException("Must set the name for the device"); } if (compassGps == null) { throw new IllegalArgumentException( buildMessage("Must set the compassGps for the device, or add it to an active CompassGps instance")); } if (!started) { if (this instanceof MirrorDataChangesGpsDevice) { internalMirrorDataChanges = ((MirrorDataChangesGpsDevice) this).isMirrorDataChanges(); } // build the filtered enteties map if (filteredEntitiesForIndex != null) { filteredEntitiesLookupForIndex = new HashSet(); for (int i = 0; i < filteredEntitiesForIndex.length; i++) { filteredEntitiesLookupForIndex.add(filteredEntitiesForIndex[i]); } } doStart(); started = true; } } /** * Derived devices can implement it in case of start event notification. * * @throws CompassGpsException */ protected void doStart() throws CompassGpsException { } public synchronized void stop() throws CompassGpsException { if (started) { doStop(); started = false; } } /** * Derived devices can implement it in case of stop event notification. * * @throws CompassGpsException */ protected void doStop() throws CompassGpsException { } /** * A no op. Subclasses should overide only if needed. */ public void refresh() throws CompassGpsException { } public boolean isRunning() { return started; } public boolean isPerformingIndexOperation() { return compassGps.isPerformingIndexOperation(); } public boolean shouldMirrorDataChanges() { if (!internalMirrorDataChanges) { return false; } return isRunning(); } }