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