001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.transaction.interceptor;
018:
019: import java.beans.PropertyEditorSupport;
020:
021: import org.springframework.util.StringUtils;
022:
023: /**
024: * PropertyEditor for {@link TransactionAttribute} objects. Accepts a String of form
025: * <p><code>PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2</code>
026: * <p>where only propagation code is required. For example:
027: * <p><code>PROPAGATION_MANDATORY,ISOLATION_DEFAULT</code>
028: *
029: * <p>The tokens can be in <strong>any</strong> order. Propagation and isolation codes
030: * must use the names of the constants in the TransactionDefinition class. Timeout values
031: * are in seconds. If no timeout is specified, the transaction manager will apply a default
032: * timeout specific to the particular transaction manager.
033: *
034: * <p>A "+" before an exception name substring indicates that transactions should commit
035: * even if this exception is thrown; a "-" that they should roll back.
036: *
037: * @author Rod Johnson
038: * @author Juergen Hoeller
039: * @since 24.04.2003
040: * @see org.springframework.transaction.TransactionDefinition
041: * @see org.springframework.core.Constants
042: */
043: public class TransactionAttributeEditor extends PropertyEditorSupport {
044:
045: /**
046: * Format is PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2.
047: * Null or the empty string means that the method is non transactional.
048: * @see java.beans.PropertyEditor#setAsText(java.lang.String)
049: */
050: public void setAsText(String text) throws IllegalArgumentException {
051: if (StringUtils.hasLength(text)) {
052: // tokenize it with ","
053: String[] tokens = StringUtils
054: .commaDelimitedListToStringArray(text);
055: RuleBasedTransactionAttribute attr = new RuleBasedTransactionAttribute();
056: for (int i = 0; i < tokens.length; i++) {
057: // Trim leading and trailing whitespace.
058: String token = StringUtils.trimWhitespace(tokens[i]
059: .trim());
060: // Check whether token contains illegal whitespace within text.
061: if (StringUtils.containsWhitespace(token)) {
062: throw new IllegalArgumentException(
063: "Transaction attribute token contains illegal whitespace: ["
064: + token + "]");
065: }
066: // Check token type.
067: if (token
068: .startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) {
069: attr.setPropagationBehaviorName(token);
070: } else if (token
071: .startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) {
072: attr.setIsolationLevelName(token);
073: } else if (token
074: .startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) {
075: String value = token
076: .substring(DefaultTransactionAttribute.PREFIX_TIMEOUT
077: .length());
078: attr.setTimeout(Integer.parseInt(value));
079: } else if (token
080: .equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) {
081: attr.setReadOnly(true);
082: } else if (token
083: .startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) {
084: attr.getRollbackRules().add(
085: new NoRollbackRuleAttribute(token
086: .substring(1)));
087: } else if (token
088: .startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) {
089: attr.getRollbackRules().add(
090: new RollbackRuleAttribute(token
091: .substring(1)));
092: } else {
093: throw new IllegalArgumentException(
094: "Invalid transaction attribute token: ["
095: + token + "]");
096: }
097: }
098: setValue(attr);
099: } else {
100: setValue(null);
101: }
102: }
103:
104: }
|