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