/*
* 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.impl;
import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.compass.core.Compass;
import org.compass.core.mapping.Cascade;
import org.compass.core.mapping.ResourceMapping;
import org.compass.core.spi.InternalCompass;
import org.compass.core.util.ClassUtils;
import org.compass.gps.CompassGpsDevice;
import org.compass.gps.CompassGpsException;
import org.compass.gps.DefaultIndexPlan;
import org.compass.gps.IndexPlan;
import org.compass.gps.spi.CompassGpsInterfaceDevice;
/**
* A simple base class for {@link org.compass.gps.CompassGps}
* implementations.
*
* @author kimchy
*/
public abstract class AbstractCompassGps implements CompassGpsInterfaceDevice {
protected Log log = LogFactory.getLog(getClass());
protected HashMap<String, CompassGpsDevice> devices = new HashMap<String, CompassGpsDevice>();
private volatile boolean started = false;
private volatile boolean performingIndexOperation = false;
public void addGpsDevice(CompassGpsDevice gpsDevice) {
checkDeviceValidity(gpsDevice);
gpsDevice.injectGps(this);
devices.put(gpsDevice.getName(), gpsDevice);
}
public void setGpsDevices(CompassGpsDevice[] devices) {
this.devices.clear();
for (CompassGpsDevice device : devices) {
checkDeviceValidity(device);
device.injectGps(this);
this.devices.put(device.getName(), device);
}
}
protected CompassGpsDevice getGpsDevice(String name) {
return devices.get(name);
}
private void checkDeviceValidity(CompassGpsDevice device) {
if (device.getName() == null) {
throw new IllegalArgumentException("Must specify a name for a gps device");
}
if (devices.get(device.getName()) != null) {
throw new IllegalArgumentException("A gps device with the name [" + device.getName()
+ "] is defined twice. It is not allowed.");
}
}
protected boolean hasRootMappingForEntity(Class clazz, Compass checkedCompass) {
return getRootMappingForEntity(clazz, checkedCompass) != null;
}
protected boolean hasMappingForEntity(Class clazz, Compass checkedCompass, Cascade cascade) {
return ((InternalCompass) checkedCompass).getMapping().hasMappingForClass(clazz, cascade);
}
protected boolean hasMappingForEntity(String name, Compass checkedCompass, Cascade cascade) {
return ((InternalCompass) checkedCompass).getMapping().hasMappingForAlias(name, cascade);
}
protected ResourceMapping getRootMappingForEntity(Class clazz, Compass checkedCompass) {
return ((InternalCompass) checkedCompass).getMapping().getRootMappingByClass(clazz);
}
protected boolean hasRootMappingForEntity(String name, Compass checkedCompass) {
return getRootMappingForEntity(name, checkedCompass) != null;
}
protected ResourceMapping getMappingForEntity(String name, Compass checkedCompass) {
ResourceMapping resourceMapping = ((InternalCompass) checkedCompass).getMapping().getMappingByAlias(name);
if (resourceMapping != null) {
return resourceMapping;
}
try {
Class clazz = ClassUtils.forName(name, checkedCompass.getSettings().getClassLoader());
return ((InternalCompass) checkedCompass).getMapping().getMappingByClass(clazz);
} catch (Exception e) {
// do nothing
}
return null;
}
protected ResourceMapping getRootMappingForEntity(String name, Compass checkedCompass) {
ResourceMapping resourceMapping = ((InternalCompass) checkedCompass).getMapping().getRootMappingByAlias(name);
if (resourceMapping != null) {
return resourceMapping;
}
try {
Class clazz = ClassUtils.forName(name, checkedCompass.getSettings().getClassLoader());
return ((InternalCompass) checkedCompass).getMapping().getRootMappingByClass(clazz);
} catch (Exception e) {
// do nothing
}
return null;
}
public synchronized void index() throws CompassGpsException, IllegalStateException {
index(new DefaultIndexPlan());
}
public void index(Class... types) throws CompassGpsException, IllegalStateException {
index(new DefaultIndexPlan().setTypes(types));
}
public void index(String... aliases) throws CompassGpsException, IllegalStateException {
index(new DefaultIndexPlan().setAliases(aliases));
}
public synchronized void index(IndexPlan indexPlan) throws CompassGpsException, IllegalStateException {
if (!isRunning()) {
throw new IllegalStateException("CompassGps must be running in order to perform the index operation");
}
if (((InternalCompass) getMirrorCompass()).getTransactionFactory().getTransactionBoundSession() != null) {
throw new CompassGpsException("index() operation is not allowed to be called within a transaction (mirror)");
}
if (((InternalCompass) getIndexCompass()).getTransactionFactory().getTransactionBoundSession() != null) {
throw new CompassGpsException("index() operation is not allowed to be called within a transaction (index)");
}
if (isPerformingIndexOperation()) {
throw new IllegalArgumentException("Indexing alredy in process, not allowed to call index()");
}
try {
performingIndexOperation = true;
doIndex(indexPlan);
} finally {
performingIndexOperation = false;
}
}
protected abstract void doIndex(IndexPlan indexPlan) throws CompassGpsException;
public synchronized void start() throws CompassGpsException {
doStart();
if (!started) {
for (CompassGpsDevice device : devices.values()) {
device.start();
}
started = true;
}
}
protected abstract void doStart() throws CompassGpsException;
protected abstract void doStop() throws CompassGpsException;
public synchronized void stop() throws CompassGpsException {
if (started) {
for (CompassGpsDevice device : devices.values()) {
device.stop();
}
started = false;
}
doStop();
}
public synchronized void refresh() throws CompassGpsException {
for (CompassGpsDevice device : devices.values()) {
device.refresh();
}
}
public boolean isRunning() {
return started;
}
public boolean isPerformingIndexOperation() {
return performingIndexOperation;
}
protected void finalize() throws Throwable {
super.finalize();
stop();
}
}