Fix child node access in FreeMarker
[lgpl/argeo-commons.git] / org.argeo.core / src / org / argeo / fm / jcr / JcrModel.java
index 5cae5c1a86394737dd9bc6bff2128266fed6af91..e41dfdae7245973167fd9093baf0581716200168 100644 (file)
@@ -1,6 +1,10 @@
 package org.argeo.fm.jcr;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.jcr.Node;
+import javax.jcr.NodeIterator;
 import javax.jcr.Property;
 import javax.jcr.PropertyIterator;
 import javax.jcr.RepositoryException;
@@ -80,12 +84,41 @@ public class JcrModel implements TemplateNodeModel, TemplateHashModel {
                        if ("jcr:properties".equals(key))
                                return new PropertiesModel();
                        if ("jcr:parent".equals(key))
-                               return node.getParent() != null ? new JcrModel(node.getParent()) : null;
+                               return !"/".equals(node.getPath()) ? new JcrModel(node.getParent()) : null;
+
+                       Property property = null;
+                       if (!node.hasProperty(key)) {
+                               List<Property> props = new ArrayList<>();
+                               PropertyIterator pit = node.getProperties("*:" + key);
+                               while (pit.hasNext())
+                                       props.add(pit.nextProperty());
+                               if (props.size() > 1)
+                                       throw new TemplateModelException(
+                                                       "Too many properties match " + key + " (" + props + "), use prefix with \\: escape");
+                               if (!props.isEmpty())
+                                       property = props.get(0);
+                       } else
+                               property = node.getProperty(key);
+                       if (property != null)
+                               return propertyValues(property);
+
+                       Node child = null;
+                       if (!node.hasNode(key)) {
+                               List<Node> children = new ArrayList<>();
+                               NodeIterator nit = node.getNodes("*:" + key);
+                               while (nit.hasNext())
+                                       children.add(nit.nextNode());
+                               if (children.size() > 1)
+                                       throw new TemplateModelException(
+                                                       "Too many properties match " + key + " (" + children + "), use prefix with \\: escape");
+                               if (!children.isEmpty())
+                                       child = children.get(0);
+                       } else
+                               child = node.getNode(key);
+                       if (child != null)
+                               return new JcrModel(child);
+                       return null;
 
-                       Property property = node.getProperty(key);
-                       if (property == null)
-                               return null;
-                       return new SimpleScalar(property.getString());
                } catch (RepositoryException e) {
                        throw new TemplateModelException("Cannot get property " + key + " of " + node, e);
                }