]> source.dussan.org Git - sonarqube.git/commitdiff
Create TypeAwareVisitor and PathAwareVisitor
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 6 Aug 2015 15:59:39 +0000 (17:59 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 10 Aug 2015 12:18:18 +0000 (14:18 +0200)
38 files changed:
server/sonar-server/src/main/java/org/sonar/server/computation/component/ComponentCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/DepthTraversalTypeAwareCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/DequeBasedPath.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitor.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorAdapter.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorWrapper.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitor.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorAdapter.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorWrapper.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/Visitor.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/component/VisitorWrapper.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/formula/FormulaExecutorComponentCrawler.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputeQProfileMeasureStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/CustomMeasuresCopyStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/FillMeasuresWithVariationsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/IntegrateIssuesStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateEventsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateMeasuresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityProfileEventsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/SizeMeasuresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/SqaleMeasuresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/ValidateProjectStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/component/PathAwareCrawlerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/component/PostOrderDepthTraversalTypeAwareCrawlerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/component/PreOrderDepthTraversalTypeAwareCrawlerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureRepositoryRule.java

index 37599cd028390d8aa1d9ee8f0b840dc3ddf938d4..5ba2fef550ca92a4fddbc81acb0adfcd31aa9e9e 100644 (file)
  */
 package org.sonar.server.computation.component;
 
+/**
+ * Allow to crawl a component tree from a given component
+ */
 public interface ComponentCrawler {
-  void visit(Component tree);
 
-  enum Order {
-    /**
-     * Each component is visited BEFORE its children. Top-down traversal of
-     * tree of components.
-     */
-    PRE_ORDER,
+  void visit(Component tree);
 
-    /**
-     * Each component is visited AFTER its children. Bottom-up traversal of
-     * tree of components.
-     */
-    POST_ORDER
-  }
 }
index 0e7d10786ef22ef8dc2e48e42d82582b3f804b9f..5557e22c38d2b8bd4a1d5eb56f3fe607673a591f 100644 (file)
@@ -29,9 +29,9 @@ import static java.util.Objects.requireNonNull;
  */
 public abstract class DepthTraversalTypeAwareCrawler implements TypeAwareCrawler {
   private final Component.Type maxDepth;
-  private final Order order;
+  private final Visitor.Order order;
 
-  protected DepthTraversalTypeAwareCrawler(Component.Type maxDepth, Order order) {
+  protected DepthTraversalTypeAwareCrawler(Component.Type maxDepth, Visitor.Order order) {
     this.maxDepth = requireNonNull(maxDepth);
     this.order = requireNonNull(order);
   }
@@ -42,17 +42,27 @@ public abstract class DepthTraversalTypeAwareCrawler implements TypeAwareCrawler
       return;
     }
 
-    if (order == Order.PRE_ORDER) {
+    if (order == Visitor.Order.PRE_ORDER) {
       visitNode(component);
     }
 
     visitChildren(component);
 
-    if (order == Order.POST_ORDER) {
+    if (order == Visitor.Order.POST_ORDER) {
       visitNode(component);
     }
   }
 
+  @Override
+  public Component.Type getMaxDepth() {
+    return maxDepth;
+  }
+
+  @Override
+  public Order getOrder() {
+    return order;
+  }
+
   private void visitNode(Component component) {
     visitAny(component);
     switch (component.getType()) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/DequeBasedPath.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/DequeBasedPath.java
new file mode 100644 (file)
index 0000000..0c7bb8f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class DequeBasedPath<T> implements PathAwareVisitor.Path<T>, Iterable<PathAwareVisitor.PathElement<T>> {
+  private final Deque<PathAwareVisitor.PathElement<T>> deque = new ArrayDeque<>();
+
+  @Override
+  public T current() {
+    return deque.getFirst().getElement();
+  }
+
+  @Override
+  public T parent() {
+    Iterator<PathAwareVisitor.PathElement<T>> iterator = deque.iterator();
+    if (iterator.hasNext()) {
+      iterator.next();
+      if (iterator.hasNext()) {
+        return iterator.next().getElement();
+      }
+    }
+    throw new NoSuchElementException("Path is either empty or has only one element. There is no parent");
+  }
+
+  @Override
+  public boolean isRoot() {
+    return deque.size() == 1;
+  }
+
+  @Override
+  public T root() {
+    return deque.getLast().getElement();
+  }
+
+  @Override
+  public Iterator<PathAwareVisitor.PathElement<T>> iterator() {
+    return deque.iterator();
+  }
+
+  @Override
+  public Iterable<PathAwareVisitor.PathElement<T>> getCurrentPath() {
+    return this;
+  }
+
+  public void add(PathAwareVisitor.PathElement<T> pathElement) {
+    deque.addFirst(pathElement);
+  }
+
+  public PathAwareVisitor.PathElement<T> pop() {
+    return deque.pop();
+  }
+}
index 119fbe6d7461fc189109e483ca38970820c27419..c73e78c355d1b09c3eb268022e6f8417b4a4d09a 100644 (file)
  */
 package org.sonar.server.computation.component;
 
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import static java.util.Objects.requireNonNull;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
- * A ComponentVisitor which provide access to a representation of the path from the root to the currently visited
+ * A {@link ComponentCrawler} which provide access to a representation of the path from the root to the currently visited
  * Component. It also provides a way to have an object associated to each Component and access it and all of its
  * parent's.
- * As for {@link DepthTraversalTypeAwareCrawler}, this visitor supports max depth visit and ordering.
+ * As for {@link DepthTraversalTypeAwareCrawler}, this crawler supports max depth visit and ordering.
  */
-public abstract class PathAwareCrawler<T> implements ComponentCrawler {
-  private final Component.Type maxDepth;
-  private final Order order;
-  private final StackElementFactory<T> factory;
+public abstract class PathAwareCrawler<T> extends PathAwareVisitorAdapter<T> implements ComponentCrawler {
+
   private final DequeBasedPath<T> stack = new DequeBasedPath<>();
 
-  public PathAwareCrawler(Component.Type maxDepth, Order order, StackElementFactory<T> factory) {
-    this.maxDepth = requireNonNull(maxDepth);
-    this.order = requireNonNull(order);
-    this.factory = requireNonNull(factory, "Factory can not be null");
+  public PathAwareCrawler(Component.Type maxDepth, Visitor.Order order, StackElementFactory<T> factory) {
+    super(maxDepth, order, factory);
   }
 
   @Override
   public void visit(Component component) {
-    if (component.getType().isDeeperThan(maxDepth)) {
+    if (component.getType().isDeeperThan(getMaxDepth())) {
       return;
     }
 
     stack.add(new PathElementImpl<>(component, createForComponent(component)));
 
-    if (order == PRE_ORDER) {
+    if (getOrder() == PRE_ORDER) {
       visitNode(component);
     }
 
     visitChildren(component);
 
-    if (order == POST_ORDER) {
+    if (getOrder() == POST_ORDER) {
       visitNode(component);
     }
 
     stack.pop();
   }
 
-  private T createForComponent(Component component) {
-    switch (component.getType()) {
-      case PROJECT:
-        return factory.createForProject(component);
-      case MODULE:
-        return factory.createForModule(component);
-      case DIRECTORY:
-        return factory.createForDirectory(component);
-      case FILE:
-        return factory.createForFile(component);
-      default:
-        return factory.createForUnknown(component);
-    }
-  }
-
   private void visitChildren(Component component) {
     for (Component child : component.getChildren()) {
-      if (!child.getType().isDeeperThan(maxDepth)) {
+      if (!child.getType().isDeeperThan(getMaxDepth())) {
         visit(child);
       }
     }
@@ -110,174 +85,26 @@ public abstract class PathAwareCrawler<T> implements ComponentCrawler {
     }
   }
 
-  protected void visitProject(Component project, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  protected void visitModule(Component module, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  protected void visitDirectory(Component directory, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  protected void visitFile(Component file, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  protected void visitUnknown(Component unknownComponent, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  protected void visitAny(Component component, Path<T> path) {
-    // empty implementation, meant to be override at will by subclasses
-  }
-
-  public interface StackElementFactory<T> {
-    T createForProject(Component project);
-
-    T createForModule(Component module);
-
-    T createForDirectory(Component directory);
-
-    T createForFile(Component file);
-
-    T createForUnknown(Component file);
-  }
-
-  /**
-   * A Simple implementation which uses the same factory method for all types which can be implemented by subclasses:
-   * {@link #createForAny(Component)}.
-   */
-  public abstract static class SimpleStackElementFactory<T> implements StackElementFactory<T> {
-
-    public abstract T createForAny(Component component);
-
-    @Override
-    public T createForProject(Component project) {
-      return createForAny(project);
-    }
-
-    @Override
-    public T createForModule(Component module) {
-      return createForAny(module);
-    }
-
-    @Override
-    public T createForDirectory(Component directory) {
-      return createForAny(directory);
-    }
-
-    @Override
-    public T createForFile(Component file) {
-      return createForAny(file);
-    }
-
-    @Override
-    public T createForUnknown(Component file) {
-      return createForAny(file);
-    }
-  }
-
-  private static class DequeBasedPath<T> implements Path<T>, Iterable<PathElement<T>> {
-    private final Deque<PathElement<T>> deque = new ArrayDeque<>();
-
-    @Override
-    public T current() {
-      return deque.getFirst().getElement();
-    }
-
-    @Override
-    public T parent() {
-      Iterator<PathElement<T>> iterator = deque.iterator();
-      if (iterator.hasNext()) {
-        iterator.next();
-        if (iterator.hasNext()) {
-          return iterator.next().getElement();
-        }
-      }
-      throw new NoSuchElementException("Path is either empty or has only one element. There is no parent");
-    }
-
-    @Override
-    public boolean isRoot() {
-      return deque.size() == 1;
-    }
-
-    @Override
-    public T root() {
-      return deque.getLast().getElement();
-    }
-
-    @Override
-    public Iterator<PathElement<T>> iterator() {
-      return deque.iterator();
-    }
-
-    @Override
-    public Iterable<PathElement<T>> getCurrentPath() {
-      return this;
-    }
-
-    public void add(PathElement<T> pathElement) {
-      deque.addFirst(pathElement);
-    }
-
-    public PathElement<T> pop() {
-      return deque.pop();
+  private T createForComponent(Component component) {
+    switch (component.getType()) {
+      case PROJECT:
+        return getFactory().createForProject(component);
+      case MODULE:
+        return getFactory().createForModule(component);
+      case DIRECTORY:
+        return getFactory().createForDirectory(component);
+      case FILE:
+        return getFactory().createForFile(component);
+      default:
+        return getFactory().createForUnknown(component);
     }
   }
 
-  public interface Path<T> {
-    /**
-     * The stacked element of the current Component.
-     */
-    T current();
-
-    /**
-     * Tells whether the current Component is the root of the tree.
-     */
-    boolean isRoot();
-
-    /**
-     * The stacked element of the parent of the current Component.
-     *
-     * @throws NoSuchElementException if the current Component is the root of the tree
-     * @see #isRoot()
-     */
-    T parent();
-
-    /**
-     * The stacked element of the root of the tree.
-     */
-    T root();
-
-    /**
-     * The path to the current Component as an Iterable of {@link PathAwareCrawler.PathElement} which starts with
-     * the {@link PathAwareCrawler.PathElement} of the current Component and ends with the
-     * {@link PathAwareCrawler.PathElement} of the root of the tree.
-     */
-    Iterable<PathElement<T>> getCurrentPath();
-  }
-
-  public interface PathElement<T> {
-    /**
-     * The Component on the path.
-     */
-    Component getComponent();
-
-    /**
-     * The stacked element for the Component of this PathElement.
-     */
-    T getElement();
-  }
-
-  private static final class PathElementImpl<T> implements PathElement<T> {
+  public static final class PathElementImpl<T> implements PathElement<T> {
     private final Component component;
     private final T element;
 
-    private PathElementImpl(Component component, T element) {
+    public PathElementImpl(Component component, T element) {
       this.component = component;
       this.element = element;
     }
@@ -292,4 +119,5 @@ public abstract class PathAwareCrawler<T> implements ComponentCrawler {
       return element;
     }
   }
+
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitor.java
new file mode 100644 (file)
index 0000000..3c4473f
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+import java.util.NoSuchElementException;
+
+/**
+ * A {@link Visitor} which provide access to a representation of the path from the root to the currently visited
+ * Component. It also provides a way to have an object associated to each Component and access it and all of its
+ * parent's.
+ */
+public interface PathAwareVisitor<T> extends Visitor {
+
+  StackElementFactory<T> getFactory();
+
+  void visitProject(Component project, Path<T> path);
+
+  void visitModule(Component module, Path<T> path);
+
+  void visitDirectory(Component directory, Path<T> path);
+
+  void visitFile(Component file, Path<T> path);
+
+  void visitUnknown(Component unknownComponent, Path<T> path);
+
+  void visitAny(Component component, Path<T> path);
+
+  interface StackElementFactory<T> {
+    T createForProject(Component project);
+
+    T createForModule(Component module);
+
+    T createForDirectory(Component directory);
+
+    T createForFile(Component file);
+
+    T createForUnknown(Component file);
+  }
+
+  interface Path<T> {
+    /**
+     * The stacked element of the current Component.
+     */
+    T current();
+
+    /**
+     * Tells whether the current Component is the root of the tree.
+     */
+    boolean isRoot();
+
+    /**
+     * The stacked element of the parent of the current Component.
+     *
+     * @throws NoSuchElementException if the current Component is the root of the tree
+     * @see #isRoot()
+     */
+    T parent();
+
+    /**
+     * The stacked element of the root of the tree.
+     */
+    T root();
+
+    /**
+     * The path to the current Component as an Iterable of {@link PathAwareVisitor.PathElement} which starts with
+     * the {@link PathAwareVisitor.PathElement} of the current Component and ends with the
+     * {@link PathAwareVisitor.PathElement} of the root of the tree.
+     */
+    Iterable<PathElement<T>> getCurrentPath();
+  }
+
+  interface PathElement<T> {
+    /**
+     * The Component on the path.
+     */
+    Component getComponent();
+
+    /**
+     * The stacked element for the Component of this PathElement.
+     */
+    T getElement();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorAdapter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorAdapter.java
new file mode 100644 (file)
index 0000000..775e7b6
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A adapter of the {@link PathAwareVisitor} to be able to visit only some component types
+ */
+public abstract class PathAwareVisitorAdapter<T> implements PathAwareVisitor<T> {
+  private final Component.Type maxDepth;
+  private final Order order;
+  private final StackElementFactory<T> factory;
+
+  public PathAwareVisitorAdapter(Component.Type maxDepth, Order order, StackElementFactory<T> factory) {
+    this.maxDepth = requireNonNull(maxDepth);
+    this.order = requireNonNull(order);
+    this.factory = requireNonNull(factory, "Factory can not be null");
+  }
+
+  @Override
+  public Component.Type getMaxDepth() {
+    return maxDepth;
+  }
+
+  @Override
+  public Order getOrder() {
+    return order;
+  }
+
+  @Override
+  public StackElementFactory<T> getFactory() {
+    return factory;
+  }
+
+  @Override
+  public void visitProject(Component project, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  @Override
+  public void visitModule(Component module, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  @Override
+  public void visitDirectory(Component directory, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  @Override
+  public void visitFile(Component file, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  @Override
+  public void visitUnknown(Component unknownComponent, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  @Override
+  public void visitAny(Component component, Path<T> path) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  /**
+   * A Simple implementation which uses the same factory method for all types which can be implemented by subclasses:
+   * {@link #createForAny(Component)}.
+   */
+  public abstract static class SimpleStackElementFactory<T> implements StackElementFactory<T> {
+
+    public abstract T createForAny(Component component);
+
+    @Override
+    public T createForProject(Component project) {
+      return createForAny(project);
+    }
+
+    @Override
+    public T createForModule(Component module) {
+      return createForAny(module);
+    }
+
+    @Override
+    public T createForDirectory(Component directory) {
+      return createForAny(directory);
+    }
+
+    @Override
+    public T createForFile(Component file) {
+      return createForAny(file);
+    }
+
+    @Override
+    public T createForUnknown(Component file) {
+      return createForAny(file);
+    }
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorWrapper.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/PathAwareVisitorWrapper.java
new file mode 100644 (file)
index 0000000..ba36b28
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+public class PathAwareVisitorWrapper<T> implements VisitorWrapper {
+
+  private final PathAwareVisitor<T> delegate;
+
+  private final DequeBasedPath<T> stack = new DequeBasedPath<>();
+
+  public PathAwareVisitorWrapper(PathAwareVisitor<T> delegate) {
+    this.delegate = delegate;
+  }
+
+  @Override
+  public void beforeComponent(Component component){
+    stack.add(new PathElementImpl<>(component, createForComponent(component)));
+  }
+
+  @Override
+  public void afterComponent(Component component){
+    stack.pop();
+  }
+
+  @Override
+  public void visitProject(Component tree) {
+    delegate.visitProject(tree, stack);
+  }
+
+  @Override
+  public void visitModule(Component tree) {
+    delegate.visitModule(tree, stack);
+  }
+
+  @Override
+  public void visitDirectory(Component tree) {
+    delegate.visitDirectory(tree, stack);
+  }
+
+  @Override
+  public void visitFile(Component tree) {
+    delegate.visitFile(tree, stack);
+  }
+
+  @Override
+  public void visitAny(Component component) {
+    delegate.visitAny(component, stack);
+  }
+
+  @Override
+  public Visitor.Order getOrder() {
+    return delegate.getOrder();
+  }
+
+  @Override
+  public Component.Type getMaxDepth() {
+    return delegate.getMaxDepth();
+  }
+
+  private T createForComponent(Component component) {
+    switch (component.getType()) {
+      case PROJECT:
+        return delegate.getFactory().createForProject(component);
+      case MODULE:
+        return delegate.getFactory().createForModule(component);
+      case DIRECTORY:
+        return delegate.getFactory().createForDirectory(component);
+      case FILE:
+        return delegate.getFactory().createForFile(component);
+      default:
+        return delegate.getFactory().createForUnknown(component);
+    }
+  }
+
+  public static final class PathElementImpl<T> implements PathAwareVisitor.PathElement<T> {
+    private final Component component;
+    private final T element;
+
+    public PathElementImpl(Component component, T element) {
+      this.component = component;
+      this.element = element;
+    }
+
+    @Override
+    public Component getComponent() {
+      return component;
+    }
+
+    @Override
+    public T getElement() {
+      return element;
+    }
+  }
+}
index 6cd47a20ed42ff2d19aac89ea3e54f315e11535f..11337d9ee3ec324e4003afc3eda81c7639f8b67b 100644 (file)
@@ -23,7 +23,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 /**
  * Holds the reference to the root of the {@link Component} tree for the current CE run.
index cf9117baadf9a490c828441847fafc505f1e674f..2a10a165a6ed4184749c73f3b4f9d367ddb93efe 100644 (file)
@@ -22,34 +22,10 @@ package org.sonar.server.computation.component;
 /**
  * A {@link ComponentCrawler} which can exposes methods which ensure the type of the visited Component.
  */
-public interface TypeAwareCrawler extends ComponentCrawler {
-  /**
-   * Called when encountering a Component of type {@link Component.Type#PROJECT}
-   */
-  void visitProject(Component tree);
-
-  /**
-   * Called when encountering a Component of type {@link Component.Type#MODULE}
-   */
-  void visitModule(Component tree);
-
-  /**
-   * Called when encountering a Component of type {@link Component.Type#DIRECTORY}
-   */
-  void visitDirectory(Component tree);
-
-  /**
-   * Called when encountering a Component of type {@link Component.Type#FILE}
-   */
-  void visitFile(Component tree);
+public interface TypeAwareCrawler extends ComponentCrawler, TypeAwareVisitor {
 
   /**
    * Called when encountering a Component of an unknown type
    */
   void visitUnknown(Component tree);
-
-  /**
-   * Called for any component, <strong>in addition</strong> to the methods specific to each type
-   */
-  void visitAny(Component component);
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitor.java
new file mode 100644 (file)
index 0000000..180ad42
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+/**
+ * A {@link Visitor} which can exposes methods which ensure the type of the visited Component.
+ */
+public interface TypeAwareVisitor extends Visitor {
+  /**
+   * Called when encountering a Component of type {@link Component.Type#PROJECT}
+   */
+  void visitProject(Component project);
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#MODULE}
+   */
+  void visitModule(Component module);
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#DIRECTORY}
+   */
+  void visitDirectory(Component directory);
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#FILE}
+   */
+  void visitFile(Component file);
+
+  /**
+   * Called for any component, <strong>in addition</strong> to the methods specific to each type
+   */
+  void visitAny(Component any);
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorAdapter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorAdapter.java
new file mode 100644 (file)
index 0000000..ad95557
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A adapter of the {@link TypeAwareVisitor} to be able to visit only some component types
+ */
+public abstract class TypeAwareVisitorAdapter implements TypeAwareVisitor {
+
+  private final Component.Type maxDepth;
+  private final Order order;
+
+  public TypeAwareVisitorAdapter(Component.Type maxDepth, Order order) {
+    this.maxDepth = requireNonNull(maxDepth);
+    this.order = requireNonNull(order);
+  }
+
+  @Override
+  public Component.Type getMaxDepth() {
+    return maxDepth;
+  }
+
+  @Override
+  public Order getOrder() {
+    return order;
+  }
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#PROJECT}
+   */
+  @Override
+  public void visitProject(Component project) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#MODULE}
+   */
+  @Override
+  public void visitModule(Component module) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#DIRECTORY}
+   */
+  @Override
+  public void visitDirectory(Component directory) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  /**
+   * Called when encountering a Component of type {@link Component.Type#FILE}
+   */
+  @Override
+  public void visitFile(Component file) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+  /**
+   * Called for any component, <strong>in addition</strong> to the methods specific to each type
+   */
+  @Override
+  public void visitAny(Component any) {
+    // empty implementation, meant to be override at will by subclasses
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorWrapper.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TypeAwareVisitorWrapper.java
new file mode 100644 (file)
index 0000000..fb28c9b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+public class TypeAwareVisitorWrapper implements VisitorWrapper {
+
+  private final TypeAwareVisitor delegate;
+
+  public TypeAwareVisitorWrapper(TypeAwareVisitor delegate) {
+    this.delegate = delegate;
+  }
+
+  @Override
+  public void beforeComponent(Component component){
+    // Nothing to do
+  }
+
+  @Override
+  public void afterComponent(Component component){
+    // Nothing to do
+  }
+
+  @Override
+  public void visitProject(Component tree) {
+    delegate.visitProject(tree);
+  }
+
+  @Override
+  public void visitModule(Component tree) {
+    delegate.visitModule(tree);
+  }
+
+  @Override
+  public void visitDirectory(Component tree) {
+    delegate.visitDirectory(tree);
+  }
+
+  @Override
+  public void visitFile(Component tree) {
+    delegate.visitFile(tree);
+  }
+
+  @Override
+  public void visitAny(Component component) {
+    delegate.visitAny(component);
+  }
+
+  @Override
+  public Visitor.Order getOrder() {
+    return delegate.getOrder();
+  }
+
+  @Override
+  public Component.Type getMaxDepth() {
+    return delegate.getMaxDepth();
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/Visitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/Visitor.java
new file mode 100644 (file)
index 0000000..017d597
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+public interface Visitor {
+
+  Order getOrder();
+
+  Component.Type getMaxDepth();
+
+  enum Order {
+    /**
+     * Each component is visited BEFORE its children. Top-down traversal of
+     * tree of components.
+     */
+    PRE_ORDER,
+
+    /**
+     * Each component is visited AFTER its children. Bottom-up traversal of
+     * tree of components.
+     */
+    POST_ORDER
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/VisitorWrapper.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/VisitorWrapper.java
new file mode 100644 (file)
index 0000000..21a782f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.component;
+
+public interface VisitorWrapper extends TypeAwareVisitor {
+
+  void beforeComponent(Component component);
+
+  void afterComponent(Component component);
+
+}
index ef0d10adc0b0d50b11ccb87990070789be014142..9b86cec3a3015e700da50deff52a95033842f83f 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Map;
 import javax.annotation.CheckForNull;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.PathAwareCrawler;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.measure.Measure;
 import org.sonar.server.computation.measure.MeasureRepository;
 import org.sonar.server.computation.metric.Metric;
@@ -58,7 +59,7 @@ public class FormulaExecutorComponentCrawler extends PathAwareCrawler<FormulaExe
   private final List<Formula> formulas;
 
   private FormulaExecutorComponentCrawler(Builder builder, List<Formula> formulas) {
-    super(Component.Type.FILE, Order.POST_ORDER, COUNTERS_FACTORY);
+    super(Component.Type.FILE, Visitor.Order.POST_ORDER, COUNTERS_FACTORY);
     this.periodsHolder = builder.periodsHolder;
     this.measureRepository = builder.measureRepository;
     this.metricRepository = builder.metricRepository;
@@ -95,22 +96,22 @@ public class FormulaExecutorComponentCrawler extends PathAwareCrawler<FormulaExe
   }
 
   @Override
-  protected void visitProject(Component project, Path<FormulaExecutorComponentCrawler.Counters> path) {
+  public void visitProject(Component project, Path<FormulaExecutorComponentCrawler.Counters> path) {
     processNotFile(project, path);
   }
 
   @Override
-  protected void visitModule(Component module, Path<FormulaExecutorComponentCrawler.Counters> path) {
+  public void visitModule(Component module, Path<FormulaExecutorComponentCrawler.Counters> path) {
     processNotFile(module, path);
   }
 
   @Override
-  protected void visitDirectory(Component directory, Path<FormulaExecutorComponentCrawler.Counters> path) {
+  public void visitDirectory(Component directory, Path<FormulaExecutorComponentCrawler.Counters> path) {
     processNotFile(directory, path);
   }
 
   @Override
-  protected void visitFile(Component file, Path<FormulaExecutorComponentCrawler.Counters> path) {
+  public void visitFile(Component file, Path<FormulaExecutorComponentCrawler.Counters> path) {
     processFile(file, path);
   }
 
index 71e2486691739cea341c3a0d95c657d210a38c88..1ba19ba8ec9bc72774200a2130b0ce831a538add 100644 (file)
@@ -36,7 +36,7 @@ import org.sonar.server.computation.qualityprofile.QPMeasureData;
 import org.sonar.server.computation.qualityprofile.QualityProfile;
 
 import static org.sonar.server.computation.component.Component.Type.MODULE;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 /**
  * Aggregates quality profile on lower-level module nodes on their parent modules and project
@@ -74,7 +74,7 @@ public class ComputeQProfileMeasureStep implements ComputationStep {
     }
 
     @Override
-    protected void visitProject(Component project, Path<QProfiles> path) {
+    public void visitProject(Component project, Path<QProfiles> path) {
       addMeasure(project, path.current());
       Optional<Measure> qProfileMeasure = measureRepository.getRawMeasure(project, qProfilesMetric);
       if (!qProfileMeasure.isPresent() || QPMeasureData.fromJson(qProfileMeasure.get().getData()).getProfiles().isEmpty()) {
@@ -84,7 +84,7 @@ public class ComputeQProfileMeasureStep implements ComputationStep {
     }
 
     @Override
-    protected void visitModule(Component module, Path<QProfiles> path) {
+    public void visitModule(Component module, Path<QProfiles> path) {
       Optional<Measure> measure = measureRepository.getRawMeasure(module, qProfilesMetric);
       QProfiles qProfiles = path.current();
       if (measure.isPresent()) {
index 3f0339c71483cc1591cdad35268930cb94023e80..bc5e02d52e91053a6a2a491f8c34174fcd64e70f 100644 (file)
@@ -29,6 +29,7 @@ import org.sonar.db.measure.custom.CustomMeasureDto;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.measure.Measure;
 import org.sonar.server.computation.measure.MeasureRepository;
 import org.sonar.server.computation.metric.Metric;
@@ -51,7 +52,7 @@ public class CustomMeasuresCopyStep implements ComputationStep {
 
   @Override
   public void execute() {
-    new DepthTraversalTypeAwareCrawler(Component.Type.FILE, DepthTraversalTypeAwareCrawler.Order.PRE_ORDER) {
+    new DepthTraversalTypeAwareCrawler(Component.Type.FILE, Visitor.Order.PRE_ORDER) {
       @Override
       public void visitAny(Component component) {
         copy(component);
index 187a17c7f11ba8eca5076e7075e1f59e4684338f..b2a87eb2a6cff0534fcec17b9fc2f2971c0c42cd 100644 (file)
@@ -46,7 +46,7 @@ import org.sonar.server.computation.metric.MetricRepository;
 import org.sonar.server.computation.period.Period;
 import org.sonar.server.computation.period.PeriodsHolder;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
  * Set variations on all numeric measures found in the repository.
index 7d30c8a853e8d2e075adc46a0125e37e1d2d3fb2..1e357c6b62452fa37ad278b55148fcf8564b2078 100644 (file)
@@ -36,7 +36,7 @@ import org.sonar.server.computation.issue.IssueVisitors;
 import org.sonar.server.computation.issue.TrackerExecution;
 import org.sonar.server.util.cache.DiskCache;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 public class IntegrateIssuesStep implements ComputationStep {
 
index 9413a9831e677ad55b1c17158ae915d4f0ffee79..920dcbf13308cd37409b05c03fbd69764b31fd58 100644 (file)
@@ -36,7 +36,7 @@ import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
  * Persist duplications into
index 0a6f75a775b5b460856689313814c68f17886a0f..152dd24c662fd9afe7a83e38bd75e695b3ad25d4 100644 (file)
@@ -32,6 +32,7 @@ import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.event.Event;
 import org.sonar.server.computation.event.EventRepository;
 
@@ -138,7 +139,7 @@ public class PersistEventsStep implements ComputationStep {
     private final long analysisDate;
 
     public PersistEventComponentCrawler(DbSession session, long analysisDate) {
-      super(Component.Type.FILE, Order.PRE_ORDER);
+      super(Component.Type.FILE, Visitor.Order.PRE_ORDER);
       this.session = session;
       this.analysisDate = analysisDate;
     }
index 1880bcec4c6b2d16cf64be66e2fef4f1895330a6..0a188c1a4cdb97a2114a061854b676224160fc1d 100644 (file)
@@ -49,7 +49,7 @@ import org.sonar.server.computation.source.LineReader;
 import org.sonar.server.computation.source.ScmLineReader;
 import org.sonar.server.computation.source.SymbolsLineReader;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 public class PersistFileSourcesStep implements ComputationStep {
 
index e57968b5cead142fbe2b664144cedc13ae413ff0..6cd01463a9bae8d1a188b8ddd876453558747359 100644 (file)
@@ -46,7 +46,7 @@ import static com.google.common.collect.FluentIterable.from;
 import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY;
 import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY;
 import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 public class PersistMeasuresStep implements ComputationStep {
 
index cd69f4d4f891f7bc4ab1502480052b0f9632e830..e40475f2ef1a0d709942c2807375af215d182c21 100644 (file)
@@ -39,7 +39,7 @@ import org.sonar.server.computation.metric.MetricRepository;
 import org.sonar.server.source.index.SourceLineIndex;
 
 import static com.google.common.base.Objects.firstNonNull;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
 
index b14e7a3a39a441ec6a124f4533a9913be93e6be3..d6c04562054891e9244d528e1cd84092ca921c74 100644 (file)
@@ -41,7 +41,7 @@ import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
 
 import static com.google.common.collect.Sets.newHashSet;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
  * Persist project and module links
index 5bbacc7f002733576c4513c9472e30ce03c4c1ac..d3f27f950b80873cd047d6ca895bc846880d0b45 100644 (file)
@@ -51,6 +51,7 @@ import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 
 public class PersistTestsStep implements ComputationStep {
 
@@ -96,7 +97,7 @@ public class PersistTestsStep implements ComputationStep {
     boolean hasUnprocessedCoverageDetails = false;
 
     public TestDepthTraversalTypeAwareCrawler(DbSession session) {
-      super(Component.Type.FILE, Order.PRE_ORDER);
+      super(Component.Type.FILE, Visitor.Order.PRE_ORDER);
       this.session = session;
       this.existingFileSourcesByUuid = new HashMap<>();
       this.projectUuid = treeRootHolder.getRoot().getUuid();
index 0e045ef70c8b2bc8c370cf82f895e6a2a6d4b6d6..450e4abe1503394c20676a6b0180de118cae99f6 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.utils.log.Loggers;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.event.Event;
 import org.sonar.server.computation.event.EventRepository;
 import org.sonar.server.computation.measure.Measure;
@@ -61,7 +62,7 @@ public class QualityGateEventsStep implements ComputationStep {
 
   @Override
   public void execute() {
-    new DepthTraversalTypeAwareCrawler(Component.Type.PROJECT, DepthTraversalTypeAwareCrawler.Order.PRE_ORDER) {
+    new DepthTraversalTypeAwareCrawler(Component.Type.PROJECT, Visitor.Order.PRE_ORDER) {
       @Override
       public void visitProject(Component project) {
         executeForProject(project);
index 1cbd1cde4f3c187a63dbc607e1a8ab53d9bd7d5b..818416f671a1f1c0c51afe9de04cca4415b4880f 100644 (file)
@@ -34,7 +34,7 @@ import org.sonar.server.computation.qualitygate.QualityGate;
 import org.sonar.server.computation.qualitygate.QualityGateService;
 
 import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
  * This step retrieves the QualityGate for the current {@link ReportQueue.Item} and stores it in
index 9d65c9c1e0e9dbd470a82df7162c407f25ecd406..12f512483dcf4f64ac0ad4a3cb1f125a243b1d39 100644 (file)
@@ -44,7 +44,7 @@ import org.sonar.server.computation.qualitygate.QualityGate;
 import org.sonar.server.computation.qualitygate.QualityGateHolder;
 
 import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 /**
  * This step:
index 003e044e533cc32e5e4512b0419d44550f62a376..f84a1dec15ffd55abf505f57d8e13088b3831693 100644 (file)
@@ -42,7 +42,7 @@ import org.sonar.server.computation.metric.MetricRepository;
 import org.sonar.server.computation.qualityprofile.QPMeasureData;
 import org.sonar.server.computation.qualityprofile.QualityProfile;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 /**
  * Computation of quality profile events
index 373b5141bd27a3ac34d4d709d0df9564b0bdf026..2c2f6700f2251e84345decc1b22826c910dd910e 100644 (file)
@@ -40,7 +40,7 @@ import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
 import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
 import static org.sonar.api.measures.CoreMetrics.STATEMENTS_KEY;
 import static org.sonar.server.computation.component.Component.Type.FILE;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
 
 /**
@@ -97,12 +97,12 @@ public class SizeMeasuresStep implements ComputationStep {
     }
 
     @Override
-    protected void visitProject(Component project, Path<Counter> path) {
+    public void visitProject(Component project, Path<Counter> path) {
       createMeasures(project, path.current().directories, path.current().files);
     }
 
     @Override
-    protected void visitModule(Component module, Path<Counter> path) {
+    public void visitModule(Component module, Path<Counter> path) {
       createMeasures(module, path.current().directories, path.current().files);
 
       path.parent().directories += path.current().directories;
@@ -110,7 +110,7 @@ public class SizeMeasuresStep implements ComputationStep {
     }
 
     @Override
-    protected void visitDirectory(Component directory, Path<Counter> path) {
+    public void visitDirectory(Component directory, Path<Counter> path) {
       createMeasures(directory, 1, path.current().files);
 
       path.parent().directories += 1;
@@ -125,7 +125,7 @@ public class SizeMeasuresStep implements ComputationStep {
     }
 
     @Override
-    protected void visitFile(Component file, Path<Counter> path) {
+    public void visitFile(Component file, Path<Counter> path) {
       if (file.getFileAttributes().isUnitTest()) {
         return;
       }
index 38fa3a2ab11a6158f40b7b1f48edbbe422f34460..441d09746e6b6003a0da504c6b6d7b05ad69ea2e 100644 (file)
@@ -24,6 +24,7 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.PathAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.measure.Measure;
 import org.sonar.server.computation.measure.MeasureRepository;
 import org.sonar.server.computation.metric.Metric;
@@ -64,7 +65,7 @@ public class SqaleMeasuresStep implements ComputationStep {
     private final Metric sqaleRatingMetric;
 
     public SqaleMeasuresCrawler() {
-      super(Component.Type.FILE, Order.POST_ORDER, new SimpleStackElementFactory<DevelopmentCost>() {
+      super(Component.Type.FILE, Visitor.Order.POST_ORDER, new SimpleStackElementFactory<DevelopmentCost>() {
         @Override
         public DevelopmentCost createForAny(Component component) {
           return new DevelopmentCost();
@@ -88,7 +89,7 @@ public class SqaleMeasuresStep implements ComputationStep {
     }
 
     @Override
-    protected void visitModule(Component module, Path<DevelopmentCost> path) {
+    public void visitModule(Component module, Path<DevelopmentCost> path) {
       computeAndSaveMeasures(module, path);
     }
 
index af6f3a24a35dcedf12a4e16f01eec0f6c5dbe401..f28b30abb12e6d8a3537d0a30ea3b1f1521d38a8 100644 (file)
@@ -44,6 +44,7 @@ import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 
 import static org.sonar.api.utils.DateUtils.formatDateTime;
 
@@ -107,7 +108,7 @@ public class ValidateProjectStep implements ComputationStep {
     private Component rawProject;
 
     public ValidateProjectsCrawler(DbSession session, ComponentDao componentDao, boolean preventAutomaticProjectCreation, Map<String, ComponentDto> baseModulesByKey) {
-      super(Component.Type.MODULE, Order.PRE_ORDER);
+      super(Component.Type.MODULE, Visitor.Order.PRE_ORDER);
       this.session = session;
       this.componentDao = componentDao;
 
index 5c3cc2e2c43cea074cf9520e13eb4d6022832f4f..bbf7aeb57fda40cbf52ddad101624ccf216cab5a 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.MutableTreeRootHolder;
 import org.sonar.server.computation.component.TreeRootHolder;
 
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 public class TreeRootHolderRule implements TestRule, MutableTreeRootHolder {
   private Component root;
index 9d14c21c66f3b69877894802ad4753bfb49334a5..5bf623620d8f909c1ae308082adc48cc2bfb4fe9 100644 (file)
@@ -38,8 +38,8 @@ import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
 import static org.sonar.server.computation.component.Component.Type.FILE;
 import static org.sonar.server.computation.component.Component.Type.MODULE;
 import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 public class PathAwareCrawlerTest {
 
@@ -258,7 +258,7 @@ public class PathAwareCrawlerTest {
   private static class TestPathAwareCrawler extends PathAwareCrawler<Integer> {
     private final List<CallRecord> callsRecords = new ArrayList<>();
 
-    public TestPathAwareCrawler(Component.Type maxDepth, ComponentCrawler.Order order) {
+    public TestPathAwareCrawler(Component.Type maxDepth, Visitor.Order order) {
       super(maxDepth, order, new SimpleStackElementFactory<Integer>() {
         @Override
         public Integer createForAny(Component component) {
@@ -268,32 +268,32 @@ public class PathAwareCrawlerTest {
     }
 
     @Override
-    protected void visitProject(Component project, Path<Integer> path) {
+    public void visitProject(Component project, Path<Integer> path) {
       callsRecords.add(newCallRecord(project, path, "visitProject"));
     }
 
     @Override
-    protected void visitModule(Component module, Path<Integer> path) {
+    public void visitModule(Component module, Path<Integer> path) {
       callsRecords.add(newCallRecord(module, path, "visitModule"));
     }
 
     @Override
-    protected void visitDirectory(Component directory, Path<Integer> path) {
+    public void visitDirectory(Component directory, Path<Integer> path) {
       callsRecords.add(newCallRecord(directory, path, "visitDirectory"));
     }
 
     @Override
-    protected void visitFile(Component file, Path<Integer> path) {
+    public void visitFile(Component file, Path<Integer> path) {
       callsRecords.add(newCallRecord(file, path, "visitFile"));
     }
 
     @Override
-    protected void visitUnknown(Component unknownComponent, Path<Integer> path) {
+    public void visitUnknown(Component unknownComponent, Path<Integer> path) {
       callsRecords.add(newCallRecord(unknownComponent, path, "visitUnknown"));
     }
 
     @Override
-    protected void visitAny(Component component, Path<Integer> path) {
+    public void visitAny(Component component, Path<Integer> path) {
       callsRecords.add(newCallRecord(component, path, "visitAny"));
     }
 
index 1f0a0f081933a70077903be4b27655f70b0258e3..9ba230af816b124d94c7552a0122b3962b975c43 100644 (file)
@@ -29,7 +29,7 @@ import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
 import static org.sonar.server.computation.component.Component.Type.FILE;
 import static org.sonar.server.computation.component.Component.Type.MODULE;
 import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.POST_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.POST_ORDER;
 
 public class PostOrderDepthTraversalTypeAwareCrawlerTest {
 
index d3650860a957b1b5662e85c2519e4f18b62ad63e..aeb2c28c823b422591a9d5d8300bc6df828a2e81 100644 (file)
@@ -29,7 +29,7 @@ import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
 import static org.sonar.server.computation.component.Component.Type.FILE;
 import static org.sonar.server.computation.component.Component.Type.MODULE;
 import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ComponentCrawler.Order.PRE_ORDER;
+import static org.sonar.server.computation.component.Visitor.Order.PRE_ORDER;
 
 public class PreOrderDepthTraversalTypeAwareCrawlerTest {
 
index ea612d42e8d653593d32bebc1d6483a876063c80..e2effb13ea3e0552fe9f01993f878ccaa6e54953 100644 (file)
@@ -33,9 +33,9 @@ import javax.annotation.Nullable;
 import org.junit.rules.ExternalResource;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ComponentCrawler;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
 import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.component.Visitor;
 import org.sonar.server.computation.debt.Characteristic;
 import org.sonar.server.computation.metric.Metric;
 import org.sonar.server.computation.metric.MetricRepositoryRule;
@@ -386,7 +386,7 @@ public class MeasureRepositoryRule extends ExternalResource implements MeasureRe
     private final Map<Integer, Component> componentsByRef = new HashMap<>();
 
     public TreeComponentProvider(Component root) {
-      new DepthTraversalTypeAwareCrawler(Component.Type.FILE, ComponentCrawler.Order.PRE_ORDER) {
+      new DepthTraversalTypeAwareCrawler(Component.Type.FILE, Visitor.Order.PRE_ORDER) {
         @Override
         public void visitAny(Component component) {
           checkState(!componentsByRef.containsKey(component.getRef()), "Tree contains more than one component with ref " + component.getRef());