package com.c2kernel.gui.tabs; import java.awt.Cursor; import java.awt.GridBagConstraints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JSplitPane; import com.c2kernel.entity.proxy.EntityProxyObserver; import com.c2kernel.entity.proxy.ItemProxy; import com.c2kernel.entity.proxy.MemberSubscription; import com.c2kernel.graph.layout.DefaultGraphLayoutGenerator; import com.c2kernel.graph.model.EdgeFactory; import com.c2kernel.graph.model.VertexFactory; import com.c2kernel.gui.ImageLoader; import com.c2kernel.gui.MainFrame; import com.c2kernel.gui.graph.controller.Selection; import com.c2kernel.gui.graph.view.EditorPanel; import com.c2kernel.gui.graph.view.VertexPropertyPanel; import com.c2kernel.gui.lifecycle.instance.TransitionPanel; import com.c2kernel.gui.lifecycle.instance.WfDirectedEdgeRenderer; import com.c2kernel.gui.lifecycle.instance.WfEdgeFactory; import com.c2kernel.gui.lifecycle.instance.WfGraphPanel; import com.c2kernel.gui.lifecycle.instance.WfVertexFactory; import com.c2kernel.gui.lifecycle.instance.WfVertexRenderer; import com.c2kernel.lifecycle.instance.CompositeActivity; import com.c2kernel.lifecycle.instance.WfVertexOutlineCreator; import com.c2kernel.lifecycle.instance.Workflow; import com.c2kernel.persistency.ClusterStorage; import com.c2kernel.process.Gateway; import com.c2kernel.utils.CastorXMLUtility; import com.c2kernel.utils.FileStringUtility; import com.c2kernel.utils.Language; import com.c2kernel.utils.Logger; public class WorkflowPane extends EntityTabPane implements EntityProxyObserver { // Only for the purpose of loading and saving protected Workflow mWorkflow = null; boolean init = false; TransitionPanel transPanel; protected JButton mLoadButton = new JButton(ImageLoader.findImage("graph/load.png")); protected JButton mSaveButton = new JButton(ImageLoader.findImage("graph/save.png")); protected JButton mLayoutButton = new JButton(ImageLoader.findImage("graph/autolayout.png")); protected JButton mZoomOutButton = new JButton(ImageLoader.findImage("graph/zoomout.png")); protected JButton[] mOtherToolBarButtons; // Workflow factories protected EdgeFactory mWfEdgeFactory; protected VertexFactory mWfVertexFactory; // Graph editor panel protected EditorPanel mEditorPanel; // Objects to view/modify the properties of the selected activity protected VertexPropertyPanel mPropertyPanel; protected JSplitPane mSplitPane; // Graph editor panel // Objects to view/modify the properties of the selected activity public WorkflowPane() { super("Workflow", "Workflow Viewer"); // Workflow factories mWfEdgeFactory = new WfEdgeFactory(); mWfVertexFactory = new WfVertexFactory(); mZoomOutButton.setToolTipText(Language.translate("Zoom Out")); mLayoutButton.setToolTipText(Language.translate("Auto Layout")); mLoadButton.setToolTipText(Language.translate("Load")); mSaveButton.setToolTipText(Language.translate("Save")); mOtherToolBarButtons = new JButton[] { mZoomOutButton, mLayoutButton, mLoadButton, mSaveButton }; } protected void createListeners() { /** * */ mLoadButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { loadWorkflow(); } }); /** * */ mSaveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { setCursor(new Cursor(Cursor.WAIT_CURSOR)); saveWorkflow(); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } }); /** * */ mLayoutButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { DefaultGraphLayoutGenerator.layoutGraph(mEditorPanel.mGraphModelManager.getModel()); } }); /** * */ mZoomOutButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { mEditorPanel.mGraphModelManager.zoomOut(); } }); } /** * Return a single ref on mEditorPanel * * @return EditorPanel */ public EditorPanel getEditorPanel() { if (mEditorPanel == null) mEditorPanel = new EditorPanel( mWfEdgeFactory, mWfVertexFactory, new WfVertexOutlineCreator(), true, mOtherToolBarButtons, new WfGraphPanel(new WfDirectedEdgeRenderer(), new WfVertexRenderer())); return mEditorPanel; } public JSplitPane getJSplitPane() { if (mSplitPane == null) { mSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, getEditorPanel(), getPropertyPanel()); mSplitPane.setDividerSize(5); mSplitPane.setDividerLocation(800); } return mSplitPane; } @Override public void add(Workflow contents) { mWorkflow = contents; addActivity((CompositeActivity) mWorkflow.search("workflow/domain")); } @Override public void remove(String id) { } protected void addActivity(CompositeActivity cAct) { // Resolve any undefined references in the workflow mEditorPanel.mGraphModelManager.replace(cAct.getChildrenGraphModel()); // Give the editor panel the edge and vertex types mEditorPanel.updateVertexTypes(cAct.getWf().getVertexTypeNameAndConstructionInfo()); mEditorPanel.updateEdgeTypes(cAct.getWf().getEdgeTypeNameAndConstructionInfo()); mEditorPanel.enterSelectMode(); mWfVertexFactory.setCreationContext(cAct); } @Override public void run() { Thread.currentThread().setName("Workflow Pane Builder"); if (!init) { getEditorPanel(); createLayout(); createListeners(); mPropertyPanel.setGraphModelManager(mEditorPanel.mGraphModelManager); mEditorPanel.setEditable(MainFrame.isAdmin); init = true; } sourceEntity.getEntity().subscribe(new MemberSubscription(this, ClusterStorage.LIFECYCLE, true)); transPanel.setItem((ItemProxy) sourceEntity.getEntity()); } @Override public void reload() { Gateway.getStorage().clearCache(sourceEntity.getSysKey(), ClusterStorage.LIFECYCLE); initForEntity(sourceEntity); } protected void createLayout() { initPanel(); // Add the editor pane getGridBagConstraints().gridx = 0; getGridBagConstraints().gridy = 1; getGridBagConstraints().fill = GridBagConstraints.BOTH; getGridBagConstraints().weighty = 2.0; gridbag.setConstraints(getJSplitPane(), getGridBagConstraints()); add(getJSplitPane()); validate(); } protected void loadWorkflow() { File selectedFile = null; int returnValue = MainFrame.xmlChooser.showOpenDialog(null); switch (returnValue) { case JFileChooser.APPROVE_OPTION : selectedFile = MainFrame.xmlChooser.getSelectedFile(); try { String newWf = FileStringUtility.file2String(selectedFile); add((Workflow) CastorXMLUtility.unmarshall(newWf)); } catch (Exception e) { e.printStackTrace(); } case JFileChooser.CANCEL_OPTION : case JFileChooser.ERROR_OPTION : default : } } protected String marshall() throws Exception { return com.c2kernel.utils.CastorXMLUtility.marshall(mWorkflow.getWf()); } protected void saveWorkflow() { try { CompositeActivity cact = (CompositeActivity)mWorkflow.getWf().search("workflow/domain"); MainFrame.userAgent.execute( (ItemProxy)sourceEntity.getEntity(), "ReplaceDomainWorkflow", new String[] { com.c2kernel.utils.CastorXMLUtility.marshall(cact)}); mEditorPanel.mGraphPanel.setSelection(new Selection(null,null,0,0,0,0)); } catch (Exception e) { Logger.error(e); } } public VertexPropertyPanel getPropertyPanel() { if (mPropertyPanel == null) { setNewPropertyPanel(); transPanel = new TransitionPanel(); mPropertyPanel.createLayout(transPanel); mPropertyPanel.setGraphModelManager(mEditorPanel.mGraphModelManager); mPropertyPanel.setEditable(MainFrame.isAdmin); } return mPropertyPanel; } public void setNewPropertyPanel() { String wfPanelClass = Gateway.getProperty("WfPropertyPanel"); if (wfPanelClass != null) { try { Class panelClass = Class.forName(wfPanelClass); mPropertyPanel = (VertexPropertyPanel) panelClass.newInstance(); return; } catch (Exception ex) { Logger.error("Could not load wf props panel:" + wfPanelClass); Logger.error(ex); } } mPropertyPanel = new VertexPropertyPanel(); } @Override public void control(String control, String msg) { // TODO Auto-generated method stub } }