org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compass Show documentation
Show all versions of compass Show documentation
Compass Search Engine Framework
/*
* Copyright 2004-2006 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.spring.device;
import org.compass.core.config.CompassEnvironment;
import org.compass.core.spi.InternalCompass;
import org.compass.core.transaction.TransactionFactory;
import org.compass.core.util.Assert;
import org.compass.gps.CompassGpsDevice;
import org.compass.gps.CompassGpsException;
import org.compass.gps.IndexPlan;
import org.compass.gps.device.AbstractGpsDeviceWrapper;
import org.compass.gps.spi.CompassGpsInterfaceDevice;
import org.compass.spring.transaction.SpringSyncTransactionFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
/**
* A Spring Transaction device wrapper, which starts a new transaction (with transaction propagation of
* REQUIRES_NEW) for the device index operation.
*
* When using {@link SpringSyncTransactionFactory}, this gps device wrapper should be used to wrap all
* the devices within the application. Spring PlatformTransactionManager
can either be
* injected, or the device wrapper will try to get it from the configured {@link org.compass.spring.LocalCompassBean}
* that is associated with the device {@link org.compass.gps.CompassGps}.
*
* By default, {@link #setAllowNoTransactionManager(boolean)} is set to true
, so changing from
* {@link SpringSyncTransactionFactory} to {@link org.compass.core.transaction.LocalTransactionFactory} will not
* require additional configuration changes. Changing it to false
will mean that a transaction manager
* must be accessible (either by setting the transcation manager, or associating one with the local compass bean).
*
* @author kimchy
*/
public class SpringSyncTransactionGpsDeviceWrapper extends AbstractGpsDeviceWrapper implements InitializingBean {
private PlatformTransactionManager transactionManager;
private boolean allowNoTransactionManager = true;
private Integer transactionTimeout;
public SpringSyncTransactionGpsDeviceWrapper() {
}
public SpringSyncTransactionGpsDeviceWrapper(CompassGpsDevice device) {
setGpsDevice(device);
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(gpsDevice, "Must set wrapped gpsDevice");
}
/**
* If a Spring PlatformTransactionManager is available, will use it to execute the wrapped gps device
* index operation within a new transcation with a propagation level of REQUIRES_NEW.
*/
public void index(final IndexPlan indexPlan) throws CompassGpsException {
if (transactionManager == null) {
TransactionFactory transactionFactory =
((InternalCompass) ((CompassGpsInterfaceDevice) gpsDevice.getGps()).getIndexCompass()).getTransactionFactory();
if (transactionFactory instanceof SpringSyncTransactionFactory) {
SpringSyncTransactionFactory springSyncTransactionFactory = (SpringSyncTransactionFactory) transactionFactory;
transactionManager = springSyncTransactionFactory.getTransactionManager();
}
}
if (transactionManager == null) {
if (allowNoTransactionManager) {
if (log.isDebugEnabled()) {
log.debug("No transaction manager found, will not execute the index operation within its own transaction");
}
gpsDevice.index(indexPlan);
} else {
throw new CompassGpsException("No transaction manager is found, and it is not allowed");
}
} else {
if (log.isDebugEnabled()) {
log.debug("Startin a new Spring transaction for device [" + gpsDevice.getName() + "] index operation");
}
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
if (transactionTimeout != null) {
transactionTemplate.setTimeout(transactionTimeout);
} else {
int timeout = ((CompassGpsInterfaceDevice) gpsDevice.getGps()).getIndexCompass().getSettings().getSettingAsInt(CompassEnvironment.Transaction.TRANSACTION_TIMEOUT, -1);
if (timeout != -1) {
transactionTemplate.setTimeout(timeout);
}
}
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
gpsDevice.index(indexPlan);
}
});
}
}
/**
* Sets the Spring PlatformTransactionManager
that will be used to start a new transaction
* for the {@link #index(org.compass.gps.IndexPlan)} operation. Note, this is an optioanl parameter, since if not set, Compass will
* try and get Spring transaction manager from the associated {@link org.compass.spring.LocalCompassBean}.
*/
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* Should the device allows for cases where no Spring transaction manager is provided (for example, when
* using Compass {@link org.compass.core.transaction.LocalTransactionFactory} and not setting an transaction
* manager. In such cases, no new transaction will be started.
*
* Defaults to true
.
*/
public void setAllowNoTransactionManager(boolean allowNoTransactionManager) {
this.allowNoTransactionManager = allowNoTransactionManager;
}
/**
* Sets the transaction timeout (see Spring {@link TransactionTemplate#setTimeout(int)}.
*/
public void setTransactionTimeout(Integer transactionTimeout) {
this.transactionTimeout = transactionTimeout;
}
}