2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
18
package org.apache.ivy.plugins.conflict;
20
import java.util.Arrays;
21
import java.util.Collection;
22
import java.util.Collections;
23
import java.util.Iterator;
24
import java.util.regex.Matcher;
25
import java.util.regex.Pattern;
27
import org.apache.ivy.core.resolve.IvyNode;
28
import org.apache.ivy.util.Message;
31
* A ConflictManager that can be used to resolve conflicts based on regular expressions of the
32
* revision of the module. The conflict manager is added like this:
35
* <!-- Match all revisions, but ignore the last dot(.) and the character after it.
36
* Used to match api changes in out milestones. -->
37
* <conflict-managers>
38
* <regexp-cm name="regexp"
39
* regexp="(.*)\..$" ignoreNonMatching="true"/>
40
* </conflict-managers>
43
* The regular expression must contain a capturing group. The group will be used to resolve the
44
* conflicts by an String.equals() test. If ignoreNonMatching is false non matching modules will
45
* result in an exception. If it is true they will be compaired by their full revision.
47
public class RegexpConflictManager extends AbstractConflictManager {
48
private Pattern pattern = Pattern.compile("(.*)");
50
private boolean mIgnoreNonMatching;
52
public RegexpConflictManager() {
55
public void setRegexp(String regexp) {
56
pattern = Pattern.compile(regexp);
57
Matcher matcher = pattern.matcher("abcdef");
58
if (matcher.groupCount() != 1) {
59
String message = "Pattern does not contain ONE (capturing group): '" + pattern + "'";
60
Message.error(message);
61
throw new IllegalArgumentException(message);
65
public void setIgnoreNonMatching(boolean ignoreNonMatching) {
66
mIgnoreNonMatching = ignoreNonMatching;
69
public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
70
IvyNode lastNode = null;
71
for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
72
IvyNode node = (IvyNode) iter.next();
74
if (lastNode != null && !matchEquals(node, lastNode)) {
75
String msg = lastNode + ":" + getMatch(lastNode) + " (needed by "
76
+ Arrays.asList(lastNode.getAllRealCallers()) + ") conflicts with " + node
77
+ ":" + getMatch(node) + " (needed by "
78
+ Arrays.asList(node.getAllRealCallers()) + ")";
79
throw new StrictConflictException(msg);
81
if (lastNode == null || nodeIsGreater(node, lastNode)) {
86
return Collections.singleton(lastNode);
89
private boolean nodeIsGreater(IvyNode node, IvyNode lastNode) {
90
return getMatch(node).compareTo(getMatch(lastNode)) > 0;
93
private boolean matchEquals(IvyNode lastNode, IvyNode node) {
94
return getMatch(lastNode).equals(getMatch(node));
97
private String getMatch(IvyNode node) {
98
String revision = node.getId().getRevision();
99
Matcher matcher = pattern.matcher(revision);
100
if (matcher.matches()) {
101
String match = matcher.group(1);
105
warnOrThrow("First group of pattern: '" + pattern + "' does not match: " + revision
108
warnOrThrow("Pattern: '" + pattern + "' does not match: " + revision + " " + node);
113
private void warnOrThrow(String message) {
114
if (mIgnoreNonMatching) {
115
Message.warn(message);
117
throw new StrictConflictException(message);