]> git.argeo.org Git - gpl/argeo-slc.git/blob - eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java
Implement kill and process progress
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.client.ui / src / main / java / org / argeo / slc / client / ui / editors / ProcessBuilderPage.java
1 package org.argeo.slc.client.ui.editors;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.SortedSet;
7 import java.util.TreeSet;
8
9 import javax.jcr.Node;
10 import javax.jcr.NodeIterator;
11 import javax.jcr.Property;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.nodetype.NodeType;
14 import javax.jcr.observation.Event;
15 import javax.jcr.observation.EventListener;
16 import javax.jcr.observation.ObservationManager;
17 import javax.jcr.query.Query;
18 import javax.jcr.query.QueryManager;
19
20 import org.argeo.ArgeoException;
21 import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
22 import org.argeo.jcr.JcrUtils;
23 import org.argeo.slc.SlcException;
24 import org.argeo.slc.client.ui.SlcImages;
25 import org.argeo.slc.core.execution.PrimitiveUtils;
26 import org.argeo.slc.execution.ExecutionProcess;
27 import org.argeo.slc.jcr.SlcJcrUtils;
28 import org.argeo.slc.jcr.SlcNames;
29 import org.argeo.slc.jcr.SlcTypes;
30 import org.eclipse.jface.viewers.CellEditor;
31 import org.eclipse.jface.viewers.ColumnLabelProvider;
32 import org.eclipse.jface.viewers.ColumnViewer;
33 import org.eclipse.jface.viewers.EditingSupport;
34 import org.eclipse.jface.viewers.ISelectionChangedListener;
35 import org.eclipse.jface.viewers.IStructuredContentProvider;
36 import org.eclipse.jface.viewers.IStructuredSelection;
37 import org.eclipse.jface.viewers.ITreeContentProvider;
38 import org.eclipse.jface.viewers.SelectionChangedEvent;
39 import org.eclipse.jface.viewers.StructuredSelection;
40 import org.eclipse.jface.viewers.TableViewer;
41 import org.eclipse.jface.viewers.TableViewerColumn;
42 import org.eclipse.jface.viewers.TextCellEditor;
43 import org.eclipse.jface.viewers.TreeViewer;
44 import org.eclipse.jface.viewers.Viewer;
45 import org.eclipse.jface.viewers.ViewerDropAdapter;
46 import org.eclipse.swt.SWT;
47 import org.eclipse.swt.custom.SashForm;
48 import org.eclipse.swt.dnd.DND;
49 import org.eclipse.swt.dnd.TextTransfer;
50 import org.eclipse.swt.dnd.Transfer;
51 import org.eclipse.swt.dnd.TransferData;
52 import org.eclipse.swt.events.SelectionEvent;
53 import org.eclipse.swt.events.SelectionListener;
54 import org.eclipse.swt.graphics.Image;
55 import org.eclipse.swt.layout.FillLayout;
56 import org.eclipse.swt.layout.GridData;
57 import org.eclipse.swt.layout.GridLayout;
58 import org.eclipse.swt.layout.RowData;
59 import org.eclipse.swt.layout.RowLayout;
60 import org.eclipse.swt.widgets.Button;
61 import org.eclipse.swt.widgets.Composite;
62 import org.eclipse.swt.widgets.Label;
63 import org.eclipse.swt.widgets.Table;
64 import org.eclipse.ui.forms.AbstractFormPart;
65 import org.eclipse.ui.forms.IManagedForm;
66 import org.eclipse.ui.forms.editor.FormPage;
67 import org.eclipse.ui.forms.widgets.FormToolkit;
68 import org.eclipse.ui.forms.widgets.ScrolledForm;
69
70 /** Definition of the process. */
71 public class ProcessBuilderPage extends FormPage implements SlcNames {
72 public final static String ID = "processBuilderPage";
73 // private final static Log log =
74 // LogFactory.getLog(ProcessBuilderPage.class);
75
76 private Node processNode;
77
78 private TreeViewer flowsViewer;
79 private TableViewer valuesViewer;
80 private Label statusLabel;
81 private Button run;
82 private Button remove;
83 private Button clear;
84
85 private AbstractFormPart formPart;
86 private EventListener statusObserver;
87
88 public ProcessBuilderPage(ProcessEditor editor, Node processNode) {
89 super(editor, ID, "Definition");
90 this.processNode = processNode;
91 }
92
93 @Override
94 protected void createFormContent(IManagedForm mf) {
95 try {
96 ScrolledForm form = mf.getForm();
97 form.setExpandHorizontal(true);
98 form.setExpandVertical(true);
99 form.setText("Process " + processNode.getName());
100 GridLayout mainLayout = new GridLayout(1, true);
101 form.getBody().setLayout(mainLayout);
102
103 createControls(form.getBody());
104 createBuilder(form.getBody());
105
106 // form
107 formPart = new AbstractFormPart() {
108
109 };
110 getManagedForm().addPart(formPart);
111
112 // observation
113 statusObserver = new AsyncUiEventListener(form.getDisplay()) {
114 protected void onEventInUiThread(List<Event> events) {
115 statusChanged();
116 }
117 };
118 ObservationManager observationManager = processNode.getSession()
119 .getWorkspace().getObservationManager();
120 observationManager.addEventListener(statusObserver,
121 Event.PROPERTY_CHANGED, processNode.getPath(), true, null,
122 null, false);
123
124 // make sure all controls are in line with status
125 statusChanged();
126
127 // add initial flows
128 addInitialFlows();
129
130 } catch (RepositoryException e) {
131 throw new ArgeoException("Cannot create form content", e);
132 }
133 }
134
135 protected void createControls(Composite parent) {
136 FormToolkit tk = getManagedForm().getToolkit();
137
138 Composite controls = tk.createComposite(parent);
139 controls.setLayout(new RowLayout());
140 controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
141
142 run = tk.createButton(controls, null, SWT.PUSH);
143 run.setToolTipText("Run");
144 run.setImage(SlcImages.LAUNCH);
145 run.addSelectionListener(new SelectionListener() {
146 public void widgetSelected(SelectionEvent e) {
147 if (isFinished(getProcessStatus())) {
148 ((ProcessEditor) getEditor()).relaunch();
149 } else if (isRunning(getProcessStatus())) {
150 ((ProcessEditor) getEditor()).kill();
151 } else {
152 ((ProcessEditor) getEditor()).process();
153 }
154 }
155
156 public void widgetDefaultSelected(SelectionEvent e) {
157 widgetSelected(e);
158 }
159 });
160
161 remove = tk.createButton(controls, null, SWT.PUSH);
162 remove.setImage(SlcImages.REMOVE_ONE);
163 remove.setToolTipText("Remove selected flows");
164 remove.addSelectionListener(new SelectionListener() {
165 public void widgetSelected(SelectionEvent e) {
166 removeSelectedFlows();
167 }
168
169 public void widgetDefaultSelected(SelectionEvent e) {
170 widgetSelected(e);
171 }
172 });
173
174 clear = tk.createButton(controls, null, SWT.PUSH);
175 clear.setImage(SlcImages.REMOVE_ALL);
176 clear.setToolTipText("Clear all flows");
177 clear.addSelectionListener(new SelectionListener() {
178 public void widgetSelected(SelectionEvent e) {
179 removeAllFlows();
180 }
181
182 public void widgetDefaultSelected(SelectionEvent e) {
183 widgetSelected(e);
184 }
185 });
186
187 Composite statusComposite = tk.createComposite(controls);
188 RowData rowData = new RowData();
189 rowData.width = 100;
190 rowData.height = 16;
191 statusComposite.setLayoutData(rowData);
192 statusComposite.setLayout(new FillLayout());
193 statusLabel = tk.createLabel(statusComposite, getProcessStatus());
194
195 }
196
197 protected void createBuilder(Composite parent) {
198 FormToolkit tk = getManagedForm().getToolkit();
199 SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL);
200 sashForm.setSashWidth(4);
201 GridData sahFormGd = new GridData(SWT.FILL, SWT.FILL, true, true);
202 sahFormGd.widthHint = 400;
203 sashForm.setLayoutData(sahFormGd);
204
205 Composite flowsComposite = tk.createComposite(sashForm);
206 flowsComposite.setLayout(new GridLayout(1, false));
207
208 flowsViewer = new TreeViewer(flowsComposite);
209 flowsViewer.getTree().setLayoutData(
210 new GridData(SWT.FILL, SWT.FILL, true, true));
211 flowsViewer.setLabelProvider(new FlowsLabelProvider());
212 flowsViewer.setContentProvider(new FlowsContentProvider());
213 flowsViewer.addSelectionChangedListener(new FlowsSelectionListener());
214
215 int operations = DND.DROP_COPY | DND.DROP_MOVE;
216 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
217 flowsViewer.addDropSupport(operations, tt, new FlowsDropListener(
218 flowsViewer));
219
220 flowsViewer.setInput(getEditorSite());
221 flowsViewer.setInput(processNode);
222
223 Composite valuesComposite = tk.createComposite(sashForm);
224 valuesComposite.setLayout(new GridLayout(1, false));
225
226 valuesViewer = new TableViewer(valuesComposite);
227 GridData valuedGd = new GridData(SWT.FILL, SWT.FILL, true, true);
228 // valuedGd.widthHint = 200;
229 valuesViewer.getTable().setLayoutData(valuedGd);
230 valuesViewer.setContentProvider(new ValuesContentProvider());
231 initializeValuesViewer(valuesViewer);
232 sashForm.setWeights(getWeights());
233 valuesViewer.setInput(getEditorSite());
234 }
235
236 /** Creates the columns of the values viewer */
237 protected void initializeValuesViewer(TableViewer viewer) {
238 String[] titles = { "Name", "Value" };
239 int[] bounds = { 200, 100 };
240
241 for (int i = 0; i < titles.length; i++) {
242 TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
243 column.getColumn().setText(titles[i]);
244 column.getColumn().setWidth(bounds[i]);
245 column.getColumn().setResizable(true);
246 column.getColumn().setMoveable(true);
247 if (i == 0) {
248 column.setLabelProvider(new ColumnLabelProvider() {
249 public String getText(Object element) {
250 try {
251 Node specAttrNode = (Node) element;
252 return specAttrNode.getName();
253 } catch (RepositoryException e) {
254 throw new SlcException("Cannot get value", e);
255 }
256 }
257 });
258 } else if (i == 1) {
259 column.setLabelProvider(new ColumnLabelProvider() {
260 public String getText(Object element) {
261 Object obj = getAttributeSpecValue((Node) element);
262 return obj != null ? obj.toString() : "";
263 }
264 });
265 column.setEditingSupport(new ValuesEditingSupport(viewer));
266 }
267
268 }
269 Table table = viewer.getTable();
270 table.setHeaderVisible(false);
271 table.setLinesVisible(true);
272 }
273
274 protected int[] getWeights() {
275 return new int[] { 50, 50 };
276 }
277
278 /*
279 * CONTROLLERS
280 */
281 /** Reflects a status change */
282 protected void statusChanged() {
283 String status = getProcessStatus();
284 statusLabel.setText(status);
285 Boolean isEditable = isEditable(status);
286 run.setEnabled(status.equals(ExecutionProcess.RUNNING) || isEditable);
287 remove.setEnabled(isEditable);
288 clear.setEnabled(isEditable);
289 // flowsViewer.getTree().setEnabled(isEditable);
290 if (status.equals(ExecutionProcess.RUNNING)) {
291 run.setEnabled(true);
292 run.setImage(SlcImages.KILL);
293 run.setToolTipText("Kill");
294 } else if (isFinished(status)) {
295 run.setEnabled(true);
296 run.setImage(SlcImages.RELAUNCH);
297 run.setToolTipText("Relaunch");
298 }
299
300 if (flowsViewer != null)
301 flowsViewer.refresh();
302 }
303
304 /** Adds initial flows from the editor input if any */
305 protected void addInitialFlows() {
306 for (String path : ((ProcessEditorInput) getEditorInput())
307 .getInitialFlowPaths()) {
308 addFlow(path);
309 }
310 }
311
312 /**
313 * Adds a new flow.
314 *
315 * @param path
316 * the path of the flow
317 */
318 protected void addFlow(String path) {
319 try {
320 Node flowNode = processNode.getSession().getNode(path);
321 Node realizedFlowNode = processNode.getNode(SLC_FLOW).addNode(
322 SLC_FLOW);
323 realizedFlowNode.addMixin(SlcTypes.SLC_REALIZED_FLOW);
324 Node address = realizedFlowNode.addNode(SLC_ADDRESS,
325 NodeType.NT_ADDRESS);
326 address.setProperty(Property.JCR_PATH, path);
327
328 // copy spec attributes
329 Node specAttrsBase;
330 if (flowNode.hasProperty(SLC_SPEC)) {
331 Node executionSpecNode = flowNode.getProperty(SLC_SPEC)
332 .getNode();
333 specAttrsBase = executionSpecNode;
334 String executionSpecName = executionSpecNode.getProperty(
335 SLC_NAME).getString();
336 realizedFlowNode.setProperty(SLC_SPEC, executionSpecName);
337 } else
338 specAttrsBase = flowNode;
339
340 specAttrs: for (NodeIterator nit = specAttrsBase.getNodes(); nit
341 .hasNext();) {
342 Node specAttrNode = nit.nextNode();
343 String attrName = specAttrNode.getName();
344 if (!specAttrNode
345 .isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
346 continue specAttrs;
347 Node realizedAttrNode = realizedFlowNode.addNode(specAttrNode
348 .getName());
349 JcrUtils.copy(specAttrNode, realizedAttrNode);
350
351 // ovveride with flow value
352 if (flowNode.hasNode(attrName)) {
353 // assuming this is a primitive
354 realizedAttrNode.setProperty(SLC_VALUE,
355 flowNode.getNode(attrName).getProperty(SLC_VALUE)
356 .getValue());
357 }
358 }
359
360 flowsViewer.refresh();
361 formPart.markDirty();
362 } catch (RepositoryException e) {
363 throw new SlcException("Cannot drop " + path, e);
364 }
365 }
366
367 @SuppressWarnings("unchecked")
368 protected void removeSelectedFlows() {
369 if (!flowsViewer.getSelection().isEmpty()) {
370 Iterator<Object> it = ((StructuredSelection) flowsViewer
371 .getSelection()).iterator();
372 while (it.hasNext()) {
373 Node node = (Node) it.next();
374 try {
375 node.remove();
376 } catch (RepositoryException e) {
377 throw new ArgeoException("Cannot remove " + node, e);
378 }
379 }
380 flowsViewer.refresh();
381 formPart.markDirty();
382 }
383 }
384
385 protected void removeAllFlows() {
386 try {
387 for (NodeIterator nit = processNode.getNode(SLC_FLOW).getNodes(); nit
388 .hasNext();) {
389 nit.nextNode().remove();
390 }
391 flowsViewer.refresh();
392 formPart.markDirty();
393 } catch (RepositoryException e) {
394 throw new ArgeoException("Cannot remove flows from " + processNode,
395 e);
396 }
397 }
398
399 public void commit(Boolean onSave) {
400 if (onSave)
401 statusLabel.setText(getProcessStatus());
402 formPart.commit(onSave);
403 }
404
405 /*
406 * STATE
407 */
408 protected String getProcessStatus() {
409 try {
410 return processNode.getProperty(SLC_STATUS).getString();
411 } catch (RepositoryException e) {
412 throw new SlcException("Cannot retrieve status for " + processNode,
413 e);
414 }
415 }
416
417 /** Optimization so that we don't call the node each time */
418 protected static Boolean isEditable(String status) {
419 return status.equals(ExecutionProcess.NEW)
420 || status.equals(ExecutionProcess.INITIALIZED);
421 }
422
423 protected static Boolean isFinished(String status) {
424 return status.equals(ExecutionProcess.COMPLETED)
425 || status.equals(ExecutionProcess.ERROR)
426 || status.equals(ExecutionProcess.KILLED);
427 }
428
429 protected static Boolean isRunning(String status) {
430 return status.equals(ExecutionProcess.RUNNING);
431 }
432
433 /*
434 * LIFECYCLE
435 */
436 @Override
437 public void dispose() {
438 JcrUtils.unregisterQuietly(processNode, statusObserver);
439 super.dispose();
440 }
441
442 /*
443 * UTILITIES
444 */
445 protected static Object getAttributeSpecValue(Node specAttrNode) {
446 try {
447 if (specAttrNode.isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
448 if (!specAttrNode.hasProperty(SLC_VALUE))
449 return null;
450 String type = specAttrNode.getProperty(SLC_TYPE).getString();
451 // TODO optimize based on data type?
452 Object value = PrimitiveUtils.convert(type, specAttrNode
453 .getProperty(SLC_VALUE).getString());
454 // log.debug(specAttrNode + ", type=" + type + ", value=" +
455 // value);
456 return value;
457 }
458 return null;
459 } catch (RepositoryException e) {
460 throw new SlcException("Cannot get value", e);
461 }
462
463 }
464
465 /*
466 * FLOWS SUBCLASSES
467 */
468 static class FlowsContentProvider implements ITreeContentProvider {
469 public Object[] getElements(Object obj) {
470 if (!(obj instanceof Node))
471 return new Object[0];
472
473 try {
474 Node node = (Node) obj;
475 List<Node> children = new ArrayList<Node>();
476 for (NodeIterator nit = node.getNode(SLC_FLOW).getNodes(); nit
477 .hasNext();)
478 children.add(nit.nextNode());
479 return children.toArray();
480 } catch (RepositoryException e) {
481 throw new SlcException("Cannot list children of " + obj, e);
482 }
483 }
484
485 public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
486 }
487
488 public void dispose() {
489 }
490
491 public Object[] getChildren(Object parentElement) {
492 // no children for the time being
493 return null;
494 }
495
496 public Object getParent(Object element) {
497 return null;
498 }
499
500 public boolean hasChildren(Object element) {
501 return false;
502 }
503
504 }
505
506 static class FlowsLabelProvider extends ColumnLabelProvider {
507
508 @Override
509 public String getText(Object element) {
510 Node node = (Node) element;
511 try {
512 if (node.isNodeType(SlcTypes.SLC_REALIZED_FLOW)) {
513 if (node.hasNode(SLC_ADDRESS)) {
514 String path = node.getNode(SLC_ADDRESS)
515 .getProperty(Property.JCR_PATH).getString();
516 return SlcJcrUtils.flowExecutionModuleName(path) + ":"
517 + SlcJcrUtils.flowRelativePath(path);
518 }
519 }
520 } catch (RepositoryException e) {
521 throw new SlcException("Cannot display " + element, e);
522 }
523 return super.getText(element);
524 }
525
526 @Override
527 public Image getImage(Object element) {
528 Node node = (Node) element;
529 try {
530 if (node.isNodeType(SlcTypes.SLC_REALIZED_FLOW)) {
531 if (node.hasProperty(SLC_STATUS)) {
532 String status = node.getProperty(SLC_STATUS)
533 .getString();
534 // TODO: factorize with process view ?
535 if (status.equals(ExecutionProcess.RUNNING))
536 return SlcImages.PROCESS_RUNNING;
537 else if (status.equals(ExecutionProcess.ERROR)
538 || status.equals(ExecutionProcess.KILLED))
539 return SlcImages.PROCESS_ERROR;
540 else if (status.equals(ExecutionProcess.COMPLETED))
541 return SlcImages.PROCESS_COMPLETED;
542 }
543 return SlcImages.FLOW;
544 }
545 } catch (RepositoryException e) {
546 throw new SlcException("Cannot display " + element, e);
547 }
548 return super.getImage(element);
549 }
550
551 }
552
553 /** Parameter view is updated each time a new line is selected */
554 class FlowsSelectionListener implements ISelectionChangedListener {
555 public void selectionChanged(SelectionChangedEvent evt) {
556 if (evt.getSelection().isEmpty()) {
557 valuesViewer.setInput(getEditorSite());
558 return;
559 }
560 Node realizedFlowNode = (Node) ((IStructuredSelection) evt
561 .getSelection()).getFirstElement();
562 valuesViewer.setInput(realizedFlowNode);
563 }
564 }
565
566 /** Manages drop event. */
567 class FlowsDropListener extends ViewerDropAdapter {
568
569 public FlowsDropListener(Viewer viewer) {
570 super(viewer);
571 }
572
573 @Override
574 public boolean performDrop(Object data) {
575 String path = data.toString();
576 try {
577 // either a node or a whole directory was dragged
578 QueryManager qm = processNode.getSession().getWorkspace()
579 .getQueryManager();
580 String statement = "SELECT * FROM ["
581 + SlcTypes.SLC_EXECUTION_FLOW
582 + "] WHERE ISDESCENDANTNODE(['" + path
583 + "']) OR ISSAMENODE(['" + path + "'])";
584 // log.debug(statement);
585 Query query = qm.createQuery(statement, Query.JCR_SQL2);
586
587 // order paths
588 SortedSet<String> paths = new TreeSet<String>();
589 for (NodeIterator nit = query.execute().getNodes(); nit
590 .hasNext();) {
591 paths.add(nit.nextNode().getPath());
592 }
593
594 for (String p : paths) {
595 addFlow(p);
596 }
597 return true;
598 } catch (RepositoryException e) {
599 throw new SlcException("Cannot query flows under " + path, e);
600 }
601 }
602
603 @Override
604 public boolean validateDrop(Object target, int operation,
605 TransferData transferType) {
606 return isEditable(getProcessStatus());
607 }
608 }
609
610 /*
611 * VALUES SUBCLASSES
612 */
613 static class ValuesContentProvider implements IStructuredContentProvider {
614
615 public Object[] getElements(Object inputElement) {
616 if (!(inputElement instanceof Node))
617 return new Object[0];
618
619 try {
620 Node realizedFlowNode = (Node) inputElement;
621 List<Node> specAttributes = new ArrayList<Node>();
622 specAttrs: for (NodeIterator nit = realizedFlowNode.getNodes(); nit
623 .hasNext();) {
624 Node specAttrNode = nit.nextNode();
625 if (!specAttrNode
626 .isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE))
627 continue specAttrs;
628 specAttributes.add(specAttrNode);
629 }
630 return specAttributes.toArray();
631 } catch (RepositoryException e) {
632 throw new SlcException("Cannot get elements", e);
633 }
634 }
635
636 public void dispose() {
637 }
638
639 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
640 }
641 }
642
643 class ValuesEditingSupport extends EditingSupport {
644 private final TableViewer tableViewer;
645
646 public ValuesEditingSupport(ColumnViewer viewer) {
647 super(viewer);
648 tableViewer = (TableViewer) viewer;
649 }
650
651 @Override
652 protected CellEditor getCellEditor(Object element) {
653 try {
654 Node specAttrNode = (Node) element;
655 if (specAttrNode
656 .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE))
657 return new TextCellEditor(tableViewer.getTable());
658 return null;
659 } catch (RepositoryException e) {
660 throw new SlcException("Cannot get celle editor", e);
661 }
662 }
663
664 @Override
665 protected boolean canEdit(Object element) {
666 try {
667 Node specAttrNode = (Node) element;
668 return !(specAttrNode.getProperty(SLC_IS_IMMUTABLE)
669 .getBoolean() || specAttrNode.getProperty(
670 SLC_IS_CONSTANT).getBoolean())
671 && specAttrNode
672 .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE);
673 } catch (RepositoryException e) {
674 throw new SlcException("Cannot check canEdit", e);
675 }
676 }
677
678 @Override
679 protected Object getValue(Object element) {
680 Node specAttrNode = (Node) element;
681 try {
682 Object value = getAttributeSpecValue(specAttrNode);
683 if (value == null)
684 throw new SlcException("Unsupported attribute " + element);
685 if (specAttrNode
686 .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE))
687 return value.toString();
688 return value;
689 } catch (RepositoryException e) {
690 throw new SlcException("Cannot get value for " + element, e);
691 }
692 }
693
694 @Override
695 protected void setValue(Object element, Object value) {
696 try {
697 Node specAttrNode = (Node) element;
698 if (specAttrNode
699 .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
700 String type = specAttrNode.getProperty(SLC_TYPE)
701 .getString();
702 SlcJcrUtils.setPrimitiveAsProperty(specAttrNode, SLC_VALUE,
703 type, value);
704 valuesViewer.refresh();
705 formPart.markDirty();
706 }
707 } catch (RepositoryException e) {
708 throw new SlcException("Cannot get celle editor", e);
709 }
710 }
711
712 }
713 }