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