View Javadoc
1   /*
2    * Copyright 2012-2022 Bloomreach
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.onehippo.forge.utilities.commons.jcrmockup;
18  
19  import java.util.Iterator;
20  import java.util.List;
21  
22  import javax.jcr.Node;
23  import javax.jcr.NodeIterator;
24  import javax.jcr.RepositoryException;
25  
26  import org.mockito.Mockito;
27  import org.mockito.invocation.InvocationOnMock;
28  import org.mockito.stubbing.Answer;
29  
30  
31  public class NodeIteratorAnswer implements Answer<NodeIterator> {
32  
33      private MockNode mockNode;
34  
35      public NodeIteratorAnswer(MockNode mockNode) {
36          this.mockNode = mockNode;
37      }
38  
39      public NodeIterator createIterator(List<MockNode> nodes) throws RepositoryException {
40          final Iterator<MockNode> mockNodeIterator = nodes.iterator();
41          final NodeIterator nodeIterator = Mockito.mock(NodeIterator.class);
42          final Answer<Boolean> hasNextAnswer = new HasNextAnswer(mockNodeIterator);
43          final Answer<Node> nextAnswer = new NextAnswer(mockNodeIterator);
44  
45          Mockito.when(nodeIterator.hasNext()).thenAnswer(hasNextAnswer);
46          Mockito.when(nodeIterator.next()).thenAnswer(nextAnswer);
47          Mockito.when(nodeIterator.nextNode()).thenAnswer(nextAnswer);
48          Mockito.doAnswer(nextAnswer).when(nodeIterator).remove();
49          Mockito.when(nodeIterator.getSize()).thenReturn((long) nodes.size());
50  
51          return nodeIterator;
52      }
53  
54      public NodeIterator answer(InvocationOnMock invocation) throws RepositoryException {
55          final Object args[] = invocation.getArguments();
56          if (args.length == 1 && args[0] instanceof String) {
57              return createIterator(mockNode.getMockChildNodesByName((String) args[0]));
58          } else if (args.length == 0) {
59              return createIterator(mockNode.getMockChildNodes());
60          }
61          return null;
62      }
63  
64      private static class HasNextAnswer implements Answer<Boolean> {
65          private final Iterator<MockNode> mockNodeIterator;
66  
67          public HasNextAnswer(final Iterator<MockNode> mockNodeIterator) {
68              this.mockNodeIterator = mockNodeIterator;
69          }
70  
71          public Boolean answer(InvocationOnMock invocationOnMock) {
72              return mockNodeIterator.hasNext();
73          }
74      }
75  
76      private static class NextAnswer implements Answer<Node> {
77          private MockNode currentNode;
78          private final Iterator<MockNode> mockNodeIterator;
79  
80          public NextAnswer(final Iterator<MockNode> mockNodeIterator) {
81              this.mockNodeIterator = mockNodeIterator;
82          }
83  
84          public Node answer(InvocationOnMock invocationOnMock) throws RepositoryException {
85              final String methodName = invocationOnMock.getMethod().getName();
86              if ("remove".equals(methodName)) {
87                  mockNodeIterator.remove();
88                  if (this.currentNode != null) {
89                      this.currentNode.setRemoved(true);
90                  }
91                  return null;
92              } else if ("next".equals(methodName) || "nextNode".equals(methodName)) {
93                  this.currentNode = mockNodeIterator.next();
94                  return this.currentNode.getJcrMock();
95              }
96              return null;
97          }
98      }
99  }