1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.onehippo.forge.utilities.commons.jcrmockup;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import javax.jcr.Item;
23 import javax.jcr.Property;
24 import javax.jcr.PropertyType;
25 import javax.jcr.RepositoryException;
26 import javax.jcr.Value;
27 import javax.jcr.nodetype.PropertyDefinition;
28 import jakarta.xml.bind.annotation.XmlAttribute;
29 import jakarta.xml.bind.annotation.XmlElement;
30 import jakarta.xml.bind.annotation.XmlTransient;
31
32 import org.mockito.Matchers;
33 import org.mockito.Mockito;
34 import org.mockito.invocation.InvocationOnMock;
35 import org.mockito.stubbing.Answer;
36
37
38
39
40 public class MockProperty {
41
42 @XmlTransient
43 private boolean removed;
44
45 @XmlTransient
46 private MockNode parent;
47
48 @XmlAttribute(name = "name", namespace = "http://www.jcp.org/jcr/sv/1.0")
49 private String name;
50
51 @XmlAttribute(name = "type", namespace = "http://www.jcp.org/jcr/sv/1.0")
52 private String type;
53
54 @XmlElement(name = "value", namespace = "http://www.jcp.org/jcr/sv/1.0")
55 private List<String> values;
56
57 public String getMockPropertyName() {
58 return this.name;
59 }
60
61 public void setMockPropertyName(String name) {
62 this.name = name;
63 }
64
65 public String getMockPropertyType() {
66 return type;
67 }
68
69 public void setMockPropertyType(String type) {
70 this.type = type;
71 }
72
73 public List<String> getMockValues() {
74 return values;
75 }
76
77 public void setMockValues(List<String> values) {
78 this.values = values;
79 }
80
81 public MockNode getParent() {
82 return this.parent;
83 }
84
85 public void setParent(MockNode parentNode) {
86 this.parent = parentNode;
87 }
88
89 public String getPath() {
90 if (this.parent == null) {
91 return this.name;
92 } else {
93 StringBuilder b = new StringBuilder(this.parent.getPath());
94 b.append('/');
95 b.append(this.name);
96 return b.toString();
97 }
98 }
99
100 public void setRemoved(boolean removed) {
101 this.removed = removed;
102 }
103
104 public boolean isRemoved() {
105 return this.removed;
106 }
107
108
109
110
111
112
113
114 public Property mockJcrProperty() throws RepositoryException {
115 final MockProperty mockProperty = this;
116 final Property jcrProperty = Mockito.mock(Property.class);
117 Mockito.when(jcrProperty.getName()).thenReturn(this.name);
118 Mockito.when(jcrProperty.getPath()).thenAnswer(new PathAnswer(mockProperty));
119 Mockito.when(jcrProperty.getParent()).thenAnswer(new ParentAnswer(mockProperty));
120
121 mockType(jcrProperty);
122 if (this.values != null) {
123 if (this.values.size() == 1) {
124 mockSingleValueProperty(jcrProperty);
125 } else if (this.values.size() > 1) {
126 mockMultiValueProperty(jcrProperty);
127 }
128 }
129
130 final PropertyDefinition definition = Mockito.mock(PropertyDefinition.class);
131 Mockito.when(jcrProperty.getDefinition()).thenReturn(definition);
132
133
134 Mockito.when(definition.isMultiple()).thenReturn(this.values == null || this.values.size() > 1);
135
136 final UnsupportedOperationException unsupportedOperation = new UnsupportedOperationException("The method set value is not supported yet.");
137 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.anyString());
138 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.anyDouble());
139 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.anyBoolean());
140 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.anyLong());
141 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.any(Value.class));
142 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.any(Value[].class));
143 Mockito.doThrow(unsupportedOperation).when(jcrProperty).setValue(Matchers.any(String[].class));
144
145 return jcrProperty;
146 }
147
148 private void mockMultiValueProperty(final Property jcrProperty) throws RepositoryException {
149 final List<Value> jcrValues = new ArrayList<Value>();
150 for (String value : this.values) {
151 jcrValues.add(mockValue(value));
152 }
153 final Value[] valuesArray = new Value[jcrValues.size()];
154 Mockito.when(jcrProperty.getValues()).thenReturn(jcrValues.toArray(valuesArray));
155 }
156
157 private void mockSingleValueProperty(final Property jcrProperty) throws RepositoryException {
158 final String stringValue = this.values.get(0);
159 Mockito.when(jcrProperty.getString()).thenReturn(stringValue);
160
161 if ("Date".equals(this.type)) {
162 Mockito.when(jcrProperty.getDate()).thenReturn(ISO8601.parse(stringValue));
163 } else if ("Boolean".equals(this.type)) {
164 Mockito.when(jcrProperty.getBoolean()).thenReturn(Boolean.parseBoolean(stringValue));
165 } else if ("Double".equals(this.type)) {
166 Mockito.when(jcrProperty.getDouble()).thenReturn(Double.parseDouble(stringValue));
167 } else if ("Long".equals(this.type)) {
168 Mockito.when(jcrProperty.getLong()).thenReturn(Long.parseLong(stringValue));
169 }
170
171 final Value mockValue = mockValue(stringValue);
172 Mockito.when(jcrProperty.getValue()).thenReturn(mockValue);
173 }
174
175 private void mockType(final Property jcrProperty) throws RepositoryException {
176 if ("Date".equals(this.type)) {
177 Mockito.when(jcrProperty.getType()).thenReturn(PropertyType.DATE);
178 } else if ("Boolean".equals(this.type)) {
179 Mockito.when(jcrProperty.getType()).thenReturn(PropertyType.BOOLEAN);
180 } else if ("Double".equals(this.type)) {
181 Mockito.when(jcrProperty.getType()).thenReturn(PropertyType.DOUBLE);
182 } else if ("Long".equals(this.type)) {
183 Mockito.when(jcrProperty.getType()).thenReturn(PropertyType.LONG);
184 } else if ("String".equals(this.type)) {
185 Mockito.when(jcrProperty.getType()).thenReturn(PropertyType.STRING);
186 }
187 }
188
189 private Value mockValue(String stringValue) throws RepositoryException {
190 Value value = Mockito.mock(Value.class);
191 Mockito.when(value.getString()).thenReturn(stringValue);
192 if ("Date".equals(this.type)) {
193 Mockito.when(value.getDate()).thenReturn(ISO8601.parse(stringValue));
194 Mockito.when(value.getType()).thenReturn(PropertyType.DATE);
195 } else if ("Boolean".equals(this.type)) {
196 Mockito.when(value.getBoolean()).thenReturn(Boolean.parseBoolean(stringValue));
197 Mockito.when(value.getType()).thenReturn(PropertyType.BOOLEAN);
198 } else if ("Double".equals(this.type)) {
199 Mockito.when(value.getDouble()).thenReturn(Double.parseDouble(stringValue));
200 Mockito.when(value.getType()).thenReturn(PropertyType.DOUBLE);
201 } else if ("Long".equals(this.type)) {
202 Mockito.when(value.getLong()).thenReturn(Long.parseLong(stringValue));
203 Mockito.when(value.getType()).thenReturn(PropertyType.LONG);
204 } else if ("String".equals(this.type) || "String[]".equals(this.type)) {
205 Mockito.when(value.getType()).thenReturn(PropertyType.STRING);
206 }
207
208 return value;
209 }
210
211 private static class PathAnswer implements Answer<String> {
212 private final MockProperty mockProperty;
213
214 public PathAnswer(final MockProperty mockProperty) {
215 this.mockProperty = mockProperty;
216 }
217
218 public String answer(final InvocationOnMock invocationOnMock) {
219 return mockProperty.getPath();
220 }
221 }
222
223 private static class ParentAnswer implements Answer<Item> {
224 private final MockProperty mockProperty;
225
226 public ParentAnswer(final MockProperty mockProperty) {
227 this.mockProperty = mockProperty;
228 }
229
230 public Item answer(final InvocationOnMock invocationOnMock) throws RepositoryException {
231 return mockProperty.getParent().getJcrMock();
232 }
233 }
234 }