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.version.ContentVersion;
37 import info.magnolia.cms.core.version.VersionManager;
38 import info.magnolia.cms.security.AccessDeniedException;
39 import info.magnolia.cms.util.Rule;
40 import info.magnolia.context.MgnlContext;
41 import info.magnolia.context.MgnlContext.Op;
42 import info.magnolia.jcr.RuntimeRepositoryException;
43 import info.magnolia.jcr.util.NodeUtil;
44 import info.magnolia.jcr.wrapper.JCRPropertiesFilteringNodeWrapper;
45 import info.magnolia.objectfactory.Components;
46 import info.magnolia.objectfactory.MgnlInstantiationException;
47 import info.magnolia.repository.RepositoryConstants;
48 import info.magnolia.repository.RepositoryManager;
49
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Collections;
53 import java.util.Comparator;
54 import java.util.List;
55
56 import javax.jcr.ItemNotFoundException;
57 import javax.jcr.Node;
58 import javax.jcr.NodeIterator;
59 import javax.jcr.PathNotFoundException;
60 import javax.jcr.Property;
61 import javax.jcr.PropertyIterator;
62 import javax.jcr.PropertyType;
63 import javax.jcr.RepositoryException;
64 import javax.jcr.Session;
65 import javax.jcr.UnsupportedRepositoryOperationException;
66 import javax.jcr.Workspace;
67 import javax.jcr.lock.Lock;
68 import javax.jcr.lock.LockException;
69 import javax.jcr.nodetype.NodeType;
70 import javax.jcr.version.Version;
71 import javax.jcr.version.VersionException;
72 import javax.jcr.version.VersionHistory;
73 import javax.jcr.version.VersionIterator;
74
75 import org.apache.commons.lang3.StringUtils;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78
79
80
81
82
83
84
85 @Deprecated
86 public class DefaultContent extends AbstractContent {
87 private static final Logger log = LoggerFactory.getLogger(DefaultContent.class);
88
89 private final RepositoryManager repositoryManager;
90
91
92
93
94 protected Node node;
95
96
97
98
99 private MetaData metaData;
100
101
102
103
104
105 @Deprecated
106 protected DefaultContent() {
107 RepositoryManager manager = null;
108 try {
109 manager = Components.getComponent(RepositoryManager.class);
110 } catch (IllegalStateException | MgnlInstantiationException e) {
111 log.error("Content is not correctly initialized and will fail if this code is executed in production mode.");
112 }
113 this.repositoryManager = manager;
114 }
115
116
117
118
119
120 @Deprecated
121 protected DefaultContent(RepositoryManager repositoryManager) {
122 this.repositoryManager = repositoryManager;
123 }
124
125
126
127
128
129
130
131
132
133
134
135 protected DefaultContent(Node rootNode, String path) throws PathNotFoundException, RepositoryException, AccessDeniedException {
136 this(rootNode.getNode(path));
137 }
138
139
140
141
142
143
144
145
146
147
148 @Deprecated
149 public DefaultContent(Node node) {
150 this(node, Components.getComponent(RepositoryManager.class));
151 }
152
153 public DefaultContent(Node node, RepositoryManager repositoryManager) {
154 this.repositoryManager = repositoryManager;
155 try {
156 this.setNode(node);
157 } catch (RepositoryException e) {
158 throw new RuntimeRepositoryException(e);
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 @Deprecated
176 protected DefaultContent(Node rootNode, String path, String contentType)
177 throws PathNotFoundException,
178 RepositoryException,
179 AccessDeniedException {
180 this(Components.getComponent(RepositoryManager.class));
181 this.setNode(rootNode.addNode(path, contentType));
182
183
184
185 this.addMixin(ItemType.MIX_LOCKABLE);
186 }
187
188 protected void setNode(Node node) throws RepositoryException {
189
190 this.node = NodeUtil.deepUnwrap(node, JCRPropertiesFilteringNodeWrapper.class);
191 }
192
193 @Override
194 public Content getContent(String name) throws PathNotFoundException, RepositoryException, AccessDeniedException {
195 return wrapAsContent(this.node, name);
196 }
197
198 @Override
199 public Content createContent(String name, String contentType) throws PathNotFoundException, RepositoryException,
200 AccessDeniedException {
201 Content content = wrapAsContent(this.node, name, contentType);
202 MetaData metaData = content.getMetaData();
203 metaData.setCreationDate();
204 return content;
205 }
206
207 @Override
208 public boolean hasNodeData(String name) throws RepositoryException {
209 if (this.node.hasProperty(name)) {
210 return true;
211 }
212 if (hasBinaryNode(name)) {
213 return true;
214 }
215 return false;
216 }
217
218 @Override
219 public NodeData newNodeDataInstance(String name, int type, boolean createIfNotExisting) throws AccessDeniedException, RepositoryException {
220
221 if (!hasNodeData(name) && !createIfNotExisting) {
222
223 return new NonExistingNodeData(this, name);
224 }
225
226 if (type == PropertyType.UNDEFINED) {
227 type = determineNodeDataType(name);
228 }
229
230 if (type == PropertyType.BINARY) {
231 return addBinaryNodeData(name);
232 }
233 return new DefaultNodeData(this, name);
234 }
235
236 protected int determineNodeDataType(String name) {
237
238 try {
239 if (this.node.hasProperty(name)) {
240 return this.node.getProperty(name).getType();
241 }
242 if (hasBinaryNode(name)) {
243 return PropertyType.BINARY;
244 }
245 } catch (RepositoryException e) {
246 throw new IllegalStateException("Can't determine property type of [" + getHandle() + "/" + name + "]", e);
247 }
248 return PropertyType.UNDEFINED;
249 }
250
251
252 @Override
253 public MetaData getMetaData() {
254 if (this.metaData == null) {
255 this.metaData = new MetaData(this.node);
256 }
257 return this.metaData;
258 }
259
260 @Override
261 public String getName() {
262 try {
263 return this.node.getName();
264 } catch (RepositoryException e) {
265 log.error(e.getMessage(), e);
266 }
267 return StringUtils.EMPTY;
268 }
269
270 @Override
271 public Collection<Content> getChildren(ContentFilter filter, String namePattern, Comparator<Content> orderCriteria) {
272 List<Content> children;
273 children = new ArrayList<Content>();
274
275 try {
276 final NodeIterator nodeIterator;
277 if (namePattern == null) {
278 nodeIterator = this.node.getNodes();
279 } else {
280 nodeIterator = this.node.getNodes(namePattern);
281 }
282
283 while (nodeIterator.hasNext()) {
284 Node subNode = (Node) nodeIterator.next();
285 Content content = wrapAsContent(subNode);
286 if (filter.accept(content)) {
287 children.add(content);
288 }
289 }
290 } catch (RepositoryException re) {
291 log.error("Exception caught", re);
292 }
293
294 if (orderCriteria != null) {
295
296 Collections.sort(children, orderCriteria);
297 }
298 return children;
299 }
300
301 protected Content wrapAsContent(Node node) {
302 return new DefaultContent(node);
303 }
304
305 protected Content wrapAsContent(Node node, String name) throws AccessDeniedException, PathNotFoundException, RepositoryException {
306 return new DefaultContent(node, name);
307 }
308
309 protected Content wrapAsContent(Node node, String name, String contentType) throws AccessDeniedException, PathNotFoundException, RepositoryException {
310 return new DefaultContent(node, name, contentType);
311 }
312
313 @Override
314 public Collection<NodeData> getNodeDataCollection(String namePattern) {
315 final ArrayList<NodeData> all = new ArrayList<NodeData>();
316 try {
317 all.addAll(getPrimitiveNodeDatas(namePattern));
318 all.addAll(getBinaryNodeDatas(namePattern));
319 } catch (RepositoryException e) {
320 throw new IllegalStateException("Can't read node datas of " + toString(), e);
321 }
322 return all;
323 }
324
325 protected Collection<NodeData> getPrimitiveNodeDatas(String namePattern) throws RepositoryException {
326 final Collection<NodeData> nodeDatas = new ArrayList<NodeData>();
327 final PropertyIterator propertyIterator;
328 if (namePattern == null) {
329 propertyIterator = this.node.getProperties();
330 } else {
331 propertyIterator = this.node.getProperties(namePattern);
332 }
333 while (propertyIterator.hasNext()) {
334 Property property = (Property) propertyIterator.next();
335 try {
336 if (!property.getName().startsWith("jcr:") && !property.getName().startsWith("mgnl:")) {
337 nodeDatas.add(getNodeData(property.getName()));
338 }
339 } catch (PathNotFoundException e) {
340 log.error("Exception caught", e);
341 } catch (AccessDeniedException e) {
342
343 }
344 }
345 return nodeDatas;
346 }
347
348
349 @Override
350 public boolean hasContent(String name) throws RepositoryException {
351 return this.node.hasNode(name);
352 }
353
354 @Override
355 public String getHandle() {
356 try {
357 return this.node.getPath();
358 } catch (RepositoryException e) {
359 log.error("Failed to get handle: {}", e.getMessage(), e);
360 return StringUtils.EMPTY;
361 }
362 }
363
364 @Override
365 public Content getParent() throws PathNotFoundException, RepositoryException, AccessDeniedException {
366 return wrapAsContent(this.node.getParent());
367 }
368
369 @Override
370 public Content getAncestor(int level) throws PathNotFoundException, RepositoryException, AccessDeniedException {
371 if (level > this.getLevel()) {
372 throw new PathNotFoundException();
373 }
374 return wrapAsContent((Node) this.node.getAncestor(level));
375 }
376
377 @Override
378 public Collection<Content> getAncestors() throws PathNotFoundException, RepositoryException {
379 List<Content> allAncestors = new ArrayList<Content>();
380 int level = this.getLevel();
381 while (level != 0) {
382 try {
383 allAncestors.add(getAncestor(--level));
384 } catch (AccessDeniedException e) {
385
386 }
387 }
388 return allAncestors;
389 }
390
391 @Override
392 public int getLevel() throws PathNotFoundException, RepositoryException {
393 return this.node.getDepth();
394 }
395
396 @Override
397 public void orderBefore(String srcName, String beforeName) throws RepositoryException {
398 this.node.orderBefore(srcName, beforeName);
399 }
400
401 @Override
402 public int getIndex() throws RepositoryException {
403 return this.node.getIndex();
404 }
405
406 @Override
407 public Node getJCRNode() {
408 return this.node;
409 }
410
411 @Override
412 public boolean isNodeType(String type) {
413 return isNodeType(this.node, type);
414 }
415
416
417
418
419 protected boolean isNodeType(Node node, String type) {
420 try {
421 return NodeUtil.isNodeType(node, type);
422 } catch (RepositoryException re) {
423 log.error(re.getMessage());
424 log.debug(re.getMessage(), re);
425 return false;
426 }
427 }
428
429 @Override
430 public NodeType getNodeType() throws RepositoryException {
431 return this.node.getPrimaryNodeType();
432 }
433
434 @Override
435 public String getNodeTypeName() throws RepositoryException {
436
437 if (this.node.hasProperty(ItemType.JCR_FROZEN_PRIMARY_TYPE)) {
438 return this.node.getProperty(ItemType.JCR_FROZEN_PRIMARY_TYPE).getString();
439 }
440 return this.node.getProperty(ItemType.JCR_PRIMARY_TYPE).getString();
441 }
442
443 @Override
444 public ItemType getItemType() throws RepositoryException {
445 return new ItemType(getNodeTypeName());
446 }
447
448 @Override
449 public void restore(String versionName, boolean removeExisting) throws VersionException, UnsupportedRepositoryOperationException, RepositoryException {
450 Version version = this.getVersionHistory().getVersion(versionName);
451 this.restore(version, removeExisting);
452 }
453
454 @Override
455 public void restore(Version version, boolean removeExisting) throws VersionException, UnsupportedRepositoryOperationException, RepositoryException {
456 VersionManager.getInstance().restore(this.getJCRNode(), version, removeExisting);
457 }
458
459 @Override
460 public void restore(Version version, String relPath, boolean removeExisting) throws VersionException, UnsupportedRepositoryOperationException, RepositoryException {
461 throw new UnsupportedRepositoryOperationException("Not implemented since 3.0 Beta");
462 }
463
464 @Override
465 public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, UnsupportedRepositoryOperationException, RepositoryException {
466
467 this.node.restoreByLabel(versionLabel, removeExisting);
468 throw new UnsupportedRepositoryOperationException("Not implemented since 3.0 Beta");
469 }
470
471 @Override
472 public Version addVersion() throws UnsupportedRepositoryOperationException, RepositoryException {
473 return VersionManager.getInstance().addVersion(this.getJCRNode());
474 }
475
476 @Override
477 public Version addVersion(Rule rule) throws UnsupportedRepositoryOperationException, RepositoryException {
478 return VersionManager.getInstance().addVersion(this.getJCRNode(), rule);
479 }
480
481 public BinaryNodeData addBinaryNodeData(String name) {
482 return new BinaryNodeData(this, name);
483 }
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499 protected boolean isCheckedOut() throws RepositoryException {
500 return this.node.isCheckedOut();
501 }
502
503 @Override
504 public boolean isModified() {
505 return this.node.isModified();
506 }
507
508 @Override
509 public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException {
510 return VersionManager.getInstance().getVersionHistory(this.getJCRNode());
511 }
512
513 @Override
514 public VersionIterator getAllVersions() throws UnsupportedRepositoryOperationException, RepositoryException {
515 return VersionManager.getInstance().getAllVersions(this.getJCRNode());
516 }
517
518 @Override
519 public ContentVersion getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException {
520 return new ContentVersion(VersionManager.getInstance().getBaseVersion(this.getJCRNode()), this);
521 }
522
523 @Override
524 public ContentVersion getVersionedContent(Version version) throws RepositoryException {
525 return new ContentVersion(version, this);
526 }
527
528 @Override
529 public ContentVersion getVersionedContent(String versionName) throws RepositoryException {
530 return new ContentVersion(VersionManager.getInstance().getVersion(this.getJCRNode(), versionName), this);
531 }
532
533 @Override
534 public void removeVersionHistory() throws AccessDeniedException, RepositoryException {
535 VersionManager.getInstance().removeVersionHistory(this.node);
536 }
537
538 @Override
539 public void save() throws RepositoryException {
540 this.node.save();
541 }
542
543 @Override
544 public void delete() throws RepositoryException {
545 final String nodePath = this.node.getPath();
546 final String workspaceName = this.node.getSession().getWorkspace().getName();
547 log.debug("removing {} from {}", this.node.getPath(), workspaceName);
548 if (!(workspaceName.endsWith("-" + RepositoryConstants.VERSION_STORE) || workspaceName.endsWith("-" + RepositoryConstants.SYSTEM))) {
549 MgnlContext.doInSystemContext((Op<Void, RepositoryException>) () -> {
550 try {
551 final String uuid = node.getIdentifier();
552 log.debug("Removing history for node {}({})", uuid, nodePath);
553 VersionManager.getInstance().removeVersionHistory(node);
554 } catch (ItemNotFoundException | UnsupportedRepositoryOperationException e) {
555
556 }
557 return null;
558 });
559 }
560 this.node.remove();
561 }
562
563 @Override
564 public void refresh(boolean keepChanges) throws RepositoryException {
565 this.node.refresh(keepChanges);
566 }
567
568 @Override
569 public String getUUID() {
570 try {
571 return this.node.getUUID();
572 } catch (UnsupportedOperationException e) {
573 log.error(e.getMessage());
574 } catch (RepositoryException re) {
575 log.error("Exception caught", re);
576 }
577 return StringUtils.EMPTY;
578 }
579
580 @Override
581 public void addMixin(String type) throws RepositoryException {
582
583 if (!this.node.canAddMixin(type)) {
584 log.debug("Node - {} does not allow mixin type - {}", this.node.getPath(), type);
585 }
586 try {
587 this.node.addMixin(type);
588 } catch (Exception e) {
589 log.error("Failed to add mixin type - {} to a node {}", type, this.node.getPath());
590 }
591 }
592
593 @Override
594 public void removeMixin(String type) throws RepositoryException {
595 this.node.removeMixin(type);
596 }
597
598 @Override
599 public NodeType[] getMixinNodeTypes() throws RepositoryException {
600 return this.node.getMixinNodeTypes();
601 }
602
603 @Override
604 public Lock lock(boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
605 return this.node.lock(isDeep, isSessionScoped);
606 }
607
608 @Override
609 public Lock lock(boolean isDeep, boolean isSessionScoped, long yieldFor) throws LockException, RepositoryException {
610 long finalTime = System.currentTimeMillis() + yieldFor;
611 LockException lockException = null;
612 while (System.currentTimeMillis() <= finalTime) {
613 try {
614 return this.node.lock(isDeep, isSessionScoped);
615 } catch (LockException e) {
616
617 lockException = e;
618 }
619 Thread.yield();
620 }
621
622 throw lockException;
623 }
624
625 @Override
626 public Lock getLock() throws LockException, RepositoryException {
627 return this.node.getLock();
628 }
629
630 @Override
631 public void unlock() throws LockException, RepositoryException {
632 this.node.unlock();
633 }
634
635 @Override
636 public boolean holdsLock() throws RepositoryException {
637 return this.node.holdsLock();
638 }
639
640 @Override
641 public boolean isLocked() throws RepositoryException {
642 return this.node.isLocked();
643 }
644
645 @Override
646 public boolean hasMetaData() {
647 return true;
648 }
649
650 @Override
651 public boolean hasMixin(String mixinName) throws RepositoryException {
652 if (StringUtils.isBlank(mixinName)) {
653 throw new IllegalArgumentException("Mixin name can't be empty.");
654 }
655 for (NodeType type : getMixinNodeTypes()) {
656 if (mixinName.equals(type.getName())) {
657 return true;
658 }
659 }
660 return false;
661 }
662
663 @Override
664 public HierarchyManager getHierarchyManager() {
665 try {
666 return createHierarchyManager(node.getSession());
667 } catch (RepositoryException e) {
668 throw new RuntimeException(e);
669 }
670 }
671
672 @Override
673 public Workspace getWorkspace() throws RepositoryException {
674 return node.getSession().getWorkspace();
675 }
676
677 @Override
678 public boolean equals(Object obj) {
679 if (obj == null || !(obj instanceof DefaultContent)) {
680 return false;
681 }
682 DefaultContentfo/magnolia/cms/core/DefaultContent.html#DefaultContent">DefaultContent otherContent = (DefaultContent) obj;
683 return getJCRNode().equals(otherContent.getJCRNode());
684 }
685
686
687
688
689 @Deprecated
690 protected HierarchyManager createHierarchyManager(Session session) {
691 return new DefaultHierarchyManager(session, repositoryManager);
692 }
693
694 protected boolean hasBinaryNode(String name) throws RepositoryException {
695 return this.node.hasNode(name) && (this.node.getNode(name).isNodeType(ItemType.NT_RESOURCE) ||
696 (this.node.hasProperty("jcr:frozenPrimaryType") && this.node.getNode(name).getProperty("jcr:frozenPrimaryType").getValue().getString().equals(ItemType.NT_RESOURCE)));
697 }
698 }