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.ui.contentapp.drop;
35
36 import info.magnolia.jcr.util.NodeTypes;
37 import info.magnolia.jcr.util.NodeUtil;
38 import info.magnolia.ui.contentapp.browser.drop.DropConstraint;
39
40 import javax.jcr.Item;
41 import javax.jcr.Node;
42 import javax.jcr.Property;
43 import javax.jcr.RepositoryException;
44
45 import com.vaadin.shared.ui.grid.DropLocation;
46
47 import lombok.Setter;
48 import lombok.SneakyThrows;
49
50
51
52
53
54
55 public class JcrDropConstraint implements DropConstraint<Item> {
56
57 @Setter
58 private String primaryNodeType;
59
60 @SneakyThrows(RepositoryException.class)
61 @Override
62 public boolean isAllowedAt(Item source, Item targetItem, DropLocation location) {
63 switch (location) {
64 case ON_TOP:
65 return allowedAsChild(source, targetItem);
66 case BELOW:
67 case ABOVE:
68 return allowedAsSibling(source, targetItem);
69 }
70 return false;
71 }
72
73 private boolean allowedAsChild(Item source, Item target) throws RepositoryException {
74 boolean movable = basicCheck(source, target);
75 if (movable) {
76
77 if (target.isSame(source.getParent())
78
79 || ((Node) target).hasNode(source.getName())
80 || ((Node) target).hasProperty(source.getName())) {
81 return false;
82 }
83
84 if (source.isNode()
85 && NodeUtil.isNodeType((Node) source, NodeTypes.Folder.NAME)
86 && !NodeUtil.isNodeType((Node) target, NodeTypes.Folder.NAME)) {
87 return false;
88 }
89 Node targetNode = (Node) target;
90
91 if (source.isNode()) {
92 Node sourceNode = (Node) source;
93
94 if (primaryNodeType != null && NodeUtil.isNodeType(sourceNode, primaryNodeType) && NodeUtil.isNodeType(targetNode, primaryNodeType)) {
95 return false;
96 }
97 return targetNode.getPrimaryNodeType().canAddChildNode(sourceNode.getName(), sourceNode.getPrimaryNodeType().getName());
98 } else {
99 Property sourceProperty = (Property) source;
100 if (sourceProperty.isMultiple()) {
101 return targetNode.getPrimaryNodeType().canSetProperty(sourceProperty.getName(), sourceProperty.getValues());
102 } else {
103 return targetNode.getPrimaryNodeType().canSetProperty(sourceProperty.getName(), sourceProperty.getValue());
104 }
105 }
106 }
107 return false;
108 }
109
110 private boolean basicCheck(Item source, Item target) throws RepositoryException {
111
112 if (!target.isNode()) {
113 return false;
114 }
115
116 return !isAncestorOf(source, target);
117 }
118
119 private boolean isAncestorOf(Item ancestor, Item node) throws RepositoryException {
120 return node.getPath().startsWith(ancestor.getPath() + "/");
121 }
122
123 private boolean allowedAsSibling(Item source, Item target) throws RepositoryException {
124
125 if (!source.isNode()) {
126 return false;
127 }
128 boolean movable = basicCheck(source, target);
129
130 return (!movable ||
131
132 !target.getParent().hasNode(source.getName()) || target.getParent().isSame(source.getParent())) && movable;
133 }
134 }