1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.services.cms.link;
18
19 import java.io.InputStream;
20 import java.security.AccessControlException;
21 import java.util.Calendar;
22 import java.util.Map;
23
24 import javax.jcr.AccessDeniedException;
25 import javax.jcr.InvalidItemStateException;
26 import javax.jcr.Item;
27 import javax.jcr.ItemExistsException;
28 import javax.jcr.ItemNotFoundException;
29 import javax.jcr.MergeException;
30 import javax.jcr.NoSuchWorkspaceException;
31 import javax.jcr.Node;
32 import javax.jcr.NodeIterator;
33 import javax.jcr.PathNotFoundException;
34 import javax.jcr.Property;
35 import javax.jcr.PropertyIterator;
36 import javax.jcr.ReferentialIntegrityException;
37 import javax.jcr.RepositoryException;
38 import javax.jcr.Session;
39 import javax.jcr.UnsupportedRepositoryOperationException;
40 import javax.jcr.Value;
41 import javax.jcr.ValueFormatException;
42 import javax.jcr.lock.Lock;
43 import javax.jcr.lock.LockException;
44 import javax.jcr.nodetype.ConstraintViolationException;
45 import javax.jcr.nodetype.NoSuchNodeTypeException;
46 import javax.jcr.nodetype.NodeDefinition;
47 import javax.jcr.nodetype.NodeType;
48 import javax.jcr.version.Version;
49 import javax.jcr.version.VersionException;
50 import javax.jcr.version.VersionHistory;
51
52 import org.exoplatform.services.jcr.access.AccessControlList;
53 import org.exoplatform.services.jcr.core.ExtendedNode;
54 import org.exoplatform.services.jcr.datamodel.InternalQName;
55 import org.exoplatform.services.log.ExoLogger;
56 import org.exoplatform.services.log.Log;
57 import org.exoplatform.services.wcm.core.NodeLocation;
58
59
60
61
62
63 public class NodeLinkAware extends ItemLinkAware implements ExtendedNode {
64
65 final static public String EXO_RESTORE_LOCATION = "exo:restoreLocation";
66
67
68
69
70 private static final Log LOG = ExoLogger.getLogger(NodeLinkAware.class.getName());
71
72 private final NodeLocation nodeLocation;
73
74 private volatile NodeLocation targetNodeLocation;
75
76 public NodeLinkAware(String originalWorkspace, String virtualPath, Node node) {
77 super(originalWorkspace, virtualPath, node);
78 this.nodeLocation = NodeLocation.getNodeLocationByNode(node);
79 }
80
81 public String getRealPath() {
82 return nodeLocation.getPath();
83 }
84
85 public Node getRealNode() {
86 return NodeLocation.getNodeByLocation(nodeLocation);
87 }
88
89 public NodeLinkAware getTargetNode() throws RepositoryException {
90 return new NodeLinkAware(originalWorkspaceName, virtualPath, getTarget());
91 }
92
93 public Session getNodeSession() throws RepositoryException {
94 return getRealNode().getSession();
95 }
96
97 Node getTarget() throws RepositoryException {
98 Node targetNode = null;
99 if (targetNodeLocation == null) {
100 synchronized (this) {
101 if (targetNodeLocation == null) {
102 LinkManager linkManager = LinkUtils.getLinkManager();
103 Node node = getRealNode();
104 if (linkManager.isLink(node)) {
105 targetNode = linkManager.getTarget(node);
106 } else {
107 targetNode = node;
108 }
109 }
110 }
111 }
112 return targetNode;
113 }
114
115 private Node getTargetReachable() throws RepositoryException {
116 try {
117 return getTarget();
118 } catch (AccessDeniedException e) {
119 if (LOG.isWarnEnabled()) {
120 LOG.warn("Cannot access to the target of the node " + nodeLocation.getPath());
121 }
122 } catch (ItemNotFoundException e) {
123 if (LOG.isWarnEnabled()) {
124 LOG.warn("The target of the node " + nodeLocation.getPath() + " doesn't exist anymore");
125 }
126 }
127 return null;
128 }
129
130 private ExtendedNode getExtendedTarget() throws RepositoryException {
131 return (ExtendedNode) getTarget();
132 }
133
134 private ExtendedNode getExtendedRealNode() {
135 return (ExtendedNode) getRealNode();
136 }
137
138 private String getVirtualPath(String relativePath) {
139 return LinkUtils.createPath(virtualPath, relativePath);
140 }
141
142
143
144
145 public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException,
146 ConstraintViolationException, LockException, RepositoryException {
147 getTarget().addMixin(mixinName);
148 }
149
150
151
152
153 public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException,
154 VersionException, ConstraintViolationException, LockException, RepositoryException {
155 return new NodeLinkAware(originalWorkspaceName, getVirtualPath(relPath), getTarget().addNode(
156 relPath));
157 }
158
159
160
161
162 public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException,
163 PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException,
164 ConstraintViolationException, RepositoryException {
165 return new NodeLinkAware(originalWorkspaceName, getVirtualPath(relPath), getTarget().addNode(
166 relPath, primaryNodeTypeName));
167 }
168
169
170
171
172 public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException {
173 return getTarget().canAddMixin(mixinName);
174 }
175
176
177
178
179 public void cancelMerge(Version version) throws VersionException, InvalidItemStateException,
180 UnsupportedRepositoryOperationException, RepositoryException {
181 getTarget().cancelMerge(version);
182 }
183
184
185
186
187 public Version checkin() throws VersionException, UnsupportedRepositoryOperationException,
188 InvalidItemStateException, LockException, RepositoryException {
189 return getTarget().checkin();
190 }
191
192
193
194
195 public void checkout() throws UnsupportedRepositoryOperationException, LockException,
196 RepositoryException {
197 getTarget().checkout();
198 }
199
200
201
202
203 public void doneMerge(Version version) throws VersionException, InvalidItemStateException,
204 UnsupportedRepositoryOperationException, RepositoryException {
205 getTarget().doneMerge(version);
206 }
207
208
209
210
211 public Version getBaseVersion() throws UnsupportedRepositoryOperationException,
212 RepositoryException {
213 return getTarget().getBaseVersion();
214 }
215
216
217
218
219 public String getCorrespondingNodePath(String workspaceName) throws ItemNotFoundException,
220 NoSuchWorkspaceException, AccessDeniedException, RepositoryException {
221 return getTarget().getCorrespondingNodePath(workspaceName);
222 }
223
224
225
226
227 public NodeDefinition getDefinition() throws RepositoryException {
228 return getTarget().getDefinition();
229 }
230
231
232
233
234 public int getIndex() throws RepositoryException {
235 return getRealNode().getIndex();
236 }
237
238
239
240
241 public Lock getLock() throws UnsupportedRepositoryOperationException, LockException,
242 AccessDeniedException, RepositoryException {
243 return getTarget().getLock();
244 }
245
246
247
248
249 public NodeType[] getMixinNodeTypes() throws RepositoryException {
250 return getTarget().getMixinNodeTypes();
251 }
252
253
254
255
256 public Node getNode(String relPath) throws PathNotFoundException, RepositoryException {
257 return new NodeLinkAware(originalWorkspaceName, getVirtualPath(relPath), (Node) LinkUtils
258 .getNodeFinder().getItem(getNodeSession(), getVirtualPath(relPath)));
259 }
260
261
262
263
264 public NodeIterator getNodes() throws RepositoryException {
265 return new NodeIteratorLinkAware(originalWorkspaceName, virtualPath, getTarget().getNodes());
266 }
267
268
269
270
271 public NodeIterator getNodes(String namePattern) throws RepositoryException {
272 return new NodeIteratorLinkAware(originalWorkspaceName, virtualPath, getTarget().getNodes(
273 namePattern));
274 }
275
276
277
278
279 public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException {
280 return ItemLinkAware.newInstance(originalWorkspaceName, getVirtualPath(super.getName()),
281 getTarget().getPrimaryItem());
282 }
283
284
285
286
287 public NodeType getPrimaryNodeType() throws RepositoryException {
288 return new NodeTypeLinkAware(this);
289 }
290
291
292
293
294 public PropertyIterator getProperties() throws RepositoryException {
295 return new PropertyIteratorLinkAware(originalWorkspaceName, virtualPath, getTarget()
296 .getProperties());
297 }
298
299
300
301
302 public PropertyIterator getProperties(String namePattern) throws RepositoryException {
303 return new PropertyIteratorLinkAware(originalWorkspaceName, virtualPath, getTarget()
304 .getProperties(namePattern));
305 }
306
307
308
309
310 public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException {
311 String path = getVirtualPath(relPath);
312 return new PropertyLinkAware(originalWorkspaceName, path, (Property) LinkUtils.getNodeFinder()
313 .getItem(getOriginalSession(), path));
314 }
315
316
317
318
319 public PropertyIterator getReferences() throws RepositoryException {
320 return getTarget().getReferences();
321 }
322
323
324
325
326 public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException {
327 return getTarget().getUUID();
328 }
329
330
331
332
333 public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException,
334 RepositoryException {
335 return getTarget().getVersionHistory();
336 }
337
338
339
340
341 public boolean hasNode(String relPath) throws RepositoryException {
342 try {
343 return LinkUtils.getNodeFinder().getItem(getOriginalSession(), getVirtualPath(relPath)) instanceof Node;
344 } catch (PathNotFoundException e) {
345 return false;
346 }
347 }
348
349
350
351
352 public boolean hasNodes() throws RepositoryException {
353 return getTarget().hasNodes();
354 }
355
356
357
358
359 public boolean hasProperties() throws RepositoryException {
360 return getTarget().hasProperties();
361 }
362
363
364
365
366 public boolean hasProperty(String relPath) throws RepositoryException {
367 try {
368 return LinkUtils.getNodeFinder().getItem(getOriginalSession(), getVirtualPath(relPath)) instanceof Property;
369 } catch (PathNotFoundException e) {
370 return false;
371 }
372 }
373
374
375
376
377 public boolean holdsLock() throws RepositoryException {
378 Node node = getTargetReachable();
379 return node == null ? false : node.holdsLock();
380 }
381
382
383
384
385 public boolean isCheckedOut() throws RepositoryException {
386 Node node = getTargetReachable();
387 return node == null ? false : node.isCheckedOut();
388 }
389
390
391
392
393 public boolean isLocked() throws RepositoryException {
394 Node node = getTargetReachable();
395 return node == null ? false : node.isLocked();
396 }
397
398
399
400
401 public boolean isNodeType(String nodeTypeName) throws RepositoryException {
402 if (EXO_RESTORE_LOCATION.equals(nodeTypeName))
403 return this.getRealNode().isNodeType(nodeTypeName);
404 Node node = getTargetReachable();
405 return node == null ? false : node.isNodeType(nodeTypeName);
406 }
407
408
409
410
411 public Lock lock(boolean isDeep, boolean isSessionScoped)
412 throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException,
413 InvalidItemStateException, RepositoryException {
414 return getTarget().lock(isDeep, isSessionScoped);
415 }
416
417
418
419
420 public NodeIterator merge(String srcWorkspace, boolean bestEffort)
421 throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException,
422 InvalidItemStateException, RepositoryException {
423 return getTarget().merge(srcWorkspace, bestEffort);
424 }
425
426
427
428
429 public void orderBefore(String srcChildRelPath, String destChildRelPath)
430 throws UnsupportedRepositoryOperationException, VersionException,
431 ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException {
432 getTarget().orderBefore(srcChildRelPath, destChildRelPath);
433 }
434
435
436
437
438 public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException,
439 ConstraintViolationException, LockException, RepositoryException {
440 getTarget().removeMixin(mixinName);
441 }
442
443
444
445
446 public void restore(String versionName, boolean removeExisting) throws VersionException,
447 ItemExistsException, UnsupportedRepositoryOperationException, LockException,
448 InvalidItemStateException, RepositoryException {
449 getTarget().restore(versionName, removeExisting);
450 }
451
452
453
454
455 public void restore(Version version, boolean removeExisting) throws VersionException,
456 ItemExistsException, UnsupportedRepositoryOperationException, LockException,
457 RepositoryException {
458 getTarget().restore(version, removeExisting);
459 }
460
461
462
463
464 public void restore(Version version, String relPath, boolean removeExisting)
465 throws PathNotFoundException, ItemExistsException, VersionException,
466 ConstraintViolationException, UnsupportedRepositoryOperationException, LockException,
467 InvalidItemStateException, RepositoryException {
468 getTarget().restore(version, relPath, removeExisting);
469 }
470
471
472
473
474 public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException,
475 ItemExistsException, UnsupportedRepositoryOperationException, LockException,
476 InvalidItemStateException, RepositoryException {
477 getTarget().restoreByLabel(versionLabel, removeExisting);
478 }
479
480
481
482
483 public Property setProperty(String name, Value value) throws ValueFormatException,
484 VersionException, LockException, ConstraintViolationException, RepositoryException {
485 return getTarget().setProperty(name, value);
486 }
487
488
489
490
491 public Property setProperty(String name, Value[] values) throws ValueFormatException,
492 VersionException, LockException, ConstraintViolationException, RepositoryException {
493 return getTarget().setProperty(name, values);
494 }
495
496
497
498
499 public Property setProperty(String name, String[] values) throws ValueFormatException,
500 VersionException, LockException, ConstraintViolationException, RepositoryException {
501 return getTarget().setProperty(name, values);
502 }
503
504
505
506
507 public Property setProperty(String name, String value) throws ValueFormatException,
508 VersionException, LockException, ConstraintViolationException, RepositoryException {
509 return getTarget().setProperty(name, value);
510 }
511
512
513
514
515 public Property setProperty(String name, InputStream value) throws ValueFormatException,
516 VersionException, LockException, ConstraintViolationException, RepositoryException {
517 return getTarget().setProperty(name, value);
518 }
519
520
521
522
523 public Property setProperty(String name, boolean value) throws ValueFormatException,
524 VersionException, LockException, ConstraintViolationException, RepositoryException {
525 return getTarget().setProperty(name, value);
526 }
527
528
529
530
531 public Property setProperty(String name, double value) throws ValueFormatException,
532 VersionException, LockException, ConstraintViolationException, RepositoryException {
533 return getTarget().setProperty(name, value);
534 }
535
536
537
538
539 public Property setProperty(String name, long value) throws ValueFormatException,
540 VersionException, LockException, ConstraintViolationException, RepositoryException {
541 return getTarget().setProperty(name, value);
542 }
543
544
545
546
547 public Property setProperty(String name, Calendar value) throws ValueFormatException,
548 VersionException, LockException, ConstraintViolationException, RepositoryException {
549 return getTarget().setProperty(name, value);
550 }
551
552
553
554
555 public Property setProperty(String name, Node value) throws ValueFormatException,
556 VersionException, LockException, ConstraintViolationException, RepositoryException {
557 return getTarget().setProperty(name, value);
558 }
559
560
561
562
563 public Property setProperty(String name, Value value, int type) throws ValueFormatException,
564 VersionException, LockException, ConstraintViolationException, RepositoryException {
565 return getTarget().setProperty(name, value, type);
566 }
567
568
569
570
571 public Property setProperty(String name, Value[] values, int type) throws ValueFormatException,
572 VersionException, LockException, ConstraintViolationException, RepositoryException {
573 return getTarget().setProperty(name, values, type);
574 }
575
576
577
578
579 public Property setProperty(String name, String[] values, int type) throws ValueFormatException,
580 VersionException, LockException, ConstraintViolationException, RepositoryException {
581 return getTarget().setProperty(name, values, type);
582 }
583
584
585
586
587 public Property setProperty(String name, String value, int type) throws ValueFormatException,
588 VersionException, LockException, ConstraintViolationException, RepositoryException {
589 return getTarget().setProperty(name, value, type);
590 }
591
592
593
594
595 public void unlock() throws UnsupportedRepositoryOperationException, LockException,
596 AccessDeniedException, InvalidItemStateException, RepositoryException {
597 getTarget().unlock();
598 }
599
600
601
602
603 public void update(String srcWorkspaceName) throws NoSuchWorkspaceException,
604 AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
605 getTarget().update(srcWorkspaceName);
606 }
607
608
609
610
611 public void save() throws AccessDeniedException, ItemExistsException,
612 ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException,
613 VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
614 getTarget().save();
615 }
616
617
618
619
620 public void checkPermission(String actions) throws AccessControlException, RepositoryException {
621 getExtendedRealNode().checkPermission(actions);
622 }
623
624
625
626
627 public void clearACL() throws RepositoryException, AccessControlException {
628 getExtendedRealNode().clearACL();
629 }
630
631
632
633
634 public AccessControlList getACL() throws RepositoryException {
635 return getExtendedRealNode().getACL();
636 }
637
638
639
640
641 public boolean isNodeType(InternalQName name) throws RepositoryException {
642 ExtendedNode node = (ExtendedNode) getTargetReachable();
643 return node == null ? false : node.isNodeType(name);
644 }
645
646
647
648
649 public Lock lock(boolean isDeep, long timeOut) throws UnsupportedRepositoryOperationException,
650 LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
651 return getExtendedTarget().lock(isDeep, timeOut);
652 }
653
654
655
656
657 public void removePermission(String identity) throws RepositoryException, AccessControlException {
658 getExtendedRealNode().removePermission(identity);
659 }
660
661
662
663
664 public void removePermission(String identity, String permission) throws RepositoryException,
665 AccessControlException {
666 getExtendedRealNode().removePermission(identity, permission);
667 }
668
669
670
671
672 public void setPermission(String identity, String[] permission) throws RepositoryException,
673 AccessControlException {
674 getExtendedRealNode().setPermission(identity, permission);
675 }
676
677
678
679
680 public void setPermissions(Map<String, String[]> permissions) throws RepositoryException,
681 AccessControlException {
682 getExtendedRealNode().setPermissions(permissions);
683 }
684
685
686
687
688 public String getIdentifier() throws RepositoryException {
689 ExtendedNode node = (ExtendedNode) getTarget();
690 return node.getIdentifier();
691 }
692
693
694
695
696 public NodeIterator getNodesLazily() throws RepositoryException {
697 ExtendedNode node = (ExtendedNode) getTarget();
698 return node.getNodesLazily();
699 }
700
701 @Override
702 public NodeIterator getNodesLazily(int pageSize) throws RepositoryException {
703 ExtendedNode node = (ExtendedNode) getTarget();
704 return node.getNodesLazily(pageSize);
705 }
706
707 @Override
708 public long getNodesCount() throws RepositoryException {
709 ExtendedNode node = (ExtendedNode) getTarget();
710 return node.getNodesCount();
711 }
712 }