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=b46b2f1b095e4d418dd62964be031e9a9b97b6de;hb=8908d07cc1fd6ac0a274c460bbd40652816ca054;hp=f5e8708aed17483f9a984a1d73bb9ebefca3b317;hpb=eef4888d3214ab92c5df3768d08c3e26269cc429;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 f5e8708ae..b46b2f1b0 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 @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Mathieu Baudier + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.argeo.slc.client.ui.editors; import java.util.ArrayList; @@ -5,16 +20,13 @@ import java.util.Iterator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; -import java.util.UUID; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Property; import javax.jcr.RepositoryException; -import javax.jcr.Session; 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; @@ -33,6 +45,7 @@ import org.argeo.slc.jcr.SlcTypes; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; @@ -64,19 +77,21 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; 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; +/** 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); + /** To be displayed in empty lists */ + final static String NONE = ""; + private Node processNode; private TreeViewer flowsViewer; @@ -115,7 +130,7 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { // observation statusObserver = new AsyncUiEventListener(form.getDisplay()) { - protected void onEventInUiThread(EventIterator events) { + protected void onEventInUiThread(List events) { statusChanged(); } }; @@ -125,6 +140,9 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { Event.PROPERTY_CHANGED, processNode.getPath(), true, null, null, false); + // make sure all controls are in line with status + statusChanged(); + // add initial flows addInitialFlows(); @@ -146,7 +164,9 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { run.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (isFinished(getProcessStatus())) { - relaunch(); + ((ProcessEditor) getEditor()).relaunch(); + } else if (isRunning(getProcessStatus())) { + ((ProcessEditor) getEditor()).kill(); } else { ((ProcessEditor) getEditor()).process(); } @@ -191,8 +211,6 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { statusComposite.setLayout(new FillLayout()); statusLabel = tk.createLabel(statusComposite, getProcessStatus()); - // make sure all controls are in line with status - statusChanged(); } protected void createBuilder(Composite parent) { @@ -259,8 +277,7 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { } else if (i == 1) { column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { - Object obj = getAttributeSpecValue((Node) element); - return obj != null ? obj.toString() : ""; + return getAttributeSpecText((Node) element); } }); column.setEditingSupport(new ValuesEditingSupport(viewer)); @@ -279,59 +296,27 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { /* * CONTROLLERS */ - /** Opens a new editor with a copy of this process */ - protected void relaunch() { - try { - Node duplicatedNode = duplicateProcess(); - IWorkbenchPage activePage = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage(); - activePage.openEditor( - new ProcessEditorInput(duplicatedNode.getPath()), - ProcessEditor.ID); - getEditor().close(false); - } catch (Exception e1) { - throw new SlcException("Cannot relaunch " + processNode, e1); - } - } - - /** Duplicates the process */ - protected Node duplicateProcess() { - try { - Session session = processNode.getSession(); - String uuid = UUID.randomUUID().toString(); - String destPath = SlcJcrUtils.createExecutionProcessPath(uuid); - Node newNode = JcrUtils.mkdirs(session, destPath, - SlcTypes.SLC_PROCESS); - JcrUtils.copy(processNode, newNode); - // session.getWorkspace().copy(processNode.getPath(), destPath); - // Node newNode = session.getNode(destPath); - // make sure that we kept the mixins - // newNode.addMixin(NodeType.MIX_CREATED); - // newNode.addMixin(NodeType.MIX_LAST_MODIFIED); - newNode.setProperty(SLC_UUID, uuid); - newNode.setProperty(SLC_STATUS, ExecutionProcess.INITIALIZED); - session.save(); - return newNode; - } catch (RepositoryException e) { - throw new SlcException("Cannot duplicate process", e); - } - } - /** Reflects a status change */ protected void statusChanged() { String status = getProcessStatus(); statusLabel.setText(status); Boolean isEditable = isEditable(status); - run.setEnabled(isEditable); + run.setEnabled(status.equals(ExecutionProcess.RUNNING) || isEditable); remove.setEnabled(isEditable); clear.setEnabled(isEditable); // flowsViewer.getTree().setEnabled(isEditable); - if (status.equals(ExecutionProcess.COMPLETED) - || status.equals(ExecutionProcess.ERROR)) { + 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 */ @@ -381,7 +366,7 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { .getName()); JcrUtils.copy(specAttrNode, realizedAttrNode); - // ovveride with flow value + // override with flow value if (flowNode.hasNode(attrName)) { // assuming this is a primitive realizedAttrNode.setProperty(SLC_VALUE, @@ -448,14 +433,19 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { } /** Optimization so that we don't call the node each time */ - protected Boolean isEditable(String status) { + protected static Boolean isEditable(String status) { return status.equals(ExecutionProcess.NEW) || status.equals(ExecutionProcess.INITIALIZED); } - protected Boolean isFinished(String status) { + protected static Boolean isFinished(String status) { return status.equals(ExecutionProcess.COMPLETED) - || status.equals(ExecutionProcess.ERROR); + || status.equals(ExecutionProcess.ERROR) + || status.equals(ExecutionProcess.KILLED); + } + + protected static Boolean isRunning(String status) { + return status.equals(ExecutionProcess.RUNNING); } /* @@ -470,24 +460,65 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { /* * UTILITIES */ - protected static Object getAttributeSpecValue(Node specAttrNode) { + // 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; + // } else if (specAttrNode.isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) { + // if (specAttrNode.hasNode(SLC_VALUE)) { + // // return the index of the sub node + // // in the future we may manage reference as well + // return specAttrNode.getProperty(SLC_VALUE).getLong(); + // } else + // return null; + // } + // return null; + // } catch (RepositoryException e) { + // throw new SlcException("Cannot get value", e); + // } + // + // } + + protected static String getAttributeSpecText(Node specAttrNode) { try { if (specAttrNode.isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) { if (!specAttrNode.hasProperty(SLC_VALUE)) - return null; + return ""; 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 value.toString(); + } else if (specAttrNode.isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) { + if (specAttrNode.hasProperty(SLC_VALUE)) { + int value = (int) specAttrNode.getProperty(SLC_VALUE) + .getLong(); + NodeIterator children = specAttrNode.getNodes(); + int index = 0; + while (children.hasNext()) { + Node child = children.nextNode(); + if (index == value) + return child.getProperty(Property.JCR_TITLE) + .getString(); + index++; + } + throw new SlcException("No child node with index " + value + + " for spec attribute " + specAttrNode); + } else + return ""; } - return null; + throw new SlcException("Unsupported type for spec attribute " + + specAttrNode); } catch (RepositoryException e) { throw new SlcException("Cannot get value", e); } - } /* @@ -556,6 +587,18 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { Node node = (Node) element; try { 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) { @@ -669,8 +712,21 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { try { Node specAttrNode = (Node) element; if (specAttrNode - .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) { return new TextCellEditor(tableViewer.getTable()); + } else if (specAttrNode + .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) { + NodeIterator children = specAttrNode.getNodes(); + ArrayList items = new ArrayList(); + while (children.hasNext()) { + Node child = children.nextNode(); + if (child.isNodeType(NodeType.MIX_TITLE)) + items.add(child.getProperty(Property.JCR_TITLE) + .getString()); + } + return new ComboBoxCellEditor(tableViewer.getTable(), + items.toArray(new String[items.size()])); + } return null; } catch (RepositoryException e) { throw new SlcException("Cannot get celle editor", e); @@ -684,24 +740,51 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { return !(specAttrNode.getProperty(SLC_IS_IMMUTABLE) .getBoolean() || specAttrNode.getProperty( SLC_IS_CONSTANT).getBoolean()) - && specAttrNode - .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE); + && isSupportedAttributeType(specAttrNode); } catch (RepositoryException e) { - throw new SlcException("Cannot check canEdit", e); + throw new SlcException("Cannot check whether " + element + + " is editable", e); } } + /** + * Supports {@link SlcTypes#SLC_PRIMITIVE_SPEC_ATTRIBUTE} and + * {@link SlcTypes#SLC_REF_SPEC_ATTRIBUTE} + */ + protected boolean isSupportedAttributeType(Node specAttrNode) + throws RepositoryException { + return specAttrNode + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE) + || specAttrNode.isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE); + } + @Override protected Object getValue(Object element) { Node specAttrNode = (Node) element; try { - Object value = getAttributeSpecValue(specAttrNode); - if (value == null) - throw new SlcException("Unsupported attribute " + element); + // Object value = getAttributeSpecValue(specAttrNode); + // if (value == null) + // throw new SlcException("Unsupported attribute " + element); if (specAttrNode - .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) + .isNodeType(SlcTypes.SLC_PRIMITIVE_SPEC_ATTRIBUTE)) { + if (!specAttrNode.hasProperty(SLC_VALUE)) + return NONE; + String type = specAttrNode.getProperty(SLC_TYPE) + .getString(); + // TODO optimize based on data type? + Object value = PrimitiveUtils.convert(type, specAttrNode + .getProperty(SLC_VALUE).getString()); return value.toString(); - return value; + } else if (specAttrNode + .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) { + if (!specAttrNode.hasProperty(SLC_VALUE)) + return 0; + // return the index of the sub node as set by setValue() + // in the future we may manage references as well + return (int) specAttrNode.getProperty(SLC_VALUE).getLong(); + } + throw new SlcException("Unsupported type for spec attribute " + + specAttrNode); } catch (RepositoryException e) { throw new SlcException("Cannot get value for " + element, e); } @@ -719,6 +802,12 @@ public class ProcessBuilderPage extends FormPage implements SlcNames { type, value); valuesViewer.refresh(); formPart.markDirty(); + } else if (specAttrNode + .isNodeType(SlcTypes.SLC_REF_SPEC_ATTRIBUTE)) { + specAttrNode.setProperty(SLC_VALUE, + ((Integer) value).longValue()); + valuesViewer.refresh(); + formPart.markDirty(); } } catch (RepositoryException e) { throw new SlcException("Cannot get celle editor", e);