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.core.search;
019:
020: import java.util.ArrayList;
021: import java.util.Arrays;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.LinkedHashSet;
027: import java.util.List;
028: import java.util.Map;
029:
030: import org.apache.ivy.core.IvyPatternHelper;
031: import org.apache.ivy.core.module.id.ModuleId;
032: import org.apache.ivy.core.module.id.ModuleRevisionId;
033: import org.apache.ivy.core.settings.IvySettings;
034: import org.apache.ivy.plugins.matcher.Matcher;
035: import org.apache.ivy.plugins.matcher.MatcherHelper;
036: import org.apache.ivy.plugins.matcher.PatternMatcher;
037: import org.apache.ivy.plugins.namespace.NameSpaceHelper;
038: import org.apache.ivy.plugins.namespace.Namespace;
039: import org.apache.ivy.plugins.resolver.AbstractResolver;
040: import org.apache.ivy.plugins.resolver.DependencyResolver;
041: import org.apache.ivy.util.Message;
042:
043: public class SearchEngine {
044: private IvySettings settings;
045:
046: public SearchEngine(IvySettings settings) {
047: this .settings = settings;
048: }
049:
050: /**
051: * Returns an empty array when no token values are found.
052: *
053: * @param token
054: * @param otherTokenValues
055: * @return
056: */
057: public String[] listTokenValues(String token, Map otherTokenValues) {
058: Collection r = new LinkedHashSet();
059: for (Iterator iter = settings.getResolvers().iterator(); iter
060: .hasNext();) {
061: DependencyResolver resolver = (DependencyResolver) iter
062: .next();
063: r.addAll(Arrays.asList(resolver.listTokenValues(token,
064: otherTokenValues)));
065: }
066: return (String[]) r.toArray(new String[r.size()]);
067: }
068:
069: public OrganisationEntry[] listOrganisationEntries() {
070: List entries = new ArrayList();
071: for (Iterator iter = settings.getResolvers().iterator(); iter
072: .hasNext();) {
073: DependencyResolver resolver = (DependencyResolver) iter
074: .next();
075: entries.addAll(Arrays.asList(resolver.listOrganisations()));
076: }
077: return (OrganisationEntry[]) entries
078: .toArray(new OrganisationEntry[entries.size()]);
079: }
080:
081: public String[] listOrganisations() {
082: Collection orgs = new HashSet();
083: for (Iterator iter = settings.getResolvers().iterator(); iter
084: .hasNext();) {
085: DependencyResolver resolver = (DependencyResolver) iter
086: .next();
087: OrganisationEntry[] entries = resolver.listOrganisations();
088: if (entries != null) {
089: for (int i = 0; i < entries.length; i++) {
090: if (entries[i] != null) {
091: orgs.add(entries[i].getOrganisation());
092: }
093: }
094: }
095: }
096: return (String[]) orgs.toArray(new String[orgs.size()]);
097: }
098:
099: public ModuleEntry[] listModuleEntries(OrganisationEntry org) {
100: List entries = new ArrayList();
101: for (Iterator iter = settings.getResolvers().iterator(); iter
102: .hasNext();) {
103: DependencyResolver resolver = (DependencyResolver) iter
104: .next();
105: entries.addAll(Arrays.asList(resolver.listModules(org)));
106: }
107: return (ModuleEntry[]) entries.toArray(new ModuleEntry[entries
108: .size()]);
109: }
110:
111: public String[] listModules(String org) {
112: List mods = new ArrayList();
113: for (Iterator iter = settings.getResolvers().iterator(); iter
114: .hasNext();) {
115: DependencyResolver resolver = (DependencyResolver) iter
116: .next();
117: ModuleEntry[] entries = resolver
118: .listModules(new OrganisationEntry(resolver, org));
119: if (entries != null) {
120: for (int i = 0; i < entries.length; i++) {
121: if (entries[i] != null) {
122: mods.add(entries[i].getModule());
123: }
124: }
125: }
126: }
127: return (String[]) mods.toArray(new String[mods.size()]);
128: }
129:
130: public RevisionEntry[] listRevisionEntries(ModuleEntry module) {
131: List entries = new ArrayList();
132: for (Iterator iter = settings.getResolvers().iterator(); iter
133: .hasNext();) {
134: DependencyResolver resolver = (DependencyResolver) iter
135: .next();
136: entries.addAll(Arrays
137: .asList(resolver.listRevisions(module)));
138: }
139: return (RevisionEntry[]) entries
140: .toArray(new RevisionEntry[entries.size()]);
141: }
142:
143: public String[] listRevisions(String org, String module) {
144: List revs = new ArrayList();
145: for (Iterator iter = settings.getResolvers().iterator(); iter
146: .hasNext();) {
147: DependencyResolver resolver = (DependencyResolver) iter
148: .next();
149: RevisionEntry[] entries = resolver
150: .listRevisions(new ModuleEntry(
151: new OrganisationEntry(resolver, org),
152: module));
153: if (entries != null) {
154: for (int i = 0; i < entries.length; i++) {
155: if (entries[i] != null) {
156: revs.add(entries[i].getRevision());
157: }
158: }
159: }
160: }
161: return (String[]) revs.toArray(new String[revs.size()]);
162: }
163:
164: /**
165: * List module ids of the module accessible through the current resolvers matching the given mid
166: * criteria according to the given matcher.
167: *
168: * @param criteria
169: * @param matcher
170: * @return
171: */
172: public ModuleId[] listModules(ModuleId criteria,
173: PatternMatcher matcher) {
174: List ret = new ArrayList();
175: Matcher orgMatcher = matcher.getMatcher(criteria
176: .getOrganisation());
177: Matcher modMatcher = matcher.getMatcher(criteria.getName());
178: Map tokenValues = new HashMap();
179: String[] orgs = listTokenValues(
180: IvyPatternHelper.ORGANISATION_KEY, tokenValues);
181: for (int i = 0; i < orgs.length; i++) {
182: if (orgMatcher.matches(orgs[i])) {
183: tokenValues.put(IvyPatternHelper.ORGANISATION_KEY,
184: orgs[i]);
185: String[] mods = listTokenValues(
186: IvyPatternHelper.MODULE_KEY, tokenValues);
187: for (int j = 0; j < mods.length; j++) {
188: if (modMatcher.matches(mods[j])) {
189: ret.add(new ModuleId(orgs[i], mods[j]));
190: }
191: }
192: }
193: }
194: return (ModuleId[]) ret.toArray(new ModuleId[ret.size()]);
195: }
196:
197: /**
198: * List module revision ids of the module accessible through the current resolvers matching the
199: * given mrid criteria according to the given matcher.
200: *
201: * @param criteria
202: * @param matcher
203: * @return
204: */
205: public ModuleRevisionId[] listModules(ModuleRevisionId criteria,
206: PatternMatcher matcher) {
207: List ret = new ArrayList();
208: Matcher orgMatcher = matcher.getMatcher(criteria
209: .getOrganisation());
210: Matcher modMatcher = matcher.getMatcher(criteria.getName());
211: Matcher branchMatcher = matcher
212: .getMatcher(criteria.getBranch());
213: Matcher revMatcher = matcher.getMatcher(criteria.getRevision());
214: Map tokenValues = new HashMap();
215: String[] orgs = listTokenValues(
216: IvyPatternHelper.ORGANISATION_KEY, tokenValues);
217: for (int i = 0; i < orgs.length; i++) {
218: if (orgMatcher.matches(orgs[i])) {
219: tokenValues.put(IvyPatternHelper.ORGANISATION_KEY,
220: orgs[i]);
221: String[] mods = listTokenValues(
222: IvyPatternHelper.MODULE_KEY, tokenValues);
223: for (int j = 0; j < mods.length; j++) {
224: if (modMatcher.matches(mods[j])) {
225: tokenValues.put(IvyPatternHelper.MODULE_KEY,
226: mods[j]);
227: String[] branches = listTokenValues(
228: IvyPatternHelper.BRANCH_KEY,
229: tokenValues);
230: if (branches == null || branches.length == 0) {
231: branches = new String[] { settings
232: .getDefaultBranch(new ModuleId(
233: orgs[i], mods[j])) };
234: }
235: for (int k = 0; k < branches.length; k++) {
236: if (branches[k] == null
237: || branchMatcher
238: .matches(branches[k])) {
239: tokenValues.put(
240: IvyPatternHelper.BRANCH_KEY,
241: tokenValues);
242: String[] revs = listTokenValues(
243: IvyPatternHelper.REVISION_KEY,
244: tokenValues);
245: for (int l = 0; l < revs.length; l++) {
246: if (revMatcher.matches(revs[l])) {
247: ret.add(ModuleRevisionId
248: .newInstance(orgs[i],
249: mods[j],
250: branches[k],
251: revs[l]));
252: }
253: }
254: tokenValues
255: .remove(IvyPatternHelper.REVISION_KEY);
256: }
257: }
258: tokenValues.remove(IvyPatternHelper.BRANCH_KEY);
259: }
260: }
261: tokenValues.remove(IvyPatternHelper.MODULE_KEY);
262: }
263: }
264: return (ModuleRevisionId[]) ret
265: .toArray(new ModuleRevisionId[ret.size()]);
266: }
267:
268: public Collection findModuleRevisionIds(
269: DependencyResolver resolver, ModuleRevisionId pattern,
270: PatternMatcher matcher) {
271: Collection mrids = new ArrayList();
272: String resolverName = resolver.getName();
273:
274: Message.verbose("looking for modules matching " + pattern
275: + " using " + matcher.getName());
276: Namespace fromNamespace = null;
277: if (resolver instanceof AbstractResolver) {
278: fromNamespace = ((AbstractResolver) resolver)
279: .getNamespace();
280: }
281:
282: Collection modules = new ArrayList();
283:
284: OrganisationEntry[] orgs = resolver.listOrganisations();
285: if (orgs == null || orgs.length == 0) {
286: // hack for resolvers which are not able to list organisation, we try to see if the
287: // asked organisation is not an exact one:
288: String org = pattern.getOrganisation();
289: if (fromNamespace != null) {
290: org = NameSpaceHelper.transform(pattern.getModuleId(),
291: fromNamespace.getFromSystemTransformer())
292: .getOrganisation();
293: }
294: modules
295: .addAll(Arrays.asList(resolver
296: .listModules(new OrganisationEntry(
297: resolver, org))));
298: } else {
299: Matcher orgMatcher = matcher.getMatcher(pattern
300: .getOrganisation());
301: for (int i = 0; i < orgs.length; i++) {
302: String org = orgs[i].getOrganisation();
303: String systemOrg = org;
304: if (fromNamespace != null) {
305: systemOrg = NameSpaceHelper
306: .transformOrganisation(org, fromNamespace
307: .getToSystemTransformer());
308: }
309: if (orgMatcher.matches(systemOrg)) {
310: modules.addAll(Arrays.asList(resolver
311: .listModules(new OrganisationEntry(
312: resolver, org))));
313: }
314: }
315: }
316: Message.debug("found " + modules.size() + " modules for "
317: + pattern.getOrganisation() + " on " + resolverName);
318: boolean foundModule = false;
319: for (Iterator iter = modules.iterator(); iter.hasNext();) {
320: ModuleEntry mEntry = (ModuleEntry) iter.next();
321:
322: ModuleId foundMid = new ModuleId(mEntry.getOrganisation(),
323: mEntry.getModule());
324: ModuleId systemMid = foundMid;
325: if (fromNamespace != null) {
326: systemMid = NameSpaceHelper.transform(foundMid,
327: fromNamespace.getToSystemTransformer());
328: }
329:
330: if (MatcherHelper.matches(matcher, pattern.getModuleId(),
331: systemMid)) {
332: // The module corresponds to the searched module pattern
333: foundModule = true;
334: RevisionEntry[] rEntries = resolver
335: .listRevisions(mEntry);
336: Message.debug("found " + rEntries.length
337: + " revisions for [" + mEntry.getOrganisation()
338: + ", " + mEntry.getModule() + "] on "
339: + resolverName);
340:
341: boolean foundRevision = false;
342: for (int j = 0; j < rEntries.length; j++) {
343: RevisionEntry rEntry = rEntries[j];
344:
345: ModuleRevisionId foundMrid = ModuleRevisionId
346: .newInstance(mEntry.getOrganisation(),
347: mEntry.getModule(), rEntry
348: .getRevision());
349: ModuleRevisionId systemMrid = foundMrid;
350: if (fromNamespace != null) {
351: systemMrid = fromNamespace
352: .getToSystemTransformer().transform(
353: foundMrid);
354: }
355:
356: if (MatcherHelper.matches(matcher, pattern,
357: systemMrid)) {
358: // We have a matching module revision
359: foundRevision = true;
360: mrids.add(systemMrid);
361: }
362: }
363: if (!foundRevision) {
364: Message.debug("no revision found matching "
365: + pattern + " in ["
366: + mEntry.getOrganisation() + ","
367: + mEntry.getModule() + "] using "
368: + resolverName);
369: }
370: }
371: }
372: if (!foundModule) {
373: Message.debug("no module found matching " + pattern
374: + " using " + resolverName);
375: }
376: return mrids;
377: }
378:
379: }
|