org.apache.aries.transaction.BundleWideTxDataUtil Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.aries.transaction;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BundleWideTxDataUtil {
/**
* based on method name and its associated compId, to check which transaction attribute should apply to
* this method from the bundle wide transaction configuration.
*
* if no transaction attribute should apply to this method, null should be returned
* @param compId
* @param method
* @param bundleData
* @return
*/
public static String getAttribute(String compId, String method, List bundleData) {
BundleWideTxData txData = null;
if (bundleData.size() == 1) {
txData = bundleData.get(0);
List beans = txData.getBean();
List mtds = txData.getMethod();
String value = txData.getValue();
if (!beans.isEmpty() && !mtds.isEmpty()) {
for (Pattern bean : beans) {
if (bean.matcher(compId).matches()) {
for (Pattern mtd : mtds) {
if (mtd.matcher(method).matches()) {
return value;
}
}
}
}
} else if (!beans.isEmpty()) {
for (Pattern bean : beans) {
if (bean.matcher(compId).matches()) {
return value;
}
}
} else if (!mtds.isEmpty()) {
for (Pattern mtd : mtds) {
if (mtd.matcher(method).matches()) {
return value;
}
}
} else {
return value;
}
} else {
// multiple bundledata available, let's try find the one that matches the compId
return getTransactionAttribute(bundleData, compId, method);
}
return null;
}
private static String getTransactionAttribute(List bundleData, String compId, String method) {
List bundleDataBothMethodAndBean = new ArrayList();
List bundleDataOnlyBean = new ArrayList();
List bundleDataOnlyMethod = new ArrayList();
List bundleDataNoRestriction = new ArrayList();
for (BundleWideTxData txData : bundleData) {
List beans = txData.getBean();
List mtds = txData.getMethod();
if (!beans.isEmpty() && !mtds.isEmpty()) {
bundleDataBothMethodAndBean.add(txData);
} else if (!beans.isEmpty() ) {
bundleDataOnlyBean.add(txData);
} else if (!mtds.isEmpty()) {
bundleDataOnlyMethod.add(txData);
} else {
bundleDataNoRestriction.add(txData);
}
}
// let's first check bundle data which has both
List matchedTxData = new ArrayList();
for (BundleWideTxData txData : bundleDataBothMethodAndBean) {
List beans = txData.getBean();
List mtds = txData.getMethod();
String value = txData.getValue();
for (Pattern bean : beans) {
if (bean.matcher(compId).matches()) {
for (Pattern mtd : mtds) {
if (mtd.matcher(method).matches()) {
//return value;
matchedTxData.add(new MatchedTxData(value, mtd, bean));
}
}
}
}
}
if (!matchedTxData.isEmpty()) {
return findBestMatch(matchedTxData);
}
// let's then check bundle data that has bean only next
for (BundleWideTxData txData : bundleDataOnlyBean) {
List beans = txData.getBean();
String value = txData.getValue();
for (Pattern bean : beans) {
if (bean.matcher(compId).matches()) {
matchedTxData.add(new MatchedTxData(value, null, bean));
}
}
}
if (!matchedTxData.isEmpty()) {
return findBestMatchBeanOnly(matchedTxData);
}
// let's then check bundle data that has method only next
for (BundleWideTxData txData : bundleDataOnlyMethod) {
List mtds = txData.getMethod();
String value = txData.getValue();
for (Pattern mtd : mtds) {
if (mtd.matcher(method).matches()) {
matchedTxData.add(new MatchedTxData(value, mtd, null));
}
}
}
if (!matchedTxData.isEmpty()) {
return findBestMatchMethodOnly(matchedTxData);
}
// let's then check bundle data that doesn't have method or bean
for (BundleWideTxData txData : bundleDataNoRestriction) {
return txData.getValue();
}
if (bundleDataNoRestriction.size() == 0) {
return null;
} else if (bundleDataNoRestriction.size() == 1) {
return bundleDataNoRestriction.get(0).getValue();
} else {
// cannot have more than 1 transaction element that has no method or bean attribute
throw new IllegalStateException(Constants.MESSAGES.getMessage("bundle.wide.tx", bundleDataNoRestriction));
}
}
// this method assume matchedTxData isn't empty.
private static String findBestMatch(List matchedTxData) {
if (matchedTxData.size() == 1) {
return matchedTxData.get(0).getValue();
} else {
// let's compare bean first
List matchesBean1 = selectPatternsWithFewestWildcards(matchedTxData, true);
if (matchesBean1.size() == 1) {
return matchesBean1.get(0).getValue();
} else {
List matchesBean2 = selectLongestPatterns(matchesBean1, true);
if (matchesBean2.size() == 1) {
return matchesBean2.get(0).getValue();
} else {
// let's compare method
List matchesMethod1 = selectPatternsWithFewestWildcards(matchesBean2, false);
if (matchesMethod1.size() == 1) {
return matchesMethod1.get(0).getValue();
} else {
List matchesMethod2 = selectLongestPatterns(matchesMethod1, false);
if (matchesMethod2.size() == 1) {
return matchesMethod2.get(0).getValue();
} else {
// unable to find the best match!!
throw new IllegalStateException(Constants.MESSAGES.getMessage("unable.to.apply.patterns", matchedTxData));
}
}
}
}
}
}
// this method assume matchedTxData isn't empty.
private static String findBestMatchBeanOnly(List matchedTxData) {
if (matchedTxData.size() == 1) {
return matchedTxData.get(0).getValue();
} else {
// let's compare bean first
List matchesBean1 = selectPatternsWithFewestWildcards(matchedTxData, true);
if (matchesBean1.size() == 1) {
return matchesBean1.get(0).getValue();
} else {
List matchesBean2 = selectLongestPatterns(matchesBean1, true);
if (matchesBean2.size() == 1) {
return matchesBean2.get(0).getValue();
} else {
// unable to find the best match!!
throw new IllegalStateException(Constants.MESSAGES.getMessage("unable.to.apply.patterns", matchedTxData));
}
}
}
}
// this method assume matchedTxData isn't empty.
private static String findBestMatchMethodOnly(List matchedTxData) {
if (matchedTxData.size() == 1) {
return matchedTxData.get(0).getValue();
} else {
// let's compare bean first
List matchesMethod1 = selectPatternsWithFewestWildcards(matchedTxData, false);
if (matchesMethod1.size() == 1) {
return matchesMethod1.get(0).getValue();
} else {
List matchesMethod2 = selectLongestPatterns(matchesMethod1, false);
if (matchesMethod2.size() == 1) {
return matchesMethod2.get(0).getValue();
} else {
// unable to find the best match!!
throw new IllegalStateException(Constants.MESSAGES.getMessage("unable.to.apply.patterns", matchedTxData));
}
}
}
}
private static List selectPatternsWithFewestWildcards(List matchedTxData, boolean isBean) {
List remainingMatches = new ArrayList();
int minWildcards = Integer.MAX_VALUE;
for (MatchedTxData mData : matchedTxData) {
Pattern p;
if (isBean) {
p = mData.getBean();
} else {
p = mData.getMethod();
}
String pattern = p.pattern();
Matcher m = Constants.WILDCARD.matcher(pattern);
int count = 0;
while (m.find()) {
count++;
}
if (count < minWildcards) {
remainingMatches.clear();
remainingMatches.add(mData);
minWildcards = count;
}
else if (count == minWildcards) {
remainingMatches.add(mData);
}
}
return remainingMatches;
}
private static List selectLongestPatterns(List matchedTxData, boolean isBean) {
List remainingMatches = new ArrayList();
int longestLength = 0;
for (MatchedTxData mData : matchedTxData) {
Pattern p;
if (isBean) {
p = mData.getBean();
} else {
p = mData.getMethod();
}
String pattern = p.pattern();
int length = pattern.length();
if (length > longestLength) {
remainingMatches.clear();
remainingMatches.add(mData);
longestLength = length;
}
else if (length == longestLength) {
remainingMatches.add(mData);
}
}
return remainingMatches;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy