]> source.dussan.org Git - sonarqube.git/blob
2882a03a93b323cdacbaa83cf2efa9d3a044b845
[sonarqube.git] /
1 /*
2  * SonarQube, open source software quality management tool.
3  * Copyright (C) 2008-2014 SonarSource
4  * mailto:contact AT sonarsource DOT com
5  *
6  * SonarQube is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * SonarQube is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 package org.sonar.server.computation.component;
22
23 import static java.util.Objects.requireNonNull;
24
25 /**
26  * Implementation of {@link ComponentCrawler} that implements a depth traversal of a {@link Component} tree.
27  * <p>It supports visiting traversal in either pre-order or post-order</p>
28  * It supports a max depth for crawling (component strictly deeper than the specified type will be ignored).
29  */
30 public final class DepthTraversalTypeAwareCrawler implements ComponentCrawler {
31   private final TypeAwareVisitor visitor;
32
33   public DepthTraversalTypeAwareCrawler(TypeAwareVisitor visitor) {
34     this.visitor = requireNonNull(visitor);
35   }
36
37   @Override
38   public void visit(Component component) {
39     try {
40       visitImpl(component);
41     } catch (RuntimeException e) {
42       VisitException.rethrowOrWrap(e, "Visit of Component %s:%s failed", component.getType(), component.getKey());
43     }
44   }
45
46   private void visitImpl(Component component) {
47     if (!verifyDepth(component)) {
48       return;
49     }
50
51     if (this.visitor.getOrder() == ComponentVisitor.Order.PRE_ORDER) {
52       visitNode(component);
53     }
54
55     visitChildren(component);
56
57     if (this.visitor.getOrder() == ComponentVisitor.Order.POST_ORDER) {
58       visitNode(component);
59     }
60   }
61
62   private boolean verifyDepth(Component component) {
63     CrawlerDepthLimit maxDepth = this.visitor.getMaxDepth();
64     return maxDepth.isSameAs(component.getType()) || maxDepth.isDeeperThan(component.getType());
65   }
66
67   private void visitNode(Component component) {
68     this.visitor.visitAny(component);
69     switch (component.getType()) {
70       case PROJECT:
71         this.visitor.visitProject(component);
72         break;
73       case MODULE:
74         this.visitor.visitModule(component);
75         break;
76       case DIRECTORY:
77         this.visitor.visitDirectory(component);
78         break;
79       case FILE:
80         this.visitor.visitFile(component);
81         break;
82       case VIEW:
83         this.visitor.visitView(component);
84         break;
85       case SUBVIEW:
86         this.visitor.visitSubView(component);
87         break;
88       case PROJECT_VIEW:
89         this.visitor.visitProjectView(component);
90         break;
91       default:
92         throw new IllegalArgumentException("Unsupported Component type " + component.getType());
93     }
94   }
95
96   private void visitChildren(Component component) {
97     for (Component child : component.getChildren()) {
98       if (verifyDepth(child)) {
99         visit(child);
100       }
101     }
102   }
103
104 }