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  
21  import javax.jcr.Property;
22  import javax.jcr.PropertyIterator;
23  import javax.jcr.RepositoryException;
24  
25  import org.mockito.Mockito;
26  import org.mockito.invocation.InvocationOnMock;
27  import org.mockito.stubbing.Answer;
28  
29  
30  public class PropertyIteratorAnswer implements Answer<PropertyIterator> {
31  
32      private static final String REMOVE = "remove";
33      private static final String NEXT = "next";
34      private static final String NEXT_PROPERTY = "nextProperty";
35      private MockNode mockNode;
36  
37      public PropertyIteratorAnswer(MockNode mockNode) {
38          this.mockNode = mockNode;
39      }
40  
41      private PropertyIterator createIterator(final Iterator<MockProperty> iterator) {
42          final PropertyIterator propertyIterator = Mockito.mock(PropertyIterator.class);
43          Mockito.when(propertyIterator.hasNext()).thenAnswer(new BooleanAnswer(iterator));
44  
45          final Answer<Property> propertyAnswer = new PropertyAnswer(iterator);
46          Mockito.when(propertyIterator.nextProperty()).thenAnswer(propertyAnswer);
47          Mockito.when(propertyIterator.next()).thenAnswer(propertyAnswer);
48          Mockito.doAnswer(propertyAnswer).when(propertyIterator).remove();
49  
50          return propertyIterator;
51      }
52  
53      public PropertyIterator answer(final InvocationOnMock invocationOnMock) {
54          final Object args[] = invocationOnMock.getArguments();
55          if (args.length == 0) {
56              return createIterator(mockNode.getMockProperties().iterator());
57          }
58          throw new UnsupportedOperationException("The mock operation is not supported.");
59      }
60  
61      private static class BooleanAnswer implements Answer<Boolean> {
62          private final Iterator<MockProperty> iterator;
63  
64          public BooleanAnswer(final Iterator<MockProperty> iterator) {
65              this.iterator = iterator;
66          }
67  
68          public Boolean answer(final InvocationOnMock invocationOnMock) {
69              return iterator.hasNext();
70          }
71      }
72  
73      private static class PropertyAnswer implements Answer<Property> {
74          private MockProperty nextProperty;
75          private final Iterator<MockProperty> iterator;
76  
77          public PropertyAnswer(final Iterator<MockProperty> iterator) {
78              this.iterator = iterator;
79              nextProperty = null;
80          }
81  
82          public Property answer(final InvocationOnMock invocationOnMock) throws RepositoryException {
83              final String methodName = invocationOnMock.getMethod().getName();
84              if (REMOVE.equals(methodName)) {
85                  this.nextProperty.setRemoved(true);
86              } else if (NEXT.equals(methodName) || NEXT_PROPERTY.equals(methodName)) {
87                  this.nextProperty = iterator.next();
88                  if (this.nextProperty != null) {
89                      return this.nextProperty.mockJcrProperty();
90                  }
91              }
92              return null;
93          }
94      }
95  }