001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027 028package org.opends.guitools.controlpanel.ui; 029 030import static org.opends.messages.AdminToolMessages.*; 031 032import java.awt.Component; 033import java.awt.Dimension; 034import java.awt.GridBagConstraints; 035import java.awt.GridBagLayout; 036import java.awt.event.ItemEvent; 037import java.awt.event.ItemListener; 038import java.util.ArrayList; 039import java.util.Calendar; 040import java.util.Collection; 041import java.util.Date; 042import java.util.GregorianCalendar; 043 044import javax.swing.Box; 045import javax.swing.DefaultComboBoxModel; 046import javax.swing.JCheckBox; 047import javax.swing.JComboBox; 048import javax.swing.JComponent; 049import javax.swing.JEditorPane; 050import javax.swing.JLabel; 051import javax.swing.JPanel; 052import javax.swing.JTextField; 053import javax.swing.text.PlainDocument; 054 055import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement; 056import org.opends.guitools.controlpanel.datamodel.ScheduleType; 057import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 058import org.opends.guitools.controlpanel.ui.components. 059 NumericLimitedSizeDocumentFilter; 060import org.opends.guitools.controlpanel.ui.components.TimeDocumentFilter; 061import org.opends.guitools.controlpanel.ui.renderer. 062 NoLeftInsetCategoryComboBoxRenderer; 063import org.opends.guitools.controlpanel.util.Utilities; 064import org.forgerock.i18n.LocalizableMessage; 065import org.opends.server.backends.task.RecurringTask; 066 067/** 068 * The panel that allows the user to specify when a task will be launched. 069 * 070 */ 071public class TaskToSchedulePanel extends StatusGenericPanel 072{ 073 private static final long serialVersionUID = 6855081932432566784L; 074 075 private String taskName; 076 077 private JComboBox scheduleType; 078 079 private JTextField time; 080 private JTextField day; 081 private JComboBox month; 082 private JComboBox year; 083 084 private JLabel lTime; 085 private JLabel lDay; 086 private JLabel lMonth; 087 private JLabel lYear; 088 089 private JLabel lDailyTime; 090 private JTextField dailyTime; 091 092 private JLabel lWeeklyTime; 093 private JLabel lWeeklyDays; 094 private JTextField weeklyTime; 095 private JCheckBox sunday, monday, tuesday, wednesday, thursday, friday, 096 saturday; 097 { 098 sunday = 099 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUNDAY.get()); 100 monday = 101 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONDAY.get()); 102 tuesday = 103 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TUESDAY.get()); 104 wednesday = 105 Utilities.createCheckBox( 106 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEDNESDAY.get()); 107 thursday = 108 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_THURSDAY.get()); 109 friday = 110 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_FRIDAY.get()); 111 saturday = 112 Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SATURDAY.get()); 113 } 114 115 JCheckBox[] weekDays = 116 { 117 sunday, monday, tuesday, wednesday, thursday, friday, saturday 118 }; 119 120 private JLabel lMonthlyTime; 121 private JLabel lMonthlyDays; 122 private JTextField monthlyTime; 123 private JCheckBox[] monthDays = new JCheckBox[31]; 124 125 private JLabel lCronMinute; 126 private JLabel lCronHour; 127 private JLabel lCronWeekDay; 128 private JLabel lCronMonthDay; 129 private JLabel lCronMonth; 130 131 private JTextField cronMinute; 132 private JTextField cronHour; 133 private JTextField cronWeekDay; 134 private JTextField cronMonthDay; 135 private JTextField cronMonth; 136 137 private Component launchLaterPanel; 138 private Component dailyPanel; 139 private Component weeklyPanel; 140 private Component monthlyPanel; 141 private Component cronPanel; 142 143 private LocalizableMessage LAUNCH_NOW = INFO_CTRL_PANEL_LAUNCH_NOW.get(); 144 private LocalizableMessage LAUNCH_LATER = INFO_CTRL_PANEL_LAUNCH_LATER.get(); 145 private LocalizableMessage LAUNCH_DAILY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAILY.get(); 146 private LocalizableMessage LAUNCH_WEEKLY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEEKLY.get(); 147 private LocalizableMessage LAUNCH_MONTHLY = 148 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTHLY.get(); 149 private LocalizableMessage CRON = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON.get(); 150 151 private ScheduleType schedule; 152 153 /** 154 * Default constructor. 155 * @param taskName the name of the task to be scheduled. 156 */ 157 public TaskToSchedulePanel(String taskName) 158 { 159 super(); 160 this.taskName = taskName; 161 createLayout(); 162 } 163 164 /** 165 * Creates the layout of the panel (but the contents are not populated here). 166 */ 167 private void createLayout() 168 { 169 GridBagConstraints gbc = new GridBagConstraints(); 170 JEditorPane explanation = Utilities.makeHtmlPane( 171 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUMMARY.get(taskName).toString(), 172 ColorAndFontConstants.defaultFont); 173 gbc.gridx = 0; 174 gbc.gridy = 0; 175 gbc.gridwidth = 1; 176 gbc.fill = GridBagConstraints.HORIZONTAL; 177 add(explanation, gbc); 178 gbc.gridy ++; 179 gbc.insets.top = 10; 180 scheduleType = Utilities.createComboBox(); 181 scheduleType.setModel(new DefaultComboBoxModel()); 182 183 ArrayList<Object> newElements = new ArrayList<>(); 184 newElements.add(new CategorizedComboBoxElement(LAUNCH_NOW, 185 CategorizedComboBoxElement.Type.REGULAR)); 186 newElements.add(COMBO_SEPARATOR); 187 newElements.add(new CategorizedComboBoxElement(LAUNCH_LATER, 188 CategorizedComboBoxElement.Type.REGULAR)); 189 newElements.add(COMBO_SEPARATOR); 190 newElements.add(new CategorizedComboBoxElement(LAUNCH_DAILY, 191 CategorizedComboBoxElement.Type.REGULAR)); 192 newElements.add(new CategorizedComboBoxElement(LAUNCH_WEEKLY, 193 CategorizedComboBoxElement.Type.REGULAR)); 194 newElements.add(new CategorizedComboBoxElement(LAUNCH_MONTHLY, 195 CategorizedComboBoxElement.Type.REGULAR)); 196 newElements.add(new CategorizedComboBoxElement(CRON, 197 CategorizedComboBoxElement.Type.REGULAR)); 198 updateComboBoxModel(newElements, 199 (DefaultComboBoxModel)scheduleType.getModel()); 200 scheduleType.setRenderer( 201 new NoLeftInsetCategoryComboBoxRenderer(scheduleType)); 202 scheduleType.addItemListener(new IgnoreItemListener(scheduleType)); 203 204 gbc.weightx = 0.0; 205 gbc.anchor = GridBagConstraints.NORTHWEST; 206 gbc.fill = GridBagConstraints.NONE; 207 add(scheduleType, gbc); 208 209 launchLaterPanel = createLaunchLaterPanel(); 210 dailyPanel = createDailyPanel(); 211 weeklyPanel = createWeeklyPanel(); 212 monthlyPanel = createMonthlyPanel(); 213 cronPanel = createCronPanel(); 214 215 scheduleType.addItemListener(new ItemListener() 216 { 217 public void itemStateChanged(ItemEvent ev) 218 { 219 Object element = scheduleType.getSelectedItem(); 220 boolean launchLaterVisible = false; 221 boolean launchDailyVisible = false; 222 boolean launchWeeklyVisible = false; 223 boolean launchMonthlyVisible = false; 224 boolean cronVisible = false; 225 if (element != null) 226 { 227 if (element instanceof CategorizedComboBoxElement) 228 { 229 element = ((CategorizedComboBoxElement)element).getValue(); 230 } 231 launchLaterVisible = element == LAUNCH_LATER; 232 launchDailyVisible = element == LAUNCH_DAILY; 233 launchWeeklyVisible = element == LAUNCH_WEEKLY; 234 launchMonthlyVisible = element == LAUNCH_MONTHLY; 235 cronVisible = element == CRON; 236 } 237 launchLaterPanel.setVisible(launchLaterVisible); 238 dailyPanel.setVisible(launchDailyVisible); 239 weeklyPanel.setVisible(launchWeeklyVisible); 240 monthlyPanel.setVisible(launchMonthlyVisible); 241 cronPanel.setVisible(cronVisible); 242 } 243 }); 244 launchLaterPanel.setVisible(false); 245 dailyPanel.setVisible(false); 246 weeklyPanel.setVisible(false); 247 monthlyPanel.setVisible(false); 248 cronPanel.setVisible(false); 249 250 int width = 0; 251 int height = 0; 252 Component[] comps = 253 {launchLaterPanel, dailyPanel, weeklyPanel, monthlyPanel, cronPanel}; 254 for (Component comp : comps) 255 { 256 width = Math.max(width, comp.getPreferredSize().width); 257 height = Math.max(height, comp.getPreferredSize().height); 258 } 259 260 gbc.gridy ++; 261 gbc.gridwidth = 1; 262 gbc.gridx = 0; 263 gbc.weightx = 0.0; 264 gbc.insets.left = 30; 265 add(launchLaterPanel, gbc); 266 add(dailyPanel, gbc); 267 add(weeklyPanel, gbc); 268 add(monthlyPanel, gbc); 269 add(cronPanel, gbc); 270 add(Box.createRigidArea(new Dimension(width, height)), gbc); 271 gbc.gridy ++; 272 gbc.gridx = 0; 273 gbc.fill = GridBagConstraints.VERTICAL; 274 gbc.weighty = 1.0; 275 add(Box.createVerticalGlue(), gbc); 276 } 277 278 /** {@inheritDoc} */ 279 public void toBeDisplayed(boolean visible) 280 { 281 // Reset the schedule and the labels 282 if (visible) 283 { 284 schedule = null; 285 setPrimaryValid(lTime); 286 setPrimaryValid(lDay); 287 setPrimaryValid(lMonth); 288 setPrimaryValid(lYear); 289 setPrimaryValid(lWeeklyTime); 290 setPrimaryValid(lWeeklyDays); 291 setPrimaryValid(lMonthlyTime); 292 setPrimaryValid(lMonthlyDays); 293 setPrimaryValid(lCronMinute); 294 setPrimaryValid(lCronHour); 295 setPrimaryValid(lCronMonthDay); 296 setPrimaryValid(lCronMonth); 297 setPrimaryValid(lCronWeekDay); 298 } 299 } 300 301 /** {@inheritDoc} */ 302 public LocalizableMessage getTitle() 303 { 304 return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TITLE.get(taskName); 305 } 306 307 /** {@inheritDoc} */ 308 public void okClicked() 309 { 310 schedule = null; 311 ArrayList<LocalizableMessage> errorMessages = new ArrayList<>(); 312 313 updateErrorMessages(errorMessages); 314 315 if (!errorMessages.isEmpty()) 316 { 317 displayErrorDialog(errorMessages); 318 } 319 else 320 { 321 schedule = createSchedule(); 322 Utilities.getParentDialog(this).setVisible(false); 323 } 324 } 325 326 /** 327 * Checks the validity of the provided information and updates the provided 328 * collection of messages with the errors that have been found. 329 * @param errorMessages the collection of messages to be updated. 330 */ 331 private void updateErrorMessages(Collection<LocalizableMessage> errorMessages) 332 { 333 Object type = 334 ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue(); 335 if (type == LAUNCH_LATER) 336 { 337 updateLaunchLaterErrorMessages(errorMessages); 338 } 339 else if (type == LAUNCH_DAILY) 340 { 341 updateLaunchDailyErrorMessages(errorMessages); 342 } 343 else if (type == LAUNCH_WEEKLY) 344 { 345 updateLaunchWeeklyErrorMessages(errorMessages); 346 } 347 else if (type == LAUNCH_MONTHLY) 348 { 349 updateLaunchMonthlyErrorMessages(errorMessages); 350 } 351 else if (type == CRON) 352 { 353 updateCronErrorMessages(errorMessages); 354 } 355 } 356 357 /** 358 * Checks the validity of the launch later information and updates 359 * the provided collection of messages with the errors that have been found. 360 * The associated labels are also updated. 361 * @param errorMessages the collection of messages to be updated. 362 */ 363 private void updateLaunchLaterErrorMessages(Collection<LocalizableMessage> errorMessages) 364 { 365 setPrimaryValid(lTime); 366 setPrimaryValid(lDay); 367 setPrimaryValid(lMonth); 368 setPrimaryValid(lYear); 369 370 int previousErrorNumber = errorMessages.size(); 371 372 int y = Integer.parseInt(year.getSelectedItem().toString()); 373 int d = -1; 374 int m = month.getSelectedIndex(); 375 int[] h = {-1}; 376 int[] min = {-1}; 377 checkTime(time, lTime, h, min, errorMessages); 378 try 379 { 380 d = Integer.parseInt(day.getText().trim()); 381 if (d < 0 || d > 31) 382 { 383 errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get()); 384 setPrimaryInvalid(lDay); 385 } 386 } 387 catch (Exception ex) 388 { 389 errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get()); 390 setPrimaryInvalid(lDay); 391 } 392 393 if (errorMessages.size() == previousErrorNumber) 394 { 395 GregorianCalendar calendar = new GregorianCalendar(y, m, d, h[0], min[0]); 396 Date date = calendar.getTime(); 397 // Check that the actual date's month date corresponds to a valid day 398 // (for instance if user specifies 30th of February, the resulting date 399 // is 2nd (or 1st depending of the year) of Mars. 400 if (calendar.get(Calendar.MONTH) != m) 401 { 402 errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY_IN_MONTH.get(d, month.getSelectedItem())); 403 setPrimaryInvalid(lDay); 404 setPrimaryInvalid(lMonth); 405 } 406 else if (date.before(new Date())) 407 { 408 errorMessages.add(ERR_CTRL_PANEL_DATE_ALREADY_PASSED.get()); 409 setPrimaryInvalid(lTime); 410 setPrimaryInvalid(lDay); 411 setPrimaryInvalid(lMonth); 412 setPrimaryInvalid(lYear); 413 } 414 } 415 } 416 417 /** 418 * Checks the validity of the launch daily information and updates 419 * the provided collection of messages with the errors that have been found. 420 * The associated labels are also updated. 421 * @param errorMessages the collection of messages to be updated. 422 */ 423 private void updateLaunchDailyErrorMessages(Collection<LocalizableMessage> errorMessages) 424 { 425 setPrimaryValid(lDailyTime); 426 427 int[] h = {-1}; 428 int[] min = {-1}; 429 checkTime(dailyTime, lDailyTime, h, min, errorMessages); 430 } 431 432 /** 433 * Checks the validity of the launch weekly information and updates 434 * the provided collection of messages with the errors that have been found. 435 * The associated labels are also updated. 436 * @param errorMessages the collection of messages to be updated. 437 */ 438 private void updateLaunchWeeklyErrorMessages( 439 Collection<LocalizableMessage> errorMessages) 440 { 441 setPrimaryValid(lWeeklyTime); 442 setPrimaryValid(lWeeklyDays); 443 444 int[] h = {-1}; 445 int[] min = {-1}; 446 checkTime(weeklyTime, lWeeklyTime, h, min, errorMessages); 447 448 boolean oneSelected = false; 449 for (JCheckBox cb : weekDays) 450 { 451 if (cb.isSelected()) 452 { 453 oneSelected = true; 454 break; 455 } 456 } 457 if (!oneSelected) 458 { 459 errorMessages.add(ERR_CTRL_PANEL_NO_WEEK_DAY_SELECTED.get()); 460 setPrimaryInvalid(lWeeklyDays); 461 } 462 } 463 464 /** 465 * Checks the validity of the launch monthly information and updates 466 * the provided collection of messages with the errors that have been found. 467 * The associated labels are also updated. 468 * @param errorMessages the collection of messages to be updated. 469 */ 470 private void updateLaunchMonthlyErrorMessages( 471 Collection<LocalizableMessage> errorMessages) 472 { 473 setPrimaryValid(lMonthlyTime); 474 setPrimaryValid(lMonthlyDays); 475 476 int[] h = {-1}; 477 int[] min = {-1}; 478 checkTime(monthlyTime, lMonthlyTime, h, min, errorMessages); 479 480 boolean oneSelected = false; 481 for (JCheckBox cb : monthDays) 482 { 483 if (cb.isSelected()) 484 { 485 oneSelected = true; 486 break; 487 } 488 } 489 if (!oneSelected) 490 { 491 errorMessages.add(ERR_CTRL_PANEL_NO_MONTH_DAY_SELECTED.get()); 492 setPrimaryInvalid(lMonthlyDays); 493 } 494 } 495 496 /** 497 * Checks the validity of the cron schedule information and updates 498 * the provided collection of messages with the errors that have been found. 499 * The associated labels are also updated. 500 * @param errorMessages the collection of messages to be updated. 501 */ 502 private void updateCronErrorMessages(Collection<LocalizableMessage> errorMessages) 503 { 504 setPrimaryValid(lCronMinute); 505 setPrimaryValid(lCronHour); 506 setPrimaryValid(lCronMonthDay); 507 setPrimaryValid(lCronMonth); 508 setPrimaryValid(lCronWeekDay); 509 510 String minute = cronMinute.getText().trim(); 511 String hour = cronHour.getText().trim(); 512 String monthDay = cronMonthDay.getText().trim(); 513 String month = cronMonth.getText().trim(); 514 String weekDay = cronWeekDay.getText().trim(); 515 516 updateCronErrorMessages(minute, lCronMinute, 517 ERR_CTRL_PANEL_NO_CRON_MINUTE_PROVIDED.get(), 518 ERR_CTRL_PANEL_NOT_VALID_CRON_MINUTE_PROVIDED.get(), 519 0, 59, 520 errorMessages); 521 updateCronErrorMessages(hour, lCronHour, 522 ERR_CTRL_PANEL_NO_CRON_HOUR_PROVIDED.get(), 523 ERR_CTRL_PANEL_NOT_VALID_CRON_HOUR_PROVIDED.get(), 524 0, 23, 525 errorMessages); 526 updateCronErrorMessages(weekDay, lCronWeekDay, 527 ERR_CTRL_PANEL_NO_CRON_WEEK_DAY_PROVIDED.get(), 528 ERR_CTRL_PANEL_NOT_VALID_CRON_WEEK_DAY_PROVIDED.get(), 529 0, 6, 530 errorMessages); 531 updateCronErrorMessages(monthDay, lCronMonthDay, 532 ERR_CTRL_PANEL_NO_CRON_MONTH_DAY_PROVIDED.get(), 533 ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_DAY_PROVIDED.get(), 534 1, 31, 535 errorMessages); 536 updateCronErrorMessages(month, lCronMonth, 537 ERR_CTRL_PANEL_NO_CRON_MONTH_PROVIDED.get(), 538 ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_PROVIDED.get(), 539 1, 12, 540 errorMessages); 541 } 542 543 /** 544 * Checks the validity of the cron schedule information tab and updates 545 * the provided collection of messages with the errors that have been found. 546 * The associated labels are also updated. 547 * @param value the value of the cron schedule tab. 548 * @param label the label associated with the cron schedule tab. 549 * @param errorIfEmpty the message to be displayed if the value tab is empty. 550 * @param contentError the message to be displayed if the value tab is not 551 * valid. 552 * @param minValue the minimum value accepted. 553 * @param maxValue the maximum value accepted. 554 * @param errorMessages the collection of messages to be updated. 555 */ 556 private void updateCronErrorMessages(String value, JLabel label, 557 LocalizableMessage errorIfEmpty, LocalizableMessage contentError, int minValue, int maxValue, 558 Collection<LocalizableMessage> errorMessages) 559 { 560 if (value.length() == 0) 561 { 562 errorMessages.add(errorIfEmpty); 563 setPrimaryInvalid(label); 564 } 565 else 566 { 567 try 568 { 569 RecurringTask.parseTaskTabField(value, minValue, maxValue); 570 } 571 catch (Exception ex) 572 { 573 errorMessages.add(contentError); 574 setPrimaryInvalid(label); 575 } 576 } 577 } 578 579 /** 580 * Returns the schedule type corresponding to the input provided by user. 581 * This method assumes that all the date provided by the user has been 582 * validated. 583 * @return the schedule type corresponding to the input provided by user. 584 */ 585 private ScheduleType createSchedule() 586 { 587 ScheduleType schedule; 588 Object type = 589 ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue(); 590 if (type == LAUNCH_NOW) 591 { 592 schedule = ScheduleType.createLaunchNow(); 593 } 594 else if (type == LAUNCH_LATER) 595 { 596 int y = Integer.parseInt(year.getSelectedItem().toString()); 597 int d = Integer.parseInt(day.getText().trim()); 598 int m = month.getSelectedIndex(); 599 String sTime = time.getText().trim(); 600 int index = sTime.indexOf(':'); 601 int h = Integer.parseInt(sTime.substring(0, index).trim()); 602 int min = Integer.parseInt(sTime.substring(index+1).trim()); 603 GregorianCalendar calendar = new GregorianCalendar(y, m, d, h, min); 604 schedule = ScheduleType.createLaunchLater(calendar.getTime()); 605 } 606 else if (type == LAUNCH_DAILY) 607 { 608 String sTime = dailyTime.getText().trim(); 609 int index = sTime.indexOf(':'); 610 int h = Integer.parseInt(sTime.substring(0, index).trim()); 611 int m = Integer.parseInt(sTime.substring(index+1).trim()); 612 String cron = m+" "+h+" * * *"; 613 schedule = ScheduleType.createCron(cron); 614 } 615 else if (type == LAUNCH_WEEKLY) 616 { 617 String sTime = weeklyTime.getText().trim(); 618 int index = sTime.indexOf(':'); 619 int h = Integer.parseInt(sTime.substring(0, index).trim()); 620 int m = Integer.parseInt(sTime.substring(index+1).trim()); 621 StringBuilder sb = new StringBuilder(); 622 sb.append(m).append(" ").append(h).append(" * * "); 623 624 boolean oneDayAdded = false; 625 for (int i=0; i<weekDays.length; i++) 626 { 627 if (weekDays[i].isSelected()) 628 { 629 if (oneDayAdded) 630 { 631 sb.append(','); 632 } 633 sb.append(i); 634 oneDayAdded = true; 635 } 636 } 637 schedule = ScheduleType.createCron(sb.toString()); 638 } 639 else if (type == LAUNCH_MONTHLY) 640 { 641 String sTime = monthlyTime.getText().trim(); 642 int index = sTime.indexOf(':'); 643 int h = Integer.parseInt(sTime.substring(0, index).trim()); 644 int m = Integer.parseInt(sTime.substring(index+1).trim()); 645 StringBuilder sb = new StringBuilder(); 646 sb.append(m).append(" ").append(h).append(" "); 647 boolean oneDayAdded = false; 648 for (int i=0; i<monthDays.length; i++) 649 { 650 if (monthDays[i].isSelected()) 651 { 652 if (oneDayAdded) 653 { 654 sb.append(','); 655 } 656 sb.append(i+1); 657 oneDayAdded = true; 658 } 659 } 660 sb.append(" * *"); 661 schedule = ScheduleType.createCron(sb.toString()); 662 } 663 else if (type == CRON) 664 { 665 String cron = cronMinute.getText().trim() + " "+ 666 cronHour.getText().trim() + " "+ 667 cronMonthDay.getText().trim() + " "+ 668 cronMonth.getText().trim() + " "+ 669 cronWeekDay.getText().trim(); 670 schedule = ScheduleType.createCron(cron); 671 } 672 else 673 { 674 throw new RuntimeException("Unknown schedule type: "+type); 675 } 676 return schedule; 677 } 678 679 /** 680 * Convenience method to retrieve the time specified by the user. 681 * @param time the text field where the user specifies time. 682 * @param lTime the label associated with the text field. 683 * @param h an integer array of size 1 where the value of the hour specified 684 * by the user will be set. 685 * @param m an integer array of size 1 where the value of the minute specified 686 * by the user will be set. 687 * @param errorMessages the collection of error messages that will be updated 688 * with the encountered problems. 689 */ 690 private void checkTime(JTextField time, JLabel lTime, int[] h, int[] m, 691 Collection<LocalizableMessage> errorMessages) 692 { 693 String sTime = time.getText().trim(); 694 int index = sTime.indexOf(':'); 695 try 696 { 697 h[0] = Integer.parseInt(sTime.substring(0, index).trim()); 698 m[0] = Integer.parseInt(sTime.substring(index+1).trim()); 699 if (h[0] < 0 || h[0] > 23) 700 { 701 errorMessages.add(ERR_CTRL_PANEL_INVALID_HOUR.get()); 702 setPrimaryInvalid(lTime); 703 } 704 if (m[0] < 0 || m[0] > 59) 705 { 706 errorMessages.add(ERR_CTRL_PANEL_INVALID_MINUTE.get()); 707 setPrimaryInvalid(lTime); 708 } 709 } 710 catch (Exception ex) 711 { 712 errorMessages.add(ERR_CTRL_PANEL_INVALID_TIME.get()); 713 setPrimaryInvalid(lTime); 714 } 715 } 716 717 /** 718 * Tells whether the user chose to close the dialog discarding the provided 719 * input. 720 * @return <CODE>true</CODE> if the user chose to close the dialog discarding 721 * the provided input and <CODE>false</CODE> otherwise. 722 */ 723 public boolean isCanceled() 724 { 725 return schedule == null; 726 } 727 728 /** {@inheritDoc} */ 729 public void configurationChanged(ConfigurationChangeEvent ev) 730 { 731 } 732 733 /** {@inheritDoc} */ 734 public Component getPreferredFocusComponent() 735 { 736 return scheduleType; 737 } 738 739 /** 740 * Returns the schedule provided by the user. 741 * @return the schedule provided by the user. 742 */ 743 public ScheduleType getSchedule() 744 { 745 return schedule; 746 } 747 748 private Component createLaunchLaterPanel() 749 { 750 JPanel panel = new JPanel(new GridBagLayout()); 751 panel.setOpaque(false); 752 GridBagConstraints gbc = new GridBagConstraints(); 753 Calendar calendar = Calendar.getInstance(); 754 755 int currentYear = calendar.get(Calendar.YEAR); 756 int currentHour = calendar.get(Calendar.HOUR_OF_DAY); 757 int currentMinute = calendar.get(Calendar.MINUTE); 758 int currentDay = calendar.get(Calendar.DAY_OF_MONTH); 759 int currentMonth = calendar.get(Calendar.MONTH); 760 761 time = Utilities.createShortTextField(); 762 PlainDocument plainTextDocument = new PlainDocument(); 763 time.setDocument(plainTextDocument); 764 String sHour = currentHour >= 10 ? 765 String.valueOf(currentHour) : "0"+currentHour; 766 String sMinute = currentMinute >= 10 ? 767 String.valueOf(currentMinute) : "0"+currentMinute; 768 time.setText(sHour+":"+sMinute); 769 plainTextDocument.setDocumentFilter(new TimeDocumentFilter(time)); 770 771 772 day = Utilities.createShortTextField(); 773 day.setColumns(4); 774 plainTextDocument = new PlainDocument(); 775 day.setDocument(plainTextDocument); 776 day.setText(String.valueOf(currentDay)); 777 plainTextDocument.setDocumentFilter( 778 new NumericLimitedSizeDocumentFilter(day, 2)); 779 month = Utilities.createComboBox(); 780 year = Utilities.createComboBox(); 781 782 int[][] maxMin = 783 { 784 {currentYear, currentYear + 5} 785 }; 786 787 JComboBox[] numericBoxes = 788 { 789 year 790 }; 791 792 int[] currentValues = 793 { 794 currentYear 795 }; 796 797 for (int i=0; i<maxMin.length; i++) 798 { 799 int min = maxMin[i][0]; 800 int max = maxMin[i][1]; 801 802 DefaultComboBoxModel model = new DefaultComboBoxModel(); 803 804 int selectedIndex = 0; 805 806 int index = 0; 807 for (int j=min; j<=max; j++) 808 { 809 String s; 810 if (j < 10) 811 { 812 s = "0"+j; 813 } 814 else 815 { 816 s = String.valueOf(j); 817 } 818 model.addElement(s); 819 820 if (j == currentValues[i]) 821 { 822 selectedIndex= index; 823 } 824 index++; 825 } 826 827 numericBoxes[i].setModel(model); 828 829 if (selectedIndex != 0) 830 { 831 numericBoxes[i].setSelectedIndex(selectedIndex); 832 } 833 } 834 835 DefaultComboBoxModel model = new DefaultComboBoxModel(); 836 month.setModel(model); 837 838 LocalizableMessage[] monthMessages = 839 { 840 INFO_CTRL_PANEL_JANUARY.get(), 841 INFO_CTRL_PANEL_FEBRUARY.get(), 842 INFO_CTRL_PANEL_MARCH.get(), 843 INFO_CTRL_PANEL_APRIL.get(), 844 INFO_CTRL_PANEL_MAY.get(), 845 INFO_CTRL_PANEL_JUNE.get(), 846 INFO_CTRL_PANEL_JULY.get(), 847 INFO_CTRL_PANEL_AUGUST.get(), 848 INFO_CTRL_PANEL_SEPTEMBER.get(), 849 INFO_CTRL_PANEL_OCTOBER.get(), 850 INFO_CTRL_PANEL_NOVEMBER.get(), 851 INFO_CTRL_PANEL_DECEMBER.get(), 852 }; 853 for (LocalizableMessage msg : monthMessages) 854 { 855 model.addElement(msg.toString()); 856 } 857 858 month.setSelectedIndex(currentMonth); 859 860 lTime = Utilities.createPrimaryLabel( 861 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); 862 lDay = Utilities.createPrimaryLabel( 863 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAY.get()); 864 lMonth = Utilities.createPrimaryLabel( 865 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTH.get()); 866 lYear = Utilities.createPrimaryLabel( 867 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_YEAR.get()); 868 869 gbc.gridy = 0; 870 871 JLabel[] labels = {lTime, lDay, lMonth, lYear}; 872 JComponent[] comps = {time, day, month, year}; 873 LocalizableMessage[] inlineHelp = 874 { 875 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME_TOOLTIP.get(), 876 null, 877 null, 878 null 879 }; 880 881 gbc.gridwidth = 1; 882 gbc.fill = GridBagConstraints.HORIZONTAL; 883 884 for (int i=0; i<labels.length; i++) 885 { 886 gbc.gridx = 0; 887 gbc.weightx = 0.0; 888 gbc.gridwidth = 1; 889 890 panel.add(labels[i], gbc); 891 gbc.gridx = 1; 892 gbc.insets.left = 10; 893 panel.add(comps[i], gbc); 894 gbc.gridx = 2; 895 gbc.weightx = 1.0; 896 gbc.insets.left = 0; 897 panel.add(Box.createHorizontalGlue(), gbc); 898 899 if (inlineHelp[i] != null) 900 { 901 gbc.gridwidth = 2; 902 gbc.insets.top = 3; 903 gbc.insets.left = 10; 904 gbc.gridx = 1; 905 gbc.gridy ++; 906 panel.add(Utilities.createInlineHelpLabel(inlineHelp[i]), gbc); 907 } 908 909 gbc.insets.top = 10; 910 gbc.gridy ++; 911 } 912 913 gbc.insets.top = 0; 914 gbc.weighty = 1.0; 915 gbc.fill = GridBagConstraints.VERTICAL; 916 panel.add(Box.createVerticalGlue(), gbc); 917 918 return panel; 919 } 920 921 private Component createDailyPanel() 922 { 923 JPanel panel = new JPanel(new GridBagLayout()); 924 panel.setOpaque(false); 925 GridBagConstraints gbc = new GridBagConstraints(); 926 gbc.gridx = 0; 927 gbc.gridy = 0; 928 gbc.weightx = 0.0; 929 930 lDailyTime = 931 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); 932 933 dailyTime = Utilities.createShortTextField(); 934 PlainDocument plainTextDocument = new PlainDocument(); 935 dailyTime.setDocument(plainTextDocument); 936 dailyTime.setColumns(4); 937 dailyTime.setText("00:00"); 938 plainTextDocument.setDocumentFilter(new TimeDocumentFilter(dailyTime)); 939 940 panel.add(lDailyTime, gbc); 941 gbc.gridx = 1; 942 gbc.insets.left = 10; 943 gbc.fill = GridBagConstraints.NONE; 944 panel.add(dailyTime, gbc); 945 gbc.gridx = 2; 946 gbc.weightx = 1.0; 947 gbc.insets.left = 0; 948 gbc.fill = GridBagConstraints.HORIZONTAL; 949 panel.add(Box.createHorizontalGlue(), gbc); 950 951 gbc.gridy ++; 952 gbc.gridwidth = 2; 953 gbc.insets.top = 3; 954 gbc.insets.left = 10; 955 gbc.gridx = 1; 956 panel.add(Utilities.createInlineHelpLabel( 957 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME_TOOLTIP.get()), gbc); 958 959 return panel; 960 } 961 962 private Component createWeeklyPanel() 963 { 964 JPanel panel = new JPanel(new GridBagLayout()); 965 panel.setOpaque(false); 966 GridBagConstraints gbc = new GridBagConstraints(); 967 gbc.gridx = 0; 968 gbc.gridy = 0; 969 gbc.weightx = 0.0; 970 971 lWeeklyTime = 972 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); 973 974 weeklyTime = Utilities.createShortTextField(); 975 PlainDocument plainTextDocument = new PlainDocument(); 976 weeklyTime.setDocument(plainTextDocument); 977 weeklyTime.setColumns(4); 978 weeklyTime.setText("00:00"); 979 plainTextDocument.setDocumentFilter(new TimeDocumentFilter(weeklyTime)); 980 981 lWeeklyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get()); 982 for (JCheckBox cb : weekDays) 983 { 984 cb.setFont(ColorAndFontConstants.inlineHelpFont); 985 } 986 sunday.setSelected(true); 987 wednesday.setSelected(true); 988 989 gbc.anchor = GridBagConstraints.WEST; 990 panel.add(lWeeklyTime, gbc); 991 gbc.gridx = 1; 992 gbc.insets.left = 10; 993 gbc.gridwidth = weekDays.length; 994 gbc.fill = GridBagConstraints.NONE; 995 panel.add(weeklyTime, gbc); 996 gbc.gridx = 2; 997 gbc.weightx = 1.0; 998 gbc.insets.left = 0; 999 gbc.gridwidth = 1; 1000 gbc.fill = GridBagConstraints.HORIZONTAL; 1001 panel.add(Box.createHorizontalGlue(), gbc); 1002 gbc.gridy ++; 1003 gbc.gridwidth = weekDays.length + 1; 1004 gbc.insets.top = 3; 1005 gbc.insets.left = 10; 1006 gbc.gridx = 1; 1007 panel.add(Utilities.createInlineHelpLabel( 1008 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME_TOOLTIP.get()), gbc); 1009 1010 gbc.gridx = 0; 1011 gbc.gridy ++; 1012 gbc.insets.top = 10; 1013 gbc.weightx = 1.0; 1014 panel.add(lWeeklyDays, gbc); 1015 gbc.insets.left = 10; 1016 gbc.gridwidth = 1; 1017 for (JCheckBox cb : weekDays) 1018 { 1019 gbc.gridx ++; 1020 panel.add(cb, gbc); 1021 } 1022 gbc.weightx = 1.0; 1023 gbc.insets.left = 0; 1024 gbc.gridwidth = 1; 1025 gbc.gridx ++; 1026 panel.add(Box.createHorizontalGlue(), gbc); 1027 1028 return panel; 1029 } 1030 1031 private Component createMonthlyPanel() 1032 { 1033 JPanel panel = new JPanel(new GridBagLayout()); 1034 panel.setOpaque(false); 1035 GridBagConstraints gbc = new GridBagConstraints(); 1036 gbc.gridx = 0; 1037 gbc.gridy = 0; 1038 gbc.weightx = 0.0; 1039 1040 lMonthlyTime = 1041 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); 1042 1043 monthlyTime = Utilities.createShortTextField(); 1044 PlainDocument plainTextDocument = new PlainDocument(); 1045 monthlyTime.setDocument(plainTextDocument); 1046 monthlyTime.setColumns(4); 1047 monthlyTime.setText("00:00"); 1048 plainTextDocument.setDocumentFilter(new TimeDocumentFilter(monthlyTime)); 1049 1050 lMonthlyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get()); 1051 1052 gbc.anchor = GridBagConstraints.WEST; 1053 panel.add(lMonthlyTime, gbc); 1054 gbc.gridx = 1; 1055 gbc.insets.left = 10; 1056 gbc.fill = GridBagConstraints.NONE; 1057 gbc.gridwidth = 7; 1058 panel.add(monthlyTime, gbc); 1059 gbc.gridx = 2; 1060 gbc.weightx = 1.0; 1061 gbc.insets.left = 0; 1062 gbc.gridwidth = 1; 1063 gbc.fill = GridBagConstraints.HORIZONTAL; 1064 panel.add(Box.createHorizontalGlue(), gbc); 1065 gbc.gridy ++; 1066 gbc.gridwidth = 8; 1067 gbc.insets.top = 3; 1068 gbc.insets.left = 10; 1069 gbc.gridx = 1; 1070 panel.add(Utilities.createInlineHelpLabel( 1071 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME_TOOLTIP.get()), gbc); 1072 1073 gbc.gridx = 0; 1074 gbc.gridy ++; 1075 gbc.insets.top = 10; 1076 gbc.weightx = 1.0; 1077 gbc.gridwidth = 1; 1078 panel.add(lMonthlyDays, gbc); 1079 gbc.insets.left = 10; 1080 gbc.gridwidth = 1; 1081 for (int i=0 ; i<monthDays.length; i++) 1082 { 1083 monthDays[i] = Utilities.createCheckBox(LocalizableMessage.raw(String.valueOf(i+1))); 1084 monthDays[i].setFont(ColorAndFontConstants.inlineHelpFont); 1085 int x = i % 7; 1086 if (x == 0 && i != 0) 1087 { 1088 gbc.gridy ++; 1089 gbc.insets.top = 5; 1090 } 1091 if (x != 0) 1092 { 1093 gbc.insets.left = 5; 1094 } 1095 else 1096 { 1097 gbc.insets.left = 10; 1098 } 1099 gbc.gridx = x + 1; 1100 panel.add(monthDays[i], gbc); 1101 } 1102 monthDays[0].setSelected(true); 1103 gbc.weightx = 1.0; 1104 gbc.insets.left = 0; 1105 gbc.gridwidth = 1; 1106 gbc.gridx ++; 1107 panel.add(Box.createHorizontalGlue(), gbc); 1108 1109 return panel; 1110 } 1111 1112 private Component createCronPanel() 1113 { 1114 JPanel panel = new JPanel(new GridBagLayout()); 1115 panel.setOpaque(false); 1116 GridBagConstraints gbc = new GridBagConstraints(); 1117 1118 JEditorPane explanation = Utilities.makeHtmlPane( 1119 INFO_CTRL_PANEL_CRON_HELP.get(), 1120 ColorAndFontConstants.inlineHelpFont); 1121 gbc.gridx = 0; 1122 gbc.gridy = 0; 1123 gbc.gridwidth = 2; 1124 gbc.fill = GridBagConstraints.HORIZONTAL; 1125 panel.add(explanation, gbc); 1126 gbc.gridy ++; 1127 gbc.insets.top = 10; 1128 1129 gbc.gridwidth = 1; 1130 lCronMinute = Utilities.createPrimaryLabel( 1131 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MINUTE.get()); 1132 lCronHour = Utilities.createPrimaryLabel( 1133 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_HOUR.get()); 1134 lCronWeekDay = Utilities.createPrimaryLabel( 1135 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_WEEK_DAY.get()); 1136 lCronMonthDay = Utilities.createPrimaryLabel( 1137 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH_DAY.get()); 1138 lCronMonth = Utilities.createPrimaryLabel( 1139 INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH.get()); 1140 1141 cronMinute = Utilities.createShortTextField(); 1142 cronMinute.setText("*"); 1143 1144 cronHour = Utilities.createShortTextField(); 1145 cronHour.setText("*"); 1146 1147 cronWeekDay = Utilities.createShortTextField(); 1148 cronWeekDay.setText("*"); 1149 1150 cronMonthDay = Utilities.createShortTextField(); 1151 cronMonthDay.setText("*"); 1152 1153 cronMonth = Utilities.createShortTextField(); 1154 cronMonth.setText("*"); 1155 1156 JLabel[] labels = {lCronMinute, lCronHour, lCronWeekDay, lCronMonthDay, 1157 lCronMonth}; 1158 Component[] comps = {cronMinute, cronHour, cronWeekDay, cronMonthDay, 1159 cronMonth}; 1160 LocalizableMessage[] help = 1161 { 1162 INFO_CTRL_PANEL_CRON_MINUTE_HELP.get(), 1163 INFO_CTRL_PANEL_CRON_HOUR_HELP.get(), 1164 INFO_CTRL_PANEL_CRON_WEEK_DAY_HELP.get(), 1165 INFO_CTRL_PANEL_CRON_MONTH_DAY_HELP.get(), 1166 INFO_CTRL_PANEL_CRON_MONTH_HELP.get(), 1167 }; 1168 1169 gbc.gridwidth = 1; 1170 gbc.fill = GridBagConstraints.HORIZONTAL; 1171 1172 for (int i=0; i<labels.length; i++) 1173 { 1174 gbc.gridx = 0; 1175 gbc.weightx = 0.0; 1176 1177 gbc.insets.left = 0; 1178 panel.add(labels[i], gbc); 1179 gbc.gridx = 1; 1180 gbc.insets.left = 10; 1181 panel.add(comps[i], gbc); 1182 gbc.gridx = 2; 1183 gbc.weightx = 1.0; 1184 gbc.insets.left = 0; 1185 panel.add(Box.createHorizontalGlue(), gbc); 1186 if (help[i] != null) 1187 { 1188 gbc.insets.top = 3; 1189 gbc.insets.left = 10; 1190 gbc.gridy ++; 1191 gbc.gridx = 1; 1192 panel.add(Utilities.createInlineHelpLabel(help[i]), gbc); 1193 } 1194 1195 gbc.insets.top = 10; 1196 gbc.gridy ++; 1197 } 1198 1199 gbc.insets.top = 0; 1200 gbc.weighty = 1.0; 1201 gbc.fill = GridBagConstraints.VERTICAL; 1202 panel.add(Box.createVerticalGlue(), gbc); 1203 1204 return panel; 1205 } 1206 1207 /** 1208 * The main method to test this panel. 1209 * @param args the arguments. 1210 */ 1211 public static void main(String[] args) 1212 { 1213 while (true) 1214 { 1215 TaskToSchedulePanel p = new TaskToSchedulePanel("TEST TASK"); 1216 GenericDialog dlg = new GenericDialog(Utilities.createFrame(), p); 1217 dlg.setModal(true); 1218 dlg.setVisible(true); 1219 } 1220 } 1221}