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 java.math.BigDecimal;
37 import java.util.Collection;
38 import java.util.Iterator;
39
40 import javax.jcr.Node;
41 import javax.jcr.NodeIterator;
42 import javax.jcr.PathNotFoundException;
43 import javax.jcr.Property;
44 import javax.jcr.PropertyIterator;
45 import javax.jcr.PropertyType;
46 import javax.jcr.RepositoryException;
47 import javax.jcr.Value;
48 import javax.jcr.ValueFormatException;
49
50 import org.apache.commons.lang.StringUtils;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import groovy.lang.DelegatingMetaClass;
55 import groovy.lang.GroovySystem;
56 import groovy.lang.MetaClass;
57 import info.magnolia.cms.core.MetaData;
58 import info.magnolia.cms.core.MgnlNodeType;
59 import info.magnolia.cms.security.AccessDeniedException;
60 import info.magnolia.jcr.RuntimeRepositoryException;
61 import info.magnolia.jcr.util.NodeUtil;
62 import info.magnolia.jcr.wrapper.ChildWrappingNodeWrapper;
63
64
65
66
67 public class MgnlGroovyJCRNode extends ChildWrappingNodeWrapper{
68
69 protected static final Logger log = LoggerFactory.getLogger(MgnlGroovyJCRNode.class);
70
71 private String name;
72
73 public MgnlGroovyJCRNode(Node node) throws RepositoryException {
74 super(node);
75 this.name = node.getName();
76 }
77
78 protected static void setMetaClass(final MetaClass metaClass, Class nodeClass) {
79 final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
80
81 @Override
82 public Object getAttribute(final Object object, final String attribute) {
83 MgnlGroovyJCRNode n = (MgnlGroovyJCRNode) object;
84 try {
85 return n.get("@" + attribute);
86 } catch (RepositoryException e) {
87 log.error(e.getMessage());
88 return null;
89 }
90 }
91
92 @Override
93 public void setAttribute(final Object object, final String attribute, final Object newValue) {
94 MgnlGroovyJCRNode n = (MgnlGroovyJCRNode) object;
95 try {
96 n.setProperty(attribute, (Value) newValue);
97 }
98 catch (AccessDeniedException e) {
99 log.error(e.getMessage());
100 }
101 catch (PathNotFoundException e) {
102 log.error(e.getMessage());
103 }
104 catch (RepositoryException e) {
105 log.error(e.getMessage());
106 }
107 }
108
109 @Override
110 public Object getProperty(Object object, String property) {
111 if (object instanceof MgnlGroovyJCRNode) {
112 MgnlGroovyJCRNode n = (MgnlGroovyJCRNode) object;
113 try {
114 return n.get(property);
115 } catch (RepositoryException e) {
116 log.error(e.getMessage());
117 return null;
118 }
119 }
120 return super.getProperty(object, property);
121 }
122
123 @Override
124 public void setProperty(Object object, String property, Object newValue) {
125 String attribute = null;
126 if (property.startsWith("@")) {
127 attribute = property.substring(1);
128 } else {
129 attribute = property;
130 }
131 MgnlGroovyJCRNode n = (MgnlGroovyJCRNode) object;
132 try {
133 if (newValue instanceof Integer) {
134 newValue = ((Integer) newValue).longValue();
135 }
136 n.setProperty(attribute, (Value) newValue);
137 }
138 catch (AccessDeniedException e) {
139 log.error(e.getMessage());
140 }
141 catch (PathNotFoundException e) {
142 log.error(e.getMessage());
143 }
144 catch (RepositoryException e) {
145 log.error(e.getMessage());
146 }
147 }
148 };
149 GroovySystem.getMetaClassRegistry().setMetaClass(nodeClass, newMetaClass);
150 }
151
152 public String name() {
153 return name;
154 }
155
156 public Object get(String key) throws RepositoryException {
157 if (key != null && key.charAt(0) == '@') {
158 String attributeName = key.substring(1);
159 return getPropertyValue(attributeName);
160 }
161 if ("parent".equals(key)) {
162 try {
163 return getParent();
164 } catch (RepositoryException e) {
165 log.error(e.getMessage());
166 return null;
167 }
168 }
169 if ("children".equals(key)) {
170 Collection<Node> retVal = NodeUtil.getCollectionFromNodeIterator(wrapped.getNodes());
171 if (!isContentNodeType()) {
172 retVal.addAll(NodeUtil.getCollectionFromNodeIterator(NodeUtil.filterNodeType(wrapped.getNodes(), MgnlNodeType.NT_CONTENTNODE)));
173 }
174 return retVal;
175 }
176 if ("metaData".equals(key)) {
177 return new MetaData(wrapped);
178 }
179 if ("nodeData".equals(key)) {
180 return wrapped.getProperties();
181 }
182 if ("name".equals(key)) {
183 return name;
184 }
185 Node retVal = getByName(key);
186 if (retVal != null) {
187 return retVal;
188 }
189 return getPropertyValue(key);
190 }
191
192 protected Object getPropertyValue(String attributeName) throws RepositoryException {
193 PropertyIterator properties = wrapped.getProperties(attributeName);
194 if (!properties.hasNext()) {
195 return null;
196 }
197 Property nodeData = properties.nextProperty();
198 Value propertyValue = nodeData.getValue();
199 Object value = null;
200 if (propertyValue != null) {
201 try {
202 switch (propertyValue.getType()) {
203 case PropertyType.STRING:
204 value = propertyValue.getString();
205 break;
206 case PropertyType.BINARY:
207 value = propertyValue;
208 break;
209 case PropertyType.DATE:
210 value = propertyValue.getDate();
211 break;
212 case PropertyType.DOUBLE:
213 value = BigDecimal.valueOf(propertyValue.getDouble());
214 break;
215 case PropertyType.LONG:
216 value = BigDecimal.valueOf(propertyValue.getLong());
217 break;
218 default:
219 value = propertyValue.getString();
220 }
221 } catch (ValueFormatException e) {
222 log.warn(e.getMessage());
223 } catch (IllegalStateException e) {
224 log.warn(e.getMessage());
225 } catch (RepositoryException e) {
226 log.warn(e.getMessage());
227 }
228 }
229 return value;
230 }
231
232 protected Node getByName(String name) {
233 try{
234 for (Iterator<Node> iter = wrapped.getNodes(); iter.hasNext();) {
235 Node childNode = iter.next();
236 String childNodeName = childNode.getName();
237 if (name.equals(childNodeName)) {
238 return childNode;
239 }
240 }
241 }catch(RepositoryException e){
242 log.error(e.getMessage());
243 }
244 return null;
245 }
246
247 @Override
248 public String toString() {
249 try{
250 StringBuilder retVal = new StringBuilder();
251 Iterator<Node> iterator = wrapped.getNodes();
252 retVal.append("(+) " + name + "\n");
253 while (iterator.hasNext()) {
254 Node node = iterator.next();
255 if(showNode(node)){
256 if (hasMoreChildren(node)) {
257 retVal.append("\t(+) ");
258 } else {
259 retVal.append("\t(-) ");
260 }
261 retVal.append(node.getName() + "\n");
262 }
263 }
264
265 PropertyIterator properties = wrapped.getProperties();
266 while (properties.hasNext()) {
267 Property property = properties.nextProperty();
268 if(showProperty(property)){
269 retVal.append("\t\t* " + property.getName() + ": ["
270 + StringUtils.abbreviate(property.getString(), 80)
271 + "]\n");
272 }
273 }
274
275 return retVal.toString();
276 }catch(RepositoryException e){
277 log.error(e.toString());
278 return null;
279 }
280 }
281
282 protected boolean showNode(Node node) {
283 try{
284 if(node.getPrimaryNodeType().getName().equals("mgnl:metaData")){
285 return false;
286 }else if(StringUtils.startsWith(node.getName(), "jcr:")){
287 return false;
288 }else if(StringUtils.startsWith(node.getName(), "rep:")){
289 return false;
290 }
291 }catch(RepositoryException e){
292 log.error(e.getMessage());
293 return false;
294 }
295 return true;
296 }
297
298 protected boolean showProperty(Property property) {
299 try{
300 if(property.isMultiple()){
301 return false;
302 }else if(StringUtils.startsWith(property.getName(), "jcr:")){
303 return false;
304 }
305 }catch(RepositoryException e){
306 log.error(e.getMessage());
307 return false;
308 }
309 return true;
310 }
311
312 private boolean hasMoreChildren(Node node) throws RepositoryException {
313 boolean hasChildren = false;
314 try{
315 NodeIterator it = node.getNodes();
316 while (it.hasNext()){
317 if(!it.nextNode().getPrimaryNodeType().getName().equals("mgnl:metaData")){
318 hasChildren = true;
319 break;
320 }
321 }
322 }catch(RepositoryException e){
323 log.error(e.getMessage());
324 }
325 return hasChildren;
326 }
327
328 @Override
329 public int hashCode() {
330 final int prime = 31;
331 int result = 1;
332 result = prime * result + ((name == null) ? 0 : name.hashCode());
333 return result;
334 }
335
336 @Override
337 public boolean equals(Object obj) {
338 try{
339 if (this == obj)
340 return true;
341 if (obj == null)
342 return false;
343 if (getClass() != obj.getClass())
344 return false;
345 MgnlGroovyJCRNode other = (MgnlGroovyJCRNode) obj;
346 if (name == null) {
347 if (other.name != null)
348 return false;
349 } else if (!wrapped.getPath().equals(other.getPath()))
350 return false;
351 return true;
352 }catch(RepositoryException e){
353 return false;
354 }
355 }
356
357 private boolean isContentNodeType() {
358 try {
359 return wrapped.isNodeType(MgnlNodeType.NT_CONTENTNODE);
360 } catch (RepositoryException e) {
361 throw new RuntimeRepositoryException(e);
362 }
363 }
364 }