View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.tree.xpath;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.configuration2.tree.ImmutableNode;
23  import org.apache.commons.configuration2.tree.InMemoryNodeModel;
24  import org.apache.commons.configuration2.tree.NodeHandler;
25  import org.apache.commons.jxpath.ri.model.NodeIterator;
26  import org.apache.commons.jxpath.ri.model.NodePointer;
27  import org.junit.jupiter.api.AfterEach;
28  import org.junit.jupiter.api.BeforeEach;
29  
30  /**
31   * A base class for testing classes of the XPath package. This base class creates a hierarchy of nodes in its setUp()
32   * method that can be used for test cases.
33   */
34  public abstract class AbstractXPathTest {
35  
36      /** Constant for the name of the counter attribute. */
37      protected static final String ATTR_NAME = "counter";
38  
39      /** Constant for a name of an attribute of the root node. */
40      protected static final String ATTR_ROOT = "rootAttr";
41  
42      /** Constant for the name of the first child. */
43      protected static final String CHILD_NAME1 = "subNode";
44  
45      /** Constant for the name of the second child. */
46      protected static final String CHILD_NAME2 = "childNode";
47  
48      /** Constant for the number of sub nodes. */
49      protected static final int CHILD_COUNT = 5;
50  
51      /** Constant for the number of levels in the hierarchy. */
52      protected static final int LEVEL_COUNT = 3;
53  
54      /** Stores the root node of the hierarchy. */
55      protected ImmutableNode root;
56  
57      /** The node handler. */
58      protected NodeHandler<ImmutableNode> handler;
59  
60      /**
61       * Builds up a hierarchy of nodes. Each node has {@code CHILD_COUNT} child nodes having the names {@code CHILD_NAME1} or
62       * {@code CHILD_NAME2}. Their values are named like their parent node with an additional index. Each node has an
63       * attribute with a counter value. The root node has a special attribute named {@value #ATTR_ROOT} with the value
64       * {@code true}.
65       *
66       * @param levels the number of levels in the hierarchy
67       * @return the root node of the hierarchy
68       */
69      protected ImmutableNode constructHierarchy(final int levels) {
70          final ImmutableNode.Builder resultBuilder = new ImmutableNode.Builder();
71          createLevel(resultBuilder, null, levels);
72          resultBuilder.addAttribute(ATTR_ROOT, String.valueOf(true));
73          return resultBuilder.create();
74      }
75  
76      /**
77       * Recursive helper method for creating a level of the node hierarchy.
78       *
79       * @param parentBuilder the builder for the parent node
80       * @param value the value of the parent node
81       * @param level the level counter
82       */
83      private void createLevel(final ImmutableNode.Builder parentBuilder, final String value, final int level) {
84          if (level >= 0) {
85              final String prefix = value == null ? "" : value + ".";
86              for (int i = 1; i <= CHILD_COUNT; i++) {
87                  final ImmutableNode.Builder childBuilder = new ImmutableNode.Builder();
88                  childBuilder.name(i % 2 == 0 ? CHILD_NAME1 : CHILD_NAME2);
89                  final String currentValue = prefix + i;
90                  childBuilder.value(currentValue);
91                  createLevel(childBuilder, currentValue, level - 1);
92                  childBuilder.addAttribute(ATTR_NAME, String.valueOf(i));
93                  parentBuilder.addChild(childBuilder.create());
94              }
95          }
96      }
97  
98      /**
99       * Returns a list with all node pointers contained in the specified iteration.
100      *
101      * @param iterator the iterator
102      * @return a list with the node pointers obtained from the iterator
103      */
104     protected List<NodePointer> iterationElements(final NodeIterator iterator) {
105         final List<NodePointer> result = new ArrayList<>();
106         for (int pos = 1; iterator.setPosition(pos); pos++) {
107             result.add(iterator.getNodePointer());
108         }
109         return result;
110     }
111 
112     /**
113      * Determines the number of elements contained in the given iterator.
114      *
115      * @param iterator the iterator
116      * @return the number of elements in this iteration
117      */
118     protected int iteratorSize(final NodeIterator iterator) {
119         int cnt = 0;
120         boolean ok;
121 
122         do {
123             ok = iterator.setPosition(cnt + 1);
124             if (ok) {
125                 cnt++;
126             }
127         } while (ok);
128 
129         return cnt;
130     }
131 
132     @BeforeEach
133     public void setUp() throws Exception {
134         root = constructHierarchy(LEVEL_COUNT);
135         handler = new InMemoryNodeModel(root).getNodeHandler();
136     }
137 
138     /**
139      * Clears the test environment.
140      */
141     @AfterEach
142     public void tearDown() throws Exception {
143         root = null;
144     }
145 }