1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.groovy.support.nodes;
35
36 import groovy.lang.DelegatingMetaClass;
37 import groovy.lang.GroovySystem;
38 import groovy.lang.MetaClass;
39 import groovy.xml.QName;
40
41 import info.magnolia.cms.core.Content;
42 import info.magnolia.cms.core.ItemType;
43 import info.magnolia.cms.core.MgnlNodeType;
44 import info.magnolia.cms.core.NodeData;
45 import info.magnolia.cms.security.AccessDeniedException;
46 import info.magnolia.cms.util.ContentWrapper;
47 import info.magnolia.jcr.RuntimeRepositoryException;
48
49 import java.math.BigDecimal;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Iterator;
53 import java.util.List;
54
55 import javax.jcr.PathNotFoundException;
56 import javax.jcr.PropertyType;
57 import javax.jcr.RepositoryException;
58 import javax.jcr.Value;
59 import javax.jcr.ValueFormatException;
60
61 import org.apache.commons.collections.IteratorUtils;
62 import org.apache.commons.lang.StringUtils;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 public class MgnlGroovyNode extends ContentWrapper {
117
118 static {
119
120 setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(MgnlGroovyNode.class), MgnlGroovyNode.class);
121 }
122
123 protected static final Logger log = LoggerFactory.getLogger(MgnlGroovyNode.class);
124
125 private String name;
126
127 public MgnlGroovyNode(Content content) {
128 super(content);
129 this.name = content.getName();
130 }
131
132 protected static void setMetaClass(final MetaClass metaClass, Class nodeClass) {
133 final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
134
135 @Override
136 public Object getAttribute(final Object object, final String attribute) {
137 MgnlGroovyNode n = (MgnlGroovyNode) object;
138 return n.get("@" + attribute);
139 }
140
141 @Override
142 public void setAttribute(final Object object, final String attribute, final Object newValue) {
143 MgnlGroovyNode n = (MgnlGroovyNode) object;
144 try {
145 n.setNodeData(attribute, newValue);
146 }
147 catch (AccessDeniedException e) {
148 log.error(e.getMessage());
149 }
150 catch (PathNotFoundException e) {
151 log.error(e.getMessage());
152 }
153 catch (RepositoryException e) {
154 log.error(e.getMessage());
155 }
156 }
157
158 @Override
159 public Object getProperty(Object object, String property) {
160 if (object instanceof MgnlGroovyNode) {
161 MgnlGroovyNode n = (MgnlGroovyNode) object;
162 return n.get(property);
163 }
164 return super.getProperty(object, property);
165 }
166
167 @Override
168 public void setProperty(Object object, String property, Object newValue) {
169 String attribute = null;
170 if (property.startsWith("@")) {
171 attribute = property.substring(1);
172 } else {
173 attribute = property;
174 }
175 MgnlGroovyNode n = (MgnlGroovyNode) object;
176 try {
177
178 if (newValue instanceof Integer) {
179 newValue = ((Integer) newValue).longValue();
180 }
181 n.setNodeData(attribute, newValue);
182 }
183 catch (AccessDeniedException e) {
184 log.error(e.getMessage());
185 }
186 catch (PathNotFoundException e) {
187 log.error(e.getMessage());
188 }
189 catch (RepositoryException e) {
190 log.error(e.getMessage());
191 }
192 }
193 };
194 GroovySystem.getMetaClassRegistry().setMetaClass(nodeClass, newMetaClass);
195 }
196
197 public Iterator<Content> iterator() {
198 return getChainedChildrenIterator();
199 }
200
201 public String name() {
202 return name;
203 }
204
205
206
207
208
209
210
211 public Object get(String key) {
212 if (key != null && key.charAt(0) == '@') {
213 String attributeName = key.substring(1);
214 return getNodeDataValue(attributeName);
215 }
216 if ("parent".equals(key)) {
217 try {
218 return getParent();
219 } catch (RepositoryException e) {
220 return null;
221 }
222 }
223 if ("children".equals(key)) {
224 Collection<Content> retVal = getChildren();
225 if (!isContentNodeType()) {
226 retVal.addAll(getChildren(MgnlNodeType.NT_CONTENTNODE));
227 }
228 return retVal;
229 }
230 if ("metaData".equals(key)) {
231 return getMetaData();
232 }
233 if ("nodeData".equals(key)) {
234 return getNodeDataCollection();
235 }
236 if ("name".equals(key)) {
237 return name;
238 }
239 Content retVal = getByName(key);
240 if (retVal != null) {
241 return retVal;
242 }
243
244 return getNodeDataValue(key);
245 }
246
247 @Override
248 protected Content wrap(Content node) {
249 return new MgnlGroovyNode(node);
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264 protected Object getNodeDataValue(String attributeName) {
265 Collection<NodeData> data = getNodeDataCollection(attributeName);
266 Iterator<NodeData> it = data.iterator();
267 if (!it.hasNext()) {
268 return null;
269 }
270 NodeData nodeData = it.next();
271 Value propertyValue = nodeData.getValue();
272 Object value = null;
273 if (propertyValue != null) {
274 try {
275 switch (propertyValue.getType()) {
276 case PropertyType.STRING:
277 value = propertyValue.getString();
278 break;
279 case PropertyType.BINARY:
280 value = propertyValue;
281 break;
282 case PropertyType.DATE:
283 value = propertyValue.getDate();
284 break;
285 case PropertyType.DOUBLE:
286 value = BigDecimal.valueOf(propertyValue.getDouble());
287 break;
288 case PropertyType.LONG:
289 value = BigDecimal.valueOf(propertyValue.getLong());
290 break;
291 default:
292 value = propertyValue.getString();
293 }
294 } catch (ValueFormatException e) {
295 log.warn(e.getMessage());
296 } catch (IllegalStateException e) {
297 log.warn(e.getMessage());
298 } catch (RepositoryException e) {
299 log.warn(e.getMessage());
300 }
301 }
302 return value;
303 }
304
305
306
307
308
309
310
311
312 @Deprecated
313 public List<Content> getAt(QName name) {
314 List<Content> answer = new ArrayList<Content>();
315 for (Iterator<Content> iter = getChainedChildrenIterator(); iter.hasNext();) {
316 Content childNode = iter.next();
317 Object childNodeName = childNode.getName();
318 if (name.matches(childNodeName)) {
319 answer.add(childNode);
320 }
321 }
322 return answer;
323 }
324
325
326
327
328
329
330
331 protected Content getByName(String name) {
332 for (Iterator<Content> iter = getChainedChildrenIterator(); iter.hasNext();) {
333 Content childNode = iter.next();
334 String childNodeName = childNode.getName();
335 if (name.equals(childNodeName)) {
336 return childNode;
337 }
338 }
339 return null;
340 }
341
342 @Override
343 public String toString() {
344 StringBuilder retVal = new StringBuilder();
345 Iterator<Content> iterator = getChainedChildrenIterator();
346 retVal.append("(+) " + name + "\n");
347 while (iterator.hasNext()) {
348 Content c = iterator.next();
349 if (hasMoreChildren(c)) {
350 retVal.append("\t(+) ");
351 } else {
352 retVal.append("\t(-) ");
353 }
354 retVal.append(c.getName() + "\n");
355 }
356
357 if (!getNodeDataCollection().isEmpty()) {
358 for (NodeData nodeData : getNodeDataCollection()) {
359 retVal.append("\t\t* " + nodeData.getName() + ": ["
360 + StringUtils.abbreviate(nodeData.getString(), 80)
361 + "]\n");
362 }
363
364 }
365
366 return retVal.toString();
367 }
368
369 @SuppressWarnings("unchecked")
370 private Iterator<Content> getChainedChildrenIterator() {
371 if (isContentNodeType()) {
372 return getChildren().iterator();
373 }
374 return IteratorUtils.chainedIterator(getChildren().iterator(), getChildren(ItemType.CONTENTNODE).iterator());
375 }
376
377 private boolean hasMoreChildren(Content c) {
378 return c.hasChildren() || c.hasChildren(ItemType.CONTENTNODE.getSystemName());
379 }
380
381 @Override
382 public int hashCode() {
383 final int prime = 31;
384 int result = 1;
385 result = prime * result + ((name == null) ? 0 : name.hashCode());
386 return result;
387 }
388
389 @Override
390 public boolean equals(Object obj) {
391 if (this == obj)
392 return true;
393 if (obj == null)
394 return false;
395 if (getClass() != obj.getClass())
396 return false;
397 MgnlGroovyNode other = (MgnlGroovyNode) obj;
398 if (name == null) {
399 if (other.name != null)
400 return false;
401 } else if (!getHandle().equals(other.getHandle()))
402 return false;
403 return true;
404 }
405
406 private boolean isContentNodeType() {
407 try {
408 return MgnlNodeType.NT_CONTENTNODE.equals(getItemType().getSystemName());
409
410 } catch (RepositoryException e) {
411 throw new RuntimeRepositoryException(e);
412 }
413 }
414
415 }