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    *     http://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      /** Constant for the name of the counter attribute. */
36      protected static final String ATTR_NAME = "counter";
37  
38      /** Constant for a name of an attribute of the root node. */
39      protected static final String ATTR_ROOT = "rootAttr";
40  
41      /** Constant for the name of the first child. */
42      protected static final String CHILD_NAME1 = "subNode";
43  
44      /** Constant for the name of the second child. */
45      protected static final String CHILD_NAME2 = "childNode";
46  
47      /** Constant for the number of sub nodes. */
48      protected static final int CHILD_COUNT = 5;
49  
50      /** Constant for the number of levels in the hierarchy. */
51      protected static final int LEVEL_COUNT = 3;
52  
53      /** Stores the root node of the hierarchy. */
54      protected ImmutableNode root;
55  
56      /** The node handler. */
57      protected NodeHandler<ImmutableNode> handler;
58  
59      /**
60       * Builds up a hierarchy of nodes. Each node has {@code CHILD_COUNT} child nodes having the names {@code CHILD_NAME1} or
61       * {@code CHILD_NAME2}. Their values are named like their parent node with an additional index. Each node has an
62       * attribute with a counter value. The root node has a special attribute named {@value #ATTR_ROOT} with the value
63       * {@code true}.
64       *
65       * @param levels the number of levels in the hierarchy
66       * @return the root node of the hierarchy
67       */
68      protected ImmutableNode constructHierarchy(final int levels) {
69          final ImmutableNode.Builder resultBuilder = new ImmutableNode.Builder();
70          createLevel(resultBuilder, null, levels);
71          resultBuilder.addAttribute(ATTR_ROOT, String.valueOf(true));
72          return resultBuilder.create();
73      }
74  
75      /**
76       * Recursive helper method for creating a level of the node hierarchy.
77       *
78       * @param parentBuilder the builder for the parent node
79       * @param value the value of the parent node
80       * @param level the level counter
81       */
82      private void createLevel(final ImmutableNode.Builder parentBuilder, final String value, final int level) {
83          if (level >= 0) {
84              final String prefix = value == null ? "" : value + ".";
85              for (int i = 1; i <= CHILD_COUNT; i++) {
86                  final ImmutableNode.Builder childBuilder = new ImmutableNode.Builder();
87                  childBuilder.name(i % 2 == 0 ? CHILD_NAME1 : CHILD_NAME2);
88                  final String currentValue = prefix + i;
89                  childBuilder.value(currentValue);
90                  createLevel(childBuilder, currentValue, level - 1);
91                  childBuilder.addAttribute(ATTR_NAME, String.valueOf(i));
92                  parentBuilder.addChild(childBuilder.create());
93              }
94          }
95      }
96  
97      /**
98       * Returns a list with all node pointers contained in the specified iteration.
99       *
100      * @param iterator the iterator
101      * @return a list with the node pointers obtained from the iterator
102      */
103     protected List<NodePointer> iterationElements(final NodeIterator iterator) {
104         final List<NodePointer> result = new ArrayList<>();
105         for (int pos = 1; iterator.setPosition(pos); pos++) {
106             result.add(iterator.getNodePointer());
107         }
108         return result;
109     }
110 
111     /**
112      * Determines the number of elements contained in the given iterator.
113      *
114      * @param iterator the iterator
115      * @return the number of elements in this iteration
116      */
117     protected int iteratorSize(final NodeIterator iterator) {
118         int cnt = 0;
119         boolean ok;
120 
121         do {
122             ok = iterator.setPosition(cnt + 1);
123             if (ok) {
124                 cnt++;
125             }
126         } while (ok);
127 
128         return cnt;
129     }
130 
131     @BeforeEach
132     public void setUp() throws Exception {
133         root = constructHierarchy(LEVEL_COUNT);
134         handler = new InMemoryNodeModel(root).getNodeHandler();
135     }
136 
137     /**
138      * Clears the test environment.
139      */
140     @AfterEach
141     public void tearDown() throws Exception {
142         root = null;
143     }
144 }