001/** 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: tao $' 006 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 007 * '$Revision: 24730 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.workflowscheduler.gui.configurationwizard; 030 031import java.awt.BorderLayout; 032import java.awt.Cursor; 033import java.awt.Dimension; 034import java.awt.GridBagConstraints; 035import java.awt.GridBagLayout; 036import java.awt.Insets; 037import java.awt.event.ActionEvent; 038import java.awt.event.ActionListener; 039import java.awt.event.WindowAdapter; 040import java.awt.event.WindowEvent; 041import java.util.Vector; 042 043import javax.swing.BorderFactory; 044import javax.swing.Box; 045import javax.swing.BoxLayout; 046import javax.swing.JButton; 047import javax.swing.JDialog; 048import javax.swing.JLabel; 049import javax.swing.JOptionPane; 050import javax.swing.JPanel; 051import javax.swing.JTextField; 052import javax.swing.border.Border; 053import javax.swing.border.EtchedBorder; 054 055import org.kepler.configuration.ConfigurationManagerException; 056import org.kepler.configuration.ConfigurationProperty; 057import org.kepler.configuration.NamespaceException; 058import org.kepler.gui.state.StateChangeEvent; 059import org.kepler.gui.state.StateChangeMonitor; 060import org.kepler.module.workflowschedulergui.Initialize; 061import org.kepler.workflowscheduler.gui.WorkflowRunEngine; 062import org.kepler.workflowscheduler.gui.WorkflowSchedulerPanel; 063 064import ptolemy.actor.gui.TableauFrame; 065import ptolemy.kernel.util.NamedObj; 066 067 068/** 069 * A dialog to configure the workflow run engines. 070 * @author tao 071 * 072 */ 073public class WorkflowRunEngineConfigurationDialog extends JDialog 074{ 075 private static final String TITLE = "Workflow Run Engine Configuration"; 076 private static final String DEFAULTNAME = "The Run Engine Name"; 077 private static final String DEFAULTURL = "http://yourhostname/workflowrunengine/services/KeplerWebService"; 078 public static final String URLAPPENDIX = "?wsdl"; 079 private static final int WIDTH = 800; 080 private static final int HEIGHT = 500; 081 static final int LEADSPACESIZE = 50; // leading space of each row 082 static final int TEXTFIELDSIZE = 600; 083 private TableauFrame parent = null; 084 private GridBagConstraints textFieldConstraint = null; 085 private GridBagConstraints labelConstraint = null; 086 private GridBagConstraints lastConstraint = null; 087 private JTextField nameTextField = null; 088 private JTextField urlTextField = null; 089 private JPanel mainPanel = null; 090 private JPanel addingEnginePanel = null; 091 private KnownWorkflowRunEnginePanel knownRunEnginePanel = null; 092 //private CompletingConfigurationListenerInterface completeListener = null; 093 094 /** 095 * Constructor 096 */ 097 public WorkflowRunEngineConfigurationDialog(TableauFrame parent) 098 { 099 //super(parent); 100 this.parent = parent; 101 //this.completeListener = completeListener; 102 init(); 103 this.pack(); 104 this.setVisible(true); 105 } 106 107 108 /* 109 * Initialize the dialog 110 */ 111 private void init() 112 { 113 setPreferredSize(new Dimension(WIDTH, HEIGHT)); 114 if(parent != null) 115 { 116 setLocation(parent.getLocation()); 117 } 118 setTitle(TITLE); 119 setModal(true); 120 setLayout(new BorderLayout()); 121 addWindowListener(new DialogWindowAdapter(this)); 122 initializeGridBagLayout(); 123 initMainPanel(); 124 initCloseButtonPanel(); 125 } 126 127 /* 128 * Initialize the grid bag layout manager 129 */ 130 private void initializeGridBagLayout() 131 { 132 textFieldConstraint = new GridBagConstraints(); 133 textFieldConstraint.fill = GridBagConstraints.HORIZONTAL; 134 //lastConstraint.anchor = GridBagConstraints.NORTHWEST; 135 // Give the "last" component as much space as possible 136 textFieldConstraint.weightx = 1.0; 137 //textFieldConstraint.gridwidth = GridBagConstraints.RELATIVE; 138 textFieldConstraint.insets = new Insets(4, 4, 4, 4); 139 140 lastConstraint = (GridBagConstraints) textFieldConstraint.clone(); 141 //These still get as much space as possible, but do 142 //not close out a row 143 lastConstraint.gridwidth = GridBagConstraints.REMAINDER; 144 145 // first component (usually it is a label) on each row 146 labelConstraint = (GridBagConstraints) textFieldConstraint.clone(); 147 // Give these as little space as necessary 148 labelConstraint.weightx = 0.0; 149 labelConstraint.gridwidth = 1; 150 151 } 152 153 /* 154 * MainPanel will contain two parts: 155 * 1. AddingEnginePanel - contains text input fields and add button 156 * 2. KnownWorkflowRunEngine panle - displays the known engines. 157 */ 158 private void initMainPanel() 159 { 160 mainPanel = new JPanel(); 161 mainPanel.setLayout(new BorderLayout()); 162 Border compound = BorderFactory.createCompoundBorder( 163 BorderFactory.createEtchedBorder(EtchedBorder.RAISED), 164 BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); 165 compound = BorderFactory.createCompoundBorder( 166 BorderFactory.createEmptyBorder(12, 5, 5, 5), compound); 167 mainPanel.setBorder(compound); 168 initAddingEnginePanel(); 169 mainPanel.add(addingEnginePanel, BorderLayout.CENTER); 170 WorkflowRunEngine[] engineList = getWorkflowRunEngineArrayFromConfig(); 171 knownRunEnginePanel = new KnownWorkflowRunEnginePanel(engineList); 172 mainPanel.add(knownRunEnginePanel, BorderLayout.SOUTH); 173 add(mainPanel, BorderLayout.CENTER); 174 } 175 176 /* 177 * Initialize the panel adding workflow run engine name and url. 178 * It has a panel for two text fields which user can input engine name and url. 179 * It also has a panel for the add button 180 */ 181 private void initAddingEnginePanel() 182 { 183 addingEnginePanel = new JPanel(); 184 addingEnginePanel.setLayout(new BorderLayout()); 185 initNameAndURLInputPanel(); 186 initAddButtonPanel(); 187 } 188 189 private void initNameAndURLInputPanel() 190 { 191 JPanel nameAndURLPanel = new JPanel(); 192 GridBagLayout gridbag = new GridBagLayout(); 193 nameAndURLPanel.setLayout(gridbag); 194 195 //name row 196 WorkflowSchedulerURLConfigurationDialog.addLeadingSpace(nameAndURLPanel, gridbag, labelConstraint); 197 JLabel nameLabel = new JLabel("Name "); 198 WorkflowSchedulerPanel.addComponent(nameAndURLPanel, nameLabel, gridbag, labelConstraint); 199 nameTextField = new JTextField(); 200 nameTextField.setText(DEFAULTNAME); 201 WorkflowSchedulerPanel.addFixWidthComponent(nameAndURLPanel, nameTextField , gridbag, textFieldConstraint); 202 WorkflowSchedulerURLConfigurationDialog.addEndingSpace(nameAndURLPanel, gridbag,lastConstraint); 203 204 //url row 205 WorkflowSchedulerURLConfigurationDialog.addLeadingSpace(nameAndURLPanel, gridbag, labelConstraint); 206 JLabel urlLabel = new JLabel("URL "); 207 WorkflowSchedulerPanel.addComponent(nameAndURLPanel, urlLabel, gridbag, labelConstraint); 208 urlTextField = new JTextField(); 209 urlTextField.setText(DEFAULTURL); 210 WorkflowSchedulerPanel.addFixWidthComponent(nameAndURLPanel, urlTextField , gridbag, textFieldConstraint); 211 WorkflowSchedulerURLConfigurationDialog.addEndingSpace(nameAndURLPanel, gridbag,lastConstraint); 212 213 addingEnginePanel.add(nameAndURLPanel, BorderLayout.CENTER); 214 } 215 216 /* 217 * Initialize the button panel which contains the add button. 218 * This button panel will be added to addingEnginePanel 219 */ 220 private void initAddButtonPanel() 221 { 222 JPanel buttonPanel = new JPanel(); 223 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 224 buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); 225 buttonPanel.add(Box.createHorizontalGlue()); 226 JButton addButton = new JButton("Add"); 227 addButton.setPreferredSize(new Dimension(100, 50)); 228 addButton.addActionListener(new ActionListener() 229 { 230 public void actionPerformed(ActionEvent e) 231 { 232 try 233 { 234 String url = urlTextField.getText(); 235 String name = nameTextField.getText(); 236 String urlWithAppendix = url+URLAPPENDIX; 237 if(WorkflowSchedulerURLConfigurationDialog.openURL(urlWithAppendix)) 238 { 239 if(name != null && !name.trim().equals("")) 240 { 241 WorkflowRunEngine engine = new WorkflowRunEngine(name); 242 engine.setURL(url); 243 addRunEngineToConfig(engine); 244 addEngineToKnownWorkflowRunEnginePanel(engine); 245 246 } 247 else 248 { 249 JOptionPane.showMessageDialog(null, "Workflow Run Engine name couldn't be blank", "Error", JOptionPane.ERROR_MESSAGE); 250 } 251 } 252 253 } 254 catch(Exception ee) 255 { 256 ee.printStackTrace(); 257 JOptionPane.showMessageDialog(null, "Couldn't add the new Run Enginel - "+ee.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 258 } 259 } 260 }); 261 buttonPanel.add(addButton); 262 addingEnginePanel.add(buttonPanel, BorderLayout.SOUTH); 263 } 264 265 /* 266 * Initialize the panel containing the close button which close the dialog(top level) 267 */ 268 private void initCloseButtonPanel() 269 { 270 JPanel buttonPanel = new JPanel(); 271 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 272 buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 273 buttonPanel.add(Box.createHorizontalGlue()); 274 JButton cancelButton = new JButton("Close"); 275 cancelButton.setPreferredSize(new Dimension(100, 50)); 276 cancelButton.addActionListener(new ActionListener() 277 { 278 public void actionPerformed(ActionEvent e) 279 { 280 /*if(completeListener != null) 281 { 282 //System.out.println("calling complete method ....."); 283 completeListener.completeConfiguration(); 284 }*/ 285 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 286 fireConfigChangeEvent(); 287 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 288 dispose(); 289 } 290 }); 291 buttonPanel.add(cancelButton); 292 //buttonPanel.add(Box.createHorizontalStrut(10)); 293 this.add(buttonPanel, BorderLayout.SOUTH); 294 } 295 296 /* 297 * A method will add a workflow run engine to the configuration 298 */ 299 private void addRunEngineToConfig(WorkflowRunEngine engine) throws ConfigurationManagerException, NamespaceException 300 { 301 String newURL = engine.getURL(); 302 String name = engine.getName(); 303 ConfigurationProperty rootProperty = Initialize.getCurrentModuleProperty(); 304 ConfigurationProperty engineListProperty = rootProperty.getProperty(Initialize.WORKFLOWRUNENGINELIST); 305 if(engineListProperty == null) 306 { 307 //add a new engine property 308 engineListProperty = new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.WORKFLOWRUNENGINELIST); 309 rootProperty.addProperty(engineListProperty); 310 311 } 312 ConfigurationProperty engineProperty = new ConfigurationProperty(Initialize.getCurrentModule(),Initialize.WORKFLOWRUNENGINE); 313 //add a new engine property to the engine list property 314 ConfigurationProperty urlProperty = new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.URL, newURL); 315 ConfigurationProperty nameProperty = new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.NAME, name); 316 engineProperty.addProperty(nameProperty); 317 engineProperty.addProperty(urlProperty); 318 engineListProperty.addProperty(engineProperty); 319 } 320 321 /* 322 * Update the known workflow run engine panel after adding a new engine 323 */ 324 private void addEngineToKnownWorkflowRunEnginePanel(WorkflowRunEngine engine) 325 { 326 knownRunEnginePanel.add(engine); 327 } 328 329 /* 330 * Get the array of workflow run engine from configuration. 331 * null will be return if we can't find one. 332 */ 333 private WorkflowRunEngine[] getWorkflowRunEngineArrayFromConfig() 334 { 335 WorkflowRunEngine[] engineList = null; 336 Vector<WorkflowRunEngine> engineVector = Initialize.getWorkflowRunEngineList(); 337 if(engineVector != null && engineVector.size() > 0) 338 { 339 engineList = new WorkflowRunEngine[engineVector.size()]; 340 engineVector.toArray(engineList); 341 } 342 return engineList; 343 } 344 345 /* 346 * Fire a configuration change event 347 */ 348 private void fireConfigChangeEvent() 349 { 350 NamedObj reference = null; 351 StateChangeEvent event = new StateChangeEvent(this,WorkflowSchedulerConfigEvent.MODIFYCONFIGEVENT, reference); 352 StateChangeMonitor.getInstance().notifyStateChange(event); 353 } 354 355 /* 356 * A customized window adapter: the dialog box will be set invisible 357 * when users close the dialog. 358 */ 359 private class DialogWindowAdapter extends WindowAdapter 360 { 361 private JDialog dialog = null; 362 363 /** 364 * Constructor 365 * @param dialog 366 */ 367 public DialogWindowAdapter(JDialog dialog) 368 { 369 this.dialog = dialog; 370 } 371 372 /** 373 * Set the dialog box invisible 374 */ 375 public void windowClosing(WindowEvent e) 376 { 377 /*if(completeListener != null) 378 { 379 //System.out.println("calling complete method ....."); 380 completeListener.completeConfiguration(); 381 }*/ 382 fireConfigChangeEvent(); 383 if(dialog != null) 384 { 385 dialog.dispose(); 386 } 387 388 } 389 } 390}