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