opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
@@ -679,6 +679,7 @@ desc.setAuthenticated(reader instanceof ConfigFromDirContext); desc.setJavaVersion(reader.getJavaVersion()); desc.setOpenConnections(reader.getOpenConnections()); desc.setTaskEntries(reader.getTaskEntries()); if (reader instanceof ConfigFromDirContext) { ConfigFromDirContext rCtx = (ConfigFromDirContext)reader; opends/src/guitools/org/opends/guitools/controlpanel/datamodel/CustomSearchResult.java
@@ -27,9 +27,13 @@ package org.opends.guitools.controlpanel.datamodel; import static org.opends.server.util.StaticUtils.toLowerCase; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; @@ -44,6 +48,17 @@ import javax.naming.directory.SearchResult; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.server.core.DirectoryServer; import org.opends.server.types.AttributeBuilder; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.AttributeValues; import org.opends.server.types.ByteString; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.util.LDIFReader; /** * This is a commodity class used to wrap the SearchResult class of JNDI. @@ -261,4 +276,89 @@ { return 23 + toString.hashCode(); } /** * Gets the Entry object equivalent to this CustomSearchResult. * The method assumes that the schema in DirectoryServer has been initialized. * @return the Entry object equivalent to this CustomSearchResult. * @throws OpenDsException if there is an error parsing the DN or retrieving * the attributes definition and objectclasses in the schema of the server. */ public Entry getEntry() throws OpenDsException { DN dn = DN.decode(this.getDN()); Map<ObjectClass,String> objectClasses = new HashMap<ObjectClass,String>(); Map<AttributeType,List<org.opends.server.types.Attribute>> userAttributes = new HashMap<AttributeType,List<org.opends.server.types.Attribute>>(); Map<AttributeType,List<org.opends.server.types.Attribute>> operationalAttributes = new HashMap<AttributeType,List<org.opends.server.types.Attribute>>(); for (String wholeName : this.getAttributeNames()) { final org.opends.server.types.Attribute attribute = LDIFReader.parseAttrDescription(wholeName); final String attrName = attribute.getName(); final String lowerName = toLowerCase(attrName); // See if this is an objectclass or an attribute. Then get the // corresponding definition and add the value to the appropriate hash. if (lowerName.equals("objectclass")) { for (Object value : this.getAttributeValues(attrName)) { String ocName = value.toString().trim(); String lowerOCName = toLowerCase(ocName); ObjectClass objectClass = DirectoryServer.getObjectClass(lowerOCName); if (objectClass == null) { objectClass = DirectoryServer.getDefaultObjectClass(ocName); } objectClasses.put(objectClass, ocName); } } else { AttributeType attrType = DirectoryServer.getAttributeType(lowerName); if (attrType == null) { attrType = DirectoryServer.getDefaultAttributeType(attrName); } AttributeBuilder builder = new AttributeBuilder(attribute, true); for (Object value : this.getAttributeValues(attrName)) { ByteString bs; if (value instanceof byte[]) { bs = ByteString.wrap((byte[])value); } else { bs = ByteString.valueOf(value.toString()); } AttributeValue attributeValue = AttributeValues.create(attrType, bs); builder.add(attributeValue); } List<org.opends.server.types.Attribute> attrList = new ArrayList<org.opends.server.types.Attribute>(1); attrList.add(builder.toAttribute()); if (attrType.isOperational()) { operationalAttributes.put(attrType, attrList); } else { userAttributes.put(attrType, attrList); } } } return new Entry(dn, objectClasses, userAttributes, operationalAttributes); } } opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ScheduleType.java
New file @@ -0,0 +1,206 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.datamodel; import java.util.Date; /** * The class to be used to describe the task schedule. * */ public class ScheduleType { /** * The different type of schedules. * */ public enum Type { /** * Launch now. */ LAUNCH_NOW, /** * Launch later in a specific date. */ LAUNCH_LATER, /** * Launch periodically. */ LAUNCH_PERIODICALLY } private Type type; private Date launchLaterDate; private String cronValue; private String toString; private int hashCode; private ScheduleType() { } /** * Returns a schedule instance that launches the task now. * @return a schedule instance that launches the task now. */ public static ScheduleType createLaunchNow() { ScheduleType schedule = new ScheduleType(); schedule.type = Type.LAUNCH_NOW; schedule.toString = schedule.calculateToString(); schedule.hashCode = schedule.calculateHashCode(); return schedule; } /** * Returns a schedule instance that launches the task at a given date. * @param date the Date at which the task must be launched. * @return a schedule instance that launches the task at a given date. */ public static ScheduleType createLaunchLater(Date date) { ScheduleType schedule = new ScheduleType(); schedule.type = Type.LAUNCH_LATER; schedule.launchLaterDate = date; schedule.toString = schedule.calculateToString(); schedule.hashCode = schedule.calculateHashCode(); return schedule; } /** * Returns a schedule instance that launches the task using a cron schedule. * @param cron the String containing the cron schedule. * @return a schedule instance that launches the task using a cron schedule. */ public static ScheduleType createCron(String cron) { ScheduleType schedule = new ScheduleType(); schedule.type = Type.LAUNCH_PERIODICALLY; schedule.cronValue = cron; schedule.toString = schedule.calculateToString(); schedule.hashCode = schedule.calculateHashCode(); return schedule; } /** * Returns the type of the schedule. * @return the type of the schedule. */ public Type getType() { return type; } /** * Returns the date on which the task will be launched. * @return the date on which the task will be launched. */ public Date getLaunchLaterDate() { return launchLaterDate; } /** * Returns the CRON String representation of the schedule. * @return the CRON String representation of the schedule. */ public String getCronValue() { return cronValue; } /** * {@inheritDoc} */ public boolean equals(Object o) { boolean equals; if (o != null) { if (o == this) { equals = true; } else { equals = toString().equals(o.toString()); } } else { equals = false; } return equals; } /** * {@inheritDoc} */ public String toString() { return toString; } /** * {@inheritDoc} */ public int hashCode() { return hashCode; } /** * Calculates the hashCode. * To be called after the calculateToString is called. * @return the value of the hashCode. */ private int calculateHashCode() { return 32 + toString.hashCode(); } private String calculateToString() { String toString; switch (type) { case LAUNCH_NOW: toString = "Schedule Type: Launch Now"; break; case LAUNCH_LATER: toString = "Schedule Type: Launch Later at date "+launchLaterDate; break; case LAUNCH_PERIODICALLY: toString = "Schedule Type: periodical schedule "+cronValue; break; default: throw new IllegalStateException("Invalid type: "+type); } return toString; } } opends/src/guitools/org/opends/guitools/controlpanel/datamodel/ServerDescriptor.java
@@ -40,6 +40,7 @@ import org.opends.guitools.controlpanel.util.ConfigFromDirContext; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.AttributeType; import org.opends.server.types.DN; import org.opends.server.types.ObjectClass; @@ -79,6 +80,8 @@ private CustomSearchResult workQueue; private Set<TaskEntry> taskEntries = new HashSet<TaskEntry>(); private long runningTime = -1; private boolean isAuthenticated; @@ -289,6 +292,24 @@ } /** * Returns the task entries. * @return the task entries. */ public Set<TaskEntry> getTaskEntries() { return taskEntries; } /** * Sets the the task entries. * @param taskEntries the task entries. */ public void setTaskEntries(Set<TaskEntry> taskEntries) { this.taskEntries = Collections.unmodifiableSet(taskEntries); } /** * {@inheritDoc} */ public boolean equals(Object o) @@ -411,6 +432,11 @@ equals = desc.isWindowsServiceEnabled() == isWindowsServiceEnabled(); } if (equals) { desc.getTaskEntries().equals(getTaskEntries()); } } } else opends/src/guitools/org/opends/guitools/controlpanel/datamodel/TaskTableModel.java
New file @@ -0,0 +1,421 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.datamodel; import static org.opends.messages.AdminToolMessages.*; import static org.opends.messages.ToolMessages.*; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.quicksetup.util.Utils; import org.opends.server.backends.task.TaskState; import org.opends.server.tools.tasks.TaskEntry; /** * The table used to display the tasks. * */ public class TaskTableModel extends SortableTableModel implements Comparator<TaskEntry> { private static final long serialVersionUID = -351142550147124L; private Set<TaskEntry> data = new HashSet<TaskEntry>(); private ArrayList<TaskEntry> dataSourceArray = new ArrayList<TaskEntry>(); LinkedHashSet<Message> displayedAttributes = new LinkedHashSet<Message>(); final LinkedHashSet<Message> defaultAttributes = new LinkedHashSet<Message>(); { defaultAttributes.add(INFO_TASKINFO_FIELD_ID.get()); defaultAttributes.add(INFO_TASKINFO_FIELD_TYPE.get()); defaultAttributes.add(INFO_TASKINFO_FIELD_STATUS.get()); defaultAttributes.add(INFO_CTRL_PANEL_TASK_CANCELABLE.get()); } LinkedHashSet<Message> allAttributes = new LinkedHashSet<Message>(); { allAttributes.addAll(defaultAttributes); allAttributes.add(INFO_TASKINFO_FIELD_SCHEDULED_START.get()); allAttributes.add(INFO_TASKINFO_FIELD_ACTUAL_START.get()); allAttributes.add(INFO_TASKINFO_FIELD_COMPLETION_TIME.get()); allAttributes.add(INFO_TASKINFO_FIELD_DEPENDENCY.get()); allAttributes.add(INFO_TASKINFO_FIELD_FAILED_DEPENDENCY_ACTION.get()); allAttributes.add(INFO_TASKINFO_FIELD_NOTIFY_ON_COMPLETION.get()); allAttributes.add(INFO_TASKINFO_FIELD_NOTIFY_ON_ERROR.get()); } private String[] columnNames = {}; /** * The sort column of the table. */ private int sortColumn = 0; /** * Whether the sorting is ascending or descending. */ private boolean sortAscending = true; /** * Default constructor. */ public TaskTableModel() { super(); setAttributes(defaultAttributes); } /** * Sets the data for this table model. * @param newData the data for this table model. */ public void setData(Set<TaskEntry> newData) { if (!newData.equals(data)) { data.clear(); data.addAll(newData); updateDataArray(); fireTableDataChanged(); } } /** * Updates the table model contents and sorts its contents depending on the * sort options set by the user. */ public void forceResort() { updateDataArray(); fireTableDataChanged(); } /** * Updates the table model contents, sorts its contents depending on the * sort options set by the user and updates the column structure. */ public void forceDataStructureChange() { updateDataArray(); fireTableStructureChanged(); fireTableDataChanged(); } /** * Updates the array data. This includes resorting it. */ private void updateDataArray() { TreeSet<TaskEntry> sortedSet = new TreeSet<TaskEntry>(this); sortedSet.addAll(data); dataSourceArray.clear(); for (TaskEntry task : sortedSet) { dataSourceArray.add(task); } } /** * Sets the operations displayed by this table model. * @param attributes the attributes displayed by this table model. */ public void setAttributes(LinkedHashSet<Message> attributes) { if (!allAttributes.containsAll(attributes)) { throw new IllegalArgumentException( "Some of the provided attributes are not valid."); } this.displayedAttributes.clear(); this.displayedAttributes.addAll(attributes); int columnCount = attributes.size(); columnNames = new String[columnCount]; int i = 0; for (Message attribute : attributes) { columnNames[i] = getHeader(attribute, 15); i++; } } /** * {@inheritDoc} */ public Class<?> getColumnClass(int column) { return Message.class; } /** * {@inheritDoc} */ public String getColumnName(int col) { return columnNames[col]; } /** * {@inheritDoc} */ public Object getValueAt(int row, int column) { Message value; column = getFixedOrderColumn(column); TaskEntry taskEntry = get(row); switch (column) { case 0: value = Message.raw(taskEntry.getId()); break; case 1: value = taskEntry.getType(); break; case 2: value = taskEntry.getState(); break; case 3: if (taskEntry.isCancelable()) { value = INFO_CTRL_PANEL_TASK_IS_CANCELABLE.get(); } else { value = INFO_CTRL_PANEL_TASK_IS_NOT_CANCELABLE.get(); } break; case 4: if (TaskState.isRecurring(get(row).getTaskState())) { value = taskEntry.getScheduleTab(); } else { value = taskEntry.getScheduledStartTime(); if (value == null || value.equals(Message.EMPTY)) { value = INFO_TASKINFO_IMMEDIATE_EXECUTION.get(); } } break; case 5: value = taskEntry.getActualStartTime(); break; case 6: value = taskEntry.getCompletionTime(); break; case 7: value = getValue(taskEntry.getDependencyIds(), INFO_TASKINFO_NONE_SPECIFIED.get()); break; case 8: value = taskEntry.getFailedDependencyAction(); if (value == null) { value = INFO_TASKINFO_NONE.get(); } break; case 9: value = getValue(taskEntry.getCompletionNotificationEmailAddresses(), INFO_TASKINFO_NONE_SPECIFIED.get()); break; case 10: value = getValue(taskEntry.getErrorNotificationEmailAddresses(), INFO_TASKINFO_NONE_SPECIFIED.get()); break; default: throw new IllegalArgumentException("Invalid column: "+column); } return value; } /** * Returns the row count. * @return the row count. */ public int getRowCount() { return dataSourceArray.size(); } /** * Returns the column count. * @return the column count. */ public int getColumnCount() { return columnNames.length; } /** * Gets the TaskDescriptor in a given row. * @param row the row. * @return the TaskDescriptor in a given row. */ public TaskEntry get(int row) { return dataSourceArray.get(row); } /** * Returns the set of attributes ordered. * @return the set of attributes ordered. */ public LinkedHashSet<Message> getDisplayedAttributes() { return displayedAttributes; } /** * Returns the set of attributes ordered. * @return the set of attributes ordered. */ public LinkedHashSet<Message> getAllAttributes() { return allAttributes; } /** * {@inheritDoc} */ public int compare(TaskEntry desc1, TaskEntry desc2) { int result; ArrayList<Integer> possibleResults = new ArrayList<Integer>(); possibleResults.add(desc1.getId().compareTo(desc2.getId())); possibleResults.add(desc1.getType().compareTo(desc2.getType())); possibleResults.add(desc1.getState().compareTo(desc2.getState())); possibleResults.add(String.valueOf(desc1.isCancelable()).compareTo( String.valueOf(desc2.isCancelable()))); result = possibleResults.get(getSortColumn()); if (result == 0) { for (int i : possibleResults) { if (i != 0) { result = i; break; } } } if (!isSortAscending()) { result = -result; } return result; } /** * Returns whether the sort is ascending or descending. * @return <CODE>true</CODE> if the sort is ascending and <CODE>false</CODE> * otherwise. */ public boolean isSortAscending() { return sortAscending; } /** * Sets whether to sort ascending of descending. * @param sortAscending whether to sort ascending or descending. */ public void setSortAscending(boolean sortAscending) { this.sortAscending = sortAscending; } /** * Returns the column index used to sort. * @return the column index used to sort. */ public int getSortColumn() { return sortColumn; } /** * Sets the column index used to sort. * @param sortColumn column index used to sort.. */ public void setSortColumn(int sortColumn) { this.sortColumn = sortColumn; } private int getFixedOrderColumn(int column) { int fixedOrderColumn = 0; int i=0; Message colMsg = null; for (Message msg : displayedAttributes) { if (i == column) { colMsg = msg; break; } i++; } for (Message msg : allAttributes) { if (msg.equals(colMsg)) { break; } fixedOrderColumn++; } return fixedOrderColumn; } private Message getValue(List<String> values, Message valueIfEmpty) { Message msg; if (values.isEmpty()) { msg = valueIfEmpty; } else { String s = Utils.getStringFromCollection(values, "<br>"); if (values.size() > 1) { msg = Message.raw( "<html>"+Utilities.applyFont(s, ColorAndFontConstants.tableFont)); } else { msg = Message.raw(s); } } return msg; } } opends/src/guitools/org/opends/guitools/controlpanel/task/CancelTaskTask.java
New file @@ -0,0 +1,261 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.task; import static org.opends.messages.AdminToolMessages.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.swing.SwingUtilities; import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.tools.ManageTasks; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.util.cli.CommandBuilder; /** * Task used to cancel tasks in server. * */ public class CancelTaskTask extends Task { private Set<String> backendSet; private List<TaskEntry> tasks; /** * Constructor of the task. * @param info the control panel information. * @param dlg the progress dialog where the task progress will be displayed. * @param tasks the tasks to be canceled. */ public CancelTaskTask(ControlPanelInfo info, ProgressDialog dlg, List<TaskEntry> tasks) { super(info, dlg); backendSet = new HashSet<String>(); for (BackendDescriptor backend : info.getServerDescriptor().getBackends()) { backendSet.add(backend.getBackendID()); } this.tasks = new ArrayList<TaskEntry>(tasks); } /** * {@inheritDoc} */ public Type getType() { // TODO: change this return Type.MODIFY_ENTRY; } /** * {@inheritDoc} */ public Set<String> getBackends() { return backendSet; } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION.get(); } /** * {@inheritDoc} */ public boolean regenerateDescriptor() { return true; } /** * {@inheritDoc} */ protected String getCommandLinePath() { return null; } /** * {@inheritDoc} */ protected ArrayList<String> getCommandLineArguments() { return new ArrayList<String>(); } /** * Returns the command-line arguments to be used to cancel the task. * @param task the task to be canceled. * @return the command-line arguments to be used to cancel the task. */ private ArrayList<String> getCommandLineArguments(TaskEntry task) { ArrayList<String> args = new ArrayList<String>(); args.add("--cancel"); args.add(task.getId()); args.addAll(getConnectionCommandLineArguments()); args.add(getNoPropertiesFileArgument()); return args; } /** * {@inheritDoc} */ public boolean canLaunch(Task taskToBeLaunched, Collection<Message> incompatibilityReasons) { boolean canLaunch = true; if (!isServerRunning()) { if (state == State.RUNNING) { // All the operations are incompatible if they apply to this // backend for safety. This is a short operation so the limitation // has not a lot of impact. Set<String> backends = new TreeSet<String>(taskToBeLaunched.getBackends()); backends.retainAll(getBackends()); if (backends.size() > 0) { incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); canLaunch = false; } } } return canLaunch; } /** * {@inheritDoc} */ public void runTask() { state = State.RUNNING; lastException = null; try { final int totalNumber = tasks.size(); int numberCanceled = 0; SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().getProgressBar().setIndeterminate(true); } }); for (final TaskEntry task : tasks) { final ArrayList<String> arguments = getCommandLineArguments(task); final boolean isFirst = numberCanceled == 0; SwingUtilities.invokeLater(new Runnable() { public void run() { if (isFirst) { getProgressDialog().appendProgressHtml("<br><br>"); } ArrayList<String> args = new ArrayList<String>(); args.add(getCommandLinePath("manage-tasks")); args.addAll(getObfuscatedCommandLineArguments(arguments)); StringBuilder sb = new StringBuilder(); for (String arg : args) { sb.append(" "+CommandBuilder.escapeValue(arg)); } getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK.get(task.getId())+ "<br><b>"+sb.toString()+"</b><br><br>", ColorAndFontConstants.progressFont)); } }); String[] args = new String[arguments.size()]; arguments.toArray(args); returnCode = ManageTasks.mainTaskInfo(args, System.in, outPrintStream, errorPrintStream); if (returnCode != 0) { break; } else { numberCanceled ++; final int fNumberCanceled = numberCanceled; SwingUtilities.invokeLater(new Runnable() { public void run() { if (fNumberCanceled == 1) { getProgressDialog().getProgressBar().setIndeterminate(false); } getProgressDialog().getProgressBar().setValue( (fNumberCanceled * 100) / totalNumber); } }); } } if (returnCode != 0) { state = State.FINISHED_WITH_ERROR; } else { state = State.FINISHED_SUCCESSFULLY; } } catch (Throwable t) { lastException = t; state = State.FINISHED_WITH_ERROR; } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/BackupPanel.java
@@ -60,9 +60,11 @@ import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; import org.opends.guitools.controlpanel.datamodel.BackupDescriptor; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ScheduleType; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.ScheduleSummaryPanel; import org.opends.guitools.controlpanel.util.BackgroundTask; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; @@ -100,6 +102,8 @@ private boolean backupIDInitialized = false; private ScheduleSummaryPanel schedulePanel; private static final Logger LOG = Logger.getLogger(BackupPanel.class.getName()); @@ -251,20 +255,27 @@ INFO_CTRL_PANEL_BACKUP_OPTIONS_LABEL.get()); add(lBackupOptions, gbc); compressData = Utilities.createCheckBox( INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get()); compressData.setSelected(false); schedulePanel = new ScheduleSummaryPanel( INFO_CTRL_PANEL_BACKUP_TASK_NAME.get().toString()); schedulePanel.setSchedule(ScheduleType.createLaunchNow()); gbc.insets.left = 10; gbc.gridx = 1; gbc.gridwidth = 2; add(schedulePanel, gbc); compressData = Utilities.createCheckBox( INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get()); compressData.setSelected(false); gbc.gridy ++; gbc.insets.top = 5; add(compressData, gbc); encryptData = Utilities.createCheckBox( INFO_CTRL_PANEL_ENCRYPT_DATA_LABEL.get()); gbc.gridy ++; gbc.insets.top = 5; add(encryptData, gbc); encryptData.setSelected(false); generateMessageDigest = Utilities.createCheckBox( @@ -351,6 +362,7 @@ setPrimaryValid(lPath); setPrimaryValid(lAvailableBackups); setPrimaryValid(lParentID); setPrimaryValid(lBackupOptions); backupIDInitialized = false; final LinkedHashSet<Message> errors = new LinkedHashSet<Message>(); @@ -434,6 +446,8 @@ } } addScheduleErrors(getSchedule(), errors, lBackupOptions); // Check that there is not a backup with the provided ID final JComponent[] components = { @@ -578,6 +592,11 @@ } } private ScheduleType getSchedule() { return schedulePanel.getSchedule(); } /** * {@inheritDoc} */ @@ -586,6 +605,7 @@ setPrimaryValid(lBackend); setPrimaryValid(lPath); setPrimaryValid(lAvailableBackups); setPrimaryValid(lBackupOptions); super.cancelClicked(); } @@ -824,6 +844,8 @@ args.addAll(getConnectionCommandLineArguments()); args.addAll(getScheduleArgs(getSchedule())); if (isServerRunning()) { args.addAll(getConfigCommandLineArguments()); opends/src/guitools/org/opends/guitools/controlpanel/ui/ConnectionHandlerMonitoringPanel.java
@@ -52,7 +52,6 @@ import javax.swing.JCheckBoxMenuItem; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; @@ -76,7 +75,8 @@ import org.opends.guitools.controlpanel.datamodel.ConnectionHandlerDescriptor. State; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer; import org.opends.guitools.controlpanel.ui.renderer. NoLeftInsetCategoryComboBoxRenderer; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.guitools.controlpanel.util.ViewPositions; import org.opends.messages.Message; @@ -193,7 +193,7 @@ } }); connectionHandlers.setRenderer( new CustomComboBoxCellRenderer(connectionHandlers)); new NoLeftInsetCategoryComboBoxRenderer(connectionHandlers)); gbc.gridx ++; viewOptions.add(connectionHandlers, gbc); gbc.gridx ++; @@ -313,7 +313,7 @@ }); for (ConnectionHandlerDescriptor ch : chs) { if (ch.getProtocol() != ConnectionHandlerDescriptor.Protocol.LDIF) if (protocolHasMonitoring(ch)) { sortedChs.add(ch); } @@ -355,7 +355,7 @@ { MessageBuilder mb = new MessageBuilder(); mb.append(INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get( server.getHostname())); server.getHostname())); mb.append("<br><br>"+getAuthenticateHTML()); errorDetails = mb.toMessage(); errorTitle = INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_SUMMARY.get(); @@ -555,7 +555,7 @@ { for (ConnectionHandlerDescriptor ch : server.getConnectionHandlers()) { if (ch.getProtocol() != Protocol.LDIF) if (protocolHasMonitoring(ch)) { cchs.add(ch); } @@ -588,6 +588,14 @@ return cchs; } private boolean protocolHasMonitoring(ConnectionHandlerDescriptor ch) { return (ch.getProtocol() == Protocol.LDAP) || (ch.getProtocol() == Protocol.LDAPS) || (ch.getProtocol() == Protocol.LDAP_STARTTLS) || (ch.getProtocol() == Protocol.OTHER); } /** * The specific menu bar of this panel. * @@ -650,43 +658,5 @@ return menu; } } /** * This class is used simply to avoid an inset on the left for the * elements of the combo box. * Since this item is a CategorizedComboBoxElement of type * CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on * the left. */ class CustomComboBoxCellRenderer extends CustomListCellRenderer { /** * The constructor. * @param combo the combo box to be rendered. */ CustomComboBoxCellRenderer(JComboBox combo) { super(combo); } /** * {@inheritDoc} */ @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof CategorizedComboBoxElement) { CategorizedComboBoxElement element = (CategorizedComboBoxElement)value; String name = getStringValue(element); ((JLabel)comp).setText(name); } comp.setFont(defaultFont); return comp; } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/ExportLDIFPanel.java
@@ -54,10 +54,12 @@ import javax.swing.event.DocumentListener; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ScheduleType; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.BrowseActionListener; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.ScheduleSummaryPanel; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.tools.ExportLDIF; @@ -89,6 +91,8 @@ private DocumentListener documentListener; private ScheduleSummaryPanel schedulePanel; /** * Default constructor. * @@ -238,13 +242,21 @@ Utilities.createPrimaryLabel(INFO_CTRL_PANEL_EXPORT_OPTIONS.get()); add(lExportOptions, gbc); compressData = Utilities.createCheckBox( INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get()); compressData.setSelected(false); schedulePanel = new ScheduleSummaryPanel( INFO_CTRL_PANEL_EXPORT_LDIF_TITLE.get().toString()); schedulePanel.setSchedule(ScheduleType.createLaunchNow()); gbc.insets.left = 10; gbc.gridx = 1; gbc.gridwidth = 3; add(schedulePanel, gbc); compressData = Utilities.createCheckBox( INFO_CTRL_PANEL_COMPRESS_DATA_LABEL.get()); compressData.setSelected(false); gbc.gridy ++; gbc.insets.top = 5; add(compressData, gbc); encryptData = Utilities.createCheckBox( @@ -384,6 +396,7 @@ } } addScheduleErrors(getSchedule(), errors, lExportOptions); if (wrapText.isSelected()) { String cols = wrapColumn.getText(); @@ -391,7 +404,12 @@ int maxValue = 1000; Message errMsg = ERR_CTRL_PANEL_INVALID_WRAP_COLUMN.get(minValue, maxValue); int size1 = errors.size(); checkIntValue(errors, cols, minValue, maxValue, errMsg); if (errors.size() > size1) { setPrimaryInvalid(lExportOptions); } } updateIncludeExclude(errors, backendName); @@ -448,6 +466,11 @@ super.cancelClicked(); } private ScheduleType getSchedule() { return schedulePanel.getSchedule(); } /** * The class that performs the export. * @@ -589,6 +612,8 @@ args.addAll(super.getCommandLineArguments()); args.addAll(getScheduleArgs(getSchedule())); if (isServerRunning()) { args.addAll(getConfigCommandLineArguments()); opends/src/guitools/org/opends/guitools/controlpanel/ui/MainActionsPane.java
@@ -217,7 +217,8 @@ { INFO_CTRL_PANEL_CATEGORY_MONITORING.get(), INFO_CTRL_PANEL_BROWSE_GENERAL_MONITORING.get(), INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get() INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get(), INFO_CTRL_PANEL_MANAGE_TASKS.get() }, { INFO_CTRL_PANEL_CATEGORY_RUNTIME_OPTIONS.get(), @@ -251,7 +252,8 @@ { INFO_CTRL_PANEL_CATEGORY_MONITORING.get(), INFO_CTRL_PANEL_BROWSE_GENERAL_MONITORING.get(), INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get() INFO_CTRL_PANEL_CONNECTION_HANDLER_MONITORING.get(), INFO_CTRL_PANEL_MANAGE_TASKS.get() }, { INFO_CTRL_PANEL_CATEGORY_RUNTIME_OPTIONS.get(), @@ -273,6 +275,7 @@ classes.add(RebuildIndexPanel.class); classes.add(BrowseGeneralMonitoringPanel.class); classes.add(ConnectionHandlerMonitoringPanel.class); classes.add(ManageTasksPanel.class); classes.add(JavaPropertiesPanel.class); if (Utilities.isWindows()) { opends/src/guitools/org/opends/guitools/controlpanel/ui/ManageTasksPanel.java
New file @@ -0,0 +1,939 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui; import static org.opends.messages.AdminToolMessages.*; import static org.opends.server.util.StaticUtils.toLowerCase; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.datamodel.TaskTableModel; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.task.CancelTaskTask; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.renderer.TaskCellRenderer; import org.opends.guitools.controlpanel.util.ConfigFromFile; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.quicksetup.util.Utils; import org.opends.server.core.DirectoryServer; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.Attribute; import org.opends.server.types.AttributeBuilder; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.AttributeValues; import org.opends.server.types.ByteString; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; /** * The panel displaying the list of scheduled tasks. * */ public class ManageTasksPanel extends StatusGenericPanel { private static final long serialVersionUID = -8034784684412532193L; private JLabel lNoTasksFound; /** * Remove task button. */ private JButton cancelTask; /** * The scroll that contains the list of tasks (actually is a table). */ private JScrollPane tableScroll; /** * The table of tasks. */ private JTable taskTable; /** * The model of the table. */ private TaskTableModel tableModel; private ManageTasksMenuBar menuBar; private MonitoringAttributesViewPanel<Message> operationViewPanel; private GenericDialog operationViewDlg; private JPanel detailsPanel; private JLabel noDetailsLabel; // The panel containing all the labels and values of the details. private JPanel detailsSubpanel; private static final Logger LOG = Logger.getLogger(ManageTasksPanel.class.getName()); /** * Default constructor. * */ public ManageTasksPanel() { super(); createLayout(); } /** * {@inheritDoc} */ public Message getTitle() { return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_LIST_TITLE.get(); } /** * {@inheritDoc} */ public boolean requiresScroll() { return false; } /** * {@inheritDoc} */ public GenericDialog.ButtonType getButtonType() { return GenericDialog.ButtonType.CLOSE; } /** * {@inheritDoc} */ public void okClicked() { // Nothing to do, it only contains a close button. } /** * {@inheritDoc} */ @Override public JMenuBar getMenuBar() { if (menuBar == null) { menuBar = new ManageTasksMenuBar(getInfo()); } return menuBar; } /** * {@inheritDoc} */ public Component getPreferredFocusComponent() { return taskTable; } /** * Returns the selected cancelable tasks in the list. * @param onlyCancelable add only the cancelable tasks. * @return the selected cancelable tasks in the list. */ private List<TaskEntry> getSelectedTasks(boolean onlyCancelable) { ArrayList<TaskEntry> tasks = new ArrayList<TaskEntry>(); int[] rows = taskTable.getSelectedRows(); for (int row : rows) { if (row != -1) { TaskEntry task = tableModel.get(row); if (!onlyCancelable || task.isCancelable()) { tasks.add(task); } } } return tasks; } /** * Creates the components and lays them in the panel. * @param gbc the grid bag constraints to be used. */ private void createLayout() { GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2; addErrorPane(gbc); gbc.weightx = 0.0; gbc.gridy ++; gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 0.0; gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 2; gbc.insets.left = 0; gbc.gridx = 0; gbc.gridy = 0; lNoTasksFound = Utilities.createDefaultLabel( INFO_CTRL_PANEL_NO_TASKS_FOUND.get()); gbc.gridy ++; gbc.anchor = GridBagConstraints.CENTER; gbc.gridheight = 2; add(lNoTasksFound, gbc); lNoTasksFound.setVisible(false); gbc.gridwidth = 1; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets.top = 10; gbc.anchor = GridBagConstraints.NORTHWEST; // Done to provide a good size to the table. tableModel = new TaskTableModel(); tableModel.setData(createDummyTaskList()); taskTable = Utilities.createSortableTable(tableModel, new TaskCellRenderer()); taskTable.getSelectionModel().setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); tableScroll = Utilities.createScrollPane(taskTable); gbc.anchor = GridBagConstraints.NORTHWEST; add(tableScroll, gbc); updateTableSizes(); gbc.gridx = 1; gbc.gridheight = 1; gbc.anchor = GridBagConstraints.EAST; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.weighty = 0.0; cancelTask = Utilities.createButton( INFO_CTRL_PANEL_CANCEL_TASK_BUTTON_LABEL.get()); cancelTask.setOpaque(false); gbc.insets.left = 10; add(cancelTask, gbc); gbc.gridy ++; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.VERTICAL; add(Box.createVerticalGlue(), gbc); cancelTask.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent ev) { cancelTaskClicked(); } }); gbc.gridy ++; gbc.gridx = 0; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 0.7; gbc.insets.left = 0; createDetailsPanel(); add(detailsPanel, gbc); ListSelectionListener listener = new ListSelectionListener() { /** * {@inheritDoc} */ public void valueChanged(ListSelectionEvent ev) { tableSelected(); } }; taskTable.getSelectionModel().addListSelectionListener(listener); listener.valueChanged(null); } /** * Creates the details panel. * */ private void createDetailsPanel() { detailsPanel = new JPanel(new GridBagLayout()); detailsPanel.setOpaque(false); detailsPanel.setBorder(Utilities.makeTitledBorder( INFO_CTRL_PANEL_TASK_SPECIFIC_DETAILS.get())); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 1.0; gbc.weighty = 1.0; noDetailsLabel = Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_TASK_SELECTED.get()); gbc.gridwidth = 2; detailsPanel.add(noDetailsLabel, gbc); detailsSubpanel = new JPanel(new GridBagLayout()); detailsSubpanel.setOpaque(false); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.BOTH; detailsPanel.add(Utilities.createBorderLessScrollBar(detailsSubpanel), gbc); } /** * Method called when the table is selected. * */ private void tableSelected() { List<TaskEntry> tasks = getSelectedTasks(true); cancelTask.setEnabled(!tasks.isEmpty()); detailsSubpanel.removeAll(); tasks = getSelectedTasks(false); boolean displayContents = false; if (tasks.isEmpty()) { noDetailsLabel.setText(INFO_CTRL_PANEL_NO_TASK_SELECTED.get().toString()); } else if (tasks.size() > 1) { noDetailsLabel.setText( INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED.get().toString()); } else { TaskEntry taskEntry = tasks.iterator().next(); Map<Message,List<String>> taskSpecificAttrs = taskEntry.getTaskSpecificAttributeValuePairs(); if (taskSpecificAttrs.isEmpty()) { noDetailsLabel.setText( INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS.get().toString()); } else { displayContents = true; GridBagConstraints gbc = new GridBagConstraints(); gbc.gridy = 1; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets.top = 10; for (Message label : taskSpecificAttrs.keySet()) { List<String> values = taskSpecificAttrs.get(label); gbc.gridx = 0; gbc.insets.left = 10; gbc.insets.right = 0; detailsSubpanel.add(Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OPERATION_NAME_AS_LABEL.get(label.toString())), gbc); gbc.gridx = 1; gbc.insets.right = 10; Message msg; String s = Utils.getStringFromCollection(values, "<br>"); if (values.size() > 1) { msg = Message.raw( "<html>"+Utilities.applyFont(s, ColorAndFontConstants.defaultFont)); } else { msg = Message.raw(s); } detailsSubpanel.add(Utilities.createDefaultLabel(msg), gbc); gbc.gridy ++; } gbc.gridx = 0; gbc.insets = new Insets(0, 0, 0, 0); detailsSubpanel.add(Box.createVerticalStrut(10), gbc); gbc.gridx = 1; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; detailsSubpanel.add(Box.createGlue(), gbc); } } noDetailsLabel.setVisible(!displayContents); revalidate(); repaint(); } /** * Creates a list with task descriptors. This is done simply to have a good * initial size for the table. * @return a list with bogus task descriptors. */ private Set<TaskEntry> createRandomTasksList() { Set<TaskEntry> list = new HashSet<TaskEntry>(); Random r = new Random(); int numberTasks = r.nextInt(10); for (int i= 0; i<numberTasks; i++) { CustomSearchResult csr = new CustomSearchResult("cn=mytask"+i+",cn=tasks"); String p = "ds-task-"; String[] attrNames = { p + "id", p + "class-name", p + "state", p + "scheduled-start-time", p + "actual-start-time", p + "completion-time", p + "dependency-id", p + "failed-dependency-action", p + "log-message", p + "notify-on-error", p + "notify-on-completion", p + "ds-recurring-task-schedule" }; String[] values = { "ID", "TheClassName", "TheState", "Schedule Start Time", "Actual Start Time", "Completion Time", "Dependency ID", "Failed Dependency Action", "Log Message. Should be pretty long"+ "Log Message. Should be pretty long"+ "Log Message. Should be pretty long"+ "Log Message. Should be pretty long"+ "Log Message. Should be pretty long", "Notify On Error", "Notify On Completion", "Recurring Task Schedule" }; for (int j=0; j < attrNames.length; j++) { Set<Object> attrValues = new HashSet<Object>(1); attrValues.add(values[j] + r.nextInt()); csr.set(attrNames[j], attrValues); } try { Entry entry = getEntry(csr); TaskEntry task = new TaskEntry(entry); list.add(task); } catch (Throwable t) { LOG.log(Level.SEVERE, "Error getting entry '"+csr.getDN()+"': "+t, t); } } return list; } /** * Creates a list with task descriptors. This is done simply to have a good * initial size for the table. * @return a list with bogus task descriptors. */ private Set<TaskEntry> createDummyTaskList() { Set<TaskEntry> list = new HashSet<TaskEntry>(); for (int i= 0; i<10; i++) { CustomSearchResult csr = new CustomSearchResult("cn=mytask"+i+",cn=tasks"); String p = "ds-task-"; String[] attrNames = { p + "id", p + "class-name", p + "state", p + "scheduled-start-time", p + "actual-start-time", p + "completion-time", p + "dependency-id", p + "failed-dependency-action", p + "log-message", p + "notify-on-error", p + "notify-on-completion", p + "ds-recurring-task-schedule" }; String[] values = { "A very 29-backup - Sun Mar 29 00:00:00 MET 2009", "A long task type", "A very long task status", "Schedule Start Time", "Actual Start Time", "Completion Time", "Dependency ID", "Failed Dependency Action", "Log Message. Should be pretty long\n"+ "Log Message. Should be pretty long\n"+ "Log Message. Should be pretty long\n"+ "Log Message. Should be pretty long\n"+ "Log Message. Should be pretty long\n", "Notify On Error", "Notify On Completion", "Recurring Task Schedule" }; for (int j=0; j < attrNames.length; j++) { Set<Object> attrValues = new HashSet<Object>(1); attrValues.add(values[j]); csr.set(attrNames[j], attrValues); } try { Entry entry = getEntry(csr); TaskEntry task = new TaskEntry(entry); list.add(task); } catch (Throwable t) { LOG.log(Level.SEVERE, "Error getting entry '"+csr.getDN()+"': "+t, t); } } return list; } private void cancelTaskClicked() { ArrayList<Message> errors = new ArrayList<Message>(); ProgressDialog dlg = new ProgressDialog( Utilities.getParentDialog(this), INFO_CTRL_PANEL_CANCEL_TASK_TITLE.get(), getInfo()); List<TaskEntry> tasks = getSelectedTasks(true); CancelTaskTask newTask = new CancelTaskTask(getInfo(), dlg, tasks); for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } if (errors.size() == 0) { boolean confirmed = displayConfirmationDialog( INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), INFO_CTRL_PANEL_CANCEL_TASK_MSG.get()); if (confirmed) { launchOperation(newTask, INFO_CTRL_PANEL_CANCELING_TASK_SUMMARY.get(), INFO_CTRL_PANEL_CANCELING_TASK_COMPLETE.get(), INFO_CTRL_PANEL_CANCELING_TASK_SUCCESSFUL.get(), ERR_CTRL_PANEL_CANCELING_TASK_ERROR_SUMMARY.get(), ERR_CTRL_PANEL_CANCELING_TASK_ERROR_DETAILS.get(), null, dlg); dlg.setVisible(true); } } } /** * Gets the Entry object equivalent to the provided CustomSearchResult. * The method assumes that the schema in DirectoryServer has been initialized. * @param csr the search result. * @return the Entry object equivalent to the provided CustomSearchResult. * @throws OpenDsException if there is an error parsing the DN or retrieving * the attributes definition and objectclasses in the schema of the server. * TODO: move somewhere better. */ public static Entry getEntry(CustomSearchResult csr) throws OpenDsException { DN dn = DN.decode(csr.getDN()); Map<ObjectClass,String> objectClasses = new HashMap<ObjectClass,String>(); Map<AttributeType,List<Attribute>> userAttributes = new HashMap<AttributeType,List<Attribute>>(); Map<AttributeType,List<Attribute>> operationalAttributes = new HashMap<AttributeType,List<Attribute>>(); for (String wholeName : csr.getAttributeNames()) { final Attribute attribute = parseAttrDescription(wholeName); final String attrName = attribute.getName(); final String lowerName = toLowerCase(attrName); // See if this is an objectclass or an attribute. Then get the // corresponding definition and add the value to the appropriate hash. if (lowerName.equals("objectclass")) { for (Object value : csr.getAttributeValues(attrName)) { String ocName = value.toString().trim(); String lowerOCName = toLowerCase(ocName); ObjectClass objectClass = DirectoryServer.getObjectClass(lowerOCName); if (objectClass == null) { objectClass = DirectoryServer.getDefaultObjectClass(ocName); } objectClasses.put(objectClass, ocName); } } else { AttributeType attrType = DirectoryServer.getAttributeType(lowerName); if (attrType == null) { attrType = DirectoryServer.getDefaultAttributeType(attrName); } AttributeBuilder builder = new AttributeBuilder(attribute, true); for (Object value : csr.getAttributeValues(attrName)) { ByteString bs; if (value instanceof byte[]) { bs = ByteString.wrap((byte[])value); } else { bs = ByteString.valueOf(value.toString()); } AttributeValue attributeValue = AttributeValues.create(attrType, bs); builder.add(attributeValue); } List<Attribute> attrList = new ArrayList<Attribute>(1); attrList.add(builder.toAttribute()); if (attrType.isOperational()) { operationalAttributes.put(attrType, attrList); } else { userAttributes.put(attrType, attrList); } } } return new Entry(dn, objectClasses, userAttributes, operationalAttributes); } /** * Parse an AttributeDescription (an attribute type name and its * options). * TODO: make this method in LDIFReader public. * * @param attrDescr * The attribute description to be parsed. * @return A new attribute with no values, representing the * attribute type and its options. */ private static Attribute parseAttrDescription(String attrDescr) { AttributeBuilder builder; int semicolonPos = attrDescr.indexOf(';'); if (semicolonPos > 0) { builder = new AttributeBuilder(attrDescr.substring(0, semicolonPos)); int nextPos = attrDescr.indexOf(';', semicolonPos + 1); while (nextPos > 0) { String option = attrDescr.substring(semicolonPos + 1, nextPos); if (option.length() > 0) { builder.setOption(option); semicolonPos = nextPos; nextPos = attrDescr.indexOf(';', semicolonPos + 1); } } String option = attrDescr.substring(semicolonPos + 1); if (option.length() > 0) { builder.setOption(option); } } else { builder = new AttributeBuilder(attrDescr); } if(builder.getAttributeType().isBinary()) { //resetting doesn't hurt and returns false. builder.setOption("binary"); } return builder.toAttribute(); } /** * The main method to test this panel. * @param args the arguments. */ public static void main(String[] args) { // This is a hack to initialize configuration new ConfigFromFile(); final ManageTasksPanel p = new ManageTasksPanel(); Thread t = new Thread(new Runnable() { public void run() { try { // To let the dialog to be displayed Thread.sleep(5000); } catch (Throwable t) { t.printStackTrace(); } while (p.isVisible()) { try { SwingUtilities.invokeLater(new Runnable(){ public void run() { Set<TaskEntry> tasks = p.createRandomTasksList(); p.tableModel.setData(tasks); boolean visible = p.tableModel.getRowCount() > 0; if (visible) { p.updateTableSizes(); } p.tableModel.fireTableDataChanged(); p.lNoTasksFound.setVisible(!visible); p.tableScroll.setVisible(visible); p.cancelTask.setVisible(visible); } }); Thread.sleep(5000); } catch (Exception ex) { ex.printStackTrace(); } } } }); t.start(); SwingUtilities.invokeLater(new Runnable(){ public void run() { GenericDialog dlg = new GenericDialog(new JFrame(), p); dlg.setModal(true); dlg.pack(); dlg.setVisible(true); } }); t = null; } /** * Displays a dialog allowing the user to select which operations to display. * */ private void operationViewClicked() { if (operationViewDlg == null) { operationViewPanel = MonitoringAttributesViewPanel.createMessageInstance( tableModel.getAllAttributes()); operationViewDlg = new GenericDialog(Utilities.getFrame(this), operationViewPanel); Utilities.centerGoldenMean(operationViewDlg, Utilities.getParentDialog(this)); operationViewDlg.setModal(true); } operationViewPanel.setSelectedAttributes( tableModel.getDisplayedAttributes()); operationViewDlg.setVisible(true); if (!operationViewPanel.isCancelled()) { LinkedHashSet<Message> displayedAttributes = operationViewPanel.getAttributes(); setAttributesToDisplay(displayedAttributes); updateTableSizes(); } } /** * {@inheritDoc} */ public void configurationChanged(ConfigurationChangeEvent ev) { updateErrorPaneIfServerRunningAndAuthRequired(ev.getNewDescriptor(), INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_REQUIRES_SERVER_RUNNING.get(), INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_AUTHENTICATION.get()); ServerDescriptor server = ev.getNewDescriptor(); final Set<TaskEntry> tasks = server.getTaskEntries(); boolean changed = tableModel.getRowCount() != tasks.size(); if (!changed) { for (int i=0; i<tableModel.getRowCount(); i++) { if (!tasks.contains(tableModel.get(i))) { changed = true; break; } } } if (changed) { SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { tableModel.setData(tasks); boolean visible = tableModel.getRowCount() > 0; if (visible) { updateTableSizes(); } tableModel.fireTableDataChanged(); lNoTasksFound.setVisible(!visible && !errorPane.isVisible()); tableScroll.setVisible(visible); cancelTask.setVisible(visible); } }); } } private void updateTableSizes() { Utilities.updateTableSizes(taskTable, 8); Utilities.updateScrollMode(tableScroll, taskTable); } private void setAttributesToDisplay(LinkedHashSet<Message> attributes) { tableModel.setAttributes(attributes); tableModel.forceDataStructureChange(); } /** * The specific menu bar of this panel. * */ class ManageTasksMenuBar extends MainMenuBar { private static final long serialVersionUID = 5051878116443370L; /** * structor. * @param info the control panel info. */ public ManageTasksMenuBar(ControlPanelInfo info) { super(info); } /** * {@inheritDoc} */ @Override protected void addMenus() { add(createViewMenuBar()); add(createHelpMenuBar()); } /** * Creates the view menu bar. * @return the view menu bar. */ @Override protected JMenu createViewMenuBar() { JMenu menu = Utilities.createMenu( INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU.get(), INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU_DESCRIPTION.get()); menu.setMnemonic(KeyEvent.VK_V); final JMenuItem viewOperations = Utilities.createMenuItem( INFO_CTRL_PANEL_OPERATIONS_VIEW.get()); menu.add(viewOperations); viewOperations.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { operationViewClicked(); } }); return menu; } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/MonitoringAttributesViewPanel.java
@@ -91,7 +91,8 @@ * Creates an instance of this panel that uses MonitoringAttributes as * attributes. * @param attributes the list of possible attributes. * @return an instance of this panel that uses String as attributes. * @return an instance of this panel that uses MonitoringAttributes as * attributes. */ public static MonitoringAttributesViewPanel<MonitoringAttributes> createMonitoringAttributesInstance( @@ -101,6 +102,18 @@ } /** * Creates an instance of this panel that uses Message as * attributes. * @param attributes the list of possible attributes. * @return an instance of this panel that uses Message as attributes. */ public static MonitoringAttributesViewPanel<Message> createMessageInstance(LinkedHashSet<Message> attributes) { return new MonitoringAttributesViewPanel<Message>(attributes); } /** * {@inheritDoc} */ @Override @@ -354,6 +367,10 @@ { m = ((MonitoringAttributes)operation).getMessage(); } else if (operation instanceof Message) { m = (Message)operation; } else { m = Message.raw(operation.toString()); opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -42,8 +42,11 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -77,6 +80,7 @@ import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; import org.opends.guitools.controlpanel.datamodel.MonitoringAttributes; import org.opends.guitools.controlpanel.datamodel.ScheduleType; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.*; import org.opends.guitools.controlpanel.task.RebuildIndexTask; @@ -147,6 +151,9 @@ private boolean sizeSet = false; private boolean focusSet = false; private static DateFormat taskDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); /** * Returns the title that will be used as title of the dialog. * @return the title that will be used as title of the dialog. @@ -2183,4 +2190,58 @@ return INFO_CTRL_PANEL_OPERATION_NAME_AS_LABEL.get( attr.getMessage().toString()); } /** * Returns the command-line arguments associated with the provided schedule. * @param schedule the schedule. * @return the command-line arguments associated with the provided schedule. */ protected List<String> getScheduleArgs(ScheduleType schedule) { List<String> args = new ArrayList<String>(2); switch (schedule.getType()) { case LAUNCH_LATER: args.add("--start"); args.add(getStartTimeForTask(schedule.getLaunchLaterDate())); break; case LAUNCH_PERIODICALLY: args.add("--recurringTask"); args.add(schedule.getCronValue()); break; } return args; } /** * Checks whether the server is running or not and depending on the schedule * updates the list of errors with the errors found. * @param schedule the schedule. * @param errors the list of errors. * @param label the label to be marked as invalid if errors where encountered. */ protected void addScheduleErrors(ScheduleType schedule, Collection<Message> errors, JLabel label) { if (!isServerRunning()) { ScheduleType.Type type = schedule.getType(); if (type == ScheduleType.Type.LAUNCH_LATER) { errors.add(ERR_CTRL_PANEL_LAUNCH_LATER_REQUIRES_SERVER_RUNNING.get()); setPrimaryInvalid(label); } else if (type == ScheduleType.Type.LAUNCH_PERIODICALLY) { errors.add( ERR_CTRL_PANEL_LAUNCH_SCHEDULE_REQUIRES_SERVER_RUNNING.get()); setPrimaryInvalid(label); } } } private String getStartTimeForTask(Date date) { return taskDateFormat.format(date); } } opends/src/guitools/org/opends/guitools/controlpanel/ui/TaskToSchedulePanel.java
New file @@ -0,0 +1,1178 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui; import static org.opends.messages.AdminToolMessages.*; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.GregorianCalendar; import javax.swing.Box; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.text.PlainDocument; import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement; import org.opends.guitools.controlpanel.datamodel.ScheduleType; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.ui.components. NumericLimitedSizeDocumentFilter; import org.opends.guitools.controlpanel.ui.components.TimeDocumentFilter; import org.opends.guitools.controlpanel.ui.renderer. NoLeftInsetCategoryComboBoxRenderer; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.backends.task.RecurringTask; /** * The panel that allows the user to specify when a task will be launched. * */ public class TaskToSchedulePanel extends StatusGenericPanel { private static final long serialVersionUID = 6855081932432566784L; private String taskName; private JComboBox scheduleType; private JTextField time; private JTextField day; private JComboBox month; private JComboBox year; private JLabel lTime; private JLabel lDay; private JLabel lMonth; private JLabel lYear; private JLabel lDailyTime; private JTextField dailyTime; private JLabel lWeeklyTime; private JLabel lWeeklyDays; private JTextField weeklyTime; private JCheckBox sunday, monday, tuesday, wednesday, thursday, friday, saturday; { sunday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUNDAY.get()); monday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONDAY.get()); tuesday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TUESDAY.get()); wednesday = Utilities.createCheckBox( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEDNESDAY.get()); thursday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_THURSDAY.get()); friday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_FRIDAY.get()); saturday = Utilities.createCheckBox(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SATURDAY.get()); } JCheckBox[] weekDays = { sunday, monday, tuesday, wednesday, thursday, friday, saturday }; private JLabel lMonthlyTime; private JLabel lMonthlyDays; private JTextField monthlyTime; private JCheckBox[] monthDays = new JCheckBox[31]; private JLabel lCronMinute; private JLabel lCronHour; private JLabel lCronWeekDay; private JLabel lCronMonthDay; private JLabel lCronMonth; private JTextField cronMinute; private JTextField cronHour; private JTextField cronWeekDay; private JTextField cronMonthDay; private JTextField cronMonth; private Component launchLaterPanel; private Component dailyPanel; private Component weeklyPanel; private Component monthlyPanel; private Component cronPanel; private Message LAUNCH_NOW = INFO_CTRL_PANEL_LAUNCH_NOW.get(); private Message LAUNCH_LATER = INFO_CTRL_PANEL_LAUNCH_LATER.get(); private Message LAUNCH_DAILY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAILY.get(); private Message LAUNCH_WEEKLY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEEKLY.get(); private Message LAUNCH_MONTHLY = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTHLY.get(); private Message CRON = INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON.get(); private ScheduleType schedule; /** * Default constructor. * @param taskName the name of the task to be scheduled. */ public TaskToSchedulePanel(String taskName) { super(); this.taskName = taskName; createLayout(); } /** * Creates the layout of the panel (but the contents are not populated here). */ private void createLayout() { GridBagConstraints gbc = new GridBagConstraints(); JEditorPane explanation = Utilities.makeHtmlPane( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUMMARY.get(taskName).toString(), ColorAndFontConstants.defaultFont); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; add(explanation, gbc); gbc.gridy ++; gbc.insets.top = 10; scheduleType = Utilities.createComboBox(); scheduleType.setModel(new DefaultComboBoxModel()); ArrayList<Object> newElements = new ArrayList<Object>(); newElements.add(new CategorizedComboBoxElement(LAUNCH_NOW, CategorizedComboBoxElement.Type.REGULAR)); newElements.add(COMBO_SEPARATOR); newElements.add(new CategorizedComboBoxElement(LAUNCH_LATER, CategorizedComboBoxElement.Type.REGULAR)); newElements.add(COMBO_SEPARATOR); newElements.add(new CategorizedComboBoxElement(LAUNCH_DAILY, CategorizedComboBoxElement.Type.REGULAR)); newElements.add(new CategorizedComboBoxElement(LAUNCH_WEEKLY, CategorizedComboBoxElement.Type.REGULAR)); newElements.add(new CategorizedComboBoxElement(LAUNCH_MONTHLY, CategorizedComboBoxElement.Type.REGULAR)); newElements.add(new CategorizedComboBoxElement(CRON, CategorizedComboBoxElement.Type.REGULAR)); updateComboBoxModel(newElements, (DefaultComboBoxModel)scheduleType.getModel()); scheduleType.setRenderer( new NoLeftInsetCategoryComboBoxRenderer(scheduleType)); scheduleType.addItemListener(new IgnoreItemListener(scheduleType)); gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.NONE; add(scheduleType, gbc); launchLaterPanel = createLaunchLaterPanel(); dailyPanel = createDailyPanel(); weeklyPanel = createWeeklyPanel(); monthlyPanel = createMonthlyPanel(); cronPanel = createCronPanel(); scheduleType.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ev) { Object element = scheduleType.getSelectedItem(); boolean launchLaterVisible = false; boolean launchDailyVisible = false; boolean launchWeeklyVisible = false; boolean launchMonthlyVisible = false; boolean cronVisible = false; if (element != null) { if (element instanceof CategorizedComboBoxElement) { element = ((CategorizedComboBoxElement)element).getValue(); } launchLaterVisible = element == LAUNCH_LATER; launchDailyVisible = element == LAUNCH_DAILY; launchWeeklyVisible = element == LAUNCH_WEEKLY; launchMonthlyVisible = element == LAUNCH_MONTHLY; cronVisible = element == CRON; } launchLaterPanel.setVisible(launchLaterVisible); dailyPanel.setVisible(launchDailyVisible); weeklyPanel.setVisible(launchWeeklyVisible); monthlyPanel.setVisible(launchMonthlyVisible); cronPanel.setVisible(cronVisible); } }); launchLaterPanel.setVisible(false); dailyPanel.setVisible(false); weeklyPanel.setVisible(false); monthlyPanel.setVisible(false); cronPanel.setVisible(false); int width = 0; int height = 0; Component[] comps = {launchLaterPanel, dailyPanel, weeklyPanel, monthlyPanel, cronPanel}; for (Component comp : comps) { width = Math.max(width, comp.getPreferredSize().width); height = Math.max(height, comp.getPreferredSize().height); } gbc.gridy ++; gbc.gridwidth = 1; gbc.gridx = 0; gbc.weightx = 0.0; gbc.insets.left = 30; add(launchLaterPanel, gbc); add(dailyPanel, gbc); add(weeklyPanel, gbc); add(monthlyPanel, gbc); add(cronPanel, gbc); add(Box.createRigidArea(new Dimension(width, height)), gbc); gbc.gridy ++; gbc.gridx = 0; gbc.fill = GridBagConstraints.VERTICAL; gbc.weighty = 1.0; add(Box.createVerticalGlue(), gbc); } /** * {@inheritDoc} */ public void toBeDisplayed(boolean visible) { // Reset the schedule if (visible) { schedule = null; } } /** * {@inheritDoc} */ public Message getTitle() { return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TITLE.get(taskName); } /** * {@inheritDoc} */ public void okClicked() { schedule = null; ArrayList<Message> errorMessages = new ArrayList<Message>(); updateErrorMessages(errorMessages); if (errorMessages.size() > 0) { displayErrorDialog(errorMessages); } else { schedule = createSchedule(); Utilities.getParentDialog(this).setVisible(false); } } /** * Checks the validity of the provided information and updates the provided * collection of messages with the errors that have been found. * @param errorMessages the collection of messages to be updated. */ private void updateErrorMessages(Collection<Message> errorMessages) { Object type = ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue(); if (type == LAUNCH_LATER) { updateLaunchLaterErrorMessages(errorMessages); } else if (type == LAUNCH_DAILY) { updateLaunchDailyErrorMessages(errorMessages); } else if (type == LAUNCH_WEEKLY) { updateLaunchWeeklyErrorMessages(errorMessages); } else if (type == LAUNCH_MONTHLY) { updateLaunchMonthlyErrorMessages(errorMessages); } else if (type == CRON) { updateCronErrorMessages(errorMessages); } } /** * Checks the validity of the launch later information and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param errorMessages the collection of messages to be updated. */ private void updateLaunchLaterErrorMessages(Collection<Message> errorMessages) { setPrimaryValid(lTime); setPrimaryValid(lDay); setPrimaryValid(lMonth); setPrimaryValid(lYear); int previousErrorNumber = errorMessages.size(); int y = Integer.parseInt(year.getSelectedItem().toString()); int d = -1; int m = month.getSelectedIndex(); int[] h = {-1}; int[] min = {-1}; checkTime(time, lTime, h, min, errorMessages); try { d = Integer.parseInt(day.getText().trim()); if ((d < 0) || (d > 31)) { errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get()); setPrimaryInvalid(lDay); } } catch (Exception ex) { errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY.get()); setPrimaryInvalid(lDay); } if (errorMessages.size() == previousErrorNumber) { GregorianCalendar calendar = new GregorianCalendar(y, m, d, h[0], min[0]); Date date = calendar.getTime(); // Check that the actual date's month date corresponds to a valid day // (for instance if user specifies 30th of February, the resulting date // is 2nd (or 1st depending of the year) of Mars. if (calendar.get(Calendar.MONTH) != m) { errorMessages.add(ERR_CTRL_PANEL_INVALID_DAY_IN_MONTH.get(d, month.getSelectedItem().toString())); setPrimaryInvalid(lDay); setPrimaryInvalid(lMonth); } else if (date.before(new Date())) { errorMessages.add(ERR_CTRL_PANEL_DATE_ALREADY_PASSED.get()); setPrimaryInvalid(lTime); setPrimaryInvalid(lDay); setPrimaryInvalid(lMonth); setPrimaryInvalid(lYear); } } } /** * Checks the validity of the launch daily information and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param errorMessages the collection of messages to be updated. */ private void updateLaunchDailyErrorMessages(Collection<Message> errorMessages) { setPrimaryValid(lDailyTime); int[] h = {-1}; int[] min = {-1}; checkTime(dailyTime, lDailyTime, h, min, errorMessages); } /** * Checks the validity of the launch weekly information and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param errorMessages the collection of messages to be updated. */ private void updateLaunchWeeklyErrorMessages( Collection<Message> errorMessages) { setPrimaryValid(lWeeklyTime); setPrimaryValid(lWeeklyDays); int[] h = {-1}; int[] min = {-1}; checkTime(weeklyTime, lWeeklyTime, h, min, errorMessages); boolean oneSelected = false; for (JCheckBox cb : weekDays) { if (cb.isSelected()) { oneSelected = true; break; } } if (!oneSelected) { errorMessages.add(ERR_CTRL_PANEL_NO_WEEK_DAY_SELECTED.get()); setPrimaryInvalid(lWeeklyDays); } } /** * Checks the validity of the launch monthly information and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param errorMessages the collection of messages to be updated. */ private void updateLaunchMonthlyErrorMessages( Collection<Message> errorMessages) { setPrimaryValid(lMonthlyTime); setPrimaryValid(lMonthlyDays); int[] h = {-1}; int[] min = {-1}; checkTime(monthlyTime, lMonthlyTime, h, min, errorMessages); boolean oneSelected = false; for (JCheckBox cb : monthDays) { if (cb.isSelected()) { oneSelected = true; break; } } if (!oneSelected) { errorMessages.add(ERR_CTRL_PANEL_NO_MONTH_DAY_SELECTED.get()); setPrimaryInvalid(lMonthlyDays); } } /** * Checks the validity of the cron schedule information and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param errorMessages the collection of messages to be updated. */ private void updateCronErrorMessages(Collection<Message> errorMessages) { setPrimaryValid(lCronMinute); setPrimaryValid(lCronHour); setPrimaryValid(lCronMonthDay); setPrimaryValid(lCronMonth); setPrimaryValid(lCronWeekDay); String minute = cronMinute.getText().trim(); String hour = cronHour.getText().trim(); String monthDay = cronMonthDay.getText().trim(); String month = cronMonth.getText().trim(); String weekDay = cronWeekDay.getText().trim(); updateCronErrorMessages(minute, lCronMinute, ERR_CTRL_PANEL_NO_CRON_MINUTE_PROVIDED.get(), ERR_CTRL_PANEL_NOT_VALID_CRON_MINUTE_PROVIDED.get(), 0, 59, errorMessages); updateCronErrorMessages(hour, lCronHour, ERR_CTRL_PANEL_NO_CRON_HOUR_PROVIDED.get(), ERR_CTRL_PANEL_NOT_VALID_CRON_HOUR_PROVIDED.get(), 0, 23, errorMessages); updateCronErrorMessages(weekDay, lCronWeekDay, ERR_CTRL_PANEL_NO_CRON_WEEK_DAY_PROVIDED.get(), ERR_CTRL_PANEL_NOT_VALID_CRON_WEEK_DAY_PROVIDED.get(), 0, 6, errorMessages); updateCronErrorMessages(monthDay, lCronMonthDay, ERR_CTRL_PANEL_NO_CRON_MONTH_DAY_PROVIDED.get(), ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_DAY_PROVIDED.get(), 1, 31, errorMessages); updateCronErrorMessages(month, lCronMonth, ERR_CTRL_PANEL_NO_CRON_MONTH_PROVIDED.get(), ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_PROVIDED.get(), 1, 12, errorMessages); } /** * Checks the validity of the cron schedule information tab and updates * the provided collection of messages with the errors that have been found. * The associated labels are also updated. * @param value the value of the cron schedule tab. * @param label the label associated with the cron schedule tab. * @param errorIfEmpty the message to be displayed if the value tab is empty. * @param contentError the message to be displayed if the value tab is not * valid. * @param minValue the minimum value accepted. * @param maxValue the maximum value accepted. * @param errorMessages the collection of messages to be updated. */ private void updateCronErrorMessages(String value, JLabel label, Message errorIfEmpty, Message contentError, int minValue, int maxValue, Collection<Message> errorMessages) { if (value.length() == 0) { errorMessages.add(errorIfEmpty); setPrimaryInvalid(label); } else { try { RecurringTask.parseTaskTabField(value, minValue, maxValue); } catch (Exception ex) { errorMessages.add(contentError); setPrimaryInvalid(label); } } } /** * Returns the schedule type corresponding to the input provided by user. * This method assumes that all the date provided by the user has been * validated. * @return the schedule type corresponding to the input provided by user. */ private ScheduleType createSchedule() { ScheduleType schedule; Object type = ((CategorizedComboBoxElement)scheduleType.getSelectedItem()).getValue(); if (type == LAUNCH_NOW) { schedule = ScheduleType.createLaunchNow(); } else if (type == LAUNCH_LATER) { int y = Integer.parseInt(year.getSelectedItem().toString()); int d = Integer.parseInt(day.getText().trim()); int m = month.getSelectedIndex(); String sTime = time.getText().trim(); int index = sTime.indexOf(':'); int h = Integer.parseInt(sTime.substring(0, index).trim()); int min = Integer.parseInt(sTime.substring(index+1).trim()); GregorianCalendar calendar = new GregorianCalendar(y, m, d, h, min); schedule = ScheduleType.createLaunchLater(calendar.getTime()); } else if (type == LAUNCH_DAILY) { String sTime = dailyTime.getText().trim(); int index = sTime.indexOf(':'); int h = Integer.parseInt(sTime.substring(0, index).trim()); int m = Integer.parseInt(sTime.substring(index+1).trim()); String cron = m+" "+h+" * * *"; schedule = ScheduleType.createCron(cron); } else if (type == LAUNCH_WEEKLY) { String sTime = weeklyTime.getText().trim(); int index = sTime.indexOf(':'); int h = Integer.parseInt(sTime.substring(0, index).trim()); int m = Integer.parseInt(sTime.substring(index+1).trim()); StringBuilder sb = new StringBuilder(); sb.append(m+" "+h+" * * "); boolean oneDayAdded = false; for (int i=0; i<weekDays.length; i++) { if (weekDays[i].isSelected()) { if (oneDayAdded) { sb.append(','); } sb.append(i); oneDayAdded = true; } } schedule = ScheduleType.createCron(sb.toString()); } else if (type == LAUNCH_MONTHLY) { String sTime = monthlyTime.getText().trim(); int index = sTime.indexOf(':'); int h = Integer.parseInt(sTime.substring(0, index).trim()); int m = Integer.parseInt(sTime.substring(index+1).trim()); StringBuilder sb = new StringBuilder(); sb.append(m+" "+h+" "); boolean oneDayAdded = false; for (int i=0; i<monthDays.length; i++) { if (monthDays[i].isSelected()) { if (oneDayAdded) { sb.append(','); } sb.append(i+1); oneDayAdded = true; } } sb.append(" * *"); schedule = ScheduleType.createCron(sb.toString()); } else if (type == CRON) { String cron = cronMinute.getText().trim() + " "+ cronHour.getText().trim() + " "+ cronMonthDay.getText().trim() + " "+ cronMonth.getText().trim() + " "+ cronWeekDay.getText().trim(); schedule = ScheduleType.createCron(cron); } else { throw new IllegalStateException("Unknown schedule type: "+type); } return schedule; } /** * Convenience method to retrieve the time specified by the user. * @param time the text field where the user specifies time. * @param lTime the label associated with the text field. * @param h an integer array of size 1 where the value of the hour specified * by the user will be set. * @param m an integer array of size 1 where the value of the minute specified * by the user will be set. * @param errorMessages the collection of error messages that will be updated * with the encountered problems. */ private void checkTime(JTextField time, JLabel lTime, int[] h, int[] m, Collection<Message> errorMessages) { String sTime = time.getText().trim(); int index = sTime.indexOf(':'); try { h[0] = Integer.parseInt(sTime.substring(0, index).trim()); m[0] = Integer.parseInt(sTime.substring(index+1).trim()); if (h[0] < 0 || h[0] > 23) { errorMessages.add(ERR_CTRL_PANEL_INVALID_HOUR.get()); setPrimaryInvalid(lTime); } if (m[0] < 0 || m[0] > 59) { errorMessages.add(ERR_CTRL_PANEL_INVALID_MINUTE.get()); setPrimaryInvalid(lTime); } } catch (Exception ex) { errorMessages.add(ERR_CTRL_PANEL_INVALID_TIME.get()); setPrimaryInvalid(lTime); } } /** * Tells whether the user chose to close the dialog discarding the provided * input. * @return <CODE>true</CODE> if the user chose to close the dialog discarding * the provided input and <CODE>false</CODE> otherwise. */ public boolean isCancelled() { return schedule == null; } /** * {@inheritDoc} */ public void configurationChanged(ConfigurationChangeEvent ev) { } /** * {@inheritDoc} */ public Component getPreferredFocusComponent() { return scheduleType; } /** * Returns the schedule provided by the user. * @return the schedule provided by the user. */ public ScheduleType getSchedule() { return schedule; } private Component createLaunchLaterPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); Calendar calendar = Calendar.getInstance(); int currentYear = calendar.get(Calendar.YEAR); int currentHour = calendar.get(Calendar.HOUR_OF_DAY); int currentMinute = calendar.get(Calendar.MINUTE); int currentDay = calendar.get(Calendar.DAY_OF_MONTH); int currentMonth = calendar.get(Calendar.MONTH); time = Utilities.createShortTextField(); PlainDocument plainTextDocument = new PlainDocument(); time.setDocument(plainTextDocument); String sHour = currentHour >= 10 ? String.valueOf(currentHour) : "0"+currentHour; String sMinute = currentMinute >= 10 ? String.valueOf(currentMinute) : "0"+currentMinute; time.setText(sHour+":"+sMinute); plainTextDocument.setDocumentFilter(new TimeDocumentFilter(time)); day = Utilities.createShortTextField(); day.setColumns(4); plainTextDocument = new PlainDocument(); day.setDocument(plainTextDocument); day.setText(String.valueOf(currentDay)); plainTextDocument.setDocumentFilter( new NumericLimitedSizeDocumentFilter(day, 2)); month = Utilities.createComboBox(); year = Utilities.createComboBox(); int[][] maxMin = { {currentYear, currentYear + 5} }; JComboBox[] numericBoxes = { year }; int[] currentValues = { currentYear }; for (int i=0; i<maxMin.length; i++) { int min = maxMin[i][0]; int max = maxMin[i][1]; DefaultComboBoxModel model = new DefaultComboBoxModel(); int selectedIndex = 0; int index = 0; for (int j=min; j<=max; j++) { String s; if (j < 10) { s = "0"+j; } else { s = String.valueOf(j); } model.addElement(s); if (j == currentValues[i]) { selectedIndex= index; } index++; } numericBoxes[i].setModel(model); if (selectedIndex != 0) { numericBoxes[i].setSelectedIndex(selectedIndex); } } DefaultComboBoxModel model = new DefaultComboBoxModel(); month.setModel(model); Message[] monthMessages = { INFO_CTRL_PANEL_JANUARY.get(), INFO_CTRL_PANEL_FEBRUARY.get(), INFO_CTRL_PANEL_MARS.get(), INFO_CTRL_PANEL_APRIL.get(), INFO_CTRL_PANEL_MAY.get(), INFO_CTRL_PANEL_JUNE.get(), INFO_CTRL_PANEL_JULY.get(), INFO_CTRL_PANEL_AUGUST.get(), INFO_CTRL_PANEL_SEPTEMBER.get(), INFO_CTRL_PANEL_OCTOBER.get(), INFO_CTRL_PANEL_NOVEMBER.get(), INFO_CTRL_PANEL_DECEMBER.get(), }; for (Message msg : monthMessages) { model.addElement(msg.toString()); } month.setSelectedIndex(currentMonth); lTime = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); lDay = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAY.get()); lMonth = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTH.get()); lYear = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_YEAR.get()); gbc.gridy = 0; JLabel[] labels = {lTime, lDay, lMonth, lYear}; Component[] comps = {time, day, month, year}; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; for (int i=0; i<labels.length; i++) { gbc.gridx = 0; gbc.weightx = 0.0; panel.add(labels[i], gbc); gbc.gridx = 1; gbc.insets.left = 10; panel.add(comps[i], gbc); gbc.gridx = 2; gbc.weightx = 1.0; gbc.insets.left = 0; panel.add(Box.createHorizontalGlue(), gbc); gbc.insets.top = 10; gbc.gridy ++; } gbc.insets.top = 0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.VERTICAL; panel.add(Box.createVerticalGlue(), gbc); return panel; } private Component createDailyPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.weightx = 0.0; lDailyTime = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); dailyTime = Utilities.createShortTextField(); PlainDocument plainTextDocument = new PlainDocument(); dailyTime.setDocument(plainTextDocument); dailyTime.setColumns(4); dailyTime.setText("00:00"); plainTextDocument.setDocumentFilter(new TimeDocumentFilter(dailyTime)); panel.add(lDailyTime, gbc); gbc.gridx = 1; gbc.insets.left = 10; gbc.fill = GridBagConstraints.NONE; panel.add(dailyTime, gbc); gbc.gridx = 2; gbc.weightx = 1.0; gbc.insets.left = 0; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(Box.createHorizontalGlue(), gbc); return panel; } private Component createWeeklyPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.0; lWeeklyTime = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); weeklyTime = Utilities.createShortTextField(); PlainDocument plainTextDocument = new PlainDocument(); weeklyTime.setDocument(plainTextDocument); weeklyTime.setColumns(4); weeklyTime.setText("00:00"); plainTextDocument.setDocumentFilter(new TimeDocumentFilter(weeklyTime)); lWeeklyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get()); for (JCheckBox cb : weekDays) { cb.setFont(ColorAndFontConstants.inlineHelpFont); } sunday.setSelected(true); wednesday.setSelected(true); gbc.anchor = GridBagConstraints.WEST; panel.add(lWeeklyTime, gbc); gbc.gridx = 1; gbc.insets.left = 10; gbc.gridwidth = weekDays.length; gbc.fill = GridBagConstraints.NONE; panel.add(weeklyTime, gbc); gbc.gridx = 2; gbc.weightx = 1.0; gbc.insets.left = 0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(Box.createHorizontalGlue(), gbc); gbc.gridx = 0; gbc.gridy ++; gbc.insets.top = 10; gbc.weightx = 1.0; panel.add(lWeeklyDays, gbc); gbc.insets.left = 10; gbc.gridwidth = 1; for (JCheckBox cb : weekDays) { gbc.gridx ++; panel.add(cb, gbc); } gbc.weightx = 1.0; gbc.insets.left = 0; gbc.gridwidth = 1; gbc.gridx ++; panel.add(Box.createHorizontalGlue(), gbc); return panel; } private Component createMonthlyPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.0; lMonthlyTime = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME.get()); monthlyTime = Utilities.createShortTextField(); PlainDocument plainTextDocument = new PlainDocument(); monthlyTime.setDocument(plainTextDocument); monthlyTime.setColumns(4); monthlyTime.setText("00:00"); plainTextDocument.setDocumentFilter(new TimeDocumentFilter(monthlyTime)); lMonthlyDays = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DAYS.get()); gbc.anchor = GridBagConstraints.WEST; panel.add(lMonthlyTime, gbc); gbc.gridx = 1; gbc.insets.left = 10; gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 7; panel.add(monthlyTime, gbc); gbc.gridx = 2; gbc.weightx = 1.0; gbc.insets.left = 0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(Box.createHorizontalGlue(), gbc); gbc.gridx = 0; gbc.gridy ++; gbc.insets.top = 10; gbc.weightx = 1.0; gbc.gridwidth = 1; panel.add(lMonthlyDays, gbc); gbc.insets.left = 10; gbc.gridwidth = 1; for (int i=0 ; i<monthDays.length; i++) { monthDays[i] = Utilities.createCheckBox(Message.raw(String.valueOf(i+1))); monthDays[i].setFont(ColorAndFontConstants.inlineHelpFont); int x = i % 7; if (x == 0 && i != 0) { gbc.gridy ++; gbc.insets.top = 5; } if (x != 0) { gbc.insets.left = 5; } else { gbc.insets.left = 10; } gbc.gridx = x + 1; panel.add(monthDays[i], gbc); } monthDays[0].setSelected(true); gbc.weightx = 1.0; gbc.insets.left = 0; gbc.gridwidth = 1; gbc.gridx ++; panel.add(Box.createHorizontalGlue(), gbc); return panel; } private Component createCronPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); JEditorPane explanation = Utilities.makeHtmlPane( INFO_CTRL_PANEL_CRON_HELP.get().toString(), ColorAndFontConstants.inlineHelpFont); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.HORIZONTAL; panel.add(explanation, gbc); gbc.gridy ++; gbc.insets.top = 10; gbc.gridwidth = 1; lCronMinute = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MINUTE.get()); lCronHour = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_HOUR.get()); lCronWeekDay = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_WEEK_DAY.get()); lCronMonthDay = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH_DAY.get()); lCronMonth = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH.get()); cronMinute = Utilities.createShortTextField(); cronMinute.setText("*"); cronHour = Utilities.createShortTextField(); cronHour.setText("*"); cronWeekDay = Utilities.createShortTextField(); cronWeekDay.setText("*"); cronMonthDay = Utilities.createShortTextField(); cronMonthDay.setText("*"); cronMonth = Utilities.createShortTextField(); cronMonth.setText("*"); JLabel[] labels = {lCronMinute, lCronHour, lCronWeekDay, lCronMonthDay, lCronMonth}; Component[] comps = {cronMinute, cronHour, cronWeekDay, cronMonthDay, cronMonth}; Message[] help = { INFO_CTRL_PANEL_CRON_MINUTE_HELP.get(), INFO_CTRL_PANEL_CRON_HOUR_HELP.get(), INFO_CTRL_PANEL_CRON_WEEK_DAY_HELP.get(), INFO_CTRL_PANEL_CRON_MONTH_DAY_HELP.get(), INFO_CTRL_PANEL_CRON_MONTH_HELP.get(), }; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; for (int i=0; i<labels.length; i++) { gbc.gridx = 0; gbc.weightx = 0.0; gbc.insets.left = 0; panel.add(labels[i], gbc); gbc.gridx = 1; gbc.insets.left = 10; panel.add(comps[i], gbc); gbc.gridx = 2; gbc.weightx = 1.0; gbc.insets.left = 0; panel.add(Box.createHorizontalGlue(), gbc); if (help[i] != null) { gbc.insets.top = 3; gbc.insets.left = 10; gbc.gridy ++; gbc.gridx = 1; panel.add(Utilities.createInlineHelpLabel(help[i]), gbc); } gbc.insets.top = 10; gbc.gridy ++; } gbc.insets.top = 0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.VERTICAL; panel.add(Box.createVerticalGlue(), gbc); return panel; } /** * The main method to test this panel. * @param args the arguments. */ public static void main(String[] args) { while (true) { TaskToSchedulePanel p = new TaskToSchedulePanel("TEST TASK"); GenericDialog dlg = new GenericDialog(new JFrame(), p); dlg.setModal(true); dlg.setVisible(true); } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/components/NumericLimitedSizeDocumentFilter.java
New file @@ -0,0 +1,116 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.components; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; import javax.swing.text.JTextComponent; /** * Document filter used to update properly a text component displaying a * numeric field with a limited size. */ public class NumericLimitedSizeDocumentFilter extends DocumentFilter { private JTextComponent tf; private int maxSize; /** * Constructor. * @param tf the text component associated with the document. * @param maxSize the maximum size. */ public NumericLimitedSizeDocumentFilter(JTextComponent tf, int maxSize) { this.tf = tf; this.maxSize = maxSize; } /** * {@inheritDoc} */ public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { int previousLength = fb.getDocument().getLength(); String newText = text.replaceAll("[^0-9]", ""); if (newText.length() > maxSize) { newText = newText.substring(0, maxSize); } if (newText.length() + previousLength > maxSize) { if (offset + newText.length() > maxSize) { int newOffset = offset + newText.length() - maxSize; fb.remove(0, newOffset); fb.insertString(newOffset, newText, attr); } else { fb.insertString(offset, newText, attr); fb.remove(maxSize, newText.length() + previousLength - maxSize); } } else { fb.insertString(offset, newText, attr); } updateCaretPosition(fb); } /** * {@inheritDoc} */ public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException { if (length > 0) { fb.remove(offset, length); } insertString(fb, offset, text, attr); } private void updateCaretPosition(DocumentFilter.FilterBypass fb) throws BadLocationException { int totalLength = fb.getDocument().getLength(); int caretPosition = tf.getCaretPosition(); if ((totalLength >= maxSize) && (caretPosition == fb.getDocument().getLength())) { tf.setCaretPosition(0); } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/components/ScheduleSummaryPanel.java
New file @@ -0,0 +1,182 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.components; import static org.opends.messages.AdminToolMessages.*; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DateFormat; import java.util.Date; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import org.opends.guitools.controlpanel.datamodel.ScheduleType; import org.opends.guitools.controlpanel.ui.GenericDialog; import org.opends.guitools.controlpanel.ui.TaskToSchedulePanel; import org.opends.guitools.controlpanel.util.Utilities; /** * A class used as component displaying the string representation of a schedule * and the possibility of updating it clicking a button. */ public class ScheduleSummaryPanel extends JPanel { private static final long serialVersionUID = 3111141404599060028L; private ScheduleType schedule = ScheduleType.createLaunchNow(); private JLabel label; private JButton change; private TaskToSchedulePanel schedulePanel; private GenericDialog scheduleDlg; private String taskName; private DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT); /** * Default constructor. * @param taskName the name of the task to be scheduled. */ public ScheduleSummaryPanel(String taskName) { super(new GridBagLayout()); setOpaque(false); this.taskName = taskName; createLayout(); } /** * Returns the schedule represented by this panel. * @return the schedule represented by this panel. */ public ScheduleType getSchedule() { return schedule; } /** * Sets the schedule represented by this panel. * @param schedule the schedule represented by this panel. */ public void setSchedule(ScheduleType schedule) { this.schedule = schedule; updateLabel(schedule); } /** * Returns whether the change button is enabled or not. * @return <CODE>true</CODE> if the change button is enabled and * <CODE>false</CODE> otherwise. */ public boolean isChangeEnabled() { return change.isEnabled(); } /** * Sets the enable state of the change button. * @param enable whether the change button must be enabled or not. */ public void setChangeEnabled(boolean enable) { change.setEnabled(enable); } private void createLayout() { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; label = Utilities.createDefaultLabel(); change = Utilities.createButton(INFO_CTRL_PANEL_CHANGE_SCHEDULE.get()); change.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { changeButtonClicked(); } }); updateLabel(schedule); gbc.fill = GridBagConstraints.NONE; add(label, gbc); gbc.gridx ++; gbc.insets.left = 10; add(change, gbc); gbc.gridx ++; gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets.left = 0; add(Box.createHorizontalGlue(), gbc); } private void updateLabel(ScheduleType schedule) { ScheduleType.Type type = schedule.getType(); if (type == ScheduleType.Type.LAUNCH_NOW) { label.setText(INFO_CTRL_PANEL_LAUNCH_NOW_SUMMARY.get().toString()); } else if (type == ScheduleType.Type.LAUNCH_LATER) { Date date = schedule.getLaunchLaterDate(); String sDate = formatter.format(date); label.setText(INFO_CTRL_PANEL_LAUNCH_LATER_SUMMARY.get(sDate).toString()); } else if (type == ScheduleType.Type.LAUNCH_PERIODICALLY) { String cron = schedule.getCronValue(); label.setText( INFO_CTRL_PANEL_LAUNCH_PERIODICALLY_SUMMARY.get(cron).toString()); } else { throw new IllegalStateException("Unknown schedule type: "+type); } } private void changeButtonClicked() { if (schedulePanel == null) { schedulePanel = new TaskToSchedulePanel(taskName); scheduleDlg = new GenericDialog(Utilities.getFrame(this), schedulePanel); Utilities.centerGoldenMean(scheduleDlg, Utilities.getParentDialog(this)); scheduleDlg.setModal(true); } scheduleDlg.setVisible(true); if (!schedulePanel.isCancelled()) { setSchedule(schedulePanel.getSchedule()); } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/components/TimeDocumentFilter.java
New file @@ -0,0 +1,198 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.components; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; import javax.swing.text.JTextComponent; /** * Document filter used to update properly a text component displaying a * time. */ public class TimeDocumentFilter extends DocumentFilter { private JTextComponent tf; /** * Constructor. * @param tf the text component associated with the document. */ public TimeDocumentFilter(JTextComponent tf) { this.tf = tf; } /** * {@inheritDoc} */ public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { int previousLength = fb.getDocument().getLength(); fb.insertString(offset, text.replaceAll("[^0-9]", ""), attr); trimPosition(fb, text, offset, previousLength); } /** * {@inheritDoc} */ public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException { String text = fb.getDocument().getText(offset, length); int index = text.indexOf(":"); if (index == -1) { fb.remove(offset, length); } else { // index value is relative to offset if (index > 0) { fb.remove(offset, index); } if (index < length - 1) { fb.remove(offset + index + 1, length - index -1); } } updateCaretPosition(fb); } /** * {@inheritDoc} */ public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException { int previousLength = fb.getDocument().getLength(); String t = fb.getDocument().getText(offset, length); int index = t.indexOf(":"); fb.replace(offset, length, text.replaceAll("[^0-9]", ""), attr); if (index != -1) { if (fb.getDocument().getLength() >= 2) { fb.insertString(2, ":", attr); } else { fb.insertString(fb.getDocument().getLength(), ":", attr); } } trimPosition(fb, text, offset, previousLength); } private void trimPosition(DocumentFilter.FilterBypass fb, String newText, int offset, int previousLength) throws BadLocationException { String allText = fb.getDocument().getText(0, fb.getDocument().getLength()); int index = allText.indexOf(':'); if ((index != -1) && (newText.length() == 1)) { int minuteLength = allText.length() - index - 1; int hourLength = index; if ((minuteLength > 2) || (hourLength > 2)) { if (offset < previousLength) { fb.remove(offset + 1, 1); } else { fb.remove(previousLength, 1); } } } updateCaretPosition(fb); } private void updateCaretPosition(DocumentFilter.FilterBypass fb) throws BadLocationException { String allText = fb.getDocument().getText(0, fb.getDocument().getLength()); int index = allText.indexOf(':'); if (index != -1) { int minuteLength = allText.length() - index - 1; int hourLength = index; int caretPosition = tf.getCaretPosition(); if ((minuteLength >= 2) && (caretPosition == allText.length())) { tf.setCaretPosition(0); } else if (hourLength == caretPosition) { if (hourLength >= 2) { tf.setCaretPosition(3); } else if (hourLength == 1) { char c = allText.charAt(0); if (c != '0' && c != '1' && c != '2') { tf.setCaretPosition(2); } } } else if (hourLength + 1 == caretPosition) { if (hourLength == 1) { char c = allText.charAt(0); if (c == '0' || c == '1' || c == '2') { tf.setCaretPosition(caretPosition - 1); } } else if (hourLength == 0) { tf.setCaretPosition(caretPosition - 1); } } } if (allText.length() == 1) { tf.setCaretPosition(0); } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/NoLeftInsetCategoryComboBoxRenderer.java
New file @@ -0,0 +1,71 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.renderer; import java.awt.Component; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement; /** * This class is used simply to avoid an inset on the left for the * elements of the combo box. * Since this item is a CategorizedComboBoxElement of type * CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on * the left. */ public class NoLeftInsetCategoryComboBoxRenderer extends CustomListCellRenderer { /** * The constructor. * @param combo the combo box to be rendered. */ public NoLeftInsetCategoryComboBoxRenderer(JComboBox combo) { super(combo); } /** * {@inheritDoc} */ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof CategorizedComboBoxElement) { CategorizedComboBoxElement element = (CategorizedComboBoxElement)value; String name = getStringValue(element); ((JLabel)comp).setText(name); } comp.setFont(defaultFont); return comp; } } opends/src/guitools/org/opends/guitools/controlpanel/ui/renderer/TaskCellRenderer.java
New file @@ -0,0 +1,95 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.renderer; import java.awt.Component; import javax.swing.BorderFactory; import javax.swing.JTable; import javax.swing.border.Border; import javax.swing.table.DefaultTableCellRenderer; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; /** * Class used to render the task tables. */ public class TaskCellRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = -84332267021523835L; /** * The border of the first column. * TODO: modify CustomCellRenderer to make this public. */ protected final static Border column0Border = BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder(0, 1, 0, 0, ColorAndFontConstants.gridColor), BorderFactory.createEmptyBorder(4, 4, 4, 4)); /** * The default border. */ public final static Border defaultBorder = CustomCellRenderer.defaultBorder; /** * Default constructor. */ public TaskCellRenderer() { setFont(ColorAndFontConstants.tableFont); setOpaque(true); setBackground(ColorAndFontConstants.treeBackground); setForeground(ColorAndFontConstants.treeForeground); } /** * {@inheritDoc} */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (hasFocus) { setBorder( CustomCellRenderer.getDefaultFocusBorder(table, value, isSelected, row, column)); } else if (column == 0) { setBorder(column0Border); } else { setBorder(defaultBorder); } return this; } } opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigFromDirContext.java
@@ -33,6 +33,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -67,7 +68,9 @@ import org.opends.server.admin.client.ldap.LDAPManagementContext; import org.opends.server.admin.std.client.*; import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType; import org.opends.server.config.ConfigConstants; import org.opends.server.core.DirectoryServer; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.DN; import org.opends.server.types.OpenDsException; import org.opends.server.util.ServerConstants; @@ -238,6 +241,7 @@ new HashSet<ConnectionHandlerDescriptor>(); Set<BackendDescriptor> bs = new HashSet<BackendDescriptor>(); Set<DN> as = new HashSet<DN>(); Set<TaskEntry> ts = new HashSet<TaskEntry>(); rootMonitor = null; jvmMemoryUsage = null; @@ -528,11 +532,23 @@ } catch (Throwable t) { LOG.log(Level.WARNING, "Error reading configuration: "+t, t); LOG.log(Level.WARNING, "Error reading monitoring: "+t, t); OnlineUpdateException oupe = new OnlineUpdateException( ERR_READING_CONFIG_LDAP.get(t.toString()), t); ex.add(oupe); } try { updateTaskInformation(ctx, ex, ts); } catch (Throwable t) { LOG.log(Level.WARNING, "Error reading task information: "+t, t); OnlineUpdateException oupe = new OnlineUpdateException( ERR_READING_CONFIG_LDAP.get(t.toString()), t); ex.add(oupe); } taskEntries = Collections.unmodifiableSet(ts); for (ConnectionHandlerDescriptor ch : getConnectionHandlers()) { ch.setMonitoringEntries(getMonitoringEntries(ch)); @@ -762,6 +778,33 @@ } } /** * Takes the provided search result and updates the task information * accordingly. * @param sr the search result. * @param searchBaseDN the base search. * @param taskEntries the collection of TaskEntries to be updated. * @throws NamingException if there is an error retrieving the values of the * search result. */ protected void handleTaskSearchResult(SearchResult sr, String searchBaseDN, Collection<TaskEntry> taskEntries) throws NamingException { CustomSearchResult csr = new CustomSearchResult(sr, searchBaseDN); try { if (isTaskEntry(csr)) { taskEntries.add(new TaskEntry(csr.getEntry())); } } catch (OpenDsException ode) { exceptions.add(ode); } } private void updateMonitorInformation(InitialLdapContext ctx, List<OpenDsException> ex) { @@ -796,6 +839,37 @@ } } private void updateTaskInformation(InitialLdapContext ctx, List<OpenDsException> ex, Collection<TaskEntry> ts) { // Read monitoring information: since it is computed, it is faster // to get everything in just one request. SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); ctls.setReturningAttributes( getMonitoringAttributes()); String filter = "(objectclass=ds-task)"; try { LdapName jndiName = new LdapName(ConfigConstants.DN_TASK_ROOT); NamingEnumeration taskEntries = ctx.search(jndiName, filter, ctls); while (taskEntries.hasMore()) { SearchResult sr = (SearchResult)taskEntries.next(); handleTaskSearchResult(sr, ConfigConstants.DN_TASK_ROOT, ts); } } catch (NamingException ne) { OnlineUpdateException oue = new OnlineUpdateException( ERR_READING_CONFIG_LDAP.get(ne.getMessage().toString()), ne); ex.add(oue); } } private ConnectionHandlerDescriptor getConnectionHandler( ConnectionHandlerCfgClient connHandler, String name) throws OpenDsException @@ -962,6 +1036,24 @@ return isConnectionHandler; } private boolean isTaskEntry(CustomSearchResult csr) throws OpenDsException { boolean isTaskEntry = false; Set<Object> vs = csr.getAttributeValues("objectclass"); if ((vs != null) && !vs.isEmpty()) { for (Object oc : vs) { if (oc.toString().equalsIgnoreCase("ds-task")) { isTaskEntry = true; break; } } } return isTaskEntry; } /** * Commodity method to get the string representation to be used in the * hash maps as key. @@ -977,11 +1069,33 @@ ConnectionHandlerDescriptor ch) { Set<CustomSearchResult> monitorEntries = new HashSet<CustomSearchResult>(); for (String key : hmConnectionHandlersMonitor.keySet()) if (ch.getState() == ConnectionHandlerDescriptor.State.ENABLED) { if (key.indexOf(getKey(ch.getName())) != -1) for (String key : hmConnectionHandlersMonitor.keySet()) { monitorEntries.add(hmConnectionHandlersMonitor.get(key)); // The name of the connection handler does not appear necessarily in the // key (which is based on the DN of the monitoring entry). In general // the DN contains the String specified in // LDAPConnectionHandler.DEFAULT_FRIENDLY_NAME, so we have to check that // this connection handler is the right one. // See org.opends.server.protocols.ldap.LDAPConnectionHandler to see // how the DN of the monitoring entry is generated. if (key.indexOf(getKey("port "+ch.getPort())) != -1) { boolean hasAllAddresses = true; for (InetAddress a : ch.getAddresses()) { if (key.indexOf(getKey(a.getHostAddress())) == -1) { hasAllAddresses = false; break; } } if (hasAllAddresses) { monitorEntries.add(hmConnectionHandlersMonitor.get(key)); } } } } opends/src/guitools/org/opends/guitools/controlpanel/util/ConfigReader.java
@@ -46,6 +46,7 @@ import org.opends.server.admin.std.meta.AdministrationConnectorCfgDefn; import org.opends.server.config.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.DN; import org.opends.server.types.DirectoryEnvironmentConfig; import org.opends.server.types.DirectoryException; @@ -166,6 +167,11 @@ protected Schema schema; /** * The task entries. **/ protected Set<TaskEntry> taskEntries = Collections.emptySet(); /** * Returns the Administrative User DNs found in the config.ldif. The set * must be unmodifiable (the inheriting classes must take care of this). * @return the Administrative User DNs found in the config.ldif. @@ -280,6 +286,15 @@ } /** * Returns the task entries. * @return the task entries. */ public Set<TaskEntry> getTaskEntries() { return taskEntries; } /** * Reads the schema from the files. * @throws ConfigException if an error occurs reading the schema. * @throws InitializationException if an error occurs initializing opends/src/guitools/org/opends/guitools/controlpanel/util/Utilities.java
@@ -993,6 +993,12 @@ } JEditorPane pane2 = makeHtmlPane(wrappedText, font); pane.setPreferredSize(pane2.getPreferredSize()); JFrame frame = getFrame(pane); if ((frame != null) && frame.isVisible()) { frame.getRootPane().revalidate(); frame.getRootPane().repaint(); } } /** opends/src/messages/messages/admin_tool.properties
@@ -1325,6 +1325,7 @@ MILD_ERR_CTRL_PANEL_RUN_BACKUP_ERROR_SUMMARY=Error during Backup MILD_ERR_CTRL_PANEL_RUN_BACKUP_ERROR_DETAILS=An error occurred during the \ backup. Error code: %d. INFO_CTRL_PANEL_BACKUP_TASK_NAME=Backup INFO_CTRL_PANEL_OTHER_BASE_DN_TITLE=Other Base DN MILD_ERR_CTRL_PANEL_NO_BASE_DN_PROVIDED=You must provide a base DN. @@ -2551,3 +2552,132 @@ SEVERE_ERR_VERSION_IN_REMOTE_SERVER_NOT_FOUND=Could not find version \ information in the remote server. The remote LDAP server does not seem to be \ manageable remotely by the control panel. INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TITLE='%s' Task Schedule INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUMMARY=Specify when the task '%s' will be \ launched. INFO_CTRL_PANEL_LAUNCH_NOW=Launch Now INFO_CTRL_PANEL_LAUNCH_LATER=Launch Later INFO_CTRL_PANEL_DAYS=Days: INFO_CTRL_PANEL_JANUARY=January INFO_CTRL_PANEL_FEBRUARY=February INFO_CTRL_PANEL_MARS=Mars INFO_CTRL_PANEL_APRIL=April INFO_CTRL_PANEL_MAY=May INFO_CTRL_PANEL_JUNE=June INFO_CTRL_PANEL_JULY=July INFO_CTRL_PANEL_AUGUST=August INFO_CTRL_PANEL_SEPTEMBER=September INFO_CTRL_PANEL_OCTOBER=October INFO_CTRL_PANEL_NOVEMBER=November INFO_CTRL_PANEL_DECEMBER=December INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TIME=Time: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAY=Day: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTH=Month: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_YEAR=Year: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_DAILY=Launch Periodically using a Daily \ Schedule INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEEKLY=Launch Periodically using a Weekly \ Schedule INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONTHLY=Launch Periodically using a Monthly \ Schedule INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SUNDAY=Sun INFO_CTRL_PANEL_TASK_TO_SCHEDULE_MONDAY=Mon INFO_CTRL_PANEL_TASK_TO_SCHEDULE_TUESDAY=Tue INFO_CTRL_PANEL_TASK_TO_SCHEDULE_WEDNESDAY=Wed INFO_CTRL_PANEL_TASK_TO_SCHEDULE_THURSDAY=Thu INFO_CTRL_PANEL_TASK_TO_SCHEDULE_FRIDAY=Fri INFO_CTRL_PANEL_TASK_TO_SCHEDULE_SATURDAY=Sat INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON=Launch Periodically using a CRON \ Schedule INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MINUTE=Minute: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_HOUR=Hour: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_WEEK_DAY=Day of Week: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH_DAY=Day of Month: INFO_CTRL_PANEL_TASK_TO_SCHEDULE_CRON_MONTH=Month: INFO_CTRL_PANEL_CRON_MINUTE_HELP=Valid values from 0 to 59 INFO_CTRL_PANEL_CRON_HOUR_HELP=Valid values from 0 to 23 INFO_CTRL_PANEL_CRON_WEEK_DAY_HELP=Valid values from 0 to 6 (0 is Sunday, \ 1 is Monday...) INFO_CTRL_PANEL_CRON_MONTH_DAY_HELP=From 1 to 31 INFO_CTRL_PANEL_CRON_MONTH_HELP=Valid values from 1 to 12 (1 is January, \ 2 is February...) # # Note that the following property contains line breaks in HTML format (<br>). # INFO_CTRL_PANEL_CRON_HELP=Use ',' to separate values. For example: \ '1,4,5'.<br>Use '-' to indicate intervals. For example '1-5'.\<br>Use '*' to \ indicate any value. SEVERE_ERR_CTRL_PANEL_INVALID_HOUR=The provided hour value is not valid. SEVERE_ERR_CTRL_PANEL_INVALID_MINUTE=The provided minute value is not valid. SEVERE_ERR_CTRL_PANEL_INVALID_DAY=The provided day value is not valid. SEVERE_ERR_CTRL_PANEL_INVALID_TIME=The provided time value is not valid. SEVERE_ERR_CTRL_PANEL_INVALID_DAY_IN_MONTH=The day '%d' does not exist in \ %s. SEVERE_ERR_CTRL_PANEL_NO_WEEK_DAY_SELECTED=You must select at least one \ day of the week. SEVERE_ERR_CTRL_PANEL_NO_MONTH_DAY_SELECTED=You must select at least one \ day of the month. SEVERE_ERR_CTRL_PANEL_DATE_ALREADY_PASSED=The provided date already passed. SEVERE_ERR_CTRL_PANEL_NO_CRON_MINUTE_PROVIDED=No minute provided. Use '*' \ to indicate any value. SEVERE_ERR_CTRL_PANEL_NO_CRON_HOUR_PROVIDED=No hour provided. Use '*' \ to indicate any value. SEVERE_ERR_CTRL_PANEL_NO_CRON_MONTH_DAY_PROVIDED=No day of month \ provided. Use '*' to indicate any value. SEVERE_ERR_CTRL_PANEL_NO_CRON_MONTH_PROVIDED=No month provided. Use '*' \ to indicate any value. SEVERE_ERR_CTRL_PANEL_NO_CRON_WEEK_DAY_PROVIDED=No day of week provided. \ Use '*' to indicate any value. SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MINUTE_PROVIDED=The minute value \ provided is not valid. SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_HOUR_PROVIDED=The hour value \ provided is not valid. SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_DAY_PROVIDED=The day of month \ value provided is not valid. SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_MONTH_PROVIDED=The month value \ provided is not valid. SEVERE_ERR_CTRL_PANEL_NOT_VALID_CRON_WEEK_DAY_PROVIDED=The day of week \ value provided is not valid. INFO_CTRL_PANEL_TASK_TO_SCHEDULE_LIST_TITLE=Scheduled Tasks INFO_CTRL_PANEL_NO_TASKS_FOUND=- No Tasks Found - INFO_CTRL_PANEL_CANCEL_TASK_BUTTON_LABEL=Cancel Task INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_REQUIRES_SERVER_RUNNING=To see the \ list of scheduled tasks the server must be running and you must provide \ authentication. INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_AUTHENTICATION=To see the list of \ scheduled tasks you must provide authentication. INFO_CTRL_PANEL_CANCEL_TASK_MSG=Are you sure you want to cancel the \ selected tasks? INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION=Cancel Selected Tasks. INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK=Equivalent command-line to \ cancel task '%s': INFO_CTRL_PANEL_TASK_CANCELABLE=Is Cancelable INFO_CTRL_PANEL_CANCELING_TASK_SUMMARY=Canceling Tasks... INFO_CTRL_PANEL_CANCELING_TASK_COMPLETE=The tasks were successfully \ canceled. INFO_CTRL_PANEL_CANCELING_TASK_SUCCESSFUL=The tasks were successfully \ canceled. MILD_ERR_CTRL_PANEL_CANCELING_TASK_ERROR_SUMMARY=Error canceling task MILD_ERR_CTRL_PANEL_CANCELING_TASK_ERROR_DETAILS=An error occurred \ canceling the selected tasks. INFO_CTRL_PANEL_CANCEL_TASK_TITLE=Cancel Tasks INFO_CTRL_PANEL_TASK_IS_CANCELABLE=Cancelable INFO_CTRL_PANEL_TASK_IS_NOT_CANCELABLE=Not Cancelable INFO_CTRL_PANEL_MANAGE_TASKS=Manage Tasks INFO_CTRL_PANEL_CHANGE_SCHEDULE=Change... INFO_CTRL_PANEL_LAUNCH_NOW_SUMMARY=Launch now INFO_CTRL_PANEL_LAUNCH_LATER_SUMMARY=Launch on %s INFO_CTRL_PANEL_LAUNCH_PERIODICALLY_SUMMARY=Launch periodically with CRON \ schedule '%s' MILD_ERR_CTRL_PANEL_LAUNCH_LATER_REQUIRES_SERVER_RUNNING=To be able to launch \ tasks on a future date, the server must be running. MILD_ERR_CTRL_PANEL_LAUNCH_SCHEDULE_REQUIRES_SERVER_RUNNING=To be able to \ launch tasks periodically, the server must be running. INFO_CTRL_PANEL_TASK_SPECIFIC_DETAILS=Task Specific Details INFO_CTRL_PANEL_NO_TASK_SELECTED=-No Task Selected- INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED=-Multiple Tasks Selected- INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS=-No Task Specific Details- opends/src/server/org/opends/server/backends/task/RecurringTask.java
@@ -521,7 +521,7 @@ * the schedule field. * @throws IllegalArgumentException if tab field is invalid. */ private boolean[] parseTaskTabField(String tabField, public static boolean[] parseTaskTabField(String tabField, int minValue, int maxValue) throws IllegalArgumentException { boolean[] valueList = new boolean[maxValue + 1]; opends/src/server/org/opends/server/tools/tasks/TaskEntry.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2009 Sun Microsystems, Inc. */ package org.opends.server.tools.tasks; @@ -66,6 +66,7 @@ private static Map<String, Message> mapAttrToDisplayName = new HashMap<String, Message>(); private int hashCode; // These attributes associated with the ds-task object // class are all handled explicitly below in the constructor @@ -154,6 +155,68 @@ } } } hashCode += id.hashCode(); hashCode += className.hashCode(); hashCode += state.hashCode(); hashCode += schedStart.hashCode(); hashCode += actStart.hashCode(); hashCode += compTime.hashCode(); hashCode += depends.hashCode(); hashCode += depFailAct.hashCode(); hashCode += logs.hashCode(); hashCode += notifyErr.hashCode(); hashCode += notifyComp.hashCode(); hashCode += schedTab.hashCode(); hashCode += taskSpecificAttrValues.hashCode(); } /** * Retrieves a hash code for this task entry. * * @return The hash code for this task entry. */ @Override() public int hashCode() { return hashCode; } /** * {@inheritDoc} */ @Override() public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (! (o instanceof TaskEntry)) { return false; } TaskEntry e = (TaskEntry) o; return e.id.equals(id) && e.className.equals(className) && e.state.equals(state) && e.schedStart.equals(schedStart) && e.actStart.equals(actStart) && e.compTime.equals(compTime) && e.depends.equals(depends) && e.depFailAct.equals(depFailAct) && e.logs.equals(logs) && e.notifyErr.equals(notifyErr) && e.notifyComp.equals(notifyComp) && e.schedTab.equals(schedTab) && e.taskSpecificAttrValues.equals(taskSpecificAttrValues); } /** opends/src/server/org/opends/server/util/LDIFReader.java
@@ -1235,7 +1235,7 @@ * @return A new attribute with no values, representing the * attribute type and its options. */ private static Attribute parseAttrDescription(String attrDescr) public static Attribute parseAttrDescription(String attrDescr) { AttributeBuilder builder; int semicolonPos = attrDescr.indexOf(';');