001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.ivy.plugins.version;
019:
020: import java.util.Collections;
021: import java.util.Comparator;
022: import java.util.Iterator;
023: import java.util.LinkedList;
024: import java.util.List;
025:
026: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
027: import org.apache.ivy.core.module.id.ModuleRevisionId;
028: import org.apache.ivy.core.settings.IvySettings;
029: import org.apache.ivy.plugins.IvySettingsAware;
030: import org.apache.ivy.util.Checks;
031:
032: /**
033: * An implementation of {@link VersionMatcher} chaining several version matchers, and implemeting
034: * the {@link VersionMatcher} interface by returning results from the first matcher in the chain
035: * accepting the version.
036: */
037: public class ChainVersionMatcher extends AbstractVersionMatcher {
038: /**
039: * The list of version matchers in the chain. This list will be queried in order, so the last
040: * matcher will be used only if no other matcher accept the revision before.
041: */
042: private List/* <VersionMatcher> */matchers = new LinkedList();
043:
044: /**
045: * Unique Constructor.
046: */
047: public ChainVersionMatcher() {
048: super ("chain");
049: }
050:
051: /**
052: * Adds a {@link VersionMatcher} to the chain.
053: *
054: * @param matcher
055: * the version matcher to add. Must not be null
056: */
057: public void add(VersionMatcher matcher) {
058: Checks.checkNotNull(matcher, "matcher");
059: matchers.add(0, matcher);
060: if (getSettings() != null
061: && matcher instanceof IvySettingsAware) {
062: ((IvySettingsAware) matcher).setSettings(getSettings());
063: }
064: }
065:
066: /**
067: * Sets the settings this matcher will use, and set to the matcher in the chain which implements
068: * {@link IvySettingsAware}.
069: *
070: * @param settings
071: * the settings to use in the whole chain. Must not be null.
072: */
073: public void setSettings(IvySettings settings) {
074: super .setSettings(settings);
075: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
076: VersionMatcher matcher = (VersionMatcher) iter.next();
077: if (matcher instanceof IvySettingsAware) {
078: ((IvySettingsAware) matcher).setSettings(settings);
079: }
080: }
081: }
082:
083: /**
084: * Returns the list of matchers in the chain.
085: * <p>
086: * The list is returned as an unmodifiable view on the actual list of matchers, and will thus
087: * reflect futher changes made in the chain.
088: *
089: * @return the list of matchers in the chain. Is never null.
090: */
091: public List getMatchers() {
092: return Collections.unmodifiableList(matchers);
093: }
094:
095: public boolean isDynamic(ModuleRevisionId askedMrid) {
096: Checks.checkNotNull(askedMrid, "askedMrid");
097: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
098: VersionMatcher matcher = (VersionMatcher) iter.next();
099: if (matcher.isDynamic(askedMrid)) {
100: return true;
101: }
102: }
103: return false;
104: }
105:
106: public int compare(ModuleRevisionId askedMrid,
107: ModuleRevisionId foundMrid, Comparator staticComparator) {
108: Checks.checkNotNull(askedMrid, "askedMrid");
109: Checks.checkNotNull(foundMrid, "foundMrid");
110: Checks.checkNotNull(staticComparator, "staticComparator");
111: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
112: VersionMatcher matcher = (VersionMatcher) iter.next();
113: if (matcher.isDynamic(askedMrid)) {
114: return matcher.compare(askedMrid, foundMrid,
115: staticComparator);
116: }
117: }
118: throw new IllegalArgumentException(
119: "impossible to compare revisions: askedMrid is not dynamic: "
120: + askedMrid);
121: }
122:
123: public boolean accept(ModuleRevisionId askedMrid,
124: ModuleRevisionId foundMrid) {
125: Checks.checkNotNull(askedMrid, "askedMrid");
126: Checks.checkNotNull(foundMrid, "foundMrid");
127: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
128: VersionMatcher matcher = (VersionMatcher) iter.next();
129: if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
130: return matcher.accept(askedMrid, foundMrid);
131: }
132: }
133: return false;
134: }
135:
136: public boolean needModuleDescriptor(ModuleRevisionId askedMrid,
137: ModuleRevisionId foundMrid) {
138: Checks.checkNotNull(askedMrid, "askedMrid");
139: Checks.checkNotNull(foundMrid, "foundMrid");
140: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
141: VersionMatcher matcher = (VersionMatcher) iter.next();
142: if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
143: return matcher.needModuleDescriptor(askedMrid,
144: foundMrid);
145: }
146: }
147: return false;
148: }
149:
150: public boolean accept(ModuleRevisionId askedMrid,
151: ModuleDescriptor foundMD) {
152: Checks.checkNotNull(askedMrid, "askedMrid");
153: Checks.checkNotNull(foundMD, "foundMD");
154: for (Iterator iter = matchers.iterator(); iter.hasNext();) {
155: VersionMatcher matcher = (VersionMatcher) iter.next();
156: if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
157: return matcher.accept(askedMrid, foundMD);
158: }
159: }
160: return false;
161: }
162: }
|