]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrExecutionModulesView.java
prevent adding a subfolder when user typed name contains a slash
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / views / JcrExecutionModulesView.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.client.ui.views;
17
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Comparator;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.SortedSet;
24 import java.util.TreeSet;
25
26 import javax.jcr.Node;
27 import javax.jcr.NodeIterator;
28 import javax.jcr.Property;
29 import javax.jcr.RepositoryException;
30 import javax.jcr.Session;
31 import javax.jcr.nodetype.NodeType;
32 import javax.jcr.observation.Event;
33 import javax.jcr.query.Query;
34 import javax.jcr.query.QueryManager;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.argeo.ArgeoException;
39 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
40 import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider;
41 import org.argeo.eclipse.ui.jcr.NodeElementComparer;
42 import org.argeo.eclipse.ui.jcr.SimpleNodeContentProvider;
43 import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
44 import org.argeo.slc.SlcException;
45 import org.argeo.slc.client.ui.ClientUiPlugin;
46 import org.argeo.slc.client.ui.SlcImages;
47 import org.argeo.slc.client.ui.editors.ProcessEditor;
48 import org.argeo.slc.client.ui.editors.ProcessEditorInput;
49 import org.argeo.slc.execution.ExecutionModulesManager;
50 import org.argeo.slc.jcr.SlcJcrConstants;
51 import org.argeo.slc.jcr.SlcNames;
52 import org.argeo.slc.jcr.SlcTypes;
53 import org.eclipse.jface.viewers.DoubleClickEvent;
54 import org.eclipse.jface.viewers.IDoubleClickListener;
55 import org.eclipse.jface.viewers.IStructuredSelection;
56 import org.eclipse.jface.viewers.ITableLabelProvider;
57 import org.eclipse.jface.viewers.TreeViewer;
58 import org.eclipse.swt.SWT;
59 import org.eclipse.swt.dnd.DND;
60 import org.eclipse.swt.dnd.DragSourceAdapter;
61 import org.eclipse.swt.dnd.DragSourceEvent;
62 import org.eclipse.swt.dnd.TextTransfer;
63 import org.eclipse.swt.dnd.Transfer;
64 import org.eclipse.swt.graphics.Image;
65 import org.eclipse.swt.widgets.Composite;
66 import org.eclipse.swt.widgets.Display;
67 import org.eclipse.ui.IWorkbenchPage;
68 import org.eclipse.ui.PlatformUI;
69 import org.eclipse.ui.part.ViewPart;
70
71 /** JCR based view of the execution modules. */
72 public class JcrExecutionModulesView extends ViewPart implements SlcTypes,
73 SlcNames {
74 private final static Log log = LogFactory
75 .getLog(JcrExecutionModulesView.class);
76
77 public static final String ID = ClientUiPlugin.ID
78 + ".jcrExecutionModulesView";
79
80 private TreeViewer viewer;
81
82 private Session session;
83
84 private ExecutionModulesManager modulesManager;
85
86 public void createPartControl(Composite parent) {
87 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
88 EclipseUiSpecificUtils.enableToolTipSupport(viewer);
89
90 ViewContentProvider contentProvider = new ViewContentProvider(session);
91 viewer.setContentProvider(contentProvider);
92 viewer.setComparer(new NodeElementComparer());
93 final ViewLabelProvider viewLabelProvider = new ViewLabelProvider();
94 viewer.setLabelProvider(viewLabelProvider);
95 viewer.setInput(getViewSite());
96 viewer.addDoubleClickListener(new ViewDoubleClickListener());
97 getViewSite().setSelectionProvider(viewer);
98
99 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
100 // Transfer[] tt = new Transfer[] { EditorInputTransfer.getInstance() };
101 int operations = DND.DROP_COPY | DND.DROP_MOVE;
102 viewer.addDragSupport(operations, tt, new ViewDragListener());
103
104 try {
105 String[] nodeTypes = { SlcTypes.SLC_AGENT,
106 SlcTypes.SLC_AGENT_FACTORY, SlcTypes.SLC_EXECUTION_MODULE };
107 session.getWorkspace()
108 .getObservationManager()
109 .addEventListener(
110 new VmAgentObserver(viewer.getTree().getDisplay()),
111 Event.NODE_ADDED | Event.NODE_REMOVED
112 | Event.NODE_MOVED,
113 SlcJcrConstants.VM_AGENT_FACTORY_PATH, true, null,
114 nodeTypes, false);
115 } catch (RepositoryException e) {
116 throw new SlcException("Cannot add observer", e);
117 }
118 }
119
120 public void setFocus() {
121 viewer.getControl().setFocus();
122 }
123
124 public TreeViewer getViewer() {
125 return viewer;
126 }
127
128 public void refreshView() {
129 viewer.setInput(getViewSite());
130 }
131
132 class ViewContentProvider extends SimpleNodeContentProvider {
133
134 public ViewContentProvider(Session session) {
135 super(session,
136 new String[] { SlcJcrConstants.VM_AGENT_FACTORY_PATH });
137 }
138
139 @Override
140 protected Object[] sort(Object parent, Object[] children) {
141 Object[] sorted = new Object[children.length];
142 System.arraycopy(children, 0, sorted, 0, children.length);
143 Arrays.sort(sorted, new ViewComparator());
144 return sorted;
145 }
146
147 @Override
148 protected List<Node> filterChildren(List<Node> children)
149 throws RepositoryException {
150 for (Iterator<Node> it = children.iterator(); it.hasNext();) {
151 Node node = it.next();
152 // execution spec definitions
153 if (node.getName().equals(SLC_EXECUTION_SPECS))
154 it.remove();
155 // flow values
156 else if (node.getParent().isNodeType(
157 SlcTypes.SLC_EXECUTION_FLOW))
158 it.remove();
159 }
160 return super.filterChildren(children);
161 }
162
163 @Override
164 public boolean hasChildren(Object element) {
165 if (element instanceof Node) {
166 Node node = (Node) element;
167 try {
168 if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
169 return false;
170 } catch (RepositoryException e) {
171 throw new SlcException("Cannot check has children", e);
172 }
173 }
174 return super.hasChildren(element);
175 }
176 }
177
178 static class ViewComparator implements Comparator<Object> {
179
180 public int compare(Object o1, Object o2) {
181 try {
182 if (o1 instanceof Node && o2 instanceof Node) {
183 Node node1 = (Node) o1;
184 Node node2 = (Node) o2;
185
186 if (node1.getName().equals(SLC_EXECUTION_SPECS))
187 return -100;
188 if (node2.getName().equals(SLC_EXECUTION_SPECS))
189 return 100;
190
191 if (node1.isNodeType(SLC_EXECUTION_FLOW)
192 && node2.isNodeType(SLC_EXECUTION_FLOW)) {
193 return node1.getName().compareTo(node2.getName());
194 } else if (node1.isNodeType(SLC_EXECUTION_FLOW)
195 && !node2.isNodeType(SLC_EXECUTION_FLOW)) {
196 return 1;
197 } else if (!node1.isNodeType(SLC_EXECUTION_FLOW)
198 && node2.isNodeType(SLC_EXECUTION_FLOW)) {
199 return -1;
200 } else {
201 // TODO: check title
202 return node1.getName().compareTo(node2.getName());
203 }
204 }
205 } catch (RepositoryException e) {
206 throw new ArgeoException("Cannot compare " + o1 + " and " + o2,
207 e);
208 }
209 return 0;
210 }
211
212 }
213
214 class VmAgentObserver extends AsyncUiEventListener {
215
216 public VmAgentObserver(Display display) {
217 super(display);
218 }
219
220 protected void onEventInUiThread(List<Event> events) {
221 for (Event event : events) {
222 try {
223 String path = event.getPath();
224
225 if (session.itemExists(path)) {
226 Node parentNode = session.getNode(path);// .getParent();
227 if (log.isTraceEnabled())
228 log.trace("Refresh " + parentNode + " after event "
229 + event);
230 viewer.refresh(parentNode);
231 }
232 } catch (RepositoryException e) {
233 log.warn("Cannot process event " + event + ": " + e);
234 }
235 }
236
237 // TODO: optimize based on event
238 viewer.refresh();
239 }
240 }
241
242 class ViewLabelProvider extends DefaultNodeLabelProvider implements
243 ITableLabelProvider {
244
245 @Override
246 protected String getText(Node node) throws RepositoryException {
247 if (node.isNodeType(NodeType.MIX_TITLE)
248 && node.hasProperty(Property.JCR_TITLE))
249 return node.getProperty(Property.JCR_TITLE).getString();
250 else if (node.getName().equals(SLC_EXECUTION_SPECS))
251 return "Execution Specifications";
252 else if (node.getPath().equals(
253 SlcJcrConstants.VM_AGENT_FACTORY_PATH))
254 return "Internal Agents";
255 return super.getText(node);
256 }
257
258 @Override
259 public Image getImage(Node node) throws RepositoryException {
260 // we try to optimize a bit by putting deeper nodes first
261 if (node.getParent().isNodeType(
262 SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
263 return SlcImages.CHOICES;
264 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
265 return SlcImages.EXECUTION_SPEC_ATTRIBUTE;
266 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_SPEC))
267 return SlcImages.EXECUTION_SPEC;
268 else if (node.getName().equals(SLC_EXECUTION_SPECS))
269 return SlcImages.EXECUTION_SPECS;
270 else if (node.isNodeType(SlcTypes.SLC_EXECUTION_FLOW))
271 return SlcImages.FLOW;
272 else if (node.isNodeType(SlcTypes.SLC_MODULE)) {
273 if (node.getProperty(SLC_STARTED).getBoolean())
274 return SlcImages.MODULE;
275 else
276 return SlcImages.MODULE_STOPPED;
277 } else if (node.isNodeType(SlcTypes.SLC_AGENT))
278 return SlcImages.AGENT;
279 else if (node.isNodeType(SlcTypes.SLC_AGENT_FACTORY))
280 return SlcImages.AGENT_FACTORY;
281 else
282 return SlcImages.FOLDER;
283 }
284
285 public String getToolTipText(Node node) throws RepositoryException {
286 if (node.isNodeType(NodeType.MIX_TITLE)
287 && node.hasProperty(Property.JCR_DESCRIPTION))
288 return node.getProperty(Property.JCR_DESCRIPTION).getString();
289 return super.getToolTipText(node);
290 }
291
292 public String getColumnText(Object obj, int index) {
293 return getText(obj);
294 }
295
296 public Image getColumnImage(Object obj, int index) {
297 return getImage(obj);
298 }
299
300 }
301
302 class ViewDoubleClickListener implements IDoubleClickListener {
303 public void doubleClick(DoubleClickEvent evt) {
304 Object obj = ((IStructuredSelection) evt.getSelection())
305 .getFirstElement();
306 try {
307 if (obj instanceof Node) {
308 Node node = (Node) obj;
309 if (node.isNodeType(SLC_EXECUTION_MODULE)) {
310 ClientUiPlugin.startStopExecutionModule(modulesManager,
311 node);
312 } else {
313 String path = node.getPath();
314 // TODO factorize with editor
315 QueryManager qm = node.getSession().getWorkspace()
316 .getQueryManager();
317 String statement = "SELECT * FROM ["
318 + SlcTypes.SLC_EXECUTION_FLOW
319 + "] WHERE ISDESCENDANTNODE(['" + path
320 + "']) OR ISSAMENODE(['" + path + "'])";
321 // log.debug(statement);
322 Query query = qm.createQuery(statement, Query.JCR_SQL2);
323
324 // order paths
325 SortedSet<String> paths = new TreeSet<String>();
326 for (NodeIterator nit = query.execute().getNodes(); nit
327 .hasNext();) {
328 paths.add(nit.nextNode().getPath());
329 }
330
331 IWorkbenchPage activePage = PlatformUI.getWorkbench()
332 .getActiveWorkbenchWindow().getActivePage();
333 activePage.openEditor(new ProcessEditorInput(
334 new ArrayList<String>(paths), true),
335 ProcessEditor.ID);
336 }
337 }
338 } catch (Exception e) {
339 throw new SlcException("Cannot open " + obj, e);
340 }
341 }
342
343 }
344
345 /** Listen to drags */
346 class ViewDragListener extends DragSourceAdapter {
347 public void dragSetData(DragSourceEvent event) {
348 IStructuredSelection selection = (IStructuredSelection) viewer
349 .getSelection();
350 if (selection.getFirstElement() instanceof Node) {
351 Node node = (Node) selection.getFirstElement();
352 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
353 try {
354 event.data = node.getPath();
355 } catch (RepositoryException e) {
356 throw new SlcException("Cannot read node", e);
357 }
358 }
359 }
360 }
361 }
362
363 public void setSession(Session session) {
364 this.session = session;
365 }
366
367 public void setModulesManager(ExecutionModulesManager modulesManager) {
368 this.modulesManager = modulesManager;
369 }
370
371 }