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 }