This project has retired. For details please refer to its
Attic page.
JcrFolder xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.chemistry.opencmis.jcr;
21
22 import org.apache.chemistry.opencmis.commons.PropertyIds;
23 import org.apache.chemistry.opencmis.commons.data.Properties;
24 import org.apache.chemistry.opencmis.commons.data.PropertyData;
25 import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
26 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
27 import org.apache.chemistry.opencmis.commons.enums.Action;
28 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
29 import org.apache.chemistry.opencmis.commons.enums.Updatability;
30 import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
31 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
32 import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
33 import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
34 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
35 import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl;
36 import org.apache.chemistry.opencmis.jcr.type.JcrTypeHandlerManager;
37 import org.apache.chemistry.opencmis.jcr.util.FilterIterator;
38 import org.apache.chemistry.opencmis.jcr.util.Predicate;
39 import org.apache.chemistry.opencmis.jcr.util.Util;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43 import javax.jcr.Node;
44 import javax.jcr.RepositoryException;
45 import javax.jcr.Session;
46 import javax.jcr.query.Query;
47 import javax.jcr.query.QueryManager;
48 import javax.jcr.query.QueryResult;
49 import javax.jcr.version.Version;
50 import java.util.Collections;
51 import java.util.HashSet;
52 import java.util.Iterator;
53 import java.util.Set;
54
55
56
57
58
59 public class JcrFolder extends JcrNode {
60 private static final Log log = LogFactory.getLog(JcrFolder.class);
61
62 public JcrFolder(Node node, JcrTypeManager typeManager, PathManager pathManager, JcrTypeHandlerManager typeHandlerManager) {
63 super(node, typeManager, pathManager, typeHandlerManager);
64 }
65
66
67
68
69
70
71
72
73 public Iterator<JcrNode> getNodes() {
74 try {
75 final FilterIterator<Node> nodes = new FilterIterator<Node>(getNode().getNodes(), typeHandlerManager.getNodePredicate());
76
77 Iterator<JcrNode> jcrNodes = new Iterator<JcrNode>() {
78 public boolean hasNext() {
79 return nodes.hasNext();
80 }
81
82 public JcrNode next() {
83 return create(nodes.next());
84 }
85
86 public void remove() {
87 throw new UnsupportedOperationException();
88 }
89 };
90
91
92
93 return new FilterIterator<JcrNode>(jcrNodes, new Predicate<JcrNode>() {
94 public boolean evaluate(JcrNode node) {
95 try {
96 if (node.isVersionable()) {
97 Version baseVersion = getBaseVersion(node.getNode());
98 return baseVersion.getPredecessors().length > 0;
99 }
100 else {
101 return true;
102 }
103 }
104 catch (RepositoryException e) {
105 log.debug(e.getMessage(), e);
106 throw new CmisRuntimeException(e.getMessage(), e);
107 }
108 }
109 });
110
111 }
112 catch (RepositoryException e) {
113 log.debug(e.getMessage(), e);
114 throw new CmisRuntimeException(e.getMessage(), e);
115 }
116 }
117
118
119
120
121
122
123 public JcrNode addNodeFromSource(JcrDocument source, Properties properties) {
124 try {
125 String destPath = PathManager.createCmisPath(getNode().getPath(), source.getName());
126 Session session = getNode().getSession();
127
128 session.getWorkspace().copy(source.getNode().getPath(), destPath);
129 JcrNode jcrNode = create(session.getNode(destPath));
130
131
132 if (properties != null && properties.getProperties() != null) {
133 updateProperties(jcrNode.getNode(), jcrNode.getTypeId(), properties);
134 }
135
136 session.save();
137 return jcrNode;
138 }
139 catch (RepositoryException e) {
140 log.debug(e.getMessage(), e);
141 throw new CmisStorageException(e.getMessage(), e);
142 }
143 }
144
145
146
147
148
149
150 @Override
151 public void delete(boolean allVersions, boolean isPwc) {
152 try {
153 if (getNode().hasNodes()) {
154 throw new CmisConstraintException("Folder is not empty!");
155 }
156 else {
157 super.delete(allVersions, isPwc);
158 }
159 }
160 catch (RepositoryException e) {
161 log.debug(e.getMessage(), e);
162 throw new CmisRuntimeException(e.getMessage(), e);
163 }
164 }
165
166
167
168
169 public FailedToDeleteDataImpl deleteTree() {
170 FailedToDeleteDataImpl result = new FailedToDeleteDataImpl();
171
172 String id = getId();
173 try {
174 Node node = getNode();
175 if (hasCheckOuts(node)) {
176 result.setIds(Collections.<String>singletonList(id));
177 }
178 else {
179 Session session = node.getSession();
180 node.remove();
181 session.save();
182 result.setIds(Collections.<String>emptyList());
183 }
184 }
185 catch (RepositoryException e) {
186 result.setIds(Collections.singletonList(id));
187 }
188
189 return result;
190 }
191
192
193
194 @Override
195 protected void compileProperties(PropertiesImpl properties, Set<String> filter, ObjectInfoImpl objectInfo)
196 throws RepositoryException {
197
198 super.compileProperties(properties, filter, objectInfo);
199
200 objectInfo.setHasContent(false);
201 objectInfo.setSupportsDescendants(true);
202 objectInfo.setSupportsFolderTree(true);
203
204 String typeId = getTypeIdInternal();
205
206 addPropertyString(properties, typeId, filter, PropertyIds.PATH, pathManager.getPath(getNode()));
207
208
209 if (pathManager.isRoot(getNode())) {
210 objectInfo.setHasParent(false);
211 }
212 else {
213 objectInfo.setHasParent(true);
214 addPropertyId(properties, typeId, filter, PropertyIds.PARENT_ID, getParent().getObjectId());
215 }
216 }
217
218 @Override
219 protected Set<Action> compileAllowableActions(Set<Action> aas) {
220 Set<Action> result = super.compileAllowableActions(aas);
221 setAction(result, Action.CAN_GET_DESCENDANTS, true);
222 setAction(result, Action.CAN_GET_CHILDREN, true);
223 setAction(result, Action.CAN_GET_FOLDER_PARENT, !pathManager.isRoot(getNode()));
224 setAction(result, Action.CAN_GET_OBJECT_PARENTS, !pathManager.isRoot(getNode()));
225 setAction(result, Action.CAN_GET_FOLDER_TREE, true);
226 setAction(result, Action.CAN_CREATE_DOCUMENT, true);
227 setAction(result, Action.CAN_CREATE_FOLDER, true);
228 setAction(result, Action.CAN_DELETE_TREE, true);
229 return result;
230 }
231
232 @Override
233 protected Node getContextNode() {
234 return getNode();
235 }
236
237 @Override
238 protected String getObjectId() throws RepositoryException {
239 return isRoot()
240 ? PathManager.CMIS_ROOT_ID
241 : super.getObjectId();
242 }
243
244 @Override
245 protected BaseTypeId getBaseTypeId() {
246 return BaseTypeId.CMIS_FOLDER;
247 }
248
249 @Override
250 protected String getTypeIdInternal() {
251 return JcrTypeManager.FOLDER_TYPE_ID;
252 }
253
254 public static void setProperties(Node node, TypeDefinition type, Properties properties) {
255 if (properties == null || properties.getProperties() == null) {
256 throw new CmisConstraintException("No properties!");
257 }
258
259 Set<String> addedProps = new HashSet<String>();
260
261 try {
262
263 for (PropertyData<?> prop : properties.getProperties().values()) {
264 PropertyDefinition<?> propDef = type.getPropertyDefinitions().get(prop.getId());
265
266
267 if (propDef == null) {
268 throw new CmisConstraintException("Property '" + prop.getId() + "' is unknown!");
269 }
270
271
272 if (propDef.getId().equals(PropertyIds.OBJECT_TYPE_ID)) {
273 log.warn("Cannot set " + PropertyIds.OBJECT_TYPE_ID + ". Ignoring");
274 addedProps.add(prop.getId());
275 continue;
276 }
277
278
279 if (propDef.getId().equals(PropertyIds.CONTENT_STREAM_FILE_NAME)) {
280 log.warn("Cannot set " + PropertyIds.CONTENT_STREAM_FILE_NAME + ". Ignoring");
281 addedProps.add(prop.getId());
282 continue;
283 }
284
285
286 if (propDef.getUpdatability() == Updatability.READONLY) {
287 throw new CmisConstraintException("Property '" + prop.getId() + "' is readonly!");
288 }
289
290
291 if (PropertyHelper.isPropertyEmpty(prop)) {
292 throw new CmisConstraintException("Property '" + prop.getId() + "' must not be empty!");
293 }
294
295
296 JcrConverter.setProperty(node, prop);
297 addedProps.add(prop.getId());
298 }
299
300
301 for (PropertyDefinition<?> propDef : type.getPropertyDefinitions().values()) {
302 if (!addedProps.contains(propDef.getId()) && propDef.getUpdatability() != Updatability.READONLY) {
303 PropertyData<?> prop = PropertyHelper.getDefaultValue(propDef);
304 if (prop == null && propDef.isRequired()) {
305 throw new CmisConstraintException("Property '" + propDef.getId() + "' is required!");
306 }
307 else if (prop != null) {
308 JcrConverter.setProperty(node, prop);
309 }
310 }
311 }
312 }
313 catch (RepositoryException e) {
314 log.debug(e.getMessage(), e);
315 throw new CmisStorageException(e.getMessage(), e);
316 }
317 }
318
319
320
321 private static boolean hasCheckOuts(Node node) throws RepositoryException {
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338