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 /** 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 }