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.version;
35
36 import info.magnolia.cms.core.AbstractContent;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.DefaultContent;
39 import info.magnolia.cms.core.HierarchyManager;
40 import info.magnolia.cms.core.ItemType;
41 import info.magnolia.cms.core.NodeData;
42 import info.magnolia.cms.security.AccessDeniedException;
43 import info.magnolia.cms.security.AccessManager;
44 import info.magnolia.cms.security.Permission;
45 import info.magnolia.cms.util.ContentWrapper;
46 import info.magnolia.cms.util.NodeDataWrapper;
47 import info.magnolia.cms.util.Rule;
48 import info.magnolia.objectfactory.Components;
49 import info.magnolia.repository.RepositoryManager;
50
51 import java.util.ArrayList;
52 import java.util.Calendar;
53 import java.util.Collection;
54 import java.util.Comparator;
55 import java.util.List;
56
57 import javax.jcr.Node;
58 import javax.jcr.PathNotFoundException;
59 import javax.jcr.PropertyType;
60 import javax.jcr.RepositoryException;
61 import javax.jcr.Value;
62 import javax.jcr.Workspace;
63 import javax.jcr.lock.Lock;
64 import javax.jcr.lock.LockException;
65 import javax.jcr.nodetype.NodeType;
66 import javax.jcr.nodetype.NodeTypeManager;
67 import javax.jcr.version.Version;
68 import javax.jcr.version.VersionHistory;
69 import javax.jcr.version.VersionIterator;
70
71 import org.apache.commons.lang3.StringUtils;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75
76
77
78
79
80
81 @Deprecated
82 public class ContentVersion extends DefaultContent {
83
84
85
86
87 private final class ContentVersionChildWrapper extends ContentWrapper {
88 private final Content parent;
89
90 private ContentVersionChildWrapper(Content./../../info/magnolia/cms/core/Content.html#Content">Content wrappedContent, Content parent) {
91 super(wrappedContent);
92 this.parent = parent;
93 }
94
95 @Override
96 public Content getParent() throws RepositoryException {
97 return parent;
98 }
99
100
101
102
103 @Override
104 public String getHandle() {
105 try {
106 return getParent().getHandle() + "/" + getName();
107 } catch (RepositoryException e) {
108 throw new RuntimeException("Can't create handle for versioned node.", e);
109 }
110 }
111
112
113
114
115 @Override
116 public NodeData newNodeDataInstance(String name, int type, boolean createIfNotExisting) throws AccessDeniedException, RepositoryException {
117 return new NodeDataWrapper(super.newNodeDataInstance(name, type, createIfNotExisting)) {
118 @Override
119 public String getHandle() {
120 return ContentVersionChildWrapper.this.getHandle() + "/" + getName();
121 }
122 };
123 }
124
125 @Override
126 protected Contentef="../../../../../info/magnolia/cms/core/Content.html#Content">Content wrap(Content node) {
127 return new ContentVersionChildWrapper(node, this);
128 }
129 }
130
131 private static Logger log = LoggerFactory.getLogger(ContentVersion.class);
132
133
134
135
136 public static final String VERSION_USER = "versionUser";
137
138
139
140
141 public static final String NAME = "name";
142
143
144
145
146 private final Version state;
147
148
149
150
151 private final Content base;
152
153
154
155
156 private Rule rule;
157
158 private final Version versionedNode;
159
160
161
162
163 @Deprecated
164 public ContentVersion(Version thisVersion, Content base) throws RepositoryException {
165 this(Components.getComponent(RepositoryManager.class), thisVersion, base);
166 }
167
168 public ContentVersion(RepositoryManager repositoryManager, Version thisVersion, Content base) throws RepositoryException {
169 super(repositoryManager);
170
171 if (thisVersion == null) {
172 throw new RepositoryException("Failed to get ContentVersion, version does not exist");
173 }
174 this.versionedNode = thisVersion;
175 if (thisVersion instanceof VersionedNode) {
176 this.state = ((VersionedNode) thisVersion).unwrap();
177 } else {
178 this.state = thisVersion;
179 }
180 this.base = base;
181
182 this.init();
183 }
184
185
186
187
188 private void init() throws RepositoryException {
189 this.setNode(this.state.getNode(ItemType.JCR_FROZENNODE));
190 try {
191 if (!StringUtils.equalsIgnoreCase(this.state.getName(), VersionManager.ROOT_VERSION)) {
192 this.rule = VersionManager.getInstance().getUsedFilter(this.getJCRNode());
193 }
194 } catch (Exception e) {
195 log.error(e.getMessage(), e);
196 }
197 if (this.rule == null) {
198 log.info("failed to get filter used for creating this version, use open filter");
199 this.rule = new Rule();
200 }
201 }
202
203
204
205
206
207
208 public Calendar getCreated() throws RepositoryException {
209 return this.state.getCreated();
210 }
211
212
213
214
215
216
217 public String getVersionLabel() throws RepositoryException {
218 return this.state.getName();
219 }
220
221
222
223
224
225
226 public VersionHistory getContainingHistory() throws RepositoryException {
227 return this.state.getContainingHistory();
228 }
229
230
231
232
233 @Override
234 public String getName() {
235 try {
236 return VersionManager.getInstance().getSystemNode(this.getJCRNode()).getProperty(NAME).getString();
237 } catch (RepositoryException re) {
238 log.error("Failed to retrieve name from version system node", re);
239 return "";
240 }
241 }
242
243
244
245
246 public String getUserName() {
247 try {
248 return VersionManager.getInstance().getSystemNode(this.getJCRNode()).getProperty(VERSION_USER).getString();
249 } catch (RepositoryException re) {
250 log.error("Failed to retrieve user from version system node", re);
251 return "";
252 }
253 }
254
255
256
257
258 @Override
259 public String getHandle() {
260 return this.base.getHandle();
261 }
262
263
264
265
266
267 @Override
268 public Content getContent(String name) throws PathNotFoundException, RepositoryException, AccessDeniedException {
269
270 if (super.hasContent(name)) {
271 return new ContentVersionChildWrapper(super.getContent(name), this);
272 }
273 Content content = base.getContent(name);
274
275 if (!rule.isAllowed(content.getJCRNode())) {
276 return content;
277 }
278 throw new PathNotFoundException(base.getHandle() + "/" + name);
279 }
280
281
282
283
284 @Override
285 public boolean hasContent(String name) throws RepositoryException {
286 if (super.hasContent(name)) {
287 return true;
288 } else if (base.hasContent(name)) {
289 Content content = base.getContent(name);
290
291 if (!rule.isAllowed(content.getJCRNode())) {
292 return true;
293 }
294 }
295 return false;
296 }
297
298
299
300
301 @Override
302 public Content createContent(String name) throws AccessDeniedException {
303 throw new AccessDeniedException("Not allowed to write on version preview");
304 }
305
306
307
308
309 @Override
310 public Content createContent(String name, String contentType) throws AccessDeniedException {
311 throw new AccessDeniedException("Not allowed to write on version preview");
312 }
313
314
315
316
317 @Override
318 public Content createContent(String name, ItemType contentType) throws AccessDeniedException {
319 throw new AccessDeniedException("Not allowed to write on version preview");
320 }
321
322
323
324
325 @Override
326 public NodeData createNodeData(String name) throws AccessDeniedException {
327 throw new AccessDeniedException("Not allowed to write on version preview");
328 }
329
330
331
332
333 public NodeData createNodeData(String name, Value value, int type) throws AccessDeniedException {
334 throw new AccessDeniedException("Not allowed to write on version preview");
335 }
336
337
338
339
340 @Override
341 public NodeData createNodeData(String name, Value value) throws AccessDeniedException {
342 throw new AccessDeniedException("Not allowed to write on version preview");
343 }
344
345
346
347
348 @Override
349 public NodeData createNodeData(String name, int type) throws AccessDeniedException {
350 throw new AccessDeniedException("Not allowed to write on version preview");
351 }
352
353
354
355
356 @Override
357 public void deleteNodeData(String name) throws RepositoryException {
358 throw new AccessDeniedException("Not allowed to write on version preview");
359 }
360
361
362
363
364 @Override
365 public void updateMetaData() throws AccessDeniedException {
366 throw new AccessDeniedException("Not allowed to write on version preview");
367 }
368
369
370
371
372
373 @Override
374 public Collection<Content> getChildren(ContentFilter filter, String namePattern, Comparator<Content> orderCriteria) {
375 ArrayList<Content> result = new ArrayList<Content>();
376 result.addAll(wrap(super.getChildren(filter, namePattern, orderCriteria)));
377
378 Collection<Content> transientChildren = ((AbstractContent) this.base).getChildren(filter, namePattern, orderCriteria);
379 for (Content transientChild : transientChildren) {
380 try {
381 if (!rule.isAllowed(transientChild.getJCRNode())) {
382 result.add(transientChild);
383 }
384 } catch (RepositoryException e) {
385 throw new RuntimeException("Can't determine node type of " + transientChild, e);
386 }
387 }
388
389 return result;
390 }
391
392 private Collection<Content> wrap(Collection<Content> children) {
393 List<Content> transformed = new ArrayList<Content>();
394 for (Content child : children) {
395 transformed.add(new ContentVersionChildWrapper(child, this));
396 }
397 return transformed;
398 }
399
400
401
402
403 @Override
404 public boolean hasChildren() {
405 return (this.getChildren().size() > 0);
406 }
407
408
409
410
411
412 @Override
413 public boolean hasChildren(String contentType) {
414 return (this.getChildren(contentType).size() > 0);
415 }
416
417
418
419
420 @Override
421 public Content getParent() throws PathNotFoundException, RepositoryException, AccessDeniedException {
422 return this.base.getParent();
423 }
424
425 @Override
426 public Content getAncestor(int level) throws PathNotFoundException, RepositoryException, AccessDeniedException {
427 return this.base.getAncestor(level);
428 }
429
430
431
432
433
434
435
436 @Override
437 public Collection<Content> getAncestors() throws PathNotFoundException, RepositoryException {
438 return this.base.getAncestors();
439 }
440
441
442
443
444
445
446
447 @Override
448 public int getLevel() throws PathNotFoundException, RepositoryException {
449 return this.base.getLevel();
450 }
451
452
453
454
455 @Override
456 public void orderBefore(String srcName, String beforeName) throws RepositoryException {
457 throw new AccessDeniedException("Not allowed to write on version preview");
458 }
459
460
461
462
463
464
465
466
467
468
469 @Override
470 public int getIndex() throws RepositoryException {
471 return this.base.getIndex();
472 }
473
474
475
476
477
478
479 @Override
480 public NodeType getNodeType() throws RepositoryException {
481 log.warn("This is a Version node, it will always return NT_FROZEN as node type.");
482 log.warn("Use getNodeTypeName to retrieve base node primary type");
483 return super.getNodeType();
484 }
485
486
487
488
489 @Override
490 public void restore(String versionName, boolean removeExisting) throws RepositoryException {
491 throw new AccessDeniedException("Not allowed to write on version preview");
492 }
493
494
495
496
497 @Override
498 public void restore(Version version, boolean removeExisting) throws RepositoryException {
499 throw new AccessDeniedException("Not allowed to write on version preview");
500 }
501
502
503
504
505 @Override
506 public void restore(Version version, String relPath, boolean removeExisting) throws RepositoryException {
507 throw new AccessDeniedException("Not allowed to write on version preview");
508 }
509
510
511
512
513 @Override
514 public void restoreByLabel(String versionLabel, boolean removeExisting) throws RepositoryException {
515 throw new AccessDeniedException("Not allowed to write on version preview");
516 }
517
518
519
520
521 @Override
522 public Version addVersion() throws RepositoryException {
523 throw new AccessDeniedException("Not allowed to add version on version preview");
524 }
525
526
527
528
529 @Override
530 public Version addVersion(Rule rule) throws RepositoryException {
531 throw new AccessDeniedException("Not allowed to add version on version preview");
532 }
533
534
535
536
537 @Override
538 public boolean isModified() {
539 log.error("Not valid for version");
540 return false;
541 }
542
543
544
545
546 @Override
547 public VersionHistory getVersionHistory() throws RepositoryException {
548 throw new AccessDeniedException("Not allowed to read VersionHistory of Version");
549 }
550
551
552
553
554 @Override
555 public VersionIterator getAllVersions() throws RepositoryException {
556 throw new AccessDeniedException("Not allowed to get VersionIterator of Version");
557 }
558
559
560
561
562 @Override
563 public ContentVersion getBaseVersion() throws RepositoryException {
564 throw new AccessDeniedException("Not allowed to get base version of Version");
565 }
566
567
568
569
570 @Override
571 public ContentVersion getVersionedContent(Version version) throws RepositoryException {
572 throw new AccessDeniedException("Not allowed to get preview of Version itself");
573 }
574
575
576
577
578 @Override
579 public ContentVersion getVersionedContent(String versionName) throws RepositoryException {
580 throw new AccessDeniedException("Not allowed to get preview of Version itself");
581 }
582
583
584
585
586 @Override
587 public void save() throws RepositoryException {
588 throw new AccessDeniedException("Not allowed to write on version preview");
589 }
590
591
592
593
594
595
596
597 @Override
598 public boolean isGranted(long permissions) {
599 return (permissions & Permission.READ) == permissions;
600 }
601
602
603
604
605 @Override
606 public void delete() throws RepositoryException {
607 throw new AccessDeniedException("Not allowed to write on version preview");
608 }
609
610
611
612
613 @Override
614 public void delete(String path) throws RepositoryException {
615 throw new AccessDeniedException("Not allowed to write on version preview");
616 }
617
618
619
620
621
622
623 @Override
624 public String getUUID() {
625 return this.base.getUUID();
626 }
627
628
629
630
631 @Override
632 public void addMixin(String type) throws RepositoryException {
633 throw new AccessDeniedException("Not allowed to write on version preview");
634 }
635
636
637
638
639 @Override
640 public void removeMixin(String type) throws RepositoryException {
641 throw new AccessDeniedException("Not allowed to write on version preview");
642 }
643
644
645
646
647 @Override
648 public Lock lock(boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
649 throw new AccessDeniedException("Lock not supported on version preview");
650 }
651
652
653
654
655 @Override
656 public Lock lock(boolean isDeep, boolean isSessionScoped, long yieldFor) throws LockException, RepositoryException {
657 throw new AccessDeniedException("Lock not supported on version preview");
658 }
659
660
661
662
663 @Override
664 public Lock getLock() throws LockException, RepositoryException {
665 throw new AccessDeniedException("Lock not supported on version preview");
666 }
667
668
669
670
671 @Override
672 public void unlock() throws LockException, RepositoryException {
673 throw new AccessDeniedException("Lock not supported on version preview");
674 }
675
676
677
678
679 @Override
680 public boolean holdsLock() throws RepositoryException {
681 throw new AccessDeniedException("Lock not supported on version preview");
682 }
683
684
685
686
687 @Override
688 public boolean isLocked() throws RepositoryException {
689 throw new AccessDeniedException("Lock not supported on version preview");
690 }
691
692
693
694
695 @Override
696 public HierarchyManager getHierarchyManager() {
697 return this.base.getHierarchyManager();
698 }
699
700
701
702
703
704
705 @Deprecated
706 @Override
707 public AccessManager getAccessManager() {
708 return this.base.getAccessManager();
709 }
710
711 @Override
712 public Workspace getWorkspace() throws RepositoryException {
713 return this.base.getWorkspace();
714 }
715
716 @Override
717 public boolean hasNodeData(String name) throws RepositoryException {
718 if (this.node.hasProperty(name)) {
719 return true;
720 }
721 if (this.node.hasNode(name) && this.node.getNode(name).getProperty("jcr:frozenPrimaryType").getValue().getString().equals(ItemType.NT_RESOURCE)) {
722 return true;
723 }
724 return false;
725 }
726
727 @Override
728 protected int determineNodeDataType(String name) {
729
730 try {
731 if (this.node.hasProperty(name)) {
732 return this.node.getProperty(name).getType();
733 }
734 if (this.node.hasNode(name) && this.node.getNode(name).getProperty("jcr:frozenPrimaryType").getValue().getString().equals(ItemType.NT_RESOURCE)) {
735 return PropertyType.BINARY;
736 }
737 } catch (RepositoryException e) {
738 throw new IllegalStateException("Can't determine property type of [" + getHandle() + "/" + name + "]", e);
739 }
740 return PropertyType.UNDEFINED;
741 }
742
743 @Override
744 public NodeType[] getMixinNodeTypes() throws RepositoryException {
745 Value[] vals = this.node.getProperty("jcr:frozenMixinTypes").getValues();
746 NodeTypeManager typeMan = getJCRNode().getSession().getWorkspace().getNodeTypeManager();
747 NodeType[] types = new NodeType[vals.length];
748 int i = 0;
749 for (Value val : vals) {
750 types[i++] = typeMan.getNodeType(val.getString());
751 }
752 return types;
753 }
754
755
756
757
758
759
760
761
762 public Version[] getPredecessors() throws RepositoryException {
763
764 return this.state.getPredecessors();
765 }
766
767 @Override
768 public Node getJCRNode() {
769
770 try {
771 if (versionedNode.hasNode("jcr:frozenNode")) {
772 return versionedNode.getFrozenNode();
773 }
774 } catch (RepositoryException e) {
775 log.error("Failed to retrieve frozen node from version {}", versionedNode, e);
776 }
777
778 return versionedNode;
779 }
780 }