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.datasource.jcr;
35
36 import info.magnolia.context.Context;
37 import info.magnolia.jcr.decoration.AbstractContentDecorator;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.ui.contentapp.Datasource;
40
41 import java.util.Collection;
42
43 import javax.inject.Inject;
44 import javax.inject.Provider;
45 import javax.jcr.InvalidItemStateException;
46 import javax.jcr.Item;
47 import javax.jcr.Node;
48 import javax.jcr.Property;
49 import javax.jcr.RepositoryException;
50 import javax.jcr.Session;
51
52 import com.machinezoo.noexception.Exceptions;
53 import com.vaadin.shared.ui.grid.DropLocation;
54
55
56
57
58 public class JcrDatasource extends AbstractContentDecorator implements Datasource<Item> {
59
60 private static final String TMP_DELETED = "mgnl:tmpDeleted";
61 static final String TMP_DELETED_NODE = TMP_DELETED + "$Node";
62 static final String TMP_DELETED_PROPERTY = TMP_DELETED + "$Property";
63
64 private final Provider<Context> contextProvider;
65 private final JcrDatasourceDefinition datasourceDefinition;
66
67 @Inject
68 public JcrDatasource(Provider<Context> contextProvider, JcrDatasourceDefinition datasourceDefinition) {
69 this.contextProvider = contextProvider;
70 this.datasourceDefinition = datasourceDefinition;
71 }
72
73 @Override
74 public boolean isMultipleWrapEnabled() {
75 return false;
76 }
77
78 @Override
79 public JcrSessionWrapper wrapSession(Session session) {
80 return new JcrSessionWrapper(session, this);
81 }
82
83 @Override
84 public JcrNodeWrapper wrapNode(Node node) {
85 return new JcrNodeWrapper(node, this);
86 }
87
88 @Override
89 public boolean evaluateNode(Node node) {
90 return super.evaluateNode(node) && !Exceptions.wrap().get(node::getName).equals(TMP_DELETED_NODE);
91 }
92
93 @Override
94 public JcrPropertyWrapper wrapProperty(Property property) {
95 return new JcrPropertyWrapper(property, this);
96 }
97
98 @Override
99 public boolean evaluateProperty(Property property) {
100 String propertyName = Exceptions.wrap().get(property::getName);
101 return super.evaluateProperty(property) && !propertyName.equals(TMP_DELETED_PROPERTY);
102 }
103
104 public Node getRoot() {
105 return Exceptions.wrap().get(() -> getJCRSession().getNode(this.datasourceDefinition.getRootPath()));
106 }
107
108 public JcrSessionWrapper getJCRSession() throws RepositoryException {
109 Session session = contextProvider.get().getJCRSession(datasourceDefinition.getWorkspace());
110 return wrapSession(session);
111 }
112
113 public Item wrapItem(Item item) {
114 return item instanceof Node ? wrapNode((Node) item) : wrapProperty((Property) item);
115 }
116
117 boolean exists(Item item) throws RepositoryException {
118 try {
119 item.getName();
120 return true;
121 } catch (InvalidItemStateException e) {
122 return false;
123 }
124 }
125
126 @Override
127 public void moveItems(Collection<Item> items, Item target, DropLocation dropLocation) {
128 items.forEach(Exceptions.wrap().consumer(item -> {
129 Node targetNode = (Node) target;
130 switch (dropLocation) {
131 case ABOVE:
132 NodeUtil.moveNodeBefore((Node) item, targetNode);
133 break;
134 case BELOW:
135 NodeUtil.moveNodeAfter((Node) item, targetNode);
136 break;
137 case ON_TOP:
138 if (item.isNode()) {
139 NodeUtil.moveNode((Node) item, targetNode);
140 } else {
141 NodeUtil.moveProperty((Property) item, targetNode);
142 }
143 break;
144 }
145 commit(target);
146 }));
147 }
148
149 @Override
150 public void commit(Item item) {
151 Exceptions.wrap().run(() -> item.getSession().save());
152 }
153
154 @Override
155 public void remove(Item item) {
156 Exceptions.wrap().run(item::remove);
157 }
158 }