1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.core;
35
36 import info.magnolia.cms.core.search.QueryManager;
37 import info.magnolia.cms.core.search.QueryManagerImpl;
38 import info.magnolia.cms.security.AccessDeniedException;
39 import info.magnolia.cms.security.AccessManager;
40 import info.magnolia.cms.security.PermissionUtil;
41 import info.magnolia.jcr.RuntimeRepositoryException;
42 import info.magnolia.jcr.util.NodeUtil;
43 import info.magnolia.jcr.util.SessionUtil;
44 import info.magnolia.jcr.wrapper.JCRPropertiesFilteringNodeWrapper;
45 import info.magnolia.logging.AuditLoggingUtil;
46
47 import java.io.ObjectStreamField;
48 import java.io.Serializable;
49 import java.util.Collection;
50
51 import javax.jcr.ItemNotFoundException;
52 import javax.jcr.Node;
53 import javax.jcr.PathNotFoundException;
54 import javax.jcr.RepositoryException;
55 import javax.jcr.Session;
56 import javax.jcr.Workspace;
57
58 import org.apache.commons.lang.StringUtils;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62
63
64
65
66
67
68
69
70
71 @Deprecated
72 public class DefaultHierarchyManager implements HierarchyManager, Serializable {
73
74 private static final long serialVersionUID = 223L;
75
76
77
78
79
80 private static final ObjectStreamField[] serialPersistentFields = {
81 new ObjectStreamField("userId", String.class),
82 new ObjectStreamField("repositoryName", String.class),
83 new ObjectStreamField("workspaceName", String.class),
84 };
85
86 private static final Logger log = LoggerFactory.getLogger(DefaultHierarchyManager.class);
87
88 private Session jcrSession;
89
90 public DefaultHierarchyManager(Session jcrSession) {
91 this.jcrSession = jcrSession;
92 }
93
94 public DefaultHierarchyManager(String userId, Session jcrSession, AccessManager ignoredAccessManager) throws RepositoryException {
95 this(userId, jcrSession);
96 }
97
98 public DefaultHierarchyManager(String ignoredUserId, Session jcrSession) throws RepositoryException {
99 this(jcrSession);
100 }
101
102
103
104
105 public DefaultHierarchyManager(Session jcrSession, String ignored) {
106 this.jcrSession = jcrSession;
107 }
108
109
110
111
112
113 protected void setAccessManager(AccessManager accessManager) {
114
115 throw new UnsupportedOperationException("Custom access managers are no longer supported. Use Repository level security checks instead.");
116 }
117
118
119
120
121
122 @Override
123 public AccessManager getAccessManager() {
124
125 throw new UnsupportedOperationException("Custom access managers are no longer supported. Use Repository level security checks instead.");
126 }
127
128
129
130
131
132 protected void setQueryManager(QueryManager queryManager) {
133 throw new UnsupportedOperationException("This Operation is no longer available.");
134 }
135
136 @Override
137 public QueryManager getQueryManager() {
138 try {
139 return new QueryManagerImpl(getJcrSession().getWorkspace().getQueryManager(), this);
140 } catch (RepositoryException e) {
141 throw new RuntimeRepositoryException(e);
142 }
143 }
144
145 private Node getRootNode() throws RepositoryException {
146 return jcrSession.getRootNode();
147 }
148
149 private String getWorkspaceName() {
150 return jcrSession.getWorkspace().getName();
151 }
152
153 protected Session getJcrSession() {
154 return this.jcrSession;
155 }
156
157 protected void setJcrSession(Session jcrSession) {
158 this.jcrSession = jcrSession;
159 }
160
161
162
163
164
165
166
167
168
169
170
171 @Override
172 public Content createContent(String path, String label, String contentType) throws PathNotFoundException,
173 RepositoryException, AccessDeniedException {
174 Content content = wrapAsContent(this.getRootNode(), this.getNodePath(path, label), contentType);
175 setMetaData(content.getMetaData());
176 AuditLoggingUtil.log( AuditLoggingUtil.ACTION_CREATE, getWorkspaceName(), content.getItemType(), content.getHandle());
177 return content;
178 }
179
180 protected Content wrapAsContent(Node rootNode, String path, String contentType) throws PathNotFoundException, RepositoryException, AccessDeniedException {
181 return new DefaultContent(rootNode, path, contentType);
182 }
183
184 private String getNodePath(String parent, String label) {
185 if (StringUtils.isEmpty(parent) || (parent.equals("/"))) {
186 return label;
187 }
188 if (!parent.endsWith("/")) {
189 parent = parent + "/";
190 }
191 return getNodePath(parent + label);
192 }
193
194 private String getNodePath(String path) {
195 if (path != null && path.startsWith("/")) {
196 return path.replaceFirst("/", StringUtils.EMPTY);
197 }
198 return path;
199 }
200
201
202
203
204
205 protected void setMetaData(MetaData md) throws RepositoryException, AccessDeniedException {
206 md.setCreationDate();
207 md.setModificationDate();
208 md.setAuthorId(this.jcrSession.getUserID());
209 md.setTitle(StringUtils.EMPTY);
210 }
211
212
213
214
215
216
217
218
219 @Override
220 public Content getContent(String path) throws PathNotFoundException, RepositoryException, AccessDeniedException {
221 if (path.equals("/")) {
222 return this.getRoot();
223 }
224 try {
225 return wrapAsContent(this.getRootNode(), getNodePath(path));
226 } catch (ItemNotFoundException e) {
227 this.getJcrSession().refresh(true);
228 return wrapAsContent(this.getRootNode(), getNodePath(path));
229 }
230 }
231
232 public Content wrapAsContent(Node rootNode, String path) throws AccessDeniedException, PathNotFoundException, RepositoryException {
233 return new DefaultContent(rootNode, path);
234 }
235
236
237
238
239
240
241
242
243
244 @Override
245 public Content getContent(String path, boolean create, ItemType type) throws AccessDeniedException,
246 RepositoryException {
247 Content node;
248 try {
249 node = getContent(path);
250 }
251 catch (PathNotFoundException e) {
252 if (create) {
253 node = this.createContent(StringUtils.substringBeforeLast(path, "/"), StringUtils.substringAfterLast(
254 path,
255 "/"), type.toString());
256 AuditLoggingUtil.log( AuditLoggingUtil.ACTION_CREATE, getWorkspaceName(), node.getItemType(), node.getHandle());
257 }
258 else {
259 throw e;
260 }
261 }
262 return node;
263 }
264
265
266
267
268
269
270
271
272
273 @Override
274 public NodeData getNodeData(String path) throws PathNotFoundException, RepositoryException, AccessDeniedException {
275 if (StringUtils.isEmpty(path)) {
276 return null;
277 }
278 final String nodePath = StringUtils.substringBeforeLast(path, "/");
279 final String nodeDataName = StringUtils.substringAfterLast(path, "/");
280 return getContent(nodePath).getNodeData(nodeDataName);
281 }
282
283
284
285
286
287
288
289
290
291
292
293
294 @Deprecated
295 public Content getPage(String path, String templateName) throws PathNotFoundException, RepositoryException,
296 AccessDeniedException {
297 Content page = getContent(path);
298 if (page.getTemplate().equals(templateName)) {
299 return page;
300 }
301 Content pageToBeFound = null;
302 try {
303 if (page.hasChildren()) {
304 Collection<Content> children = page.getChildren(ItemType.CONTENT.getSystemName());
305 for (Content child : children) {
306 if (child.getTemplate().equals(templateName)) {
307 return child;
308 }
309 if (child.hasChildren()) {
310 pageToBeFound = getPage(child.getHandle(), templateName);
311 }
312 if (pageToBeFound != null) {
313 return pageToBeFound;
314 }
315 }
316 }
317 }
318 catch (Exception e) {
319 log.error("Failed to get - " + path + " : " + e.getMessage(), e);
320 }
321 return pageToBeFound;
322 }
323
324
325
326
327
328
329
330
331 @Override
332 public void delete(String path) throws PathNotFoundException, RepositoryException, AccessDeniedException {
333 ItemType type = null;
334 if (this.isNodeData(path)) {
335 this.getNodeData(makeRelative(path)).delete();
336 }
337 else {
338 Node aNode = this.getRootNode().getNode(makeRelative(path));
339 aNode = NodeUtil.deepUnwrap(aNode, JCRPropertiesFilteringNodeWrapper.class);
340 if (aNode.hasProperty(ItemType.JCR_FROZEN_PRIMARY_TYPE)) {
341 type = new ItemType(aNode.getProperty(ItemType.JCR_FROZEN_PRIMARY_TYPE).getString());
342 }
343 type = new ItemType(aNode.getProperty(ItemType.JCR_PRIMARY_TYPE).getString());
344 aNode.remove();
345 }
346 AuditLoggingUtil.log( AuditLoggingUtil.ACTION_DELETE, getWorkspaceName(), type, path);
347 }
348
349 private String makeRelative(String path) {
350 return StringUtils.stripStart(path, "/");
351 }
352
353
354
355
356 @Override
357 public Content getRoot() throws RepositoryException, AccessDeniedException {
358 return (new DefaultContent(this.getRootNode()));
359 }
360
361
362
363
364
365
366
367 @Override
368 public boolean isExist(String path) {
369 if (!PermissionUtil.isGranted(jcrSession, path, Session.ACTION_READ)) {
370 return false;
371 }
372 try {
373 this.getJcrSession().refresh(true);
374 return this.getJcrSession().itemExists(path);
375 } catch (RepositoryException re) {
376
377 if (re.getCause().getClass().getName().equals("org.apache.jackrabbit.spi.commons.conversion.MalformedPathException")) {
378
379 log.debug("{} is not valid jcr path.", path);
380 } else {
381 log.error("Exception caught", re);
382 }
383 return false;
384 }
385 }
386
387 @Override
388 public boolean isGranted(String path, long oldPermissions) {
389 return PermissionUtil.isGranted(jcrSession, path, oldPermissions);
390 }
391
392
393
394
395
396
397 @Override
398 public boolean isNodeData(String path) throws AccessDeniedException {
399 boolean result = false;
400 String nodePath = getNodePath(path);
401 if (StringUtils.isEmpty(nodePath)) {
402 return false;
403 }
404 try {
405 result = this.getRootNode().hasProperty(nodePath);
406 if (!result) {
407
408 result = this.getRootNode().hasProperty(nodePath + "/" + ItemType.JCR_DATA);
409 }
410 }
411 catch (RepositoryException e) {
412
413 }
414 return result;
415 }
416
417
418
419
420
421
422 @Override
423 public Content getContentByUUID(String uuid) throws ItemNotFoundException, RepositoryException,
424 AccessDeniedException {
425 try {
426 return wrapAsContent(this.getJcrSession().getNodeByIdentifier(uuid));
427 } catch (ItemNotFoundException e) {
428
429 this.getJcrSession().refresh(true);
430 return wrapAsContent(this.getJcrSession().getNodeByIdentifier(uuid));
431 }
432 }
433
434 protected Content wrapAsContent(Node node) {
435 return new DefaultContent(node);
436 }
437
438
439
440
441 @Override
442 public Workspace getWorkspace() {
443 return getJcrSession().getWorkspace();
444 }
445
446
447
448
449
450
451
452
453 @Override
454 public void moveTo(String source, String destination) throws PathNotFoundException, RepositoryException,
455 AccessDeniedException {
456 this.getWorkspace().move(source, destination);
457 AuditLoggingUtil.log( AuditLoggingUtil.ACTION_MOVE, getWorkspaceName(), source, destination);
458 }
459
460
461
462
463
464
465
466
467 @Override
468 public void copyTo(String source, String destination) throws PathNotFoundException, RepositoryException,
469 AccessDeniedException {
470 this.getWorkspace().copy(source, destination);
471 AuditLoggingUtil.log( AuditLoggingUtil.ACTION_COPY, getWorkspaceName(), source, destination);
472 }
473
474
475
476
477
478 @Override
479 public void save() throws RepositoryException {
480 try {
481 this.getJcrSession().save();
482 }
483 catch (RepositoryException re) {
484
485 log.error(re.getMessage(), re);
486 throw re;
487 }
488 }
489
490
491
492
493 @Override
494 public boolean hasPendingChanges() throws RepositoryException {
495 return this.getJcrSession().hasPendingChanges();
496 }
497
498
499
500
501
502
503
504 @Override
505 public void refresh(boolean keepChanges) throws RepositoryException {
506 this.getJcrSession().refresh(keepChanges);
507 }
508
509 @Override
510 public String getName() {
511 return getWorkspaceName();
512 }
513
514 @Override
515 public int hashCode() {
516 final int prime = 31;
517 int result = 1;
518 result = prime * result + ((jcrSession == null) ? 0 : jcrSession.hashCode());
519 return result;
520 }
521
522 @Override
523 public boolean equals(Object obj) {
524 if (this == obj) {
525 return true;
526 }
527 if (obj == null) {
528 return false;
529 }
530 if (getClass() != obj.getClass()) {
531 return false;
532 }
533 DefaultHierarchyManager other = (DefaultHierarchyManager) obj;
534 if (jcrSession == null) {
535 if (other.jcrSession != null) {
536 return false;
537 }
538 } else if (!SessionUtil.hasSameUnderlyingSession(jcrSession, other.jcrSession)) {
539 return false;
540 }
541 return true;
542 }
543 }