/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.transaction; import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.context.MuleContextAware; import org.mule.runtime.core.api.transaction.TransactionConfig; import org.mule.runtime.core.api.transaction.TransactionFactory; import org.mule.runtime.core.config.i18n.CoreMessages; import org.mule.runtime.core.util.ClassUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p/> * <code>MuleTransactionConfig</code> defines transaction configuration for a transactional endpoint. */ public class MuleTransactionConfig implements TransactionConfig, MuleContextAware { /** * logger used by this class */ protected static final Logger logger = LoggerFactory.getLogger(MuleTransactionConfig.class); public static final String ACTION_NONE_STRING = "NONE"; public static final String ACTION_ALWAYS_BEGIN_STRING = "ALWAYS_BEGIN"; public static final String ACTION_BEGIN_OR_JOIN_STRING = "BEGIN_OR_JOIN"; public static final String ACTION_ALWAYS_JOIN_STRING = "ALWAYS_JOIN"; public static final String ACTION_JOIN_IF_POSSIBLE_STRING = "JOIN_IF_POSSIBLE"; public static final String ACTION_NEVER_STRING = "NEVER"; public static final String ACTION_INDIFFERENT_STRING = "INDIFFERENT"; public static final String ACTION_NOT_SUPPORTED_STRING = "NOT_SUPPORTED"; private TransactionFactory factory; private byte action = ACTION_DEFAULT; private Integer timeout; private boolean interactWithExternal = false; public MuleTransactionConfig() {} public MuleTransactionConfig(byte action) { this.action = action; } public void setMuleContext(MuleContext context) { // override only if not set in config if (this.timeout == null) { this.timeout = context.getConfiguration().getDefaultTransactionTimeout(); } } public TransactionFactory getFactory() { return factory; } public void setFactory(TransactionFactory factory) { if (factory == null) { throw new IllegalArgumentException("Transaction Factory cannot be null"); } this.factory = factory; } public byte getAction() { return action; } public void setAction(byte action) { this.action = action; } public boolean isInteractWithExternal() { return interactWithExternal; } public void setInteractWithExternal(boolean interactWithExternal) { this.interactWithExternal = interactWithExternal; } public void setActionAsString(String action) { if (ACTION_ALWAYS_BEGIN_STRING.equals(action)) { this.action = ACTION_ALWAYS_BEGIN; } else if (ACTION_BEGIN_OR_JOIN_STRING.equals(action)) { this.action = ACTION_BEGIN_OR_JOIN; } else if (ACTION_ALWAYS_JOIN_STRING.equals(action)) { this.action = ACTION_ALWAYS_JOIN; } else if (ACTION_JOIN_IF_POSSIBLE_STRING.equals(action)) { this.action = ACTION_JOIN_IF_POSSIBLE; } else if (ACTION_NONE_STRING.equals(action)) { this.action = ACTION_NONE; } else if (ACTION_NEVER_STRING.equals(action)) { this.action = ACTION_NEVER; } else if (ACTION_INDIFFERENT_STRING.equals(action)) { this.action = ACTION_INDIFFERENT; } else if (ACTION_NOT_SUPPORTED_STRING.equals(action)) { this.action = ACTION_NOT_SUPPORTED; } else { throw new IllegalArgumentException("Action " + action + " is not recognised as a begin action."); } } public String getActionAsString() { switch (action) { case ACTION_ALWAYS_BEGIN: return ACTION_ALWAYS_BEGIN_STRING; case ACTION_BEGIN_OR_JOIN: return ACTION_BEGIN_OR_JOIN_STRING; case ACTION_ALWAYS_JOIN: return ACTION_ALWAYS_JOIN_STRING; case ACTION_JOIN_IF_POSSIBLE: return ACTION_JOIN_IF_POSSIBLE_STRING; case ACTION_NONE: return ACTION_NONE_STRING; case ACTION_INDIFFERENT: return ACTION_INDIFFERENT_STRING; default: return ACTION_NEVER_STRING; } } /** * Will the result, at the end of running the transaction template, be an active transaction? */ public boolean isTransacted() { if (action == ACTION_NEVER || action == ACTION_NONE || action == ACTION_NOT_SUPPORTED) { return false; } if (factory == null) { if (action != ACTION_INDIFFERENT) { // TODO use TransactionException here? This causes API changes as TE is a checked exception ... throw new MuleRuntimeException(CoreMessages.transactionFactoryIsMandatory(getActionAsString())); } } else if (!factory.isTransacted()) { return false; } switch (action) { case ACTION_ALWAYS_BEGIN: case ACTION_ALWAYS_JOIN: case ACTION_BEGIN_OR_JOIN: return true; case ACTION_JOIN_IF_POSSIBLE: case ACTION_INDIFFERENT: return TransactionCoordination.getInstance().getTransaction() != null; default: // should not happen return false; } } public boolean isConfigured() { return factory != null; } public int getTimeout() { return timeout == null ? 0 : timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public String toString() { StringBuilder buf = new StringBuilder(); buf.append("Transaction{factory=").append(factory).append(", action=").append(getActionAsString()).append(", timeout=") .append(timeout == null ? 0 : timeout).append("}"); return buf.toString(); } public int hashCode() { return ClassUtils.hash(new Object[] {factory, action, timeout == null ? 0 : timeout}); } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; final MuleTransactionConfig other = (MuleTransactionConfig) obj; return ClassUtils.equal(factory, other.factory) && ClassUtils.equal(action, other.action) && ClassUtils.equal(timeout, other.timeout); } }