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