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.jcr.util;
35
36 import info.magnolia.cms.core.Path;
37 import info.magnolia.cms.security.AccessDeniedException;
38 import info.magnolia.cms.security.PermissionUtil;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.jcr.RuntimeRepositoryException;
41 import info.magnolia.jcr.iterator.NodeIterableAdapter;
42 import info.magnolia.jcr.predicate.AbstractPredicate;
43 import info.magnolia.jcr.wrapper.DelegateNodeWrapper;
44 import info.magnolia.jcr.wrapper.JCRPropertiesFilteringNodeWrapper;
45
46 import java.io.File;
47 import java.io.FileInputStream;
48 import java.io.FileOutputStream;
49 import java.io.IOException;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Iterator;
53 import java.util.LinkedHashSet;
54 import java.util.List;
55 import java.util.NoSuchElementException;
56
57 import javax.jcr.ImportUUIDBehavior;
58 import javax.jcr.Node;
59 import javax.jcr.NodeIterator;
60 import javax.jcr.PathNotFoundException;
61 import javax.jcr.Property;
62 import javax.jcr.RepositoryException;
63 import javax.jcr.Session;
64 import javax.jcr.nodetype.NodeType;
65 import javax.jcr.nodetype.NodeTypeManager;
66 import javax.jcr.query.Row;
67 import javax.jcr.query.RowIterator;
68
69 import org.apache.commons.io.IOUtils;
70 import org.apache.commons.lang.RandomStringUtils;
71 import org.apache.commons.lang.StringUtils;
72 import org.apache.jackrabbit.JcrConstants;
73 import org.apache.jackrabbit.commons.iterator.FilteringNodeIterator;
74 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
75 import org.apache.jackrabbit.commons.predicate.NodeTypePredicate;
76 import org.apache.jackrabbit.commons.predicate.Predicate;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80
81
82
83 public class NodeUtil {
84
85 private static final Logger log = LoggerFactory.getLogger(NodeUtil.class);
86
87
88
89
90
91
92 public static AbstractPredicate<Property> ALL_PROPERTIES_EXCEPT_JCR_AND_MGNL_FILTER = new AbstractPredicate<Property>() {
93
94 @Override
95 public boolean evaluateTyped(Property property) {
96 try {
97 String name = property.getName();
98 return !name.startsWith(NodeTypes.JCR_PREFIX) && !name.startsWith(NodeTypes.MGNL_PREFIX);
99 } catch (RepositoryException e) {
100 String path;
101 try {
102 path = property.getPath();
103 } catch (RepositoryException e1) {
104 path = "<path not available>";
105 }
106 log.error("Unable to read name of property {}", path);
107
108 return false;
109 }
110 }
111 };
112
113
114
115
116
117
118 public static Predicate ALL_NODES_EXCEPT_JCR_FILTER = new AbstractPredicate<Node>() {
119 @Override
120 public boolean evaluateTyped(Node node) {
121 try {
122 return !node.getName().startsWith(NodeTypes.JCR_PREFIX);
123 } catch (RepositoryException e) {
124 log.error("Unable to read name for node {}", getNodePathIfPossible(node));
125 return false;
126 }
127 }
128 };
129
130
131
132
133
134
135 public static AbstractPredicate<Node> EXCLUDE_META_DATA_FILTER = new AbstractPredicate<Node>() {
136
137 @Override
138 public boolean evaluateTyped(Node node) {
139 try {
140 return !node.getName().startsWith(NodeTypes.JCR_PREFIX)
141 && !NodeUtil.isNodeType(node, NodeTypes.MetaData.NAME);
142 } catch (RepositoryException e) {
143 log.error("Unable to read name or nodeType for node {}", getNodePathIfPossible(node));
144 return false;
145 }
146 }
147 };
148
149
150
151
152 public static AbstractPredicate<Node> MAGNOLIA_FILTER = new AbstractPredicate<Node>() {
153
154 @Override
155 public boolean evaluateTyped(Node node) {
156
157 try {
158 String nodeTypeName = node.getPrimaryNodeType().getName();
159
160 return nodeTypeName.startsWith(NodeTypes.MGNL_PREFIX);
161 } catch (RepositoryException e) {
162 log.error("Unable to read nodeType for node {}", getNodePathIfPossible(node));
163 }
164 return false;
165 }
166 };
167
168
169
170
171 public static Node getNodeByIdentifier(String workspace, String identifier) throws RepositoryException {
172 Node target = null;
173 Session jcrSession;
174 if (workspace == null || identifier == null) {
175 return target;
176 }
177
178 jcrSession = MgnlContext.getJCRSession(workspace);
179 if (jcrSession != null) {
180 target = jcrSession.getNodeByIdentifier(identifier);
181 }
182 return target;
183 }
184
185
186
187
188
189
190 public static boolean hasMixin(Node node, String mixinName) throws RepositoryException {
191 if (StringUtils.isBlank(mixinName)) {
192 throw new IllegalArgumentException("Mixin name can't be empty.");
193 }
194 for (NodeType type : node.getMixinNodeTypes()) {
195 if (mixinName.equals(type.getName())) {
196 return true;
197 }
198 }
199 return false;
200 }
201
202
203
204
205
206 public static boolean isNodeType(Node node, String nodeTypeName) throws RepositoryException {
207 node = NodeUtil.deepUnwrap(node, JCRPropertiesFilteringNodeWrapper.class);
208 final String actualType = node.getProperty(JcrConstants.JCR_PRIMARYTYPE).getString();
209
210
211 if (JcrConstants.NT_FROZENNODE.equals(actualType) && !(JcrConstants.NT_FROZENNODE.equals(nodeTypeName))) {
212 final Property p = node.getProperty(JcrConstants.JCR_FROZENPRIMARYTYPE);
213 final String s = p.getString();
214 NodeTypeManager ntManager = node.getSession().getWorkspace().getNodeTypeManager();
215 NodeType primaryNodeType = ntManager.getNodeType(s);
216 return primaryNodeType.isNodeType(nodeTypeName);
217 }
218 return node.isNodeType(nodeTypeName);
219 }
220
221 public static Node unwrap(Node node) throws RepositoryException {
222 Node unwrappedNode = node;
223 while (unwrappedNode instanceof DelegateNodeWrapper) {
224 unwrappedNode = ((DelegateNodeWrapper) unwrappedNode).getWrappedNode();
225 }
226 return unwrappedNode;
227 }
228
229
230
231
232
233 public static Node deepUnwrap(Node node, Class<? extends DelegateNodeWrapper> wrapper) {
234 if (node instanceof DelegateNodeWrapper) {
235 return ((DelegateNodeWrapper) node).deepUnwrap(wrapper);
236 }
237 return node;
238 }
239
240
241
242
243
244 public static Node deepUnwrapAll(Node node, Class<? extends DelegateNodeWrapper> wrapperClass) {
245 while (node instanceof DelegateNodeWrapper) {
246 Node unwrapped = ((DelegateNodeWrapper) node).deepUnwrap(wrapperClass);
247
248 if (unwrapped == node) {
249 break;
250 }
251 node = unwrapped;
252 }
253 return node;
254 }
255
256 public static boolean isWrappedWith(Node node, Class<? extends DelegateNodeWrapper> wrapper) {
257 if (wrapper.isInstance(node)) {
258 return true;
259 }
260
261 if (node instanceof DelegateNodeWrapper) {
262 return isWrappedWith(((DelegateNodeWrapper) node).getWrappedNode(), wrapper);
263 }
264 return false;
265 }
266
267
268
269
270 public static void orderBefore(Node node, String siblingName) throws RepositoryException {
271 node.getParent().orderBefore(node.getName(), siblingName);
272 }
273
274
275
276
277 public static void orderAfter(Node node, String siblingName) throws RepositoryException {
278
279 if (siblingName == null) {
280 orderFirst(node);
281 return;
282 }
283
284 Node parent = node.getParent();
285 Node sibling = parent.getNode(siblingName);
286 Node siblingAfter = getSiblingAfter(sibling);
287
288 if (siblingAfter == null) {
289 orderLast(node);
290 return;
291 }
292
293
294 parent.orderBefore(node.getName(), siblingAfter.getName());
295 }
296
297
298
299
300 public static void orderFirst(Node node) throws RepositoryException {
301 Node parent = node.getParent();
302 NodeIterator siblings = parent.getNodes();
303 Node firstSibling = siblings.nextNode();
304 if (!firstSibling.isSame(node)) {
305 parent.orderBefore(node.getName(), firstSibling.getName());
306 }
307 }
308
309
310
311
312 public static void orderLast(Node node) throws RepositoryException {
313 node.getParent().orderBefore(node.getName(), null);
314 }
315
316
317
318
319
320 public static void orderNodeUp(Node node) throws RepositoryException {
321 Node siblingBefore = getSiblingBefore(node);
322 if (siblingBefore != null) {
323 node.getParent().orderBefore(node.getName(), siblingBefore.getName());
324 }
325 }
326
327
328
329
330
331 public static void orderNodeDown(Node node) throws RepositoryException {
332 Node siblingAfter = getSiblingAfter(node);
333 if (siblingAfter != null) {
334 node.getParent().orderBefore(siblingAfter.getName(), node.getName());
335 }
336 }
337
338 public static Node getSiblingBefore(Node node) throws RepositoryException {
339 Node parent = node.getParent();
340 NodeIterator siblings = parent.getNodes();
341 Node previousSibling = null;
342 while (siblings.hasNext()) {
343 Node sibling = siblings.nextNode();
344 if (isSame(node, sibling)) {
345 return previousSibling;
346 }
347 previousSibling = sibling;
348 }
349 return null;
350 }
351
352 public static Node getSiblingAfter(Node node) throws RepositoryException {
353 Node parent = node.getParent();
354 NodeIterator siblings = parent.getNodes();
355 while (siblings.hasNext()) {
356 Node sibling = siblings.nextNode();
357 if (isSame(node, sibling)) {
358 break;
359 }
360 }
361 return siblings.hasNext() ? siblings.nextNode() : null;
362 }
363
364
365
366
367
368
369
370 public static Iterable<Node> getSiblings(Node node) throws RepositoryException {
371 Node parent = node.getParent();
372 Iterable<Node> allSiblings = NodeUtil.getNodes(parent);
373 List<Node> siblings = new ArrayList<Node>();
374
375 for (Node sibling : allSiblings) {
376 if (!NodeUtil.isSame(node, sibling)) {
377 siblings.add(sibling);
378 }
379 }
380 return siblings;
381 }
382
383
384
385
386
387
388
389
390 public static Iterable<Node> getSiblings(Node node, String nodeTypeName) throws RepositoryException {
391 Node parent = node.getParent();
392 Iterable<Node> allSiblings = NodeUtil.getNodes(parent, nodeTypeName);
393 List<Node> sameTypeSiblings = new ArrayList<Node>();
394
395 for (Node sibling : allSiblings) {
396 if (!NodeUtil.isSame(node, sibling)) {
397 sameTypeSiblings.add(sibling);
398 }
399 }
400 return sameTypeSiblings;
401 }
402
403
404
405
406
407
408
409
410 public static Iterable<Node> getSiblings(Node node, Predicate predicate) throws RepositoryException {
411 Node parent = node.getParent();
412 Iterable<Node> allSiblings = NodeUtil.getNodes(parent, predicate);
413 List<Node> sameTypeSiblings = new ArrayList<Node>();
414
415 for (Node sibling : allSiblings) {
416 if (!NodeUtil.isSame(node, sibling)) {
417 sameTypeSiblings.add(sibling);
418 }
419 }
420 return sameTypeSiblings;
421 }
422
423
424
425
426
427
428
429 public static Iterable<Node> getSiblingsBefore(Node node) throws RepositoryException {
430 int toIndex = 0;
431 Node parent = node.getParent();
432 List<Node> allSiblings = NodeUtil.asList(NodeUtil.getNodes(parent));
433
434 for (Node sibling : allSiblings) {
435 if (NodeUtil.isSame(node, sibling)) {
436 break;
437 }
438 toIndex++;
439 }
440 return allSiblings.subList(0, toIndex);
441 }
442
443
444
445
446
447
448
449 public static Iterable<Node> getSiblingsAfter(Node node) throws RepositoryException {
450 int fromIndex = 0;
451 Node parent = node.getParent();
452 List<Node> allSiblings = NodeUtil.asList(NodeUtil.getNodes(parent));
453
454 for (Node sibling : allSiblings) {
455 if (NodeUtil.isSame(node, sibling)) {
456 fromIndex++;
457 break;
458 }
459 fromIndex++;
460 }
461 return allSiblings.subList(fromIndex, allSiblings.size());
462 }
463
464
465
466
467
468
469
470
471 public static Iterable<Node> getSiblingsBefore(Node node, String nodeTypeName) throws RepositoryException {
472 Node parent = node.getParent();
473 Iterable<Node> allSiblings = NodeUtil.getNodes(parent);
474 List<Node> sameTypeSiblings = new ArrayList<Node>();
475
476 for (Node sibling : allSiblings) {
477 if (NodeUtil.isSame(node, sibling)) {
478 break;
479 }
480 if (isNodeType(sibling, nodeTypeName)) {
481 sameTypeSiblings.add(sibling);
482 }
483 }
484 return sameTypeSiblings;
485 }
486
487
488
489
490
491
492
493
494 public static Iterable<Node> getSiblingsAfter(Node node, String nodeTypeName) throws RepositoryException {
495 Node parent = node.getParent();
496 List<Node> allSiblings = NodeUtil.asList(NodeUtil.getNodes(parent));
497 int fromIndex = 0;
498
499 for (Node sibling : allSiblings) {
500 fromIndex++;
501 if (NodeUtil.isSame(node, sibling)) {
502 break;
503 }
504 }
505
506 List<Node> sameTypeSiblings = new ArrayList<Node>();
507 for (Node sibling : allSiblings.subList(fromIndex, allSiblings.size())) {
508 if (isNodeType(sibling, nodeTypeName)) {
509 sameTypeSiblings.add(sibling);
510 }
511 }
512 return sameTypeSiblings;
513 }
514
515 public static void moveNode(Node nodeToMove, Node newParent) throws RepositoryException {
516 if (!isSame(newParent, nodeToMove.getParent())) {
517 String newPath = combinePathAndName(newParent.getPath(), nodeToMove.getName());
518 nodeToMove.getSession().move(nodeToMove.getPath(), newPath);
519 }
520 }
521
522 public static void moveNodeBefore(Node nodeToMove, Node target) throws RepositoryException {
523 Node targetParent = target.getParent();
524 moveNode(nodeToMove, targetParent);
525 targetParent.orderBefore(nodeToMove.getName(), target.getName());
526 }
527
528 public static void moveNodeAfter(Node nodeToMove, Node target) throws RepositoryException {
529 Node targetParent = target.getParent();
530 moveNode(nodeToMove, targetParent);
531 orderAfter(nodeToMove, target.getName());
532 }
533
534 public static boolean isFirstSibling(Node node) throws RepositoryException {
535 Node parent = node.getParent();
536 NodeIterator nodes = parent.getNodes();
537 return isSame(nodes.nextNode(), node);
538 }
539
540
541
542
543 public static boolean isSameNameSiblings(Node node1, Node node2) throws RepositoryException {
544 Node parent1 = node1.getParent();
545 Node parent2 = node2.getParent();
546 return isSame(parent1, parent2) && node1.getName().equals(node2.getName());
547 }
548
549 public static boolean isLastSibling(Node node) throws RepositoryException {
550 Node parent = node.getParent();
551 NodeIterator nodes = parent.getNodes();
552 Node last = null;
553 while (nodes.hasNext()) {
554 last = nodes.nextNode();
555 }
556 return isSame(last, node);
557 }
558
559 public static void renameNode(Node node, String newName) throws RepositoryException {
560 if (node.getName().equals(newName)) {
561 return;
562 }
563 final Node parent = node.getParent();
564 final String newPath = combinePathAndName(parent.getPath(), newName);
565 final Node siblingAfter = NodeUtil.getSiblingAfter(node);
566
567 node.getSession().move(node.getPath(), newPath);
568
569 if (siblingAfter != null) {
570 parent.orderBefore(newName, siblingAfter.getName());
571 }
572 }
573
574
575
576
577
578 public static boolean isGranted(Node node, long permissions) {
579 try {
580 return PermissionUtil.isGranted(node, permissions);
581 } catch (RepositoryException e) {
582 throw new RuntimeRepositoryException(e);
583 }
584 }
585
586
587
588
589
590 public static boolean isSame(Node lhs, Node rhs) throws RepositoryException {
591 return unwrap(lhs).isSame(unwrap(rhs));
592 }
593
594
595
596
597 public static String combinePathAndName(String path, String name) {
598 if ("/".equals(path)) {
599 return "/" + name;
600 }
601 return path + "/" + name;
602 }
603
604
605
606
607
608 public static Node createPath(Node parent, String relPath, String primaryNodeTypeName) throws RepositoryException, PathNotFoundException, AccessDeniedException {
609 return createPath(parent, relPath, primaryNodeTypeName, false);
610 }
611
612
613
614
615
616 public static Node createPath(Node parent, String relPath, String primaryNodeTypeName, boolean save) throws RepositoryException, PathNotFoundException, AccessDeniedException {
617
618 String currentPath = StringUtils.removeStart(relPath, "/");
619
620 if (StringUtils.isEmpty(currentPath)) {
621 return parent;
622 }
623
624 Node root = parent;
625 String[] names = currentPath.split("/");
626
627 for (int i = 0; i < names.length; i++) {
628 String name = names[i];
629 if (root.hasNode(name)) {
630 root = root.getNode(name);
631 } else {
632 final Node newNode = root.addNode(name, primaryNodeTypeName);
633 if (newNode.canAddMixin(JcrConstants.MIX_LOCKABLE)) {
634 newNode.addMixin(JcrConstants.MIX_LOCKABLE);
635 }
636 if (save) {
637 root.getSession().save();
638 }
639 root = newNode;
640 }
641 }
642 return root;
643 }
644
645
646
647
648 public static void visit(Node node, NodeVisitor visitor) throws RepositoryException {
649 visit(node, visitor, EXCLUDE_META_DATA_FILTER);
650 }
651
652 public static void visit(Node node, NodeVisitor visitor, Predicate predicate) throws RepositoryException {
653
654 visitor.visit(node);
655 for (Node child : getNodes(node, predicate)) {
656 visit(child, visitor, predicate);
657 }
658 if (visitor instanceof PostNodeVisitor) {
659 ((PostNodeVisitor) visitor).postVisit(node);
660 }
661 }
662
663 public static Iterable<Node> getNodes(Node parent, Predicate predicate) throws RepositoryException {
664 return asIterable(new FilteringNodeIterator(parent.getNodes(), predicate));
665 }
666
667 public static Iterable<Node> getNodes(Node parent) throws RepositoryException {
668 return getNodes(parent, EXCLUDE_META_DATA_FILTER);
669 }
670
671 public static Iterable<Node> getNodes(Node parent, String nodeTypeName) throws RepositoryException {
672 return getNodes(parent, new NodeTypePredicate(nodeTypeName, false));
673 }
674
675 public static Iterable<Node> asIterable(NodeIterator iterator) {
676 return new NodeIterableAdapter(iterator);
677 }
678
679 public static List<Node> asList(Iterable<Node> nodes) {
680 List<Node> nodesList = new ArrayList<Node>();
681 for (Node node : nodes) {
682 nodesList.add(node);
683 }
684 return nodesList;
685 }
686
687
688
689
690 public static String getName(Node content) {
691 try {
692 return content.getName();
693 } catch (RepositoryException e) {
694 throw new RuntimeRepositoryException(e);
695 }
696 }
697
698
699
700
701 public static Iterable<Node> collectAllChildren(Node node) throws RepositoryException {
702 List<Node> nodes = new ArrayList<Node>();
703 return collectAllChildren(nodes, node, MAGNOLIA_FILTER);
704 }
705
706
707
708
709 public static Iterable<Node> collectAllChildren(Node node, Predicate predicate) throws RepositoryException {
710 List<Node> nodes = new ArrayList<Node>();
711 return collectAllChildren(nodes, node, predicate);
712 }
713
714
715
716
717
718 public static Iterable<Node> collectAllChildren(List<Node> nodes, Node parent, Predicate predicate) throws RepositoryException {
719
720 nodes.addAll(asList(getNodes(parent, predicate)));
721
722
723 Iterator<Node> allChildren = getNodes(parent, EXCLUDE_META_DATA_FILTER).iterator();
724
725
726 while (allChildren.hasNext()) {
727 collectAllChildren(nodes, allChildren.next(), predicate);
728 }
729
730 return nodes;
731 }
732
733
734
735
736 public static Collection<Node> getAncestors(Node node) throws RepositoryException {
737 List<Node> allAncestors = new ArrayList<Node>();
738 int level = node.getDepth();
739 while (level != 0) {
740 try {
741 allAncestors.add((Node) node.getAncestor(--level));
742 } catch (AccessDeniedException e) {
743 log.debug("Node " + node.getIdentifier() + " didn't allow access to Ancestor's ");
744 }
745 }
746 return allAncestors;
747 }
748
749
750
751
752
753
754
755
756
757 public static Node getNearestAncestorOfType(Node node, String nodeTypeName) throws RepositoryException {
758 if (node.getDepth() == 0) {
759 return null;
760 }
761
762 node = node.getParent();
763
764 while (true) {
765 if (NodeUtil.isNodeType(node, nodeTypeName)) {
766 return node;
767 }
768 if (node.getDepth() == 0) {
769 break;
770 }
771 node = node.getParent();
772 }
773 return null;
774 }
775
776
777
778
779 public static String getNodeIdentifierIfPossible(Node content) {
780 try {
781 return content.getIdentifier();
782 } catch (RepositoryException e) {
783 return "<not available>";
784 }
785 }
786
787 public static String getNodePathIfPossible(Node node) {
788 try {
789 return node.getPath();
790 } catch (RepositoryException e) {
791 return "<not available>";
792 }
793 }
794
795
796
797
798
799
800 public static String getPathIfPossible(Node node) {
801 try {
802 return node.getPath();
803 } catch (RepositoryException e) {
804 log.error("Failed to get handle: " + e.getMessage(), e);
805 return "";
806 }
807 }
808
809 public static NodeIterator filterNodeType(NodeIterator iterator, String nodeType) {
810 return new FilteringNodeIterator(iterator, new info.magnolia.jcr.predicate.NodeTypePredicate(nodeType));
811 }
812
813 public static NodeIterator filterDuplicates(NodeIterator iterator) {
814 return new FilteringNodeIterator(iterator, new info.magnolia.jcr.predicate.DuplicateNodePredicate());
815 }
816
817 public static NodeIterator filterParentNodeType(NodeIterator iterator, final String nodeType) throws RepositoryException {
818 return new FilteringNodeIterator(iterator, new info.magnolia.jcr.predicate.NodeTypeParentPredicate(nodeType)) {
819 @Override
820 public Node nextNode() {
821 Node node = super.nextNode();
822 try {
823 while (node.getDepth() != 0 && !node.isNodeType(nodeType)) {
824 if (node.getDepth() != 0) {
825 node = node.getParent();
826 }
827 }
828 } catch (RepositoryException e) {
829 throw new RuntimeException(e.getMessage(), e);
830 }
831 return node;
832 }
833 };
834 }
835
836
837
838
839
840
841
842
843
844 public static NodeIterator filterParentNodeType(RowIterator iterator, final String selector) throws RepositoryException {
845 return new NodeIteratorAdapter(iterator) {
846 @Override
847 public Node nextNode() throws NoSuchElementException {
848 Row row = (Row) next();
849 try {
850 return row.getNode(selector);
851 } catch (RepositoryException e) {
852
853 log.debug(e.getMessage(), e);
854 throw new NoSuchElementException(e.getMessage());
855 }
856 }
857 };
858 }
859
860 public static Collection<Node> getCollectionFromNodeIterator(NodeIterator iterator) {
861 Collection<Node> nodeCollection = new LinkedHashSet<Node>(150);
862 while (iterator.hasNext()) {
863 nodeCollection.add(iterator.nextNode());
864 }
865 return nodeCollection;
866 }
867
868
869
870
871 @Deprecated
872 public static Collection<Node> getSortedCollectionFromNodeIterator(NodeIterator iterator) {
873 return getCollectionFromNodeIterator(iterator);
874 }
875
876
877
878
879
880
881
882
883
884 public static void copyInSession(Node src, String destAbsPath) throws RepositoryException {
885 final Session session = src.getSession();
886 final String destTmpNodeName = Path.getUniqueLabel(session, src.getParent().getPath(), "tmp_" + RandomStringUtils.randomAlphabetic(12));
887 final String destTmpParentPath = combinePathAndName(src.getParent().getPath(), destTmpNodeName);
888 final Node destTmpNode = createPath(src.getParent(), destTmpNodeName, src.getPrimaryNodeType().getName());
889 FileInputStream inStream = null;
890 FileOutputStream outStream = null;
891 File file = null;
892 try {
893 file = File.createTempFile("mgnl", null, Path.getTempDirectory());
894 outStream = new FileOutputStream(file);
895 session.exportSystemView(src.getPath(), outStream, false, false);
896 outStream.flush();
897 IOUtils.closeQuietly(outStream);
898 inStream = new FileInputStream(file);
899 session.importXML(
900 destTmpParentPath,
901 inStream,
902 ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
903
904 String currentPath = destTmpParentPath + "/" + src.getName();
905 session.move(currentPath, destAbsPath);
906
907 } catch (IOException e) {
908 throw new RepositoryException("Can't copy node " + src + " to " + destAbsPath, e);
909 } finally {
910 IOUtils.closeQuietly(inStream);
911 IOUtils.closeQuietly(outStream);
912 if (file != null) {
913 file.delete();
914 }
915 destTmpNode.remove();
916 }
917 }
918 }