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