]> git.argeo.org Git - lgpl/argeo-commons.git/blob - jcr/acr/JcrContent.java
Prepare next development cycle
[lgpl/argeo-commons.git] / jcr / acr / JcrContent.java
1 package org.argeo.cms.jcr.acr;
2
3 import java.util.Calendar;
4 import java.util.Iterator;
5 import java.util.Optional;
6
7 import javax.jcr.Node;
8 import javax.jcr.NodeIterator;
9 import javax.jcr.Property;
10 import javax.jcr.PropertyIterator;
11 import javax.jcr.PropertyType;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.Value;
14 import javax.jcr.nodetype.NodeType;
15 import javax.xml.namespace.QName;
16
17 import org.argeo.api.acr.Content;
18 import org.argeo.api.acr.spi.AbstractContent;
19 import org.argeo.api.acr.spi.ProvidedSession;
20 import org.argeo.jcr.Jcr;
21 import org.argeo.jcr.JcrException;
22
23 public class JcrContent extends AbstractContent {
24 private Node jcrNode;
25
26 private JcrContentProvider provider;
27 private ProvidedSession session;
28
29 protected JcrContent(ProvidedSession session, JcrContentProvider provider, Node node) {
30 this.session = session;
31 this.provider = provider;
32 this.jcrNode = node;
33 }
34
35 @Override
36 public QName getName() {
37 return session.parsePrefixedName(Jcr.getName(jcrNode));
38 }
39
40 @Override
41 public <A> Optional<A> get(QName key, Class<A> clss) {
42 if (isDefaultAttrTypeRequested(clss)) {
43 return Optional.of((A) get(jcrNode, key.toString()));
44 }
45 return Optional.of((A) Jcr.get(jcrNode, key.toString()));
46 }
47
48 @Override
49 public Iterator<Content> iterator() {
50 try {
51 return new JcrContentIterator(jcrNode.getNodes());
52 } catch (RepositoryException e) {
53 throw new JcrException("Cannot list children of " + jcrNode, e);
54 }
55 }
56
57 @Override
58 protected Iterable<QName> keys() {
59 return new Iterable<QName>() {
60
61 @Override
62 public Iterator<QName> iterator() {
63 try {
64 PropertyIterator propertyIterator = jcrNode.getProperties();
65 return new JcrKeyIterator(provider, propertyIterator);
66 } catch (RepositoryException e) {
67 throw new JcrException("Cannot retrive properties from " + jcrNode, e);
68 }
69 }
70 };
71 }
72
73 public Node getJcrNode() {
74 return jcrNode;
75 }
76
77 /** Cast to a standard Java object. */
78 static Object get(Node node, String property) {
79 try {
80 Value value = node.getProperty(property).getValue();
81 switch (value.getType()) {
82 case PropertyType.STRING:
83 return value.getString();
84 case PropertyType.DOUBLE:
85 return (Double) value.getDouble();
86 case PropertyType.LONG:
87 return (Long) value.getLong();
88 case PropertyType.BOOLEAN:
89 return (Boolean) value.getBoolean();
90 case PropertyType.DATE:
91 Calendar calendar = value.getDate();
92 return calendar.toInstant();
93 case PropertyType.BINARY:
94 throw new IllegalArgumentException("Binary is not supported as an attribute");
95 default:
96 return value.getString();
97 }
98 } catch (RepositoryException e) {
99 throw new JcrException("Cannot cast value from " + property + " of node " + node, e);
100 }
101 }
102
103 class JcrContentIterator implements Iterator<Content> {
104 private final NodeIterator nodeIterator;
105 // we keep track in order to be able to delete it
106 private JcrContent current = null;
107
108 protected JcrContentIterator(NodeIterator nodeIterator) {
109 this.nodeIterator = nodeIterator;
110 }
111
112 @Override
113 public boolean hasNext() {
114 return nodeIterator.hasNext();
115 }
116
117 @Override
118 public Content next() {
119 current = new JcrContent(session, provider, nodeIterator.nextNode());
120 return current;
121 }
122
123 @Override
124 public void remove() {
125 if (current != null) {
126 Jcr.remove(current.getJcrNode());
127 }
128 }
129
130 }
131
132 @Override
133 public Content getParent() {
134 return new JcrContent(session, provider, Jcr.getParent(getJcrNode()));
135 }
136
137 @Override
138 public Content add(QName name, QName... classes) {
139 if (classes.length > 0) {
140 QName primaryType = classes[0];
141 Node child = Jcr.addNode(getJcrNode(), name.toString(), primaryType.toString());
142 for (int i = 1; i < classes.length; i++) {
143 try {
144 child.addMixin(classes[i].toString());
145 } catch (RepositoryException e) {
146 throw new JcrException("Cannot add child to " + getJcrNode(), e);
147 }
148 }
149
150 } else {
151 Jcr.addNode(getJcrNode(), name.toString(), NodeType.NT_UNSTRUCTURED);
152 }
153 return null;
154 }
155
156 @Override
157 public void remove() {
158 Jcr.remove(getJcrNode());
159 }
160
161 @Override
162 protected void removeAttr(QName key) {
163 Property property = Jcr.getProperty(getJcrNode(), key.toString());
164 if (property != null) {
165 try {
166 property.remove();
167 } catch (RepositoryException e) {
168 throw new JcrException("Cannot remove property " + key + " from " + getJcrNode(), e);
169 }
170 }
171
172 }
173
174 class JcrKeyIterator implements Iterator<QName> {
175 private final JcrContentProvider contentSession;
176 private final PropertyIterator propertyIterator;
177
178 protected JcrKeyIterator(JcrContentProvider contentSession, PropertyIterator propertyIterator) {
179 this.contentSession = contentSession;
180 this.propertyIterator = propertyIterator;
181 }
182
183 @Override
184 public boolean hasNext() {
185 return propertyIterator.hasNext();
186 }
187
188 @Override
189 public QName next() {
190 Property property = null;
191 try {
192 property = propertyIterator.nextProperty();
193 // TODO map standard property names
194 return session.parsePrefixedName(property.getName());
195 } catch (RepositoryException e) {
196 throw new JcrException("Cannot retrieve property " + property, null);
197 }
198 }
199
200 }
201 }