Fix child node access in FreeMarker
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 21 Mar 2019 09:49:07 +0000 (10:49 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 21 Mar 2019 09:49:07 +0000 (10:49 +0100)
org.argeo.core/src/org/argeo/fm/jcr/JcrModel.java

index 6a834142e4b963c7cb18f98a05dd3e1e13a4e9ed..e41dfdae7245973167fd9093baf0581716200168 100644 (file)
@@ -4,6 +4,7 @@ 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;
@@ -85,21 +86,39 @@ public class JcrModel implements TemplateNodeModel, TemplateHashModel {
                        if ("jcr:parent".equals(key))
                                return !"/".equals(node.getPath()) ? new JcrModel(node.getParent()) : null;
 
-                       Property property;
+                       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() == 0)
-                                       return null;
                                if (props.size() > 1)
                                        throw new TemplateModelException(
                                                        "Too many properties match " + key + " (" + props + "), use prefix with \\: escape");
-                               property = props.get(0);
+                               if (!props.isEmpty())
+                                       property = props.get(0);
                        } else
                                property = node.getProperty(key);
-                       return propertyValues(property);
+                       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;
+
                } catch (RepositoryException e) {
                        throw new TemplateModelException("Cannot get property " + key + " of " + node, e);
                }