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;
+import javax.jcr.Value;
import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateHashModelEx2;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateModelIterator;
import freemarker.template.TemplateNodeModel;
import freemarker.template.TemplateSequenceModel;
}
}
+ // HASH
+
@Override
public TemplateModel get(String key) throws TemplateModelException {
try {
- Property property = node.getProperty(key);
- if (property == null)
- return null;
- return new SimpleScalar(property.getString());
+ if ("jcr:path".equals(key))
+ return new SimpleScalar(node.getPath());
+ if ("jcr:name".equals(key))
+ return new SimpleScalar(node.getName());
+ if ("jcr:properties".equals(key))
+ return new PropertiesModel();
+ if ("jcr:parent".equals(key))
+ 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;
+
} catch (RepositoryException e) {
throw new TemplateModelException("Cannot get property " + key + " of " + node, e);
}
@Override
public boolean isEmpty() throws TemplateModelException {
- // JCR default properties always accessible
return false;
}
- // HASH
+ public Node getNode() {
+ return node;
+ }
+
+ protected TemplateModel propertyValues(Property property) throws RepositoryException {
+ if (!property.isMultiple())
+ return new SimpleScalar(property.getString());
+ Value[] values = property.getValues();
+ StringBuilder sb = new StringBuilder();
+ for (Value value : values) {
+ sb.append(value.getString()).append('\n');
+ }
+ return new SimpleScalar(sb.toString());
+ }
+
+ class PropertiesModel implements TemplateHashModelEx2 {
+ @Override
+ public TemplateModel get(String key) throws TemplateModelException {
+ return JcrModel.this.get(key);
+ }
+
+ @Override
+ public boolean isEmpty() throws TemplateModelException {
+ return false;
+ }
+
+ @Override
+ public TemplateCollectionModel keys() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new TemplateCollectionModel() {
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ try {
+ return new SimpleScalar(pit.nextProperty().getName());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public int size() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return (int) pit.getSize();
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public TemplateCollectionModel values() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new TemplateCollectionModel() {
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ try {
+ return propertyValues(pit.nextProperty());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public KeyValuePairIterator keyValuePairIterator() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new KeyValuePairIterator() {
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+
+ @Override
+ public KeyValuePair next() throws TemplateModelException {
+ Property property = pit.nextProperty();
+ return new KeyValuePair() {
+
+ @Override
+ public TemplateModel getValue() throws TemplateModelException {
+ try {
+ return propertyValues(property);
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public TemplateModel getKey() throws TemplateModelException {
+ try {
+ return new SimpleScalar(property.getName());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ }
}