Source Code Cross Referenced for IvyNode.java in  » Code-Analyzer » apache-ivy » org » apache » ivy » core » resolve » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » apache ivy » org.apache.ivy.core.resolve 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         *
0017:         */
0018:        package org.apache.ivy.core.resolve;
0019:
0020:        import java.util.ArrayList;
0021:        import java.util.Arrays;
0022:        import java.util.Collection;
0023:        import java.util.HashMap;
0024:        import java.util.HashSet;
0025:        import java.util.Iterator;
0026:        import java.util.LinkedHashSet;
0027:        import java.util.LinkedList;
0028:        import java.util.List;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:        import java.util.Stack;
0032:        import java.util.regex.Matcher;
0033:        import java.util.regex.Pattern;
0034:
0035:        import org.apache.ivy.core.IvyContext;
0036:        import org.apache.ivy.core.LogOptions;
0037:        import org.apache.ivy.core.event.resolve.EndResolveDependencyEvent;
0038:        import org.apache.ivy.core.event.resolve.StartResolveDependencyEvent;
0039:        import org.apache.ivy.core.module.descriptor.Artifact;
0040:        import org.apache.ivy.core.module.descriptor.Configuration;
0041:        import org.apache.ivy.core.module.descriptor.DefaultArtifact;
0042:        import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
0043:        import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
0044:        import org.apache.ivy.core.module.descriptor.IncludeRule;
0045:        import org.apache.ivy.core.module.descriptor.MDArtifact;
0046:        import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
0047:        import org.apache.ivy.core.module.id.ArtifactId;
0048:        import org.apache.ivy.core.module.id.ModuleId;
0049:        import org.apache.ivy.core.module.id.ModuleRevisionId;
0050:        import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
0051:        import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData;
0052:        import org.apache.ivy.plugins.conflict.ConflictManager;
0053:        import org.apache.ivy.plugins.matcher.MatcherHelper;
0054:        import org.apache.ivy.plugins.resolver.DependencyResolver;
0055:        import org.apache.ivy.util.Message;
0056:        import org.apache.ivy.util.StringUtils;
0057:        import org.apache.ivy.util.filter.Filter;
0058:        import org.apache.ivy.util.filter.FilterHelper;
0059:
0060:        public class IvyNode implements  Comparable {
0061:            private static final Pattern FALLBACK_CONF_PATTERN = Pattern
0062:                    .compile("(.+)\\((.*)\\)");
0063:
0064:            private static final class NodeConf {
0065:                private IvyNode node;
0066:
0067:                private String conf;
0068:
0069:                public NodeConf(IvyNode node, String conf) {
0070:                    if (node == null) {
0071:                        throw new NullPointerException("node must not null");
0072:                    }
0073:                    if (conf == null) {
0074:                        throw new NullPointerException("conf must not null");
0075:                    }
0076:                    this .node = node;
0077:                    this .conf = conf;
0078:                }
0079:
0080:                public final String getConf() {
0081:                    return conf;
0082:                }
0083:
0084:                public final IvyNode getNode() {
0085:                    return node;
0086:                }
0087:
0088:                public boolean equals(Object obj) {
0089:                    if (!(obj instanceof  NodeConf)) {
0090:                        return false;
0091:                    }
0092:                    return getNode().equals(((NodeConf) obj).getNode())
0093:                            && getConf().equals(((NodeConf) obj).getConf());
0094:                }
0095:
0096:                public int hashCode() {
0097:                    //CheckStyle:MagicNumber| OFF
0098:                    int hash = 33;
0099:                    hash += getNode().hashCode() * 17;
0100:                    hash += getConf().hashCode() * 17;
0101:                    //CheckStyle:MagicNumber| OFF
0102:                    return hash;
0103:                }
0104:
0105:                public String toString() {
0106:                    return "NodeConf(" + conf + ")";
0107:                }
0108:            }
0109:
0110:            // //////// CONTEXT
0111:            private ResolveData data;
0112:
0113:            private ResolveEngineSettings settings;
0114:
0115:            // //////// DELEGATES
0116:            private IvyNodeCallers callers;
0117:
0118:            private IvyNodeEviction eviction;
0119:
0120:            // //////// MAIN DATA
0121:
0122:            private IvyNode root;
0123:
0124:            // id as requested, i.e. may be with latest rev
0125:            private ModuleRevisionId id;
0126:
0127:            // set only when node has been built or updated from a DependencyDescriptor
0128:            // Map(IvyNode parent -> DependencyDescriptor)
0129:            private Map dds = new HashMap();
0130:
0131:            // Set when data has been loaded only, or when constructed from a module descriptor
0132:            private ModuleDescriptor md;
0133:
0134:            private ResolvedModuleRevision module;
0135:
0136:            // //////// LOADING METADATA
0137:            private Exception problem = null;
0138:
0139:            private boolean downloaded = false;
0140:
0141:            private boolean searched = false;
0142:
0143:            private Collection confsToFetch = new HashSet();
0144:
0145:            private Collection fetchedConfigurations = new HashSet();
0146:
0147:            private Collection loadedRootModuleConfs = new HashSet();
0148:
0149:            // //////// USAGE DATA
0150:
0151:            // Map (String rootConfName -> Set(String confName))
0152:            // used to know which configurations of the dependency are required
0153:            // for each root module configuration
0154:            private Map rootModuleConfs = new HashMap();
0155:
0156:            // Map (NodeConf in -> Set(String conf))
0157:            private Map requiredConfs = new HashMap();
0158:
0159:            // Map (String rootModuleConf -> Set(DependencyArtifactDescriptor))
0160:            private Map dependencyArtifacts = new HashMap();
0161:
0162:            // Map (String rootModuleConf -> Set(IncludeRule))
0163:            private Map dependencyIncludes = new HashMap();
0164:
0165:            // Map (String rootModuleConf -> IvyNodeBlacklist)
0166:            private Map blacklisted = new HashMap();
0167:
0168:            public IvyNode(ResolveData data, IvyNode parent,
0169:                    DependencyDescriptor dd) {
0170:                id = dd.getDependencyRevisionId();
0171:                dds.put(parent, dd);
0172:                root = parent.getRoot();
0173:                init(data);
0174:            }
0175:
0176:            public IvyNode(ResolveData data, ModuleDescriptor md) {
0177:                id = md.getModuleRevisionId();
0178:                this .md = md;
0179:                root = this ;
0180:                init(data);
0181:            }
0182:
0183:            private void init(ResolveData data) {
0184:                this .data = data;
0185:                settings = data.getSettings();
0186:                eviction = new IvyNodeEviction(this );
0187:                callers = new IvyNodeCallers(this );
0188:            }
0189:
0190:            /**
0191:             * After the call node may be discarded. To avoid using discarded node, make sure to get the
0192:             * real node after the call IvyNode node = ... node.loadData(); node = node.getRealNode(); ...
0193:             */
0194:            public boolean loadData(String rootModuleConf, IvyNode parent,
0195:                    String parentConf, String conf, boolean shouldBePublic) {
0196:                Message.debug("loadData of " + this .toString()
0197:                        + " of rootConf=" + rootModuleConf);
0198:                if (!isRoot() && (data.getReport() != null)) {
0199:                    data.getReport().addDependency(this );
0200:                }
0201:
0202:                boolean loaded = false;
0203:                if (hasProblem()) {
0204:                    Message.debug("Node has problem.  Skip loading");
0205:                } else if (isEvicted(rootModuleConf)) {
0206:                    Message
0207:                            .debug(rootModuleConf
0208:                                    + " is evicted.  Skip loading");
0209:                } else if (!hasConfigurationsToLoad()
0210:                        && isRootModuleConfLoaded(rootModuleConf)) {
0211:                    Message.debug(rootModuleConf
0212:                            + " is loaded and no conf to load.  Skip loading");
0213:                } else {
0214:                    markRootModuleConfLoaded(rootModuleConf);
0215:                    if (md == null) {
0216:                        DependencyResolver resolver = data.getSettings()
0217:                                .getResolver(getId());
0218:                        if (resolver == null) {
0219:                            Message.error("no resolver found for "
0220:                                    + getModuleId()
0221:                                    + ": check your configuration");
0222:                            problem = new RuntimeException(
0223:                                    "no resolver found for " + getModuleId()
0224:                                            + ": check your configuration");
0225:                            return false;
0226:                        }
0227:                        try {
0228:                            Message.debug("\tusing " + resolver
0229:                                    + " to resolve " + getId());
0230:                            DependencyDescriptor dependencyDescriptor = getDependencyDescriptor(parent);
0231:                            long start = System.currentTimeMillis();
0232:                            data.getEventManager().fireIvyEvent(
0233:                                    new StartResolveDependencyEvent(resolver,
0234:                                            dependencyDescriptor));
0235:                            module = resolver.getDependency(
0236:                                    dependencyDescriptor, data);
0237:                            data.getEventManager()
0238:                                    .fireIvyEvent(
0239:                                            new EndResolveDependencyEvent(
0240:                                                    resolver,
0241:                                                    dependencyDescriptor,
0242:                                                    module,
0243:                                                    System.currentTimeMillis()
0244:                                                            - start));
0245:                            if (module != null) {
0246:                                module.getResolver()
0247:                                        .getRepositoryCacheManager()
0248:                                        .saveResolvers(
0249:                                                module.getDescriptor(),
0250:                                                module.getResolver().getName(),
0251:                                                module.getArtifactResolver()
0252:                                                        .getName());
0253:                                if (settings.logModuleWhenFound()
0254:                                        && LogOptions.LOG_DEFAULT
0255:                                                .equals(getData().getOptions()
0256:                                                        .getLog())) {
0257:                                    Message.info("\tfound " + module.getId()
0258:                                            + " in "
0259:                                            + module.getResolver().getName());
0260:                                } else {
0261:                                    Message.verbose("\tfound " + module.getId()
0262:                                            + " in "
0263:                                            + module.getResolver().getName());
0264:                                }
0265:
0266:                                if (settings.getVersionMatcher().isDynamic(
0267:                                        getId())) {
0268:                                    // IVY-56: check if revision has actually been resolved
0269:                                    if (settings.getVersionMatcher().isDynamic(
0270:                                            module.getId())) {
0271:                                        Message
0272:                                                .error("impossible to resolve dynamic revision for "
0273:                                                        + getId()
0274:                                                        + ": check your configuration and make sure revision is part of your pattern");
0275:                                        problem = new RuntimeException(
0276:                                                "impossible to resolve dynamic revision");
0277:                                        return false;
0278:                                    }
0279:                                    IvyNode resolved = data.getNode(module
0280:                                            .getId());
0281:                                    if (resolved != null) {
0282:                                        // exact revision has already been resolved
0283:                                        // => update it and discard this node
0284:                                        md = module.getDescriptor(); // needed for handleConfiguration
0285:                                        if (!handleConfiguration(loaded,
0286:                                                rootModuleConf, parent,
0287:                                                parentConf, conf,
0288:                                                shouldBePublic)) {
0289:                                            return false;
0290:                                        }
0291:
0292:                                        if (resolved.md == null) {
0293:                                            resolved.md = md;
0294:                                        }
0295:                                        if (resolved.module == null) {
0296:                                            resolved.module = module;
0297:                                        }
0298:                                        resolved.downloaded |= module
0299:                                                .getReport().isDownloaded();
0300:                                        resolved.searched |= module.getReport()
0301:                                                .isSearched();
0302:                                        resolved.dds.putAll(dds);
0303:                                        resolved.updateDataFrom(this ,
0304:                                                rootModuleConf, true);
0305:                                        resolved.loadData(rootModuleConf,
0306:                                                parent, parentConf, conf,
0307:                                                shouldBePublic);
0308:                                        DependencyDescriptor dd = dependencyDescriptor;
0309:                                        if (dd != null) {
0310:                                            resolved
0311:                                                    .addDependencyArtifacts(
0312:                                                            rootModuleConf,
0313:                                                            dd
0314:                                                                    .getDependencyArtifacts(parentConf));
0315:                                            resolved
0316:                                                    .addDependencyIncludes(
0317:                                                            rootModuleConf,
0318:                                                            dd
0319:                                                                    .getIncludeRules(parentConf));
0320:                                        }
0321:
0322:                                        data.replaceNode(getId(), resolved,
0323:                                                rootModuleConf);
0324:                                        // this actually discards the node
0325:
0326:                                        if (settings.logResolvedRevision()) {
0327:                                            Message.info("\t["
0328:                                                    + module.getId()
0329:                                                            .getRevision()
0330:                                                    + "] " + getId());
0331:                                        } else {
0332:                                            Message.verbose("\t["
0333:                                                    + module.getId()
0334:                                                            .getRevision()
0335:                                                    + "] " + getId());
0336:                                        }
0337:
0338:                                        return true;
0339:                                    }
0340:                                }
0341:                                downloaded = module.getReport().isDownloaded();
0342:                                searched = module.getReport().isSearched();
0343:                            } else {
0344:                                Message.warn("\tmodule not found: " + getId());
0345:                                resolver.reportFailure();
0346:                                problem = new RuntimeException("not found");
0347:                            }
0348:                        } catch (ResolveProcessException e) {
0349:                            throw e;
0350:                        } catch (Exception e) {
0351:                            e.printStackTrace();
0352:                            problem = e;
0353:                        }
0354:
0355:                        // still not resolved, report error
0356:                        if (module == null) {
0357:                            return false;
0358:                        } else {
0359:                            loaded = true;
0360:                            if (settings.getVersionMatcher().isDynamic(getId())) {
0361:                                if (settings.logResolvedRevision()) {
0362:                                    Message.info("\t["
0363:                                            + module.getId().getRevision()
0364:                                            + "] " + getId());
0365:                                } else {
0366:                                    Message.verbose("\t["
0367:                                            + module.getId().getRevision()
0368:                                            + "] " + getId());
0369:                                }
0370:                            }
0371:                            md = module.getDescriptor();
0372:                            confsToFetch.remove("*");
0373:                            updateConfsToFetch(Arrays
0374:                                    .asList(resolveSpecialConfigurations(
0375:                                            getRequiredConfigurations(parent,
0376:                                                    parentConf), this )));
0377:                        }
0378:                    } else {
0379:                        loaded = true;
0380:                    }
0381:                }
0382:                handleConfiguration(loaded, rootModuleConf, parent, parentConf,
0383:                        conf, shouldBePublic);
0384:                if (hasProblem()) {
0385:                    Message.debug("problem : " + problem.getMessage());
0386:                    return false;
0387:                } else {
0388:                    DependencyDescriptor dd = getDependencyDescriptor(parent);
0389:                    if (dd != null) {
0390:                        addDependencyArtifacts(rootModuleConf, dd
0391:                                .getDependencyArtifacts(parentConf));
0392:                        addDependencyIncludes(rootModuleConf, dd
0393:                                .getIncludeRules(parentConf));
0394:                    }
0395:                    return loaded;
0396:                }
0397:            }
0398:
0399:            public Collection getDependencies(String rootModuleConf,
0400:                    String[] confs) {
0401:                if (md == null) {
0402:                    throw new IllegalStateException(
0403:                            "impossible to get dependencies when data has not been loaded");
0404:                }
0405:                if (Arrays.asList(confs).contains("*")) {
0406:                    confs = md.getConfigurationsNames();
0407:                }
0408:                Collection deps = new HashSet();
0409:                for (int i = 0; i < confs.length; i++) {
0410:                    deps.addAll(getDependencies(rootModuleConf, confs[i],
0411:                            confs[i]));
0412:                }
0413:                return deps;
0414:            }
0415:
0416:            public Collection getDependencies(String rootModuleConf,
0417:                    String conf, String requestedConf) {
0418:                if (md == null) {
0419:                    throw new IllegalStateException(
0420:                            "impossible to get dependencies when data has not been loaded");
0421:                }
0422:                DependencyDescriptor[] dds = md.getDependencies();
0423:                Collection dependencies = new LinkedHashSet(); // it's important to respect order
0424:                for (int i = 0; i < dds.length; i++) {
0425:                    DependencyDescriptor dd = dds[i];
0426:                    String[] dependencyConfigurations = dd
0427:                            .getDependencyConfigurations(conf, requestedConf);
0428:                    if (dependencyConfigurations.length == 0) {
0429:                        // no configuration of the dependency is required for current confs :
0430:                        // it is exactly the same as if there was no dependency at all on it
0431:                        continue;
0432:                    }
0433:                    if (isDependencyModuleExcluded(rootModuleConf, dd
0434:                            .getDependencyRevisionId(), conf)) {
0435:                        // the whole module is excluded, it is considered as not being part of dependencies
0436:                        // at all
0437:                        Message.verbose("excluding "
0438:                                + dd.getDependencyRevisionId() + " in " + conf);
0439:                        continue;
0440:                    }
0441:                    IvyNode depNode = data
0442:                            .getNode(dd.getDependencyRevisionId());
0443:                    if (depNode == null) {
0444:                        depNode = new IvyNode(data, this , dd);
0445:                    } else {
0446:                        depNode.addDependencyDescriptor(this , dd);
0447:                        if (depNode.hasProblem()) {
0448:                            // dependency already tried to be resolved, but unsuccessfully
0449:                            // nothing special to do
0450:                        }
0451:
0452:                    }
0453:                    Collection confs = Arrays
0454:                            .asList(resolveSpecialConfigurations(
0455:                                    dependencyConfigurations, depNode));
0456:                    depNode.updateConfsToFetch(confs);
0457:                    depNode.setRequiredConfs(this , conf, confs);
0458:
0459:                    depNode.addCaller(rootModuleConf, this , conf,
0460:                            dependencyConfigurations, dd);
0461:                    dependencies.add(depNode);
0462:                }
0463:                return dependencies;
0464:            }
0465:
0466:            private void addDependencyDescriptor(IvyNode parent,
0467:                    DependencyDescriptor dd) {
0468:                dds.put(parent, dd);
0469:            }
0470:
0471:            public DependencyDescriptor getDependencyDescriptor(IvyNode parent) {
0472:                return (DependencyDescriptor) dds.get(parent);
0473:            }
0474:
0475:            private boolean isDependencyModuleExcluded(String rootModuleConf,
0476:                    ModuleRevisionId dependencyRevisionId, String conf) {
0477:                return callers.doesCallersExclude(rootModuleConf,
0478:                        DefaultArtifact.newIvyArtifact(dependencyRevisionId,
0479:                                null));
0480:            }
0481:
0482:            public boolean hasConfigurationsToLoad() {
0483:                return !confsToFetch.isEmpty();
0484:            }
0485:
0486:            private boolean markRootModuleConfLoaded(String rootModuleConf) {
0487:                return loadedRootModuleConfs.add(rootModuleConf);
0488:            }
0489:
0490:            private boolean isRootModuleConfLoaded(String rootModuleConf) {
0491:                return loadedRootModuleConfs.contains(rootModuleConf);
0492:            }
0493:
0494:            private boolean handleConfiguration(boolean loaded,
0495:                    String rootModuleConf, IvyNode parent, String parentConf,
0496:                    String conf, boolean shouldBePublic) {
0497:                if (md != null) {
0498:                    String[] confs = getRealConfs(conf);
0499:                    for (int i = 0; i < confs.length; i++) {
0500:                        Configuration c = md.getConfiguration(confs[i]);
0501:                        if (c == null) {
0502:                            confsToFetch.remove(conf);
0503:                            if (!conf.equals(confs[i])) {
0504:                                problem = new RuntimeException(
0505:                                        "configuration(s) not found in " + this 
0506:                                                + ": " + conf
0507:                                                + ". Missing configuration: "
0508:                                                + confs[i]
0509:                                                + ". It was required from "
0510:                                                + parent + " " + parentConf);
0511:                            } else {
0512:                                problem = new RuntimeException(
0513:                                        "configuration(s) not found in " + this 
0514:                                                + ": " + confs[i]
0515:                                                + ". It was required from "
0516:                                                + parent + " " + parentConf);
0517:                            }
0518:                            return false;
0519:                        } else if (shouldBePublic
0520:                                && !isRoot()
0521:                                && c.getVisibility() != Configuration.Visibility.PUBLIC) {
0522:                            confsToFetch.remove(conf);
0523:                            problem = new RuntimeException(
0524:                                    "configuration not public in " + this 
0525:                                            + ": " + c
0526:                                            + ". It was required from "
0527:                                            + parent + " " + parentConf);
0528:                            return false;
0529:                        }
0530:                        if (loaded) {
0531:                            fetchedConfigurations.add(conf);
0532:                            confsToFetch.removeAll(Arrays.asList(confs));
0533:                            confsToFetch.remove(conf);
0534:                        }
0535:                        addRootModuleConfigurations(rootModuleConf, confs);
0536:                    }
0537:                }
0538:                return true;
0539:            }
0540:
0541:            private String getDefaultConf(String conf) {
0542:                Matcher m = FALLBACK_CONF_PATTERN.matcher(conf);
0543:                if (m.matches()) {
0544:                    return m.group(2);
0545:                } else {
0546:                    return conf;
0547:                }
0548:            }
0549:
0550:            private String getMainConf(String conf) {
0551:                Matcher m = FALLBACK_CONF_PATTERN.matcher(conf);
0552:                if (m.matches()) {
0553:                    return m.group(1);
0554:                } else {
0555:                    return null;
0556:                }
0557:            }
0558:
0559:            public void updateConfsToFetch(Collection confs) {
0560:                confsToFetch.addAll(confs);
0561:                confsToFetch.removeAll(fetchedConfigurations);
0562:            }
0563:
0564:            /**
0565:             * resolve the '*' special configurations if necessary and possible
0566:             */
0567:            private String[] resolveSpecialConfigurations(
0568:                    String[] dependencyConfigurations, IvyNode node) {
0569:                if (dependencyConfigurations.length == 1
0570:                        && dependencyConfigurations[0].startsWith("*")
0571:                        && node != null && node.isLoaded()) {
0572:                    String conf = dependencyConfigurations[0];
0573:                    if ("*".equals(conf)) {
0574:                        return node.getDescriptor()
0575:                                .getPublicConfigurationsNames();
0576:                    }
0577:                    // there are exclusions in the configuration
0578:                    List exclusions = Arrays.asList(conf.substring(2).split(
0579:                            "\\!"));
0580:
0581:                    List ret = new ArrayList(Arrays.asList(node.getDescriptor()
0582:                            .getPublicConfigurationsNames()));
0583:                    ret.removeAll(exclusions);
0584:
0585:                    return (String[]) ret.toArray(new String[ret.size()]);
0586:                }
0587:                return dependencyConfigurations;
0588:            }
0589:
0590:            /**
0591:             * returns the required configurations from the given node
0592:             * 
0593:             * @param in
0594:             * @return
0595:             */
0596:            public String[] getRequiredConfigurations(IvyNode in, String inConf) {
0597:                Collection req = (Collection) requiredConfs.get(new NodeConf(
0598:                        in, inConf));
0599:                return req == null ? new String[0] : (String[]) req
0600:                        .toArray(new String[req.size()]);
0601:            }
0602:
0603:            /**
0604:             * returns all the current required configurations of the node
0605:             * 
0606:             * @return
0607:             */
0608:            public String[] getRequiredConfigurations() {
0609:                Collection required = new ArrayList(confsToFetch.size()
0610:                        + fetchedConfigurations.size());
0611:                required.addAll(fetchedConfigurations);
0612:                required.addAll(confsToFetch);
0613:                return (String[]) required.toArray(new String[required.size()]);
0614:            }
0615:
0616:            private void setRequiredConfs(IvyNode parent, String parentConf,
0617:                    Collection confs) {
0618:                requiredConfs.put(new NodeConf(parent, parentConf),
0619:                        new HashSet(confs));
0620:            }
0621:
0622:            public Configuration getConfiguration(String conf) {
0623:                if (md == null) {
0624:                    throw new IllegalStateException(
0625:                            "impossible to get configuration when data has not been loaded");
0626:                }
0627:                String defaultConf = getDefaultConf(conf);
0628:                conf = getMainConf(conf);
0629:                Configuration configuration = md.getConfiguration(conf);
0630:                if (configuration == null) {
0631:                    configuration = md.getConfiguration(defaultConf);
0632:                }
0633:                return configuration;
0634:            }
0635:
0636:            /**
0637:             * Returns the configurations of the dependency required in a given root module configuration.
0638:             * 
0639:             * @param rootModuleConf
0640:             * @return
0641:             */
0642:            public String[] getConfigurations(String rootModuleConf) {
0643:                Set depConfs = (Set) rootModuleConfs.get(rootModuleConf);
0644:                if (depConfs == null) {
0645:                    return new String[0];
0646:                }
0647:                return (String[]) depConfs.toArray(new String[depConfs.size()]);
0648:            }
0649:
0650:            //This is never called.  Could we remove it?
0651:            public void discardConf(String rootModuleConf, String conf) {
0652:                Set depConfs = (Set) rootModuleConfs.get(rootModuleConf);
0653:                if (depConfs == null) {
0654:                    depConfs = new HashSet();
0655:                    rootModuleConfs.put(rootModuleConf, depConfs);
0656:                }
0657:                if (md != null) {
0658:                    // remove all given dependency configurations to the set + extended ones
0659:                    Configuration c = md.getConfiguration(conf);
0660:                    if (conf != null) {
0661:                        String[] exts = c.getExtends();
0662:                        for (int i = 0; i < exts.length; i++) {
0663:                            discardConf(rootModuleConf, exts[i]); // recursive remove of extended
0664:                            // configurations
0665:                        }
0666:                        depConfs.remove(c.getName());
0667:                    } else {
0668:                        Message.warn("unknown configuration in " + getId()
0669:                                + ": " + conf);
0670:                    }
0671:                } else {
0672:                    depConfs.remove(conf);
0673:                }
0674:            }
0675:
0676:            private void addRootModuleConfigurations(String rootModuleConf,
0677:                    String[] dependencyConfs) {
0678:                Set depConfs = (Set) rootModuleConfs.get(rootModuleConf);
0679:                if (depConfs == null) {
0680:                    depConfs = new HashSet();
0681:                    rootModuleConfs.put(rootModuleConf, depConfs);
0682:                }
0683:                if (md != null) {
0684:                    // add all given dependency configurations to the set + extended ones
0685:                    for (int i = 0; i < dependencyConfs.length; i++) {
0686:                        Configuration conf = md
0687:                                .getConfiguration(dependencyConfs[i]);
0688:                        if (conf != null) {
0689:                            String[] exts = conf.getExtends();
0690:                            addRootModuleConfigurations(rootModuleConf, exts); // recursive add of extended
0691:                            // configurations
0692:                            depConfs.add(conf.getName());
0693:                        } else {
0694:                            Message.warn("unknown configuration in " + getId()
0695:                                    + ": " + dependencyConfs[i]);
0696:                        }
0697:                    }
0698:                } else {
0699:                    for (int i = 0; i < dependencyConfs.length; i++) {
0700:                        depConfs.add(dependencyConfs[i]);
0701:                    }
0702:                }
0703:            }
0704:
0705:            /**
0706:             * Returns the root module configurations in which this dependency is required
0707:             * 
0708:             * @return
0709:             */
0710:            public String[] getRootModuleConfigurations() {
0711:                return (String[]) rootModuleConfs.keySet().toArray(
0712:                        new String[rootModuleConfs.size()]);
0713:            }
0714:
0715:            public String[] getConfsToFetch() {
0716:                return (String[]) confsToFetch.toArray(new String[confsToFetch
0717:                        .size()]);
0718:            }
0719:
0720:            public String[] getRealConfs(String conf) {
0721:                if (md == null) {
0722:                    return new String[] { conf };
0723:                }
0724:                String defaultConf = getDefaultConf(conf);
0725:                conf = getMainConf(conf);
0726:                if (md.getConfiguration(conf) == null) {
0727:                    if ("".equals(defaultConf)) {
0728:                        return new String[0];
0729:                    }
0730:                    conf = defaultConf;
0731:                }
0732:                if (conf.startsWith("*")) {
0733:                    return resolveSpecialConfigurations(new String[] { conf },
0734:                            this );
0735:                } else if (conf.indexOf(',') != -1) {
0736:                    String[] confs = conf.split(",");
0737:                    for (int i = 0; i < confs.length; i++) {
0738:                        confs[i] = confs[i].trim();
0739:                    }
0740:                }
0741:                return new String[] { conf };
0742:
0743:            }
0744:
0745:            /**
0746:             * Finds and returns a path in callers from the given module id to the current node
0747:             * 
0748:             * @param from
0749:             *            the module id to start the path from
0750:             * @return a collection representing the path, starting with the from node, followed by the list
0751:             *         of nodes being one path to the current node, excluded
0752:             */
0753:            private Collection findPath(ModuleId from) {
0754:                return findPath(from, this , new LinkedList());
0755:            }
0756:
0757:            private Collection findPath(ModuleId from, IvyNode node, List path) {
0758:                IvyNode parent = (IvyNode) node.getDirectCallerFor(from);
0759:                if (parent == null) {
0760:                    throw new IllegalArgumentException("no path from " + from
0761:                            + " to " + getId() + " found");
0762:                }
0763:                if (path.contains(parent)) {
0764:                    path.add(0, parent);
0765:                    Message
0766:                            .verbose("circular dependency found while looking for the path for another one: was looking for "
0767:                                    + from
0768:                                    + " as a caller of "
0769:                                    + path.get(path.size() - 1));
0770:                    return path;
0771:                }
0772:                path.add(0, parent);
0773:                if (parent.getId().getModuleId().equals(from)) {
0774:                    return path;
0775:                }
0776:                return findPath(from, parent, path);
0777:            }
0778:
0779:            /**
0780:             * Update data in this node from data of the given node, for the given root module
0781:             * configuration.
0782:             * 
0783:             * @param node
0784:             *            the source node from which data should be copied
0785:             * @param rootModuleConf
0786:             *            the root module configuration for which data should be updated
0787:             * @param real
0788:             *            true if the node to update from actually corresponds to the same real node
0789:             *            (usually updated because of dynamic revision resolution), false if it's not the
0790:             *            same real node (usually updated because of node eviction)
0791:             */
0792:            private void updateDataFrom(IvyNode node, String rootModuleConf,
0793:                    boolean real) {
0794:                // update callers
0795:                callers.updateFrom(node.callers, rootModuleConf, real);
0796:
0797:                // update requiredConfs
0798:                updateMapOfSet(node.requiredConfs, requiredConfs);
0799:
0800:                // update rootModuleConfs
0801:                updateMapOfSetForKey(node.rootModuleConfs, rootModuleConfs,
0802:                        rootModuleConf);
0803:
0804:                // update dependencyArtifactsIncludes
0805:                updateMapOfSetForKey(node.dependencyArtifacts,
0806:                        dependencyArtifacts, rootModuleConf);
0807:
0808:                // update confsToFetch
0809:                updateConfsToFetch(node.fetchedConfigurations);
0810:                updateConfsToFetch(node.confsToFetch);
0811:            }
0812:
0813:            private void updateMapOfSet(Map from, Map to) {
0814:                for (Iterator iter = from.keySet().iterator(); iter.hasNext();) {
0815:                    Object key = iter.next();
0816:                    updateMapOfSetForKey(from, to, key);
0817:                }
0818:            }
0819:
0820:            private void updateMapOfSetForKey(Map from, Map to, Object key) {
0821:                Set set = (Set) from.get(key);
0822:                if (set != null) {
0823:                    Set toupdate = (Set) to.get(key);
0824:                    if (toupdate != null) {
0825:                        toupdate.addAll(set);
0826:                    } else {
0827:                        to.put(key, new HashSet(set));
0828:                    }
0829:                }
0830:            }
0831:
0832:            /**
0833:             * Returns all the artifacts of this dependency required in all the root module configurations
0834:             * 
0835:             * @return
0836:             */
0837:            public Artifact[] getAllArtifacts() {
0838:                Set ret = new HashSet();
0839:                for (Iterator it = rootModuleConfs.keySet().iterator(); it
0840:                        .hasNext();) {
0841:                    String rootModuleConf = (String) it.next();
0842:                    ret.addAll(Arrays.asList(getArtifacts(rootModuleConf)));
0843:                }
0844:                return (Artifact[]) ret.toArray(new Artifact[ret.size()]);
0845:            }
0846:
0847:            /**
0848:             * Returns all the artifacts of this dependency required in the root module configurations in
0849:             * which the node is not evicted nor blacklisted
0850:             * 
0851:             * @param artifactFilter
0852:             * @return
0853:             */
0854:            public Artifact[] getSelectedArtifacts(Filter artifactFilter) {
0855:                Collection ret = new HashSet();
0856:                for (Iterator it = rootModuleConfs.keySet().iterator(); it
0857:                        .hasNext();) {
0858:                    String rootModuleConf = (String) it.next();
0859:                    if (!isEvicted(rootModuleConf)
0860:                            && !isBlacklisted(rootModuleConf)) {
0861:                        ret.addAll(Arrays.asList(getArtifacts(rootModuleConf)));
0862:                    }
0863:                }
0864:                ret = FilterHelper.filter(ret, artifactFilter);
0865:                return (Artifact[]) ret.toArray(new Artifact[ret.size()]);
0866:            }
0867:
0868:            /**
0869:             * Returns the artifacts of this dependency required in the configurations themselves required
0870:             * in the given root module configuration
0871:             * 
0872:             * @param rootModuleConf
0873:             * @return
0874:             */
0875:            public Artifact[] getArtifacts(String rootModuleConf) {
0876:                // first we look for the dependency configurations required
0877:                // in the given root module configuration
0878:                Set confs = (Set) rootModuleConfs.get(rootModuleConf);
0879:                if (confs == null) {
0880:                    // no configuration required => no artifact required
0881:                    return new Artifact[0];
0882:                }
0883:                if (md == null) {
0884:                    throw new IllegalStateException(
0885:                            "impossible to get artefacts when data has not been loaded. IvyNode = "
0886:                                    + this .toString());
0887:                }
0888:
0889:                Set artifacts = new HashSet(); // the set we fill before returning
0890:
0891:                // we check if we have dependencyArtifacts includes description for this rootModuleConf
0892:                Set dependencyArtifacts = (Set) this .dependencyArtifacts
0893:                        .get(rootModuleConf);
0894:
0895:                if (md.isDefault() && dependencyArtifacts != null
0896:                        && !dependencyArtifacts.isEmpty()) {
0897:                    // the descriptor is a default one: it has been generated from nothing
0898:                    // moreover, we have dependency artifacts description
0899:                    // these descritions are thus used as if they were declared in the module
0900:                    // descriptor. If one is not really present, the error will be raised
0901:                    // at download time
0902:                    for (Iterator it = dependencyArtifacts.iterator(); it
0903:                            .hasNext();) {
0904:                        DependencyArtifactDescriptor dad = (DependencyArtifactDescriptor) it
0905:                                .next();
0906:                        artifacts.add(new MDArtifact(md, dad.getName(), dad
0907:                                .getType(), dad.getExt(), dad.getUrl(), dad
0908:                                .getExtraAttributes()));
0909:                    }
0910:                } else {
0911:                    Set includes = (Set) dependencyIncludes.get(rootModuleConf);
0912:
0913:                    if ((dependencyArtifacts == null || dependencyArtifacts
0914:                            .isEmpty())
0915:                            && (includes == null || includes.isEmpty())) {
0916:                        // no artifacts / includes: we get all artifacts as defined by the descriptor
0917:                        for (Iterator iter = confs.iterator(); iter.hasNext();) {
0918:                            String conf = (String) iter.next();
0919:                            artifacts.addAll(Arrays.asList(md
0920:                                    .getArtifacts(conf)));
0921:                        }
0922:                    } else {
0923:                        // we have to get only artifacts listed as "includes"
0924:
0925:                        // first we get all artifacts as defined by the module descriptor
0926:                        // and classify them by artifact id
0927:                        Map allArtifacts = new HashMap();
0928:                        for (Iterator iter = confs.iterator(); iter.hasNext();) {
0929:                            String conf = (String) iter.next();
0930:                            Artifact[] arts = md.getArtifacts(conf);
0931:                            for (int i = 0; i < arts.length; i++) {
0932:                                allArtifacts.put(arts[i].getId()
0933:                                        .getArtifactId(), arts[i]);
0934:                            }
0935:                        }
0936:
0937:                        // now we add caller defined ones
0938:                        for (Iterator it = dependencyArtifacts.iterator(); it
0939:                                .hasNext();) {
0940:                            DependencyArtifactDescriptor dad = (DependencyArtifactDescriptor) it
0941:                                    .next();
0942:                            artifacts.add(new MDArtifact(md, dad.getName(), dad
0943:                                    .getType(), dad.getExt(), dad.getUrl(), dad
0944:                                    .getExtraAttributes()));
0945:                        }
0946:
0947:                        // and now we filter according to include rules
0948:                        for (Iterator it = includes.iterator(); it.hasNext();) {
0949:                            IncludeRule dad = (IncludeRule) it.next();
0950:                            Collection arts = findArtifactsMatching(dad,
0951:                                    allArtifacts);
0952:                            if (arts.isEmpty()) {
0953:                                Message
0954:                                        .error("a required artifact is not listed by module descriptor: "
0955:                                                + dad.getId());
0956:                                // we remove it from required list to prevent message to be displayed more
0957:                                // than once
0958:                                it.remove();
0959:                            } else {
0960:                                Message.debug(this  + " in " + rootModuleConf
0961:                                        + ": including " + arts);
0962:                                artifacts.addAll(arts);
0963:                            }
0964:                        }
0965:                    }
0966:                }
0967:
0968:                // now excludes artifacts that aren't accepted by any caller
0969:                for (Iterator iter = artifacts.iterator(); iter.hasNext();) {
0970:                    Artifact artifact = (Artifact) iter.next();
0971:                    boolean excluded = callers.doesCallersExclude(
0972:                            rootModuleConf, artifact);
0973:                    if (excluded) {
0974:                        Message.debug(this  + " in " + rootModuleConf
0975:                                + ": excluding " + artifact);
0976:                        iter.remove();
0977:                    }
0978:                }
0979:                return (Artifact[]) artifacts.toArray(new Artifact[artifacts
0980:                        .size()]);
0981:            }
0982:
0983:            private static Collection findArtifactsMatching(IncludeRule rule,
0984:                    Map allArtifacts) {
0985:                Collection ret = new ArrayList();
0986:                for (Iterator iter = allArtifacts.keySet().iterator(); iter
0987:                        .hasNext();) {
0988:                    ArtifactId aid = (ArtifactId) iter.next();
0989:                    if (MatcherHelper.matches(rule.getMatcher(), rule.getId(),
0990:                            aid)) {
0991:                        ret.add(allArtifacts.get(aid));
0992:                    }
0993:                }
0994:                return ret;
0995:            }
0996:
0997:            private void addDependencyArtifacts(String rootModuleConf,
0998:                    DependencyArtifactDescriptor[] dependencyArtifacts) {
0999:                addObjectsForConf(rootModuleConf, Arrays
1000:                        .asList(dependencyArtifacts), this .dependencyArtifacts);
1001:            }
1002:
1003:            private void addDependencyIncludes(String rootModuleConf,
1004:                    IncludeRule[] rules) {
1005:                addObjectsForConf(rootModuleConf, Arrays.asList(rules),
1006:                        dependencyIncludes);
1007:            }
1008:
1009:            private void addObjectsForConf(String rootModuleConf,
1010:                    Collection objectsToAdd, Map map) {
1011:                Set set = (Set) map.get(rootModuleConf);
1012:                if (set == null) {
1013:                    set = new HashSet();
1014:                    map.put(rootModuleConf, set);
1015:                }
1016:                set.addAll(objectsToAdd);
1017:            }
1018:
1019:            public boolean hasProblem() {
1020:                return problem != null;
1021:            }
1022:
1023:            public Exception getProblem() {
1024:                return problem;
1025:            }
1026:
1027:            public String getProblemMessage() {
1028:                return StringUtils.getErrorMessage(problem);
1029:            }
1030:
1031:            public boolean isDownloaded() {
1032:                return downloaded;
1033:            }
1034:
1035:            public boolean isSearched() {
1036:                return searched;
1037:            }
1038:
1039:            public boolean isLoaded() {
1040:                return md != null;
1041:            }
1042:
1043:            public boolean isFetched(String conf) {
1044:                return fetchedConfigurations.contains(conf);
1045:            }
1046:
1047:            public IvyNode findNode(ModuleRevisionId mrid) {
1048:                return data.getNode(mrid);
1049:            }
1050:
1051:            boolean isRoot() {
1052:                return root == this ;
1053:            }
1054:
1055:            public IvyNode getRoot() {
1056:                return root;
1057:            }
1058:
1059:            public ConflictManager getConflictManager(ModuleId mid) {
1060:                if (md == null) {
1061:                    throw new IllegalStateException(
1062:                            "impossible to get conflict manager when data has not been loaded. IvyNode = "
1063:                                    + this .toString());
1064:                }
1065:                ConflictManager cm = md.getConflictManager(mid);
1066:                return cm == null ? settings.getConflictManager(mid) : cm;
1067:            }
1068:
1069:            public IvyNode getRealNode() {
1070:                IvyNode real = data.getNode(getId());
1071:                return real != null ? real : this ;
1072:            }
1073:
1074:            public ModuleRevisionId getId() {
1075:                return id;
1076:            }
1077:
1078:            public ModuleId getModuleId() {
1079:                return id.getModuleId();
1080:            }
1081:
1082:            public ModuleDescriptor getDescriptor() {
1083:                return md;
1084:            }
1085:
1086:            public ResolveData getData() {
1087:                return data;
1088:            }
1089:
1090:            public ResolvedModuleRevision getModuleRevision() {
1091:                return module;
1092:            }
1093:
1094:            public long getPublication() {
1095:                if (module != null) {
1096:                    return module.getPublicationDate().getTime();
1097:                }
1098:                return 0;
1099:            }
1100:
1101:            /**
1102:             * Returns the last modified timestamp of the module represented by this Node, or 0 if the last
1103:             * modified timestamp is currently unkwown (module not loaded)
1104:             * 
1105:             * @return the last modified timestamp of the module represented by this Node
1106:             */
1107:            public long getLastModified() {
1108:                if (md != null) {
1109:                    return md.getLastModified();
1110:                }
1111:                return 0;
1112:            }
1113:
1114:            public ModuleRevisionId getResolvedId() {
1115:                if (md != null
1116:                        && md.getResolvedModuleRevisionId().getRevision() != null) {
1117:                    return md.getResolvedModuleRevisionId();
1118:                } else if (module != null) {
1119:                    return module.getId();
1120:                } else {
1121:                    return getId();
1122:                }
1123:            }
1124:
1125:            /**
1126:             * Clean data related to one root module configuration only
1127:             */
1128:            public void clean() {
1129:                confsToFetch.clear();
1130:            }
1131:
1132:            // /////////////////////////////////////////////////////////////////////////////
1133:            // CALLERS MANAGEMENT
1134:            // /////////////////////////////////////////////////////////////////////////////
1135:
1136:            boolean canExclude(String rootModuleConf) {
1137:                Caller[] callers = getCallers(rootModuleConf);
1138:                for (int i = 0; i < callers.length; i++) {
1139:                    if (callers[i].canExclude()) {
1140:                        return true;
1141:                    }
1142:                }
1143:                return false;
1144:            }
1145:
1146:            private IvyNode getDirectCallerFor(ModuleId from) {
1147:                return callers.getDirectCallerFor(from);
1148:            }
1149:
1150:            public Caller[] getCallers(String rootModuleConf) {
1151:                return callers.getCallers(rootModuleConf);
1152:            }
1153:
1154:            public Collection getAllCallersModuleIds() {
1155:                return callers.getAllCallersModuleIds();
1156:            }
1157:
1158:            public Caller[] getAllCallers() {
1159:                return callers.getAllCallers();
1160:            }
1161:
1162:            public Caller[] getAllRealCallers() {
1163:                return callers.getAllRealCallers();
1164:            }
1165:
1166:            public void addCaller(String rootModuleConf, IvyNode callerNode,
1167:                    String callerConf, String[] dependencyConfs,
1168:                    DependencyDescriptor dd) {
1169:                callers.addCaller(rootModuleConf, callerNode, callerConf,
1170:                        dependencyConfs, dd);
1171:                boolean isCircular = callers.getAllCallersModuleIds().contains(
1172:                        getId().getModuleId());
1173:                if (isCircular) {
1174:                    IvyContext.getContext().getCircularDependencyStrategy()
1175:                            .handleCircularDependency(
1176:                                    toMrids(findPath(getId().getModuleId()),
1177:                                            this ));
1178:                }
1179:            }
1180:
1181:            public boolean doesCallersExclude(String rootModuleConf,
1182:                    Artifact artifact, Stack callersStack) {
1183:                return callers.doesCallersExclude(rootModuleConf, artifact,
1184:                        callersStack);
1185:            }
1186:
1187:            private ModuleRevisionId[] toMrids(Collection path, IvyNode depNode) {
1188:                ModuleRevisionId[] ret = new ModuleRevisionId[path.size() + 1];
1189:                int i = 0;
1190:                for (Iterator iter = path.iterator(); iter.hasNext(); i++) {
1191:                    IvyNode node = (IvyNode) iter.next();
1192:                    ret[i] = node.getId();
1193:                }
1194:                ret[ret.length - 1] = depNode.getId();
1195:                return ret;
1196:            }
1197:
1198:            // /////////////////////////////////////////////////////////////////////////////
1199:            // EVICTION MANAGEMENT
1200:            // /////////////////////////////////////////////////////////////////////////////
1201:
1202:            public Collection getResolvedNodes(ModuleId moduleId,
1203:                    String rootModuleConf) {
1204:                return eviction.getResolvedNodes(moduleId, rootModuleConf);
1205:            }
1206:
1207:            public Collection getResolvedRevisions(ModuleId moduleId,
1208:                    String rootModuleConf) {
1209:                return eviction.getResolvedRevisions(moduleId, rootModuleConf);
1210:            }
1211:
1212:            public void markEvicted(EvictionData evictionData) {
1213:                eviction.markEvicted(evictionData);
1214:                if (!rootModuleConfs.keySet().contains(
1215:                        evictionData.getRootModuleConf())) {
1216:                    rootModuleConfs.put(evictionData.getRootModuleConf(), null);
1217:                }
1218:
1219:                // bug 105: update selected data with evicted one
1220:                if (evictionData.getSelected() != null) {
1221:                    for (Iterator iter = evictionData.getSelected().iterator(); iter
1222:                            .hasNext();) {
1223:                        IvyNode selected = (IvyNode) iter.next();
1224:                        selected.updateDataFrom(this , evictionData
1225:                                .getRootModuleConf(), false);
1226:                    }
1227:                }
1228:            }
1229:
1230:            public Collection getAllEvictingConflictManagers() {
1231:                return eviction.getAllEvictingConflictManagers();
1232:            }
1233:
1234:            public Collection getAllEvictingNodes() {
1235:                return eviction.getAllEvictingNodes();
1236:            }
1237:
1238:            public Collection/*<String>*/getAllEvictingNodesDetails() {
1239:                return eviction.getAllEvictingNodesDetails();
1240:            }
1241:
1242:            public String[] getEvictedConfs() {
1243:                return eviction.getEvictedConfs();
1244:            }
1245:
1246:            public EvictionData getEvictedData(String rootModuleConf) {
1247:                return eviction.getEvictedData(rootModuleConf);
1248:            }
1249:
1250:            public Collection getEvictedNodes(ModuleId mid,
1251:                    String rootModuleConf) {
1252:                return eviction.getEvictedNodes(mid, rootModuleConf);
1253:            }
1254:
1255:            public Collection getEvictedRevisions(ModuleId mid,
1256:                    String rootModuleConf) {
1257:                return eviction.getEvictedRevisions(mid, rootModuleConf);
1258:            }
1259:
1260:            public EvictionData getEvictionDataInRoot(String rootModuleConf,
1261:                    IvyNode ancestor) {
1262:                return eviction.getEvictionDataInRoot(rootModuleConf, ancestor);
1263:            }
1264:
1265:            public boolean isCompletelyEvicted() {
1266:                return eviction.isCompletelyEvicted();
1267:            }
1268:
1269:            public boolean isEvicted(String rootModuleConf) {
1270:                return eviction.isEvicted(rootModuleConf);
1271:            }
1272:
1273:            public void markEvicted(String rootModuleConf, IvyNode node,
1274:                    ConflictManager conflictManager, Collection resolved) {
1275:                EvictionData evictionData = new EvictionData(rootModuleConf,
1276:                        node, conflictManager, resolved);
1277:                markEvicted(evictionData);
1278:            }
1279:
1280:            public void setEvictedNodes(ModuleId moduleId,
1281:                    String rootModuleConf, Collection evicted) {
1282:                eviction.setEvictedNodes(moduleId, rootModuleConf, evicted);
1283:            }
1284:
1285:            public void setResolvedNodes(ModuleId moduleId,
1286:                    String rootModuleConf, Collection resolved) {
1287:                eviction.setResolvedNodes(moduleId, rootModuleConf, resolved);
1288:            }
1289:
1290:            public String toString() {
1291:                return getResolvedId().toString();
1292:            }
1293:
1294:            public boolean equals(Object obj) {
1295:                if (!(obj instanceof  IvyNode)) {
1296:                    return false;
1297:                }
1298:                IvyNode node = (IvyNode) obj;
1299:                return node.getId().equals(getId());
1300:            }
1301:
1302:            public int compareTo(Object obj) {
1303:                IvyNode that = (IvyNode) obj;
1304:                return this .getModuleId().compareTo(that.getModuleId());
1305:            }
1306:
1307:            public int hashCode() {
1308:                return getId().hashCode();
1309:            }
1310:
1311:            /**
1312:             * Returns a collection of Nodes in conflict for which conflict has been detected but conflict
1313:             * resolution hasn't been done yet
1314:             * 
1315:             * @param rootModuleConf
1316:             * @param mid
1317:             *            the module id for which pending conflicts should be found
1318:             * @return a Collection of IvyNode in pending conflict
1319:             */
1320:            public Collection getPendingConflicts(String rootModuleConf,
1321:                    ModuleId mid) {
1322:                return eviction.getPendingConflicts(rootModuleConf, mid);
1323:            }
1324:
1325:            public void setPendingConflicts(ModuleId moduleId,
1326:                    String rootModuleConf, Collection conflicts) {
1327:                eviction.setPendingConflicts(moduleId, rootModuleConf,
1328:                        conflicts);
1329:            }
1330:
1331:            // /////////////////////////////////////////////////////////////////////////////
1332:            // BLACKLISTING MANAGEMENT
1333:            // /////////////////////////////////////////////////////////////////////////////
1334:
1335:            /**
1336:             * Blacklists the current node, so that a new resolve process won't ever consider this node as
1337:             * available in the repository.
1338:             * <p>
1339:             * This is useful in combination with {@link RestartResolveProcess} for conflict manager
1340:             * implementation which use a best effort strategy to find compatible dependency set, like
1341:             * {@link LatestCompatibleConflictManager}
1342:             * </p>
1343:             * 
1344:             * @param rootModuleConf the root module configuration in which the node should be blacklisted
1345:             */
1346:            public void blacklist(IvyNodeBlacklist bdata) {
1347:                if (data.getSettings().logResolvedRevision()) {
1348:                    Message.info("BLACKLISTING " + bdata);
1349:                } else {
1350:                    Message.verbose("BLACKLISTING " + bdata);
1351:                }
1352:
1353:                Stack callerStack = new Stack();
1354:                callerStack.push(this );
1355:                clearEvictionDataInAllCallers(bdata.getRootModuleConf(),
1356:                        callerStack);
1357:
1358:                blacklisted.put(bdata.getRootModuleConf(), bdata);
1359:                data.blacklist(this );
1360:            }
1361:
1362:            private void clearEvictionDataInAllCallers(String rootModuleConf,
1363:                    Stack/*<IvyNode>*/callerStack) {
1364:                IvyNode node = (IvyNode) callerStack.peek();
1365:                Caller[] callers = node.getCallers(rootModuleConf);
1366:                for (int i = 0; i < callers.length; i++) {
1367:                    IvyNode callerNode = findNode(callers[i]
1368:                            .getModuleRevisionId());
1369:                    if (callerNode != null) {
1370:                        callerNode.eviction = new IvyNodeEviction(callerNode);
1371:                        if (!callerStack.contains(callerNode)) {
1372:                            callerStack.push(callerNode);
1373:                            clearEvictionDataInAllCallers(rootModuleConf,
1374:                                    callerStack);
1375:                            callerStack.pop();
1376:                        }
1377:                    }
1378:                }
1379:            }
1380:
1381:            /**
1382:             * Indicates if this node has been blacklisted in the given root module conf.
1383:             * <p>
1384:             * A blacklisted node should be considered as if it doesn't even exist on the repository.
1385:             * </p>
1386:             * 
1387:             * @param rootModuleConf
1388:             *            the root module conf for which we'd like to know if the node is blacklisted
1389:             * 
1390:             * @return true if this node is blacklisted int he given root module conf, false otherwise
1391:             * @see #blacklist(String)
1392:             */
1393:            public boolean isBlacklisted(String rootModuleConf) {
1394:                return blacklisted.containsKey(rootModuleConf);
1395:            }
1396:
1397:            /**
1398:             * Indicates if this node has been blacklisted in all root module configurations.
1399:             * 
1400:             * @return true if this node is blacklisted in all root module configurations, false otherwise
1401:             * @see #blacklist(String)
1402:             */
1403:            public boolean isCompletelyBlacklisted() {
1404:                if (isRoot()) {
1405:                    return false;
1406:                }
1407:                String[] rootModuleConfigurations = getRootModuleConfigurations();
1408:                for (int i = 0; i < rootModuleConfigurations.length; i++) {
1409:                    if (!isBlacklisted(rootModuleConfigurations[i])) {
1410:                        return false;
1411:                    }
1412:                }
1413:                return true;
1414:            }
1415:
1416:            /**
1417:             * Returns the blacklist data of this node in the given root module conf, or <code>null</code>
1418:             * if this node is not blacklisted in this root module conf.
1419:             * 
1420:             * @param rootModuleConf
1421:             *            the root module configuration to consider
1422:             * @return the blacklist data if any
1423:             */
1424:            public IvyNodeBlacklist getBlacklistData(String rootModuleConf) {
1425:                return (IvyNodeBlacklist) blacklisted.get(rootModuleConf);
1426:            }
1427:
1428:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.