X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=eclipse%2Fplugins%2Forg.argeo.slc.client.ui%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fclient%2Fui%2Feditors%2FProcessBuilderPage.java;h=28c2f69c611a6bd485256a70f055f1759a5cc287;hb=f48476cba243066d5797b8073c15d6ab6842eb6a;hp=6a0e2652a941d4f9f397f7a6090ec751eae1f4f1;hpb=a181e3d059185a9dc108e81f38c66f48f4e4aac8;p=gpl%2Fargeo-slc.git diff --git a/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java b/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java index 6a0e2652a..28c2f69c6 100644 --- a/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java +++ b/eclipse/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/editors/ProcessBuilderPage.java @@ -3,6 +3,8 @@ package org.argeo.slc.client.ui.editors; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -10,26 +12,34 @@ import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.nodetype.NodeType; import javax.jcr.observation.Event; -import javax.jcr.observation.EventIterator; import javax.jcr.observation.EventListener; import javax.jcr.observation.ObservationManager; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; +import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; import org.argeo.slc.client.ui.SlcImages; +import org.argeo.slc.core.execution.PrimitiveUtils; import org.argeo.slc.execution.ExecutionProcess; import org.argeo.slc.jcr.SlcJcrUtils; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; -import org.argeo.slc.process.RealizedFlow; +import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerDropAdapter; @@ -45,40 +55,47 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.PlatformUI; +import org.eclipse.swt.widgets.Table; import org.eclipse.ui.forms.AbstractFormPart; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; -public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { +/** Definition of the process. */ +public class ProcessBuilderPage extends FormPage implements SlcNames { public final static String ID = "processBuilderPage"; - private final static Log log = LogFactory.getLog(ProcessBuilderPage.class); + // private final static Log log = + // LogFactory.getLog(ProcessBuilderPage.class); private Node processNode; private TreeViewer flowsViewer; - private Label status; + private TableViewer valuesViewer; + private Label statusLabel; + private Button run; + private Button remove; + private Button clear; private AbstractFormPart formPart; - private StatusObserver statusObserver; + private EventListener statusObserver; public ProcessBuilderPage(ProcessEditor editor, Node processNode) { super(editor, ID, "Definition"); this.processNode = processNode; - } @Override protected void createFormContent(IManagedForm mf) { try { ScrolledForm form = mf.getForm(); + form.setExpandHorizontal(true); + form.setExpandVertical(true); form.setText("Process " + processNode.getName()); GridLayout mainLayout = new GridLayout(1, true); form.getBody().setLayout(mainLayout); @@ -91,17 +108,25 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { }; getManagedForm().addPart(formPart); - if (getProcessStatus().equals(ExecutionProcess.UNINITIALIZED)) - formPart.markDirty(); // observation - statusObserver = new StatusObserver(); + statusObserver = new AsyncUiEventListener(form.getDisplay()) { + protected void onEventInUiThread(List events) { + statusChanged(); + } + }; ObservationManager observationManager = processNode.getSession() .getWorkspace().getObservationManager(); observationManager.addEventListener(statusObserver, Event.PROPERTY_CHANGED, processNode.getPath(), true, null, null, false); + // make sure all controls are in line with status + statusChanged(); + + // add initial flows + addInitialFlows(); + } catch (RepositoryException e) { throw new ArgeoException("Cannot create form content", e); } @@ -114,12 +139,18 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { controls.setLayout(new RowLayout()); controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - Button run = tk.createButton(controls, null, SWT.PUSH); + run = tk.createButton(controls, null, SWT.PUSH); run.setToolTipText("Run"); run.setImage(SlcImages.LAUNCH); run.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { - ((ProcessEditor) getEditor()).process(); + if (isFinished(getProcessStatus())) { + ((ProcessEditor) getEditor()).relaunch(); + } else if (isRunning(getProcessStatus())) { + ((ProcessEditor) getEditor()).kill(); + } else { + ((ProcessEditor) getEditor()).process(); + } } public void widgetDefaultSelected(SelectionEvent e) { @@ -127,7 +158,7 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } }); - Button remove = tk.createButton(controls, null, SWT.PUSH); + remove = tk.createButton(controls, null, SWT.PUSH); remove.setImage(SlcImages.REMOVE_ONE); remove.setToolTipText("Remove selected flows"); remove.addSelectionListener(new SelectionListener() { @@ -140,7 +171,7 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } }); - Button clear = tk.createButton(controls, null, SWT.PUSH); + clear = tk.createButton(controls, null, SWT.PUSH); clear.setImage(SlcImages.REMOVE_ALL); clear.setToolTipText("Clear all flows"); clear.addSelectionListener(new SelectionListener() { @@ -153,62 +184,179 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } }); - status = tk.createLabel(controls, getProcessStatus()); - } + Composite statusComposite = tk.createComposite(controls); + RowData rowData = new RowData(); + rowData.width = 100; + rowData.height = 16; + statusComposite.setLayoutData(rowData); + statusComposite.setLayout(new FillLayout()); + statusLabel = tk.createLabel(statusComposite, getProcessStatus()); - protected String getProcessStatus() { - try { - return processNode.getProperty(SLC_STATUS).getString(); - } catch (RepositoryException e) { - throw new SlcException("Cannot retrieve status for " + processNode, - e); - } } protected void createBuilder(Composite parent) { FormToolkit tk = getManagedForm().getToolkit(); SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL); sashForm.setSashWidth(4); - sashForm.setLayout(new FillLayout()); - sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridData sahFormGd = new GridData(SWT.FILL, SWT.FILL, true, true); + sahFormGd.widthHint = 400; + sashForm.setLayoutData(sahFormGd); - Composite top = tk.createComposite(sashForm); - GridLayout gl = new GridLayout(1, false); - top.setLayout(gl); + Composite flowsComposite = tk.createComposite(sashForm); + flowsComposite.setLayout(new GridLayout(1, false)); - flowsViewer = new TreeViewer(top); + flowsViewer = new TreeViewer(flowsComposite); flowsViewer.getTree().setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true)); - flowsViewer.setLabelProvider(new ViewLabelProvider()); - flowsViewer.setContentProvider(new ViewContentProvider()); - flowsViewer.addSelectionChangedListener(new SelectionChangedListener()); + flowsViewer.setLabelProvider(new FlowsLabelProvider()); + flowsViewer.setContentProvider(new FlowsContentProvider()); + flowsViewer.addSelectionChangedListener(new FlowsSelectionListener()); int operations = DND.DROP_COPY | DND.DROP_MOVE; Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; - flowsViewer.addDropSupport(operations, tt, new ViewDropListener( + flowsViewer.addDropSupport(operations, tt, new FlowsDropListener( flowsViewer)); flowsViewer.setInput(getEditorSite()); flowsViewer.setInput(processNode); - Composite bottom = tk.createComposite(sashForm); - bottom.setLayout(new GridLayout(1, false)); + Composite valuesComposite = tk.createComposite(sashForm); + valuesComposite.setLayout(new GridLayout(1, false)); + + valuesViewer = new TableViewer(valuesComposite); + GridData valuedGd = new GridData(SWT.FILL, SWT.FILL, true, true); + // valuedGd.widthHint = 200; + valuesViewer.getTable().setLayoutData(valuedGd); + valuesViewer.setContentProvider(new ValuesContentProvider()); + initializeValuesViewer(valuesViewer); sashForm.setWeights(getWeights()); + valuesViewer.setInput(getEditorSite()); + } + + /** Creates the columns of the values viewer */ + protected void initializeValuesViewer(TableViewer viewer) { + String[] titles = { "Name", "Value" }; + int[] bounds = { 200, 100 }; + + for (int i = 0; i < titles.length; i++) { + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setText(titles[i]); + column.getColumn().setWidth(bounds[i]); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(true); + if (i == 0) { + column.setLabelProvider(new ColumnLabelProvider() { + public String getText(Object element) { + try { + Node specAttrNode = (Node) element; + return specAttrNode.getName(); + } catch (RepositoryException e) { + throw new SlcException("Cannot get value", e); + } + } + }); + } else if (i == 1) { + column.setLabelProvider(new ColumnLabelProvider() { + public String getText(Object element) { + Object obj = getAttributeSpecValue((Node) element); + return obj != null ? obj.toString() : ""; + } + }); + column.setEditingSupport(new ValuesEditingSupport(viewer)); + } + + } + Table table = viewer.getTable(); + table.setHeaderVisible(false); + table.setLinesVisible(true); } protected int[] getWeights() { - return new int[] { 70, 30 }; + return new int[] { 50, 50 }; } /* * CONTROLLERS */ + /** Reflects a status change */ + protected void statusChanged() { + String status = getProcessStatus(); + statusLabel.setText(status); + Boolean isEditable = isEditable(status); + run.setEnabled(status.equals(ExecutionProcess.RUNNING) || isEditable); + remove.setEnabled(isEditable); + clear.setEnabled(isEditable); + // flowsViewer.getTree().setEnabled(isEditable); + if (status.equals(ExecutionProcess.RUNNING)) { + run.setEnabled(true); + run.setImage(SlcImages.KILL); + run.setToolTipText("Kill"); + } else if (isFinished(status)) { + run.setEnabled(true); + run.setImage(SlcImages.RELAUNCH); + run.setToolTipText("Relaunch"); + } + + if (flowsViewer != null) + flowsViewer.refresh(); + } + + /** Adds initial flows from the editor input if any */ + protected void addInitialFlows() { + for (String path : ((ProcessEditorInput) getEditorInput()) + .getInitialFlowPaths()) { + addFlow(path); + } + } + + /** + * Adds a new flow. + * + * @param path + * the path of the flow + */ protected void addFlow(String path) { try { - Node flowNode = processNode.getNode(SLC_FLOW).addNode(SLC_FLOW); - flowNode.addMixin(SLC_REALIZED_FLOW); - Node address = flowNode.addNode(SLC_ADDRESS, NodeType.NT_ADDRESS); + Node flowNode = processNode.getSession().getNode(path); + Node realizedFlowNode = processNode.getNode(SLC_FLOW).addNode( + SLC_FLOW); + realizedFlowNode.addMixin(SlcTypes.SLC_REALIZED_FLOW); + Node address = realizedFlowNode.addNode(SLC_ADDRESS, + NodeType.NT_ADDRESS); address.setProperty(Property.JCR_PATH, path); + + // copy spec attributes + Node specAttrsBase; + if (flowNode.hasProperty(SLC_SPEC)) { + Node executionSpecNode = flowNode.getProperty(SLC_SPEC) + .getNode(); + specAttrsBase = executionSpecNode; + String executionSpecName = executionSpecNode.getProperty( + SLC_NAME).getString(); + realizedFlowNode.setProperty(SLC_SPEC, executionSpecName); + } else + specAttrsBase = flowNode; + + specAttrs: for (NodeIterator nit = specAttrsBase.getNodes(); nit + .hasNext();) { + Node specAttrNode = nit.nextNode(); + String attrName = specAttrNode.getName(); + if (!specAttrNode + .isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE)) + continue specAttrs; + Node realizedAttrNode = realizedFlowNode.addNode(specAttrNode + .getName()); + JcrUtils.copy(specAttrNode, realizedAttrNode); + + // ovveride with flow value + if (flowNode.hasNode(attrName)) { + // assuming this is a primitive + realizedAttrNode.setProperty(SLC_VALUE, + flowNode.getNode(attrName).getProperty(SLC_VALUE) + .getValue()); + } + } + flowsViewer.refresh(); formPart.markDirty(); } catch (RepositoryException e) { @@ -249,35 +397,75 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } public void commit(Boolean onSave) { + if (onSave) + statusLabel.setText(getProcessStatus()); formPart.commit(onSave); } - @Override - public void setFocus() { - flowsViewer.getTree().setFocus(); + /* + * STATE + */ + protected String getProcessStatus() { + try { + return processNode.getProperty(SLC_STATUS).getString(); + } catch (RepositoryException e) { + throw new SlcException("Cannot retrieve status for " + processNode, + e); + } + } + + /** Optimization so that we don't call the node each time */ + protected static Boolean isEditable(String status) { + return status.equals(ExecutionProcess.NEW) + || status.equals(ExecutionProcess.INITIALIZED); + } + + protected static Boolean isFinished(String status) { + return status.equals(ExecutionProcess.COMPLETED) + || status.equals(ExecutionProcess.ERROR) + || status.equals(ExecutionProcess.KILLED); + } + + protected static Boolean isRunning(String status) { + return status.equals(ExecutionProcess.RUNNING); } + /* + * LIFECYCLE + */ @Override public void dispose() { - try { - if (statusObserver != null) { - processNode.getSession().getWorkspace().getObservationManager() - .removeEventListener(statusObserver); - } - } catch (Exception e) { - log.error("Cannot dispose observer for " + processNode + ": " + e); - } + JcrUtils.unregisterQuietly(processNode, statusObserver); super.dispose(); } - // Specific Providers for the current view. - protected class ViewContentProvider implements ITreeContentProvider { - public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + /* + * UTILITIES + */ + protected static Object getAttributeSpecValue(Node specAttrNode) { + try { + if (specAttrNode.isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) { + if (!specAttrNode.hasProperty(SLC_VALUE)) + return null; + String type = specAttrNode.getProperty(SLC_TYPE).getString(); + // TODO optimize based on data type? + Object value = PrimitiveUtils.convert(type, specAttrNode + .getProperty(SLC_VALUE).getString()); + // log.debug(specAttrNode + ", type=" + type + ", value=" + + // value); + return value; + } + return null; + } catch (RepositoryException e) { + throw new SlcException("Cannot get value", e); } - public void dispose() { - } + } + /* + * FLOWS SUBCLASSES + */ + static class FlowsContentProvider implements ITreeContentProvider { public Object[] getElements(Object obj) { if (!(obj instanceof Node)) return new Object[0]; @@ -294,7 +482,14 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } } + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + public Object[] getChildren(Object parentElement) { + // no children for the time being return null; } @@ -308,13 +503,13 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } - protected class ViewLabelProvider extends ColumnLabelProvider { + static class FlowsLabelProvider extends ColumnLabelProvider { @Override public String getText(Object element) { Node node = (Node) element; try { - if (node.isNodeType(SLC_REALIZED_FLOW)) { + if (node.isNodeType(SlcTypes.SLC_REALIZED_FLOW)) { if (node.hasNode(SLC_ADDRESS)) { String path = node.getNode(SLC_ADDRESS) .getProperty(Property.JCR_PATH).getString(); @@ -332,7 +527,19 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { public Image getImage(Object element) { Node node = (Node) element; try { - if (node.isNodeType(SLC_REALIZED_FLOW)) { + if (node.isNodeType(SlcTypes.SLC_REALIZED_FLOW)) { + if (node.hasProperty(SLC_STATUS)) { + String status = node.getProperty(SLC_STATUS) + .getString(); + // TODO: factorize with process view ? + if (status.equals(ExecutionProcess.RUNNING)) + return SlcImages.PROCESS_RUNNING; + else if (status.equals(ExecutionProcess.ERROR) + || status.equals(ExecutionProcess.KILLED)) + return SlcImages.PROCESS_ERROR; + else if (status.equals(ExecutionProcess.COMPLETED)) + return SlcImages.PROCESS_COMPLETED; + } return SlcImages.FLOW; } } catch (RepositoryException e) { @@ -343,52 +550,163 @@ public class ProcessBuilderPage extends FormPage implements SlcNames, SlcTypes { } - // Parameter view is updated each time a new line is selected - class SelectionChangedListener implements ISelectionChangedListener { + /** Parameter view is updated each time a new line is selected */ + class FlowsSelectionListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent evt) { - - IStructuredSelection curSelection = (IStructuredSelection) evt - .getSelection(); - Object obj = curSelection.getFirstElement(); - - if (obj instanceof RealizedFlow) { - // RealizedFlow rf = (RealizedFlow) obj; - // curSelectedRow = realizedFlows.indexOf(rf); - // refreshParameterview(); - // setFocus(); + if (evt.getSelection().isEmpty()) { + valuesViewer.setInput(getEditorSite()); + return; } + Node realizedFlowNode = (Node) ((IStructuredSelection) evt + .getSelection()).getFirstElement(); + valuesViewer.setInput(realizedFlowNode); } } - protected class ViewDropListener extends ViewerDropAdapter { + /** Manages drop event. */ + class FlowsDropListener extends ViewerDropAdapter { - public ViewDropListener(Viewer viewer) { + public FlowsDropListener(Viewer viewer) { super(viewer); } @Override public boolean performDrop(Object data) { String path = data.toString(); - addFlow(path); - return true; + try { + // either a node or a whole directory was dragged + QueryManager qm = processNode.getSession().getWorkspace() + .getQueryManager(); + String statement = "SELECT * FROM [" + + SlcTypes.SLC_EXECUTION_FLOW + + "] WHERE ISDESCENDANTNODE(['" + path + + "']) OR ISSAMENODE(['" + path + "'])"; + // log.debug(statement); + Query query = qm.createQuery(statement, Query.JCR_SQL2); + + // order paths + SortedSet paths = new TreeSet(); + for (NodeIterator nit = query.execute().getNodes(); nit + .hasNext();) { + paths.add(nit.nextNode().getPath()); + } + + for (String p : paths) { + addFlow(p); + } + return true; + } catch (RepositoryException e) { + throw new SlcException("Cannot query flows under " + path, e); + } } @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { - return true; + return isEditable(getProcessStatus()); + } + } + + /* + * VALUES SUBCLASSES + */ + static class ValuesContentProvider implements IStructuredContentProvider { + + public Object[] getElements(Object inputElement) { + if (!(inputElement instanceof Node)) + return new Object[0]; + + try { + Node realizedFlowNode = (Node) inputElement; + List specAttributes = new ArrayList(); + specAttrs: for (NodeIterator nit = realizedFlowNode.getNodes(); nit + .hasNext();) { + Node specAttrNode = nit.nextNode(); + if (!specAttrNode + .isNodeType(SlcTypes.SLC_EXECUTION_SPEC_ATTRIBUTE)) + continue specAttrs; + specAttributes.add(specAttrNode); + } + return specAttributes.toArray(); + } catch (RepositoryException e) { + throw new SlcException("Cannot get elements", e); + } + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } - class StatusObserver implements EventListener { + class ValuesEditingSupport extends EditingSupport { + private final TableViewer tableViewer; + + public ValuesEditingSupport(ColumnViewer viewer) { + super(viewer); + tableViewer = (TableViewer) viewer; + } + + @Override + protected CellEditor getCellEditor(Object element) { + try { + Node specAttrNode = (Node) element; + if (specAttrNode + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) + return new TextCellEditor(tableViewer.getTable()); + return null; + } catch (RepositoryException e) { + throw new SlcException("Cannot get celle editor", e); + } + } + + @Override + protected boolean canEdit(Object element) { + try { + Node specAttrNode = (Node) element; + return !(specAttrNode.getProperty(SLC_IS_IMMUTABLE) + .getBoolean() || specAttrNode.getProperty( + SLC_IS_CONSTANT).getBoolean()) + && specAttrNode + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE); + } catch (RepositoryException e) { + throw new SlcException("Cannot check canEdit", e); + } + } + + @Override + protected Object getValue(Object element) { + Node specAttrNode = (Node) element; + try { + Object value = getAttributeSpecValue(specAttrNode); + if (value == null) + throw new SlcException("Unsupported attribute " + element); + if (specAttrNode + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) + return value.toString(); + return value; + } catch (RepositoryException e) { + throw new SlcException("Cannot get value for " + element, e); + } + } - public void onEvent(EventIterator events) { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - public void run() { - status.setText(getProcessStatus()); + @Override + protected void setValue(Object element, Object value) { + try { + Node specAttrNode = (Node) element; + if (specAttrNode + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) { + String type = specAttrNode.getProperty(SLC_TYPE) + .getString(); + SlcJcrUtils.setPrimitiveAsProperty(specAttrNode, SLC_VALUE, + type, value); + valuesViewer.refresh(); + formPart.markDirty(); } - }); - // flowsViewer.refresh(); + } catch (RepositoryException e) { + throw new SlcException("Cannot get celle editor", e); + } } }