1 package org
.argeo
.slc
.client
.ui
.editors
;
3 import java
.util
.ArrayList
;
4 import java
.util
.Iterator
;
6 import java
.util
.SortedSet
;
7 import java
.util
.TreeSet
;
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
;
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
.ComboBoxCellEditor
;
34 import org
.eclipse
.jface
.viewers
.EditingSupport
;
35 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
36 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
37 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
38 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
39 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
40 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
41 import org
.eclipse
.jface
.viewers
.TableViewer
;
42 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
43 import org
.eclipse
.jface
.viewers
.TextCellEditor
;
44 import org
.eclipse
.jface
.viewers
.TreeViewer
;
45 import org
.eclipse
.jface
.viewers
.Viewer
;
46 import org
.eclipse
.jface
.viewers
.ViewerDropAdapter
;
47 import org
.eclipse
.swt
.SWT
;
48 import org
.eclipse
.swt
.custom
.SashForm
;
49 import org
.eclipse
.swt
.dnd
.DND
;
50 import org
.eclipse
.swt
.dnd
.TextTransfer
;
51 import org
.eclipse
.swt
.dnd
.Transfer
;
52 import org
.eclipse
.swt
.dnd
.TransferData
;
53 import org
.eclipse
.swt
.events
.SelectionEvent
;
54 import org
.eclipse
.swt
.events
.SelectionListener
;
55 import org
.eclipse
.swt
.graphics
.Image
;
56 import org
.eclipse
.swt
.layout
.FillLayout
;
57 import org
.eclipse
.swt
.layout
.GridData
;
58 import org
.eclipse
.swt
.layout
.GridLayout
;
59 import org
.eclipse
.swt
.layout
.RowData
;
60 import org
.eclipse
.swt
.layout
.RowLayout
;
61 import org
.eclipse
.swt
.widgets
.Button
;
62 import org
.eclipse
.swt
.widgets
.Composite
;
63 import org
.eclipse
.swt
.widgets
.Label
;
64 import org
.eclipse
.swt
.widgets
.Table
;
65 import org
.eclipse
.ui
.forms
.AbstractFormPart
;
66 import org
.eclipse
.ui
.forms
.IManagedForm
;
67 import org
.eclipse
.ui
.forms
.editor
.FormPage
;
68 import org
.eclipse
.ui
.forms
.widgets
.FormToolkit
;
69 import org
.eclipse
.ui
.forms
.widgets
.ScrolledForm
;
71 /** Definition of the process. */
72 public class ProcessBuilderPage
extends FormPage
implements SlcNames
{
73 public final static String ID
= "processBuilderPage";
74 // private final static Log log =
75 // LogFactory.getLog(ProcessBuilderPage.class);
77 /** To be displayed in empty lists */
78 final static String NONE
= "<none>";
80 private Node processNode
;
82 private TreeViewer flowsViewer
;
83 private TableViewer valuesViewer
;
84 private Label statusLabel
;
86 private Button remove
;
89 private AbstractFormPart formPart
;
90 private EventListener statusObserver
;
92 public ProcessBuilderPage(ProcessEditor editor
, Node processNode
) {
93 super(editor
, ID
, "Definition");
94 this.processNode
= processNode
;
98 protected void createFormContent(IManagedForm mf
) {
100 ScrolledForm form
= mf
.getForm();
101 form
.setExpandHorizontal(true);
102 form
.setExpandVertical(true);
103 form
.setText("Process " + processNode
.getName());
104 GridLayout mainLayout
= new GridLayout(1, true);
105 form
.getBody().setLayout(mainLayout
);
107 createControls(form
.getBody());
108 createBuilder(form
.getBody());
111 formPart
= new AbstractFormPart() {
114 getManagedForm().addPart(formPart
);
117 statusObserver
= new AsyncUiEventListener(form
.getDisplay()) {
118 protected void onEventInUiThread(List
<Event
> events
) {
122 ObservationManager observationManager
= processNode
.getSession()
123 .getWorkspace().getObservationManager();
124 observationManager
.addEventListener(statusObserver
,
125 Event
.PROPERTY_CHANGED
, processNode
.getPath(), true, null,
128 // make sure all controls are in line with status
134 } catch (RepositoryException e
) {
135 throw new ArgeoException("Cannot create form content", e
);
139 protected void createControls(Composite parent
) {
140 FormToolkit tk
= getManagedForm().getToolkit();
142 Composite controls
= tk
.createComposite(parent
);
143 controls
.setLayout(new RowLayout());
144 controls
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
146 run
= tk
.createButton(controls
, null, SWT
.PUSH
);
147 run
.setToolTipText("Run");
148 run
.setImage(SlcImages
.LAUNCH
);
149 run
.addSelectionListener(new SelectionListener() {
150 public void widgetSelected(SelectionEvent e
) {
151 if (isFinished(getProcessStatus())) {
152 ((ProcessEditor
) getEditor()).relaunch();
153 } else if (isRunning(getProcessStatus())) {
154 ((ProcessEditor
) getEditor()).kill();
156 ((ProcessEditor
) getEditor()).process();
160 public void widgetDefaultSelected(SelectionEvent e
) {
165 remove
= tk
.createButton(controls
, null, SWT
.PUSH
);
166 remove
.setImage(SlcImages
.REMOVE_ONE
);
167 remove
.setToolTipText("Remove selected flows");
168 remove
.addSelectionListener(new SelectionListener() {
169 public void widgetSelected(SelectionEvent e
) {
170 removeSelectedFlows();
173 public void widgetDefaultSelected(SelectionEvent e
) {
178 clear
= tk
.createButton(controls
, null, SWT
.PUSH
);
179 clear
.setImage(SlcImages
.REMOVE_ALL
);
180 clear
.setToolTipText("Clear all flows");
181 clear
.addSelectionListener(new SelectionListener() {
182 public void widgetSelected(SelectionEvent e
) {
186 public void widgetDefaultSelected(SelectionEvent e
) {
191 Composite statusComposite
= tk
.createComposite(controls
);
192 RowData rowData
= new RowData();
195 statusComposite
.setLayoutData(rowData
);
196 statusComposite
.setLayout(new FillLayout());
197 statusLabel
= tk
.createLabel(statusComposite
, getProcessStatus());
201 protected void createBuilder(Composite parent
) {
202 FormToolkit tk
= getManagedForm().getToolkit();
203 SashForm sashForm
= new SashForm(parent
, SWT
.HORIZONTAL
);
204 sashForm
.setSashWidth(4);
205 GridData sahFormGd
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
206 sahFormGd
.widthHint
= 400;
207 sashForm
.setLayoutData(sahFormGd
);
209 Composite flowsComposite
= tk
.createComposite(sashForm
);
210 flowsComposite
.setLayout(new GridLayout(1, false));
212 flowsViewer
= new TreeViewer(flowsComposite
);
213 flowsViewer
.getTree().setLayoutData(
214 new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
215 flowsViewer
.setLabelProvider(new FlowsLabelProvider());
216 flowsViewer
.setContentProvider(new FlowsContentProvider());
217 flowsViewer
.addSelectionChangedListener(new FlowsSelectionListener());
219 int operations
= DND
.DROP_COPY
| DND
.DROP_MOVE
;
220 Transfer
[] tt
= new Transfer
[] { TextTransfer
.getInstance() };
221 flowsViewer
.addDropSupport(operations
, tt
, new FlowsDropListener(
224 flowsViewer
.setInput(getEditorSite());
225 flowsViewer
.setInput(processNode
);
227 Composite valuesComposite
= tk
.createComposite(sashForm
);
228 valuesComposite
.setLayout(new GridLayout(1, false));
230 valuesViewer
= new TableViewer(valuesComposite
);
231 GridData valuedGd
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
232 // valuedGd.widthHint = 200;
233 valuesViewer
.getTable().setLayoutData(valuedGd
);
234 valuesViewer
.setContentProvider(new ValuesContentProvider());
235 initializeValuesViewer(valuesViewer
);
236 sashForm
.setWeights(getWeights());
237 valuesViewer
.setInput(getEditorSite());
240 /** Creates the columns of the values viewer */
241 protected void initializeValuesViewer(TableViewer viewer
) {
242 String
[] titles
= { "Name", "Value" };
243 int[] bounds
= { 200, 100 };
245 for (int i
= 0; i
< titles
.length
; i
++) {
246 TableViewerColumn column
= new TableViewerColumn(viewer
, SWT
.NONE
);
247 column
.getColumn().setText(titles
[i
]);
248 column
.getColumn().setWidth(bounds
[i
]);
249 column
.getColumn().setResizable(true);
250 column
.getColumn().setMoveable(true);
252 column
.setLabelProvider(new ColumnLabelProvider() {
253 public String
getText(Object element
) {
255 Node specAttrNode
= (Node
) element
;
256 return specAttrNode
.getName();
257 } catch (RepositoryException e
) {
258 throw new SlcException("Cannot get value", e
);
263 column
.setLabelProvider(new ColumnLabelProvider() {
264 public String
getText(Object element
) {
265 return getAttributeSpecText((Node
) element
);
268 column
.setEditingSupport(new ValuesEditingSupport(viewer
));
272 Table table
= viewer
.getTable();
273 table
.setHeaderVisible(false);
274 table
.setLinesVisible(true);
277 protected int[] getWeights() {
278 return new int[] { 50, 50 };
284 /** Reflects a status change */
285 protected void statusChanged() {
286 String status
= getProcessStatus();
287 statusLabel
.setText(status
);
288 Boolean isEditable
= isEditable(status
);
289 run
.setEnabled(status
.equals(ExecutionProcess
.RUNNING
) || isEditable
);
290 remove
.setEnabled(isEditable
);
291 clear
.setEnabled(isEditable
);
292 // flowsViewer.getTree().setEnabled(isEditable);
293 if (status
.equals(ExecutionProcess
.RUNNING
)) {
294 run
.setEnabled(true);
295 run
.setImage(SlcImages
.KILL
);
296 run
.setToolTipText("Kill");
297 } else if (isFinished(status
)) {
298 run
.setEnabled(true);
299 run
.setImage(SlcImages
.RELAUNCH
);
300 run
.setToolTipText("Relaunch");
303 if (flowsViewer
!= null)
304 flowsViewer
.refresh();
307 /** Adds initial flows from the editor input if any */
308 protected void addInitialFlows() {
309 for (String path
: ((ProcessEditorInput
) getEditorInput())
310 .getInitialFlowPaths()) {
319 * the path of the flow
321 protected void addFlow(String path
) {
323 Node flowNode
= processNode
.getSession().getNode(path
);
324 Node realizedFlowNode
= processNode
.getNode(SLC_FLOW
).addNode(
326 realizedFlowNode
.addMixin(SlcTypes
.SLC_REALIZED_FLOW
);
327 Node address
= realizedFlowNode
.addNode(SLC_ADDRESS
,
328 NodeType
.NT_ADDRESS
);
329 address
.setProperty(Property
.JCR_PATH
, path
);
331 // copy spec attributes
333 if (flowNode
.hasProperty(SLC_SPEC
)) {
334 Node executionSpecNode
= flowNode
.getProperty(SLC_SPEC
)
336 specAttrsBase
= executionSpecNode
;
337 String executionSpecName
= executionSpecNode
.getProperty(
338 SLC_NAME
).getString();
339 realizedFlowNode
.setProperty(SLC_SPEC
, executionSpecName
);
341 specAttrsBase
= flowNode
;
343 specAttrs
: for (NodeIterator nit
= specAttrsBase
.getNodes(); nit
345 Node specAttrNode
= nit
.nextNode();
346 String attrName
= specAttrNode
.getName();
348 .isNodeType(SlcTypes
.SLC_EXECUTION_SPEC_ATTRIBUTE
))
350 Node realizedAttrNode
= realizedFlowNode
.addNode(specAttrNode
352 JcrUtils
.copy(specAttrNode
, realizedAttrNode
);
354 // override with flow value
355 if (flowNode
.hasNode(attrName
)) {
356 // assuming this is a primitive
357 realizedAttrNode
.setProperty(SLC_VALUE
,
358 flowNode
.getNode(attrName
).getProperty(SLC_VALUE
)
363 flowsViewer
.refresh();
364 formPart
.markDirty();
365 } catch (RepositoryException e
) {
366 throw new SlcException("Cannot drop " + path
, e
);
370 @SuppressWarnings("unchecked")
371 protected void removeSelectedFlows() {
372 if (!flowsViewer
.getSelection().isEmpty()) {
373 Iterator
<Object
> it
= ((StructuredSelection
) flowsViewer
374 .getSelection()).iterator();
375 while (it
.hasNext()) {
376 Node node
= (Node
) it
.next();
379 } catch (RepositoryException e
) {
380 throw new ArgeoException("Cannot remove " + node
, e
);
383 flowsViewer
.refresh();
384 formPart
.markDirty();
388 protected void removeAllFlows() {
390 for (NodeIterator nit
= processNode
.getNode(SLC_FLOW
).getNodes(); nit
392 nit
.nextNode().remove();
394 flowsViewer
.refresh();
395 formPart
.markDirty();
396 } catch (RepositoryException e
) {
397 throw new ArgeoException("Cannot remove flows from " + processNode
,
402 public void commit(Boolean onSave
) {
404 statusLabel
.setText(getProcessStatus());
405 formPart
.commit(onSave
);
411 protected String
getProcessStatus() {
413 return processNode
.getProperty(SLC_STATUS
).getString();
414 } catch (RepositoryException e
) {
415 throw new SlcException("Cannot retrieve status for " + processNode
,
420 /** Optimization so that we don't call the node each time */
421 protected static Boolean
isEditable(String status
) {
422 return status
.equals(ExecutionProcess
.NEW
)
423 || status
.equals(ExecutionProcess
.INITIALIZED
);
426 protected static Boolean
isFinished(String status
) {
427 return status
.equals(ExecutionProcess
.COMPLETED
)
428 || status
.equals(ExecutionProcess
.ERROR
)
429 || status
.equals(ExecutionProcess
.KILLED
);
432 protected static Boolean
isRunning(String status
) {
433 return status
.equals(ExecutionProcess
.RUNNING
);
440 public void dispose() {
441 JcrUtils
.unregisterQuietly(processNode
, statusObserver
);
448 // protected static Object getAttributeSpecValue(Node specAttrNode) {
450 // if (specAttrNode.isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) {
451 // if (!specAttrNode.hasProperty(SLC_VALUE))
453 // String type = specAttrNode.getProperty(SLC_TYPE).getString();
454 // // TODO optimize based on data type?
455 // Object value = PrimitiveUtils.convert(type, specAttrNode
456 // .getProperty(SLC_VALUE).getString());
457 // // log.debug(specAttrNode + ", type=" + type + ", value=" +
460 // } else if (specAttrNode.isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) {
461 // if (specAttrNode.hasNode(SLC_VALUE)) {
462 // // return the index of the sub node
463 // // in the future we may manage reference as well
464 // return specAttrNode.getProperty(SLC_VALUE).getLong();
469 // } catch (RepositoryException e) {
470 // throw new SlcException("Cannot get value", e);
475 protected static String
getAttributeSpecText(Node specAttrNode
) {
477 if (specAttrNode
.isNodeType(SlcTypes
.SLC_PRIMITIVE_SPEC_ATTRIBUTE
)) {
478 if (!specAttrNode
.hasProperty(SLC_VALUE
))
480 String type
= specAttrNode
.getProperty(SLC_TYPE
).getString();
481 Object value
= PrimitiveUtils
.convert(type
, specAttrNode
482 .getProperty(SLC_VALUE
).getString());
483 return value
.toString();
484 } else if (specAttrNode
.isNodeType(SlcTypes
.SLC_REF_SPEC_ATTRIBUTE
)) {
485 if (specAttrNode
.hasProperty(SLC_VALUE
)) {
486 int value
= (int) specAttrNode
.getProperty(SLC_VALUE
)
488 NodeIterator children
= specAttrNode
.getNodes();
490 while (children
.hasNext()) {
491 Node child
= children
.nextNode();
493 return child
.getProperty(Property
.JCR_TITLE
)
497 throw new SlcException("No child node with index " + value
498 + " for spec attribute " + specAttrNode
);
502 throw new SlcException("Unsupported type for spec attribute "
504 } catch (RepositoryException e
) {
505 throw new SlcException("Cannot get value", e
);
512 static class FlowsContentProvider
implements ITreeContentProvider
{
513 public Object
[] getElements(Object obj
) {
514 if (!(obj
instanceof Node
))
515 return new Object
[0];
518 Node node
= (Node
) obj
;
519 List
<Node
> children
= new ArrayList
<Node
>();
520 for (NodeIterator nit
= node
.getNode(SLC_FLOW
).getNodes(); nit
522 children
.add(nit
.nextNode());
523 return children
.toArray();
524 } catch (RepositoryException e
) {
525 throw new SlcException("Cannot list children of " + obj
, e
);
529 public void inputChanged(Viewer arg0
, Object arg1
, Object arg2
) {
532 public void dispose() {
535 public Object
[] getChildren(Object parentElement
) {
536 // no children for the time being
540 public Object
getParent(Object element
) {
544 public boolean hasChildren(Object element
) {
550 static class FlowsLabelProvider
extends ColumnLabelProvider
{
553 public String
getText(Object element
) {
554 Node node
= (Node
) element
;
556 if (node
.isNodeType(SlcTypes
.SLC_REALIZED_FLOW
)) {
557 if (node
.hasNode(SLC_ADDRESS
)) {
558 String path
= node
.getNode(SLC_ADDRESS
)
559 .getProperty(Property
.JCR_PATH
).getString();
560 return SlcJcrUtils
.flowExecutionModuleName(path
) + ":"
561 + SlcJcrUtils
.flowRelativePath(path
);
564 } catch (RepositoryException e
) {
565 throw new SlcException("Cannot display " + element
, e
);
567 return super.getText(element
);
571 public Image
getImage(Object element
) {
572 Node node
= (Node
) element
;
574 if (node
.isNodeType(SlcTypes
.SLC_REALIZED_FLOW
)) {
575 if (node
.hasProperty(SLC_STATUS
)) {
576 String status
= node
.getProperty(SLC_STATUS
)
578 // TODO: factorize with process view ?
579 if (status
.equals(ExecutionProcess
.RUNNING
))
580 return SlcImages
.PROCESS_RUNNING
;
581 else if (status
.equals(ExecutionProcess
.ERROR
)
582 || status
.equals(ExecutionProcess
.KILLED
))
583 return SlcImages
.PROCESS_ERROR
;
584 else if (status
.equals(ExecutionProcess
.COMPLETED
))
585 return SlcImages
.PROCESS_COMPLETED
;
587 return SlcImages
.FLOW
;
589 } catch (RepositoryException e
) {
590 throw new SlcException("Cannot display " + element
, e
);
592 return super.getImage(element
);
597 /** Parameter view is updated each time a new line is selected */
598 class FlowsSelectionListener
implements ISelectionChangedListener
{
599 public void selectionChanged(SelectionChangedEvent evt
) {
600 if (evt
.getSelection().isEmpty()) {
601 valuesViewer
.setInput(getEditorSite());
604 Node realizedFlowNode
= (Node
) ((IStructuredSelection
) evt
605 .getSelection()).getFirstElement();
606 valuesViewer
.setInput(realizedFlowNode
);
610 /** Manages drop event. */
611 class FlowsDropListener
extends ViewerDropAdapter
{
613 public FlowsDropListener(Viewer viewer
) {
618 public boolean performDrop(Object data
) {
619 String path
= data
.toString();
621 // either a node or a whole directory was dragged
622 QueryManager qm
= processNode
.getSession().getWorkspace()
624 String statement
= "SELECT * FROM ["
625 + SlcTypes
.SLC_EXECUTION_FLOW
626 + "] WHERE ISDESCENDANTNODE(['" + path
627 + "']) OR ISSAMENODE(['" + path
+ "'])";
628 // log.debug(statement);
629 Query query
= qm
.createQuery(statement
, Query
.JCR_SQL2
);
632 SortedSet
<String
> paths
= new TreeSet
<String
>();
633 for (NodeIterator nit
= query
.execute().getNodes(); nit
635 paths
.add(nit
.nextNode().getPath());
638 for (String p
: paths
) {
642 } catch (RepositoryException e
) {
643 throw new SlcException("Cannot query flows under " + path
, e
);
648 public boolean validateDrop(Object target
, int operation
,
649 TransferData transferType
) {
650 return isEditable(getProcessStatus());
657 static class ValuesContentProvider
implements IStructuredContentProvider
{
659 public Object
[] getElements(Object inputElement
) {
660 if (!(inputElement
instanceof Node
))
661 return new Object
[0];
664 Node realizedFlowNode
= (Node
) inputElement
;
665 List
<Node
> specAttributes
= new ArrayList
<Node
>();
666 specAttrs
: for (NodeIterator nit
= realizedFlowNode
.getNodes(); nit
668 Node specAttrNode
= nit
.nextNode();
670 .isNodeType(SlcTypes
.SLC_EXECUTION_SPEC_ATTRIBUTE
))
672 specAttributes
.add(specAttrNode
);
674 return specAttributes
.toArray();
675 } catch (RepositoryException e
) {
676 throw new SlcException("Cannot get elements", e
);
680 public void dispose() {
683 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
687 class ValuesEditingSupport
extends EditingSupport
{
688 private final TableViewer tableViewer
;
690 public ValuesEditingSupport(ColumnViewer viewer
) {
692 tableViewer
= (TableViewer
) viewer
;
696 protected CellEditor
getCellEditor(Object element
) {
698 Node specAttrNode
= (Node
) element
;
700 .isNodeType(SlcTypes
.SLC_PRIMITIVE_SPEC_ATTRIBUTE
)) {
701 return new TextCellEditor(tableViewer
.getTable());
702 } else if (specAttrNode
703 .isNodeType(SlcTypes
.SLC_REF_SPEC_ATTRIBUTE
)) {
704 NodeIterator children
= specAttrNode
.getNodes();
705 ArrayList
<String
> items
= new ArrayList
<String
>();
706 while (children
.hasNext()) {
707 Node child
= children
.nextNode();
708 if (child
.isNodeType(NodeType
.MIX_TITLE
))
709 items
.add(child
.getProperty(Property
.JCR_TITLE
)
712 return new ComboBoxCellEditor(tableViewer
.getTable(),
713 items
.toArray(new String
[items
.size()]));
716 } catch (RepositoryException e
) {
717 throw new SlcException("Cannot get celle editor", e
);
722 protected boolean canEdit(Object element
) {
724 Node specAttrNode
= (Node
) element
;
725 return !(specAttrNode
.getProperty(SLC_IS_IMMUTABLE
)
726 .getBoolean() || specAttrNode
.getProperty(
727 SLC_IS_CONSTANT
).getBoolean())
728 && isSupportedAttributeType(specAttrNode
);
729 } catch (RepositoryException e
) {
730 throw new SlcException("Cannot check whether " + element
731 + " is editable", e
);
736 * Supports {@link SlcTypes#SLC_PRIMITIVE_SPEC_ATTRIBUTE} and
737 * {@link SlcTypes#SLC_REF_SPEC_ATTRIBUTE}
739 protected boolean isSupportedAttributeType(Node specAttrNode
)
740 throws RepositoryException
{
742 .isNodeType(SlcTypes
.SLC_PRIMITIVE_SPEC_ATTRIBUTE
)
743 || specAttrNode
.isNodeType(SlcTypes
.SLC_REF_SPEC_ATTRIBUTE
);
747 protected Object
getValue(Object element
) {
748 Node specAttrNode
= (Node
) element
;
750 // Object value = getAttributeSpecValue(specAttrNode);
751 // if (value == null)
752 // throw new SlcException("Unsupported attribute " + element);
754 .isNodeType(SlcTypes
.SLC_PRIMITIVE_SPEC_ATTRIBUTE
)) {
755 if (!specAttrNode
.hasProperty(SLC_VALUE
))
757 String type
= specAttrNode
.getProperty(SLC_TYPE
)
759 // TODO optimize based on data type?
760 Object value
= PrimitiveUtils
.convert(type
, specAttrNode
761 .getProperty(SLC_VALUE
).getString());
762 return value
.toString();
763 } else if (specAttrNode
764 .isNodeType(SlcTypes
.SLC_REF_SPEC_ATTRIBUTE
)) {
765 if (!specAttrNode
.hasProperty(SLC_VALUE
))
767 // return the index of the sub node as set by setValue()
768 // in the future we may manage references as well
769 return (int) specAttrNode
.getProperty(SLC_VALUE
).getLong();
771 throw new SlcException("Unsupported type for spec attribute "
773 } catch (RepositoryException e
) {
774 throw new SlcException("Cannot get value for " + element
, e
);
779 protected void setValue(Object element
, Object value
) {
781 Node specAttrNode
= (Node
) element
;
783 .isNodeType(SlcTypes
.SLC_PRIMITIVE_SPEC_ATTRIBUTE
)) {
784 String type
= specAttrNode
.getProperty(SLC_TYPE
)
786 SlcJcrUtils
.setPrimitiveAsProperty(specAttrNode
, SLC_VALUE
,
788 valuesViewer
.refresh();
789 formPart
.markDirty();
790 } else if (specAttrNode
791 .isNodeType(SlcTypes
.SLC_REF_SPEC_ATTRIBUTE
)) {
792 specAttrNode
.setProperty(SLC_VALUE
,
793 ((Integer
) value
).longValue());
794 valuesViewer
.refresh();
795 formPart
.markDirty();
797 } catch (RepositoryException e
) {
798 throw new SlcException("Cannot get celle editor", e
);