View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.rat.documentation.velocity;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.List;
24  import java.util.stream.Collectors;
25  
26  import org.apache.rat.analysis.IHeaderMatcher;
27  import org.apache.rat.config.parameters.Description;
28  
29  /**
30   * The representation of the Matcher tree found in a License.
31   */
32  public class MatcherTree {
33      /**
34       * The root of the tree.
35       */
36      private final IHeaderMatcher root;
37  
38      /**
39       * Constructor.
40       * @param root the root of the tree. The matcher from a license.
41       */
42      public MatcherTree(final IHeaderMatcher root) {
43          this.root = root;
44      }
45  
46      /**
47       * Gets the description of the root of the tree.
48       * @return the description of the root of the tree.
49       */
50      public Description getRoot() {
51          return root.getDescription();
52      }
53  
54      /**
55       * Executes an in-order-traversal of the tree.
56       * @return A list of {@link Node}s from an in-order-traversal.
57       */
58      public List<Node> traverse() {
59          List<Node> result = new ArrayList<>();
60          result.add(new Node(0, root));
61          processNode(result, result.get(0));
62          return result;
63      }
64  
65      /**
66       * Process a node and create all the children of it.
67       * @param result the result to add the children to.
68       * @param node the node to process.
69       */
70      private void processNode(final List<Node> result, final Node node) {
71          Collection<Matcher> children = node.getChildren();
72          if (children.isEmpty()) {
73              return;
74          }
75          for (Matcher child : children) {
76              Node childNode = new Node(node.level + 1, child);
77              result.add(childNode);
78              processNode(result, childNode);
79          }
80      }
81  
82      /**
83       * The representation of a node in a License Matcher tree.
84       * A node is a Matcher that tracks the level of the tree in which it appears.
85       */
86      public static class Node extends Matcher {
87          /** The level of the tree that this node appears in. */
88          private final int level;
89  
90          /**
91           * Constructor.
92           * @param level the level of the tree. (root = 0)
93           * @param matcher the matcher being processed.
94           */
95          Node(final int level, final Matcher matcher) {
96              super(matcher);
97              this.level = level;
98          }
99  
100         /**
101          * Constructor.
102          * @param level the level of the tree. (root = 0)
103          * @param root the matcher to wrap.
104          */
105         Node(final int level, final IHeaderMatcher root) {
106             super(root);
107             this.level = level;
108         }
109 
110         /**
111          * Gets the level in the tree of this node.
112          * @return the level in the tree of this node.
113          */
114         public int level() {
115             return level;
116         }
117 
118         /**
119          * Gets the enclosed node only if it is another matcher.
120          * @return the enclosed node.
121          */
122         @Override
123         public Enclosed getEnclosed() {
124             Enclosed result = super.getEnclosed();
125             return result != null && IHeaderMatcher.class.equals(result.getChildType()) ? null : result;
126         }
127 
128         /**
129          * Gets the attributes only if they have values.
130          * @return the collection of attributes that have values.
131          */
132         @Override
133         public Collection<Attribute> getAttributes() {
134             return super.getAttributes().stream().filter(attr -> attr.getValue() != null).collect(Collectors.toList());
135         }
136     }
137 }