001/** A tab pane to display properties of a server workflow. 002 * 003 * Copyright (c) 2010 The Regents of the University of California. 004 * All rights reserved. 005 * 006 * '$Author: crawl $' 007 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 008 * '$Revision: 24730 $' 009 * 010 * Permission is hereby granted, without written agreement and without 011 * license or royalty fees, to use, copy, modify, and distribute this 012 * software and its documentation for any purpose, provided that the above 013 * copyright notice and the following two paragraphs appear in all copies 014 * of this software. 015 * 016 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 017 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 018 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 019 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 020 * SUCH DAMAGE. 021 * 022 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 023 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 025 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 026 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 027 * ENHANCEMENTS, OR MODIFICATIONS. 028 * 029 */ 030 031package org.kepler.workflowscheduler.gui; 032 033import java.awt.BorderLayout; 034import java.awt.Cursor; 035import java.awt.Dimension; 036import java.awt.GridBagConstraints; 037import java.awt.GridBagLayout; 038import java.awt.Insets; 039import java.awt.event.ActionEvent; 040import java.awt.event.ItemEvent; 041import java.awt.event.ItemListener; 042import java.io.File; 043import java.io.FileInputStream; 044import java.io.FileOutputStream; 045import java.io.ObjectInputStream; 046import java.io.ObjectOutputStream; 047import java.io.StringReader; 048import java.text.ParseException; 049import java.text.SimpleDateFormat; 050import java.util.Collections; 051import java.util.Date; 052import java.util.HashMap; 053import java.util.TimeZone; 054import java.util.Vector; 055import java.util.concurrent.locks.Lock; 056import java.util.concurrent.locks.ReentrantLock; 057 058import javax.swing.AbstractAction; 059import javax.swing.BorderFactory; 060import javax.swing.Box; 061import javax.swing.BoxLayout; 062import javax.swing.JButton; 063import javax.swing.JComboBox; 064import javax.swing.JComponent; 065import javax.swing.JLabel; 066import javax.swing.JOptionPane; 067import javax.swing.JPanel; 068import javax.swing.JTextArea; 069import javax.swing.JTextField; 070 071import org.apache.commons.logging.Log; 072import org.apache.commons.logging.LogFactory; 073import org.kepler.gui.TabManager; 074import org.kepler.module.workflowschedulergui.Initialize; 075import org.kepler.objectmanager.repository.Repository; 076import org.kepler.objectmanager.repository.RepositoryManager; 077import org.kepler.util.DotKeplerManager; 078import org.xml.sax.ContentHandler; 079import org.xml.sax.ErrorHandler; 080import org.xml.sax.InputSource; 081import org.xml.sax.XMLReader; 082import org.xml.sax.helpers.XMLReaderFactory; 083 084import edu.ucsb.nceas.schedulerclient.WorkflowSchedulerClient; 085import ptolemy.actor.gui.TableauFrame; 086 087 088/** A tab pane to display a scheduler of a server workflow. 089 * 090 * @author Daniel Crawl 091 * @version $Id: ServerWorkflowPropertiesPanel.java 24730 2010-06-03 23:45:10Z crawl $ 092 */ 093public class WorkflowSchedulerPanel extends JPanel 094{ 095 private static final Log log = LogFactory.getLog(WorkflowSchedulerPanel.class 096 .getName()); 097 private static final int LEADSPACESIZE = 50; // leading space of each row 098 private static final int TEXTFIELDSIZE = 400; 099 public static final String[] INTERVALUNITLABEL = {"hours", "days", "weeks", "months"}; 100 public static final String[] INTERVALUNITVALUE = {Schedule.HOUR, Schedule.DAY, Schedule.WEEK, Schedule.MONTH}; 101 public static final String WORKFLOWRUNENGINECOMBOBOX = "workflowRunEngineCombo"; 102 public static final String DESTINATIONSERVERCOMBOBOX = "destinationServerCombo"; 103 public static final String TIMEEXAMPLE = "MM/dd/yyyy hh:mm:ss"; 104 private static final int UINTCOMBOXWIDTH = 100; 105 private static final String WARNING = "Warning"; 106 public static final String TIMESTAMPFORMAT = "MM/dd/yyyy HH:mm:ss"; 107 public static final String TIMESTAMPFORMATWITHTIMEZONE = TIMESTAMPFORMAT+" zzzz"; 108 private static final String URL = "url"; 109 private static final String NOTE = "Schedule the selected workflow by filling in "+ 110 "the fields below, choosing an execution engine, and the "+ 111 "destination repository for the workflow result archive:"; 112 private static final String UNKNOWN = "Unknown"; 113 private static final String SOURCEKARLOCATION = "Location "; 114 private static final int TIMEZONESTYLE = TimeZone.LONG; 115 private static final String TIMEZONEIDCACHEFILENAME = "time_zone_ids_cache_"; 116 private TableauFrame parent; 117 private JPanel schedulerPanel = null; 118 private JPanel parameterPanel = null; 119 private JPanel buttonPanel = null; 120 private ExistingSchedulePanel existingSchedulePanel = null; 121 private GridBagConstraints textFieldConstraint = null; 122 private GridBagConstraints labelConstraint = null; 123 private GridBagConstraints lastConstraint = null; 124 private JLabel nameTextLabel = null; 125 private JLabel karSourceLocationLabel = null; 126 private JTextField intervalTextField = null; 127 private JTextField startTimeTextField = null; 128 private JTextField endTimeTextField = null; 129 private String startTime = null; 130 private String endTime = null; 131 private String interval = null; 132 private JComboBox intervalUnitComboBox = null; 133 private JComboBox startTimeZoneComboBox = null; 134 private JComboBox endTimeZoneComboBox = null; 135 //private String intervalUnit = INTERVALUNITVALUE[0]; 136 private String workflowId = null; 137 private String workflowName = null; 138 private String karLSID = null; 139 private String karSourceRepositoryName = null; 140 private String runKarDestinationRepositoryName = null; 141 private String workflowRunEngineURL = null; 142 //private String schedulerURL = "http://fakeurl"; 143 //private String returnedWorkflowJobName = null; 144 private Schedule[] existingScheduleList = null; 145 private ScheduleWorkflowAction scheduleAction = null; 146 private ScheduleChangeController scheduleChangeController = null; 147 private JComboBox workflowRunEngineBox = null; 148 private JComboBox resultDestinationBox = null; 149 private Vector<WorkflowRunEngine> workflowRunEngineList = new Vector<WorkflowRunEngine>(); 150 private Vector <Repository> repositoryList = null; 151 private SearchScheduleSwingWorker searchWorker = null; 152 private Vector<String> availableTimeZoneIDsInServer = new Vector<String>(); 153 private static String[] availableTimeZoneIDsInLocal = null; 154 private Vector <String> availableTimeZoneNames = new Vector<String>(); 155 //private SearchSchedulesWorkerListenerInterface searchWorkerListener = null; 156 WorkflowSchedulerParentPanel schedulerParentPanel = null; 157 private final Lock existingScheduleTablelock = new ReentrantLock(); 158 private IntervalUnitComboBoxAction intervalUnitSelectionaction = new IntervalUnitComboBoxAction(); 159 private HashMap<String, TimeZone> timeZoneDisplayHash = new HashMap <String, TimeZone>(); 160 private String startTimeZoneID = null; 161 private String startTimeZoneName = null; 162 private String startTimeLabel = null; 163 private String endTimeZoneID = null; 164 private String endTimeZoneName = null; 165 private String endTimeLabel = null; 166 private File timeZoneIDsCacheFile = null; 167 private String schedulerURL = Initialize.getSchedulerURL(); 168 169 170 /** Construct a new ServerWorkflowSchedulePanel in a frame with a specific title. */ 171 public WorkflowSchedulerPanel(TableauFrame parent, WorkflowSchedulerParentPanel schedulerParentPanel, 172 ScheduleChangeController scheduleChangeController) throws Exception 173 { 174 super(); 175 this.parent = parent; 176 this.schedulerParentPanel = schedulerParentPanel; 177 this.scheduleChangeController = scheduleChangeController; 178 try 179 { 180 initialize(); 181 } 182 catch (Exception e) 183 { 184 throw new Exception("\nWorkflowSchedulerPanel -- couldn't initialize the workflow scheduler panel -- "+e.getMessage()); 185 } 186 187 setBackground(TabManager.BGCOLOR); 188 } 189 190 191 /** 192 * This method must return the TableauFrame this tab is associated with. 193 */ 194 public TableauFrame getParentFrame() 195 { 196 return parent; 197 } 198 199 200 /* Initialize the contents of the panel. */ 201 private void initialize() throws Exception 202 { 203 //getSchedulerURL(); 204 initializeTimeZones(); 205 initializeGridBagLayout(); 206 initializeSchedulerPanel(); 207 //initializeParameterPanel(); 208 initializeButtonPanel(); 209 initializeExistingSchedulePanel(); 210 211 //whole panel will be box layout 212 this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 213 this.add(Box.createVerticalStrut(10)); 214 Box box = Box.createHorizontalBox(); 215 //JLabel noteLabel = new JLabel(NOTE, JLabel.LEFT); 216 //noteLabel.setForeground(Color.blue); 217 //noteLabel.setOpaque(true); 218 //noteLabel.setBackground(Color.blue); 219 JTextArea noteTextArea = new JTextArea(NOTE); 220 noteTextArea.setEditable(false); 221 noteTextArea.setLineWrap(true); 222 noteTextArea.setWrapStyleWord(true); 223 //descriptionTextArea.setPreferredSize(new Dimension(400, 400)); 224 noteTextArea.setBackground(TabManager.BGCOLOR); 225 box.add(noteTextArea); 226 box.add(Box.createHorizontalGlue()); 227 this.add(box); 228 229 this.add(Box.createVerticalStrut(15)); 230 231 this.add(schedulerPanel); 232 //this.add(parameterPanel); 233 this.add(buttonPanel); 234 //this.add(Box.createVerticalStrut(60)); 235 this.add(existingSchedulePanel); 236 237 238 } 239 240 241 /* 242 * Initialize the available time zones 243 */ 244 private void initializeTimeZones() throws Exception 245 { 246 247 if(schedulerURL != null && !schedulerURL.trim().equals("")) 248 { 249 String newURL = schedulerURL.replaceAll("/", "_"); 250 newURL = newURL.replaceAll(":", "_"); 251 timeZoneIDsCacheFile = new File(DotKeplerManager.getInstance().getTransientModuleDirectory(Initialize.MODULENAME), 252 TIMEZONEIDCACHEFILENAME+newURL); 253 //System.out.println("The cache file path is "+timeZoneIDsCacheFile.getAbsolutePath()); 254 } 255 256 //System.out.println("start !!!!!!!!!!!!!!!!!!!!!!!!!!!11 initialize time zone"); 257 availableTimeZoneIDsInLocal = TimeZone.getAvailableIDs(); 258 initializeSchedulerServerAvailableTimeZoneIDs(); 259 for( String id : availableTimeZoneIDsInServer) 260 { 261 //only display the ids found in both server and local 262 if(localContainsTimeZoneID(id)) 263 { 264 //add standard time zone name 265 Boolean notDayLight = false; 266 TimeZone zone = TimeZone.getTimeZone(id); 267 String standName = zone.getDisplayName(notDayLight, TIMEZONESTYLE); 268 if(!availableTimeZoneNames.contains(standName)) 269 { 270 availableTimeZoneNames.add(standName); 271 timeZoneDisplayHash.put(standName, zone); 272 } 273 //add day light time zone name if it is available 274 Boolean useDayLight = zone.useDaylightTime(); 275 if(useDayLight) 276 { 277 String dayLightName = zone.getDisplayName(useDayLight, TIMEZONESTYLE); 278 if (!availableTimeZoneNames.contains(dayLightName)) 279 { 280 availableTimeZoneNames.add(dayLightName); 281 timeZoneDisplayHash.put(dayLightName, zone); 282 } 283 } 284 } 285 286 } 287 Collections.sort(availableTimeZoneNames); 288 //System.out.println("end !!!!!!!!!!!!!!!!!!!!!!!!!!!11 initialize time zone"); 289 } 290 291 292 private void initializeSchedulerServerAvailableTimeZoneIDs() throws Exception 293 { 294 if(timeZoneIDsCacheFile != null && timeZoneIDsCacheFile.exists()) 295 { 296 //try to get the available ids from the cache 297 try 298 { 299 getAvailableServerTimeZoneIDFromCache(); 300 if(availableTimeZoneIDsInServer == null || availableTimeZoneIDsInServer.isEmpty()) 301 { 302 getAvailableServerTimeZoneIDFromServer(); 303 } 304 } 305 catch(Exception e) 306 { 307 log.warn("WorkflowSchedulerPanel.initializeSchedulerServerAvailableTimeZoneIDs - Failed to get the available time zone from the cache.\n"+ 308 "Try to get the time zone ids from server again"); 309 getAvailableServerTimeZoneIDFromServer(); 310 } 311 } 312 else 313 { 314 //try to get the available ids from the server 315 getAvailableServerTimeZoneIDFromServer(); 316 } 317 318 } 319 320 /* 321 * Get the available server time zone id from a cache file 322 */ 323 private void getAvailableServerTimeZoneIDFromCache() throws Exception 324 { 325 if(timeZoneIDsCacheFile != null) 326 { 327 //System.out.println("===== get ids from cache "); 328 FileInputStream fileInput = new FileInputStream(timeZoneIDsCacheFile); 329 ObjectInputStream objectInput = new ObjectInputStream(fileInput); 330 availableTimeZoneIDsInServer = (Vector<String>)objectInput.readObject(); 331 } 332 } 333 334 /* 335 * Gets the available server time zone id from the workflow scheduler server 336 */ 337 private void getAvailableServerTimeZoneIDFromServer() throws Exception 338 { 339 //System.out.println("===== get ids from sever "); 340 String sessionID = "blank"; 341 String authURL = "blank"; 342 WorkflowSchedulerClient client = new WorkflowSchedulerClient(schedulerURL, sessionID, authURL); 343 String result = null; 344 try 345 { 346 parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 347 result = client.getAvailableTimeZoneIDs(); 348 parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 349 } 350 catch(Exception e) 351 { 352 parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 353 throw new Exception("\nCouldn't contact the scheduler -- "+schedulerURL+" to get its available time zone ids --\n "+e.getMessage()); 354 } 355 if(result != null && !result.trim().equals("")) 356 { 357 StringReader xmlReader = new StringReader(result); 358 try 359 { 360 XMLReader parser = null; 361 parser = XMLReaderFactory.createXMLReader(SearchScheduleSwingWorker.PARSERNAME); 362 ServerTimeZoneIDParser handler = new ServerTimeZoneIDParser(); 363 parser.setContentHandler((ContentHandler) handler); 364 parser.setErrorHandler((ErrorHandler) handler); 365 parser.parse(new InputSource(xmlReader)); 366 availableTimeZoneIDsInServer = handler.getValaibleTimeZoneIDs(); 367 saveAvailableServerTimeZoneIDToCache(); 368 } 369 catch(Exception e) 370 { 371 throw new Exception("\nCouldn't parse the information about the server available time zone ids in "+ 372 schedulerURL+" - "+e.getMessage()); 373 } 374 } 375 } 376 377 378 /* 379 * Save the time zone ids from the server into a cache file 380 */ 381 private void saveAvailableServerTimeZoneIDToCache() 382 { 383 if(availableTimeZoneIDsInServer != null) { 384 try 385 { 386 if(timeZoneIDsCacheFile != null) 387 { 388 timeZoneIDsCacheFile.delete(); 389 } 390 FileOutputStream fileOutput = new FileOutputStream(timeZoneIDsCacheFile); 391 ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput); 392 objectOutput.writeObject(availableTimeZoneIDsInServer); 393 } 394 catch(Exception e) 395 { 396 log.error("WorkflowSchedulerPanel.saveAvailableServerTimeZoneIDToCache - Can't save the server time zone ids into a cache file :"+e.getMessage()); 397 } 398 } 399 } 400 /* 401 * Initialize the grid bag layout manager 402 */ 403 private void initializeGridBagLayout() 404 { 405 textFieldConstraint = new GridBagConstraints(); 406 textFieldConstraint.fill = GridBagConstraints.HORIZONTAL; 407 //lastConstraint.anchor = GridBagConstraints.NORTHWEST; 408 // Give the "last" component as much space as possible 409 textFieldConstraint.weightx = 1.0; 410 //textFieldConstraint.gridwidth = GridBagConstraints.RELATIVE; 411 textFieldConstraint.insets = new Insets(4, 4, 4, 4); 412 413 lastConstraint = (GridBagConstraints) textFieldConstraint.clone(); 414 //These still get as much space as possible, but do 415 //not close out a row 416 lastConstraint.gridwidth = GridBagConstraints.REMAINDER; 417 418 // first component (usually it is a label) on each row 419 labelConstraint = (GridBagConstraints) textFieldConstraint.clone(); 420 // Give these as little space as necessary 421 labelConstraint.weightx = 0.0; 422 labelConstraint.gridwidth = 1; 423 424 } 425 426 /* 427 * Initialize the scheduler panel. This panel contains 428 * workflow name, start time, end time and interval. 429 */ 430 private void initializeSchedulerPanel() 431 { 432 schedulerPanel = new JPanel(); 433 GridBagLayout gridbag = new GridBagLayout(); 434 schedulerPanel.setLayout(gridbag); 435 // Name row 436 addLeadingSpace(schedulerPanel, gridbag); 437 JLabel nameLabel = new JLabel("Workflow "); 438 addComponent(schedulerPanel, nameLabel, gridbag, labelConstraint); 439 nameTextLabel = new JLabel(UNKNOWN); 440 addFixWidthComponent(schedulerPanel, nameTextLabel, gridbag, textFieldConstraint); 441 addEndingSpace(schedulerPanel, gridbag); 442 443 //source kar file location row 444 addLeadingSpace(schedulerPanel, gridbag); 445 JLabel karSourceLocation = new JLabel(SOURCEKARLOCATION); 446 addComponent(schedulerPanel, karSourceLocation, gridbag, labelConstraint); 447 karSourceLocationLabel = new JLabel(UNKNOWN); 448 addFixWidthComponent(schedulerPanel, karSourceLocationLabel, gridbag, textFieldConstraint); 449 addEndingSpace(schedulerPanel, gridbag); 450 451 //start time row 452 addLeadingSpace(schedulerPanel, gridbag); 453 JLabel startTimeLabel = new JLabel("Start Time "); 454 addComponent(schedulerPanel, startTimeLabel, gridbag, labelConstraint); 455 startTimeTextField = new JTextField(); 456 startTimeTextField.setText(TIMEEXAMPLE); 457 addFixWidthComponent(schedulerPanel, startTimeTextField , gridbag, textFieldConstraint); 458 startTimeZoneComboBox = new JComboBox(availableTimeZoneNames); 459 startTimeZoneComboBox.addItemListener(new StartTimeZoneItemListener()); 460 startTimeZoneComboBox.setSelectedItem(getDefaultTimeZoneName()); 461 addComponent(schedulerPanel, startTimeZoneComboBox, gridbag, labelConstraint); 462 addEndingSpace(schedulerPanel, gridbag); 463 464 //end time row 465 addLeadingSpace(schedulerPanel, gridbag); 466 JLabel endTimeLabel = new JLabel("End Time "); 467 addComponent(schedulerPanel, endTimeLabel, gridbag, labelConstraint); 468 endTimeTextField = new JTextField(); 469 endTimeTextField.setText(TIMEEXAMPLE); 470 addFixWidthComponent(schedulerPanel, endTimeTextField, gridbag, textFieldConstraint); 471 endTimeZoneComboBox = new JComboBox(availableTimeZoneNames); 472 endTimeZoneComboBox.addItemListener(new EndTimeZoneItemListener()); 473 endTimeZoneComboBox.setSelectedItem(getDefaultTimeZoneName()); 474 addComponent(schedulerPanel, endTimeZoneComboBox, gridbag, labelConstraint); 475 addEndingSpace(schedulerPanel, gridbag); 476 477 //interval row 478 addLeadingSpace(schedulerPanel, gridbag); 479 JLabel intervalLabel = new JLabel("Interval "); 480 addComponent(schedulerPanel, intervalLabel, gridbag, labelConstraint); 481 intervalTextField = new JTextField(); 482 addFixWidthComponent(schedulerPanel, intervalTextField, gridbag, textFieldConstraint); 483 intervalUnitComboBox = new JComboBox(INTERVALUNITLABEL); 484 485 intervalUnitComboBox.addActionListener(intervalUnitSelectionaction); 486 Dimension size = intervalUnitComboBox.getPreferredSize(); 487 size.width = UINTCOMBOXWIDTH; 488 addComponent(schedulerPanel, intervalUnitComboBox, gridbag, labelConstraint); 489 addEndingSpace(schedulerPanel, gridbag); 490 491 //workflow run engine combobox row 492 addLeadingSpace(schedulerPanel, gridbag); 493 JLabel workflowRunEngineLabel = new JLabel("Workflow Run Engine "); 494 addComponent(schedulerPanel, workflowRunEngineLabel, gridbag, labelConstraint); 495 workflowRunEngineList = Initialize.getWorkflowRunEngineList(); 496 workflowRunEngineBox = new JComboBox(workflowRunEngineList); 497 workflowRunEngineBox.setRenderer(new RepositoryAndRunEngineComboBoxRenderer(WORKFLOWRUNENGINECOMBOBOX)); 498 addFixWidthComponent(schedulerPanel, workflowRunEngineBox, gridbag, textFieldConstraint); 499 addEndingSpace(schedulerPanel, gridbag); 500 501 //result destination combobox row 502 addLeadingSpace(schedulerPanel, gridbag); 503 JLabel resultDestinationLabel = new JLabel("Result Destination "); 504 addComponent(schedulerPanel, resultDestinationLabel, gridbag, labelConstraint); 505 try 506 { 507 repositoryList= RepositoryManager.getInstance().getRepositories(); 508 } 509 catch(Exception e) 510 { 511 log.warn("ServerWorkflowSchedulePanel.initializeSchedulerPane - couldn't get repository list "+e.getMessage()); 512 } 513 514 if(repositoryList == null) 515 { 516 repositoryList = new Vector<Repository>(); 517 } 518 resultDestinationBox = new JComboBox(repositoryList); 519 resultDestinationBox.setRenderer(new RepositoryAndRunEngineComboBoxRenderer(DESTINATIONSERVERCOMBOBOX)); 520 addFixWidthComponent(schedulerPanel, resultDestinationBox, gridbag, textFieldConstraint); 521 addEndingSpace(schedulerPanel, gridbag); 522 523 524 } 525 526 527 528 /* 529 * Initialize button panel. The panel contains "Schedule" button. 530 */ 531 private void initializeButtonPanel() 532 { 533 scheduleAction = new ScheduleWorkflowAction(parent, schedulerParentPanel,scheduleChangeController); 534 buttonPanel = new JPanel(); 535 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); 536 buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 537 buttonPanel.add(Box.createHorizontalGlue()); 538 JButton scheduleButton = new JButton("Schedule"); 539 scheduleButton.setPreferredSize(new Dimension(100, 50)); 540 scheduleButton.addActionListener(new AbstractAction() 541 { 542 public void actionPerformed(ActionEvent e) 543 { 544 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 545 boolean valid = validateInputField(); 546 if (valid == true) 547 { 548 Schedule schedule = new Schedule(); 549 schedule.setWorkflowId(workflowId); 550 schedule.setKarLSID(karLSID); 551 schedule.setWorkflowName(workflowName); 552 553 //appendTimeZoneToTimeString(); 554 //System.out.println("The start time is "+startTime); 555 //System.out.println("The end time is "+endTime); 556 schedule.setStartTime(startTime); 557 schedule.setStartTimeLabel(startTime+" "+startTimeZoneName); 558 schedule.setStartTimeZoneID(startTimeZoneID); 559 schedule.setStartTimeFormat(TIMESTAMPFORMAT); 560 schedule.setEndTime(endTime); 561 schedule.setEndTimeLabel(endTime+" "+endTimeZoneName); 562 schedule.setEndTimeZoneID(endTimeZoneID); 563 schedule.setEndTimeFormat(TIMESTAMPFORMAT); 564 schedule.setInterval(interval); 565 566 schedule.setWorkflowRunEngine( 567 (WorkflowRunEngine)workflowRunEngineBox.getSelectedItem()); 568 schedule.setWorkflowRunDestination( 569 (Repository)resultDestinationBox.getSelectedItem()); 570 try 571 { 572 String intervalUnit = intervalUnitSelectionaction.getIntervalUnit(); 573 schedule.setIntervalUnit(intervalUnit); 574 } 575 catch(Exception ee) 576 { 577 JOptionPane.showMessageDialog(parent, ee.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 578 return; 579 } 580 scheduleAction.setSchedule(schedule); 581 scheduleAction.actionPerformed(e); 582 } 583 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 584 } 585 }); 586 buttonPanel.add(scheduleButton); 587 588 } 589 590 /* 591 * Initialize the existing schedule panel 592 */ 593 private void initializeExistingSchedulePanel() 594 { 595 existingSchedulePanel = new ExistingSchedulePanel(existingScheduleList, parent, schedulerParentPanel, scheduleChangeController); 596 scheduleChangeController.addListener(existingSchedulePanel); 597 } 598 599 600 601 602 /* 603 *Add leading space in each row of a panel 604 */ 605 private void addLeadingSpace(JPanel panel, GridBagLayout layout) 606 { 607 String space = " "; 608 JLabel leadingLabel = new JLabel(space); 609 Dimension size = leadingLabel.getPreferredSize(); 610 size.width = LEADSPACESIZE; 611 leadingLabel.setPreferredSize(size); 612 addComponent(panel, leadingLabel, layout, labelConstraint); 613 } 614 615 /* 616 *Add ending space in each row of a panel 617 */ 618 private void addEndingSpace(JPanel panel, GridBagLayout layout) 619 { 620 String space = " "; 621 JLabel leadingLabel = new JLabel(space); 622 addComponent(panel, leadingLabel, layout, lastConstraint); 623 } 624 625 private String getDefaultTimeZoneName() 626 { 627 String name = null; 628 TimeZone timeZone = TimeZone.getDefault(); 629 boolean daylight = timeZone.inDaylightTime(new Date()); 630 name = timeZone.getDisplayName(daylight, TIMEZONESTYLE); 631 return name; 632 } 633 634 /* 635 * Create a blank "last field" component gets us to a new line. 636 */ 637 /*private void addNewLine(JPanel panel, GridBagLayout layout) 638 { 639 String space = " "; 640 JLabel leadingLabel = new JLabel(space); 641 addComponentWithGridBagLayout(panel, leadingLabel, layout, lastConstraint); 642 }*/ 643 644 /* 645 * Add a component with specified layout to the given panel 646 */ 647 public static void addComponent(JPanel panel, JComponent component, GridBagLayout layout, GridBagConstraints constraint) 648 { 649 if(component != null && panel != null && layout != null) 650 { 651 layout.setConstraints(component, constraint); 652 panel.add(component); 653 } 654 655 } 656 657 /* 658 * Add a component with specified layout to the given panel 659 */ 660 public static void addFixWidthComponent(JPanel panel, JComponent component, GridBagLayout layout, GridBagConstraints constraint) 661 { 662 if(component != null && panel != null && layout != null) 663 { 664 Dimension size = component.getPreferredSize(); 665 size.width = TEXTFIELDSIZE; 666 layout.setConstraints(component, constraint); 667 panel.add(component); 668 } 669 670 } 671 672 /* 673 * Validate the input fields on the schedule panel 674 */ 675 private boolean validateInputField() 676 { 677 boolean success = true; 678 startTime = startTimeTextField.getText(); 679 endTime = endTimeTextField.getText(); 680 interval = intervalTextField.getText(); 681 //validate startTime 682 if(startTime== null || startTime.trim().equals("")) 683 { 684 JOptionPane.showMessageDialog(parent, "\"Start Time\" field can't be blank!", WARNING, JOptionPane.WARNING_MESSAGE); 685 success = false; 686 return success; 687 } 688 else 689 { 690 success = validateTimeString(startTime, TIMESTAMPFORMAT); 691 if(success == false) 692 { 693 JOptionPane.showMessageDialog(parent, "\"Start Time\" field should be the format \"MM/dd/yyyy hh:mm:ss\"!", WARNING, JOptionPane.WARNING_MESSAGE); 694 return success; 695 } 696 } 697 //validate endTime 698 if(endTime== null || endTime.trim().equals("")) 699 { 700 JOptionPane.showMessageDialog(parent, "\"End Time\" field can't be blank!", WARNING, JOptionPane.WARNING_MESSAGE); 701 success = false; 702 return success; 703 } 704 else 705 { 706 success = validateTimeString(endTime, TIMESTAMPFORMAT); 707 if(success == false) 708 { 709 JOptionPane.showMessageDialog(parent, "\"End Time\" field should be the format \"MM/dd/yyyy hh:mm:ss\"!", WARNING, JOptionPane.WARNING_MESSAGE); 710 return success; 711 } 712 } 713 //validate interval 714 if(interval == null || interval.trim().equals("")) 715 { 716 JOptionPane.showMessageDialog(parent, "\"Interval\" field can't be blank!", WARNING, JOptionPane.WARNING_MESSAGE); 717 success = false; 718 return success; 719 } 720 else 721 { 722 try 723 { 724 int intValue = Integer.parseInt(interval); 725 if(intValue < 1) 726 { 727 JOptionPane.showMessageDialog(parent, "\"Interval\" should be greater than zero!", WARNING, JOptionPane.WARNING_MESSAGE); 728 success = false; 729 return success; 730 } 731 } 732 catch(NumberFormatException e) 733 { 734 JOptionPane.showMessageDialog(parent, "\"Interval\" field should be an integer!", WARNING, JOptionPane.WARNING_MESSAGE); 735 success = false; 736 return success; 737 } 738 } 739 return success; 740 } 741 742 /* 743 * Validate the time string with specified format 744 */ 745 private boolean validateTimeString(String dateString, String format) 746 { 747 boolean valid = true; 748 749 try 750 { 751 SimpleDateFormat dateFormat = new SimpleDateFormat(format); 752 dateFormat.setLenient(false); 753 Date startDate = dateFormat.parse(dateString); 754 } 755 catch (ParseException pe) 756 { 757 valid = false; 758 } 759 760 return valid; 761 } 762 763 764 765 /* 766 * Set the kar source eporsitory name. 767 * @param name 768 */ 769 private void setKarSourceRepositoryName(String name) 770 { 771 this.karSourceRepositoryName = name; 772 } 773 /** 774 * Get the id of the workflow (LSID format) 775 * @return the id 776 */ 777 public String getWorkflowId() 778 { 779 return workflowId; 780 } 781 782 /** 783 * Set the workflow id (LSID format) 784 * @param workflowId the id will be set 785 */ 786 public void setWorkflowId(String workflowId) 787 { 788 this.workflowId = workflowId; 789 } 790 791 /** 792 * Get the name of the workflow 793 * @return the name 794 */ 795 public String getWorkflowName() 796 { 797 return workflowName; 798 } 799 800 /* 801 * Set the name of the workflow. It will update the workflow name label 802 * on the gui as well 803 * @param workflowName the name will be set 804 */ 805 private void setWorkflowName(String workflowName) 806 { 807 if(workflowName == null || workflowName.trim().equals("")) 808 { 809 this.workflowName = UNKNOWN; 810 } 811 else 812 { 813 this.workflowName = workflowName; 814 } 815 //updateWorkflowNameLabel(); 816 } 817 818 /* 819 * Update workflow name text label 820 */ 821 private void updateWorkflowNameLabel() 822 { 823 nameTextLabel.setText(workflowName); 824 nameTextLabel.repaint(); 825 nameTextLabel.validate(); 826 } 827 828 /* 829 * Update the source kar file location 830 */ 831 private void updateSourceKarFileLocationLabel() 832 { 833 if(karSourceRepositoryName != null && 834 !karSourceRepositoryName.trim().equals("")) 835 { 836 karSourceLocationLabel.setText(karSourceRepositoryName); 837 karSourceLocationLabel.repaint(); 838 karSourceLocationLabel.validate(); 839 } 840 } 841 842 /** 843 * Get the kar file id associated with the workflow. 844 * @return the id fo the kar file 845 */ 846 public String getKarLSID() 847 { 848 return karLSID; 849 } 850 851 /** 852 * Set the id of the kar file 853 * @param karId id will be set 854 */ 855 public void setKarLSID(String karId) 856 { 857 this.karLSID = karId; 858 } 859 860 /** 861 * Pass a workflow information to the scheulder. The scheduler will update 862 * its gui as well. 863 * @param workflowName name of the workflow 864 * @param workflowLSID lsid of the workflow 865 * @param karSourceRepositoryName name of the repository where the kar file stays 866 * @param karLSID lsid of the kar file which the workflow stays 867 */ 868 public void setWorkflowForScheduling(String workflowName, String workflowLSID, 869 String karSourceRepositoryName, String karLSID, boolean hasReportLayout) 870 { 871 872 schedulerParentPanel.removeAll(); 873 schedulerParentPanel.add(this, BorderLayout.CENTER); 874 setWorkflowId(workflowLSID); 875 setKarSourceRepositoryName(karSourceRepositoryName); 876 updateSourceKarFileLocationLabel(); 877 try 878 { 879 SchedulerAbstractAction.setSourceRespositoryName(karSourceRepositoryName); 880 SchedulerAbstractAction.setHasReportLayout(hasReportLayout); 881 } 882 catch(Exception e) 883 { 884 JOptionPane.showMessageDialog(parent, "User will NOT do any schedule-related action since kepler couldn't find the repository named "+ 885 karSourceRepositoryName+" - "+e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 886 } 887 setKarLSID(karLSID); 888 setWorkflowName(workflowName); 889 updateWorkflowNameLabel(); 890 addExistingSchedules(); 891 } 892 893 /* 894 * Search the scheudler to find the existing schedules for the workflow, 895 * and add those schedules to the existing workflow panel. 896 */ 897 private void addExistingSchedules() 898 { 899 if(searchWorker != null) 900 { 901 //System.out.println("interrupt===="); 902 searchWorker.cancel(true); 903 searchWorker = null; 904 905 } 906 try 907 { 908 searchWorker = new SearchScheduleSwingWorker(scheduleChangeController, 909 workflowId, karLSID, existingScheduleTablelock); 910 //searchWorker.setSearchWorkerListener(searchWorkerListener); 911 searchWorker.execute(); 912 } 913 catch(Exception e) 914 { 915 if(scheduleChangeController != null) 916 { 917 scheduleChangeController.stopProgressBar(); 918 } 919 JOptionPane.showMessageDialog(parent, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 920 } 921 } 922 923 924 /** 925 * Look for couterpart of interval unit for a specified unit label 926 * @param unitLabel the specified unit label 927 * @return the actual unit for the label. Null will be returned if no match was found 928 */ 929 public static String lookupIntervalUnit(String unitLabel) 930 { 931 String unit = null; 932 if(unitLabel != null) 933 { 934 for(int i=0; i< INTERVALUNITLABEL.length; i++) 935 { 936 String label = INTERVALUNITLABEL[i]; 937 if(label != null && label.equals(unitLabel)) 938 { 939 unit = INTERVALUNITVALUE[i]; 940 break; 941 } 942 } 943 } 944 return unit; 945 } 946 947 948 /** 949 * Look for counterpart of interval unit label for a specified unit 950 * @param unit the specified unit 951 * @return the unit label for the unit. Null will be returned if no match was found 952 */ 953 public static String lookupIntervalUnitLabel(String unit) 954 { 955 String unitLabel = null; 956 if(unit != null) 957 { 958 for(int i=0; i< INTERVALUNITVALUE.length; i++) 959 { 960 String unitValue = INTERVALUNITVALUE[i]; 961 if(unitValue != null && unitValue.equals(unit)) 962 { 963 unitLabel =INTERVALUNITLABEL[i]; 964 break; 965 } 966 } 967 } 968 return unitLabel; 969 } 970 971 /* 972 * Append time zone to the time string. 973 */ 974 /*private void appendTimeZoneToTimeString() 975 { 976 //TimeZone timeZone = Calendar.getInstance().getTimeZone(); 977 //String name = timeZone.getDisplayName(true, TimeZone.LONG); 978 String selectedStartTimeZone = (String)startTimeZoneComboBox.getSelectedItem(); 979 //System.out.println("The selected start time zone is "+selectedStartTimeZone); 980 startTime = startTime+" "+selectedStartTimeZone; 981 //System.out.println("The start time is "+startTime); 982 String selectedEndTimeZone = (String)endTimeZoneComboBox.getSelectedItem(); 983 //System.out.println("The selected end time zone is "+selectedEndTimeZone); 984 endTime = endTime+" "+selectedEndTimeZone; 985 //System.out.println("The end time is "+endTime); 986 987 }*/ 988 989 public static boolean localContainsTimeZoneID(String id) 990 { 991 boolean contains = false; 992 if(id != null && !id.trim().equals("")) 993 { 994 for(String timeZoneId : availableTimeZoneIDsInLocal) 995 { 996 if(timeZoneId != null && !timeZoneId.trim().equals("") && timeZoneId.equals(id)) 997 { 998 //System.out.println("local time zone cotains the id "+id); 999 contains = true; 1000 break; 1001 } 1002 } 1003 } 1004 return contains; 1005 } 1006 1007 /* 1008 * A listener to handle a selection on the start time zone drop-down box. 1009 * It decides the start time zone id. 1010 * It also sets the end time zone as same as the start time zone when user 1011 * change the start time zone. 1012 */ 1013 private class StartTimeZoneItemListener implements ItemListener 1014 { 1015 public void itemStateChanged(ItemEvent e) 1016 { 1017 //System.out.println("====== event: selec"+e.getItem()); 1018 startTimeZoneName = (String) e.getItem(); 1019 //System.out.println("The selected start time name is "+startTimeZoneName); 1020 TimeZone zone = timeZoneDisplayHash.get(startTimeZoneName); 1021 startTimeZoneID = zone.getID(); 1022 //System.out.println("selected this id in start time zone"+startTimeZoneID); 1023 if(endTimeZoneComboBox != null) 1024 { 1025 endTimeZoneComboBox.setSelectedItem(e.getItem()); 1026 } 1027 } 1028 } 1029 1030 1031 /* 1032 * A listener to handle a selection on the end time zone drop-down box. 1033 * It decides the end time zone id. 1034 */ 1035 private class EndTimeZoneItemListener implements ItemListener 1036 { 1037 public void itemStateChanged(ItemEvent e) 1038 { 1039 //System.out.println("====== event: selec"+e.getItem()); 1040 endTimeZoneName = (String) e.getItem(); 1041 //System.out.println("The selected end time name is "+endTimeZoneName); 1042 TimeZone zone = timeZoneDisplayHash.get(endTimeZoneName); 1043 endTimeZoneID = zone.getID(); 1044 //System.out.println("selected this id in end time zone "+endTimeZoneID); 1045 1046 } 1047 } 1048 1049}