From 8a4435e154a3307e0602fe359f8f1210c183af73 Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Tue, 02 Oct 2007 16:38:40 +0000
Subject: [PATCH] Partially addressed issues 2335 and 2336 which call for support of task notifications and dependencies in client task scheduling tools.

---
 opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java    |   41 +++++
 opendj-sdk/opends/src/server/org/opends/server/backends/task/FailedDependencyAction.java   |   28 +++-
 opendj-sdk/opends/src/server/org/opends/server/util/StaticUtils.java                       |   40 +++++
 opendj-sdk/opends/src/messages/messages/tools.properties                                   |   23 +++
 opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskClient.java                 |   50 +++++++
 opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskTool.java                   |  160 ++++++++++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java                     |    2 
 opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java                    |   70 ++++++++++
 opendj-sdk/opends/src/server/org/opends/server/tools/RestoreDB.java                        |    2 
 opendj-sdk/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java |    2 
 10 files changed, 406 insertions(+), 12 deletions(-)

diff --git a/opendj-sdk/opends/src/messages/messages/tools.properties b/opendj-sdk/opends/src/messages/messages/tools.properties
index a0902ab..05acf52 100644
--- a/opendj-sdk/opends/src/messages/messages/tools.properties
+++ b/opendj-sdk/opends/src/messages/messages/tools.properties
@@ -2160,4 +2160,25 @@
 INFO_DESCRIPTION_GENERAL_ARGS_1465=General Options
 INFO_DESCRIPTION_IO_ARGS_1466=Utility Input/Output Options
 INFO_DESCRIPTION_LDAP_CONNECTION_ARGS_1467=LDAP Connection Options
-INFO_DESCRIPTION_CONFIG_OPTIONS_ARGS_1468=Configuration Options
\ No newline at end of file
+INFO_DESCRIPTION_CONFIG_OPTIONS_ARGS_1468=Configuration Options
+INFO_DESCRIPTION_TASK_COMPLETION_NOTIFICATION_1469=Specifies the email address \
+  of a recipient to be notified when the task completes.  This option may be \
+  specified more than once
+INFO_DESCRIPTION_TASK_ERROR_NOTIFICATION_1470=Specifies the email address \
+  of a recipient to be notified if an error occurs when this task executes.  \
+  This option may be specified more than once
+INFO_DESCRIPTION_TASK_DEPENDENCY_ID_1471=Specifies the ID of a task upon which \
+  this task depends.  A task will not start execution until all its \
+  dependencies have completed execution
+INFO_DESCRIPTION_TASK_FAILED_DEPENDENCY_ACTION_1472=Action this task will \
+  take should one if its dependent tasks fail.  The value must be one of %s.  \
+  If not specified defaults to %s
+SEVERE_ERR_TASKTOOL_OPTIONS_FOR_TASK_ONLY_1473=The option %s is only \
+  applicable when scheduling this operation as a task
+SEVERE_ERR_TASKTOOL_INVALID_EMAIL_ADDRESS_1474=The value %s for option %s is \
+  not a valid email address
+SEVERE_ERR_TASKTOOL_INVALID_FDA_1475=The failed dependency action value %s is \
+  invalid.  The value must be one of %s
+SEVERE_ERR_TASKTOOL_FDA_WITH_NO_DEPENDENCY_1476=The failed dependency action \
+  option is to be used in conjunction with one or more dependencies
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/FailedDependencyAction.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/FailedDependencyAction.java
index 68b38d3..3e59556 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/FailedDependencyAction.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/FailedDependencyAction.java
@@ -27,7 +27,7 @@
 package org.opends.server.backends.task;
 
 import org.opends.messages.Message;
-import org.opends.messages.TaskMessages;
+import static org.opends.messages.TaskMessages.*;
 
 
 /**
@@ -41,14 +41,14 @@
    * The action that indicates that the dependent task should be processed
    * anyway.
    */
-  PROCESS(TaskMessages.INFO_FAILED_DEPENDENCY_ACTION_PROCESS.get()),
+  PROCESS(INFO_FAILED_DEPENDENCY_ACTION_PROCESS.get()),
 
 
 
   /**
    * The action that indicates that the dependent task should be canceled.
    */
-  CANCEL(TaskMessages.INFO_FAILED_DEPENDENCY_ACTION_CANCEL.get()),
+  CANCEL(INFO_FAILED_DEPENDENCY_ACTION_CANCEL.get()),
 
 
 
@@ -56,9 +56,17 @@
    * The action that indicates that the dependent task should be disabled so
    * that an administrator will have to re-enable it before it can start.
    */
-  DISABLE(TaskMessages.INFO_FAILED_DEPENDENCY_ACTION_DISABLE.get());
+  DISABLE(INFO_FAILED_DEPENDENCY_ACTION_DISABLE.get());
 
 
+  /**
+   * Returns the default action.
+   *
+   * @return the default action
+   */
+  public static FailedDependencyAction defaultValue() {
+    return CANCEL;
+  }
 
   /**
    * Retrieves the failed dependency action that corresponds to the provided
@@ -73,15 +81,21 @@
   public static FailedDependencyAction fromString(String s)
   {
     String lowerString = s.toLowerCase();
-    if (lowerString.equals("process"))
+    if (lowerString.equals("process") ||
+            lowerString.equals(INFO_FAILED_DEPENDENCY_ACTION_PROCESS.get().
+                    toString().toLowerCase()))
     {
       return PROCESS;
     }
-    else if (lowerString.equals("cancel"))
+    else if (lowerString.equals("cancel") ||
+            lowerString.equals(INFO_FAILED_DEPENDENCY_ACTION_CANCEL.get().
+                    toString().toLowerCase()))
     {
       return CANCEL;
     }
-    else if (lowerString.equals("disable"))
+    else if (lowerString.equals("disable") ||
+            lowerString.equals(INFO_FAILED_DEPENDENCY_ACTION_DISABLE.get().
+                    toString().toLowerCase()))
     {
       return DISABLE;
     }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
index a44fd3a..e26ec54 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/Task.java
@@ -351,7 +351,7 @@
       failedDependencyAction = FailedDependencyAction.fromString(actionString);
       if (failedDependencyAction == null)
       {
-        failedDependencyAction = FailedDependencyAction.CANCEL;
+        failedDependencyAction = FailedDependencyAction.defaultValue();
       }
     }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/RestoreDB.java b/opendj-sdk/opends/src/server/org/opends/server/tools/RestoreDB.java
index 8fe73d6..b3c75a7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/RestoreDB.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/RestoreDB.java
@@ -265,7 +265,7 @@
     }
 
 
-    if (listBackups.isPresent() && argParser.argumentsPresent()) {
+    if (listBackups.isPresent() && argParser.connectionArgumentsPresent()) {
       Message message = ERR_LDAP_CONN_INCOMPATIBLE_ARGS.get(
               listBackups.getLongIdentifier());
       err.println(wrapText(message, MAX_LINE_WIDTH));
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
index 89148d9..9e9469d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -832,5 +832,75 @@
    * Long form of option specifying no wrapping of the command-line.
    */
   public static final String OPTION_LONG_DONT_WRAP = "dontWrap";
+
+
+  /**
+   * Long form of email notification upon completion option.
+   */
+  public static final String OPTION_LONG_COMPLETION_NOTIFICATION_EMAIL =
+          "completionNotify";
+
+  /**
+   * Short form of email notification upon completion option.
+   */
+  public static final Character OPTION_SHORT_COMPLETION_NOTIFICATION_EMAIL =
+          null;
+
+
+  /**
+   * Long form of email notification upon error option.
+   */
+  public static final String OPTION_LONG_ERROR_NOTIFICATION_EMAIL =
+          "errorNotify";
+
+
+  /**
+   * Short form of email notification upon error option.
+   */
+  public static final Character OPTION_SHORT_ERROR_NOTIFICATION_EMAIL =
+          null;
+
+
+  /**
+   * Long form of dependency option.
+   */
+  public static final String OPTION_LONG_DEPENDENCY = "dependency";
+
+
+  /**
+   * Short form of dependency option.
+   */
+  public static final Character OPTION_SHORT_DEPENDENCY = null;
+
+
+  /**
+   * Long form of failed dependency action option.
+   */
+  public static final String OPTION_LONG_FAILED_DEPENDENCY_ACTION =
+          "failedDependencyAction";
+
+
+  /**
+   * Short form of failed dependency action option.
+   */
+  public static final Character OPTION_SHORT_FAILED_DEPENDENCY_ACTION = null;
+
+
+  /**
+   * Value placeholder for options taking email addresses.
+   */
+  public static final String OPTION_VALUE_EMAIL_ADDRESS = "{emailAddress}";
+
+
+  /**
+   * Value placeholder for options taking task IDs.
+   */
+  public static final String OPTION_VALUE_TASK_ID = "{taskId}";
+
+
+  /**
+   * Value placeholder for options taking actions.
+   */
+  public static final String OPTION_VALUE_ACTION = "{action}";
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskClient.java b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskClient.java
index e3ca663..455df9d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskClient.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskClient.java
@@ -59,6 +59,7 @@
 import org.opends.server.types.SearchScope;
 import static org.opends.server.types.ResultCode.*;
 import org.opends.server.backends.task.TaskState;
+import org.opends.server.backends.task.FailedDependencyAction;
 import static org.opends.server.util.ServerConstants.*;
 import org.opends.server.util.StaticUtils;
 
@@ -149,6 +150,55 @@
               startDateValues));
     }
 
+    // add dependency IDs
+    List<String> dependencyIds = information.getDependencyIds();
+    if (dependencyIds != null && dependencyIds.size() > 0) {
+      ArrayList<ASN1OctetString> dependencyIdValues =
+              new ArrayList<ASN1OctetString>(dependencyIds.size());
+      for (String dependencyId : dependencyIds) {
+        dependencyIdValues.add(new ASN1OctetString(dependencyId));
+      }
+      attributes.add(new LDAPAttribute(ATTR_TASK_DEPENDENCY_IDS,
+              dependencyIdValues));
+
+      // add the dependency action
+      FailedDependencyAction fda = information.getFailedDependencyAction();
+      if (fda == null) {
+        fda = FailedDependencyAction.defaultValue();
+      }
+      ArrayList<ASN1OctetString> fdaValues =
+              new ArrayList<ASN1OctetString>(1);
+      fdaValues.add(new ASN1OctetString(fda.name()));
+      attributes.add(new LDAPAttribute(ATTR_TASK_FAILED_DEPENDENCY_ACTION,
+              fdaValues));
+    }
+
+    // add completion notification email addresses
+    List<String> compNotifEmailAddresss =
+            information.getNotifyUponCompletionEmailAddresses();
+    if (compNotifEmailAddresss != null && compNotifEmailAddresss.size() > 0) {
+      ArrayList<ASN1OctetString> compNotifEmailAddrValues =
+              new ArrayList<ASN1OctetString>(compNotifEmailAddresss.size());
+      for (String emailAddr : compNotifEmailAddresss) {
+        compNotifEmailAddrValues.add(new ASN1OctetString(emailAddr));
+      }
+      attributes.add(new LDAPAttribute(ATTR_TASK_NOTIFY_ON_COMPLETION,
+              compNotifEmailAddrValues));
+    }
+
+    // add error notification email addresses
+    List<String> errNotifEmailAddresss =
+            information.getNotifyUponErrorEmailAddresses();
+    if (errNotifEmailAddresss != null && errNotifEmailAddresss.size() > 0) {
+      ArrayList<ASN1OctetString> errNotifEmailAddrValues =
+              new ArrayList<ASN1OctetString>(errNotifEmailAddresss.size());
+      for (String emailAddr : errNotifEmailAddresss) {
+        errNotifEmailAddrValues.add(new ASN1OctetString(emailAddr));
+      }
+      attributes.add(new LDAPAttribute(ATTR_TASK_NOTIFY_ON_ERROR,
+              errNotifEmailAddrValues));
+    }
+
     information.addTaskAttributes(attributes);
 
     AddRequestProtocolOp addRequest = new AddRequestProtocolOp(entryDN,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
index 54e6dd7..378f086 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskScheduleInformation.java
@@ -28,6 +28,7 @@
 package org.opends.server.tools.tasks;
 
 import org.opends.server.types.RawAttribute;
+import org.opends.server.backends.task.FailedDependencyAction;
 
 import java.util.List;
 import java.util.Date;
@@ -40,6 +41,7 @@
  */
 public interface TaskScheduleInformation {
 
+
   /**
    * Adds utility specific attributes to <code>attributes</code> for
    * population of the entry that is added to the task backend.
@@ -48,6 +50,7 @@
    */
   void addTaskAttributes(List<RawAttribute> attributes);
 
+
   /**
    * Gets the objectclass used to represent scheduled instances of this
    * utility in the task backend.
@@ -56,6 +59,7 @@
    */
   String getTaskObjectclass();
 
+
   /**
    * Gets the Class that implements the utility to execute.
    *
@@ -63,10 +67,47 @@
    */
   Class getTaskClass();
 
+
   /**
    * Gets the date at which this task should be scheduled to start.
    *
    * @return date/time at which the task should be scheduled
    */
   Date getStartDateTime();
+
+
+  /**
+   * Gets a list of task IDs upon which this task is dependent.
+   *
+   * @return list of task IDs
+   */
+  List<String> getDependencyIds();
+
+
+  /**
+   * Gets the action to take should one of the dependent task fail.
+   *
+   * @return action to take
+   */
+  FailedDependencyAction getFailedDependencyAction();
+
+
+  /**
+   * Gets a list of email address to which an email will be sent when this
+   * task completes.
+   *
+   * @return list of email addresses
+   */
+  List<String> getNotifyUponCompletionEmailAddresses();
+
+
+  /**
+   * Gets a list of email address to which an email will be sent if this
+   * task encounters an error during execution.
+   *
+   * @return list of email addresses
+   */
+  List<String> getNotifyUponErrorEmailAddresses();
+
+
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskTool.java b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskTool.java
index 891441c..0feebd3 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskTool.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/tasks/TaskTool.java
@@ -43,6 +43,7 @@
 import org.opends.server.types.OpenDsException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.backends.task.TaskState;
+import org.opends.server.backends.task.FailedDependencyAction;
 import org.opends.messages.Message;
 import static org.opends.messages.ToolMessages.*;
 
@@ -52,6 +53,9 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.List;
+import java.util.LinkedList;
+import java.util.EnumSet;
+import java.util.Collections;
 import java.io.IOException;
 
 /**
@@ -77,6 +81,21 @@
   // Argument for describing the task's start time
   StringArgument startArg;
 
+  // Argument for specifying completion notifications
+  StringArgument completionNotificationArg;
+
+  // Argument for specifying error notifications
+  StringArgument errorNotificationArg;
+
+  // Argument for specifying dependency
+  StringArgument dependencyArg;
+
+  // Argument for specifying a failed dependency action
+  StringArgument failedDependencyActionArg;
+
+  // Client for interacting with the task backend
+  TaskClient taskClient;
+
   /**
    * Called when this utility should perform its actions locally in this
    * JVM.
@@ -120,6 +139,42 @@
               null, null,
               INFO_DESCRIPTION_START_DATETIME.get());
       argParser.addArgument(startArg, taskGroup);
+
+      completionNotificationArg = new StringArgument(
+              OPTION_LONG_COMPLETION_NOTIFICATION_EMAIL,
+              OPTION_SHORT_COMPLETION_NOTIFICATION_EMAIL,
+              OPTION_LONG_COMPLETION_NOTIFICATION_EMAIL,
+              false, true, true, OPTION_VALUE_EMAIL_ADDRESS,
+              null, null, INFO_DESCRIPTION_TASK_COMPLETION_NOTIFICATION.get());
+      argParser.addArgument(completionNotificationArg, taskGroup);
+
+      errorNotificationArg = new StringArgument(
+              OPTION_LONG_ERROR_NOTIFICATION_EMAIL,
+              OPTION_SHORT_ERROR_NOTIFICATION_EMAIL,
+              OPTION_LONG_ERROR_NOTIFICATION_EMAIL,
+              false, true, true, OPTION_VALUE_EMAIL_ADDRESS,
+              null, null, INFO_DESCRIPTION_TASK_ERROR_NOTIFICATION.get());
+      argParser.addArgument(errorNotificationArg, taskGroup);
+
+      dependencyArg = new StringArgument(
+              OPTION_LONG_DEPENDENCY,
+              OPTION_SHORT_DEPENDENCY,
+              OPTION_LONG_DEPENDENCY,
+              false, true, true, OPTION_VALUE_TASK_ID,
+              null, null, INFO_DESCRIPTION_TASK_DEPENDENCY_ID.get());
+      argParser.addArgument(dependencyArg, taskGroup);
+
+      Set fdaValSet = EnumSet.allOf(FailedDependencyAction.class);
+      failedDependencyActionArg = new StringArgument(
+              OPTION_LONG_FAILED_DEPENDENCY_ACTION,
+              OPTION_SHORT_FAILED_DEPENDENCY_ACTION,
+              OPTION_LONG_FAILED_DEPENDENCY_ACTION,
+              false, true, true, OPTION_VALUE_ACTION,
+              null, null, INFO_DESCRIPTION_TASK_FAILED_DEPENDENCY_ACTION.get(
+                StaticUtils.collectionToString(fdaValSet, ","),
+                FailedDependencyAction.defaultValue().name()));
+      argParser.addArgument(failedDependencyActionArg, taskGroup);
+
     } catch (ArgumentException e) {
       // should never happen
     }
@@ -142,6 +197,60 @@
         throw new ArgumentException(ERR_START_DATETIME_FORMAT.get());
       }
     }
+
+    if (!processAsTask() && completionNotificationArg.isPresent()) {
+      throw new ArgumentException(ERR_TASKTOOL_OPTIONS_FOR_TASK_ONLY.get(
+              completionNotificationArg.getLongIdentifier()));
+    }
+
+    if (!processAsTask() && errorNotificationArg.isPresent()) {
+      throw new ArgumentException(ERR_TASKTOOL_OPTIONS_FOR_TASK_ONLY.get(
+              errorNotificationArg.getLongIdentifier()));
+    }
+
+    if (!processAsTask() && dependencyArg.isPresent()) {
+      throw new ArgumentException(ERR_TASKTOOL_OPTIONS_FOR_TASK_ONLY.get(
+              dependencyArg.getLongIdentifier()));
+    }
+
+    if (!processAsTask() && failedDependencyActionArg.isPresent()) {
+      throw new ArgumentException(ERR_TASKTOOL_OPTIONS_FOR_TASK_ONLY.get(
+              failedDependencyActionArg.getLongIdentifier()));
+    }
+
+    if (completionNotificationArg.isPresent()) {
+      LinkedList<String> addrs = completionNotificationArg.getValues();
+      for (String addr : addrs) {
+        if (!StaticUtils.isEmailAddress(addr)) {
+          throw new ArgumentException(ERR_TASKTOOL_INVALID_EMAIL_ADDRESS.get(
+                  addr, completionNotificationArg.getLongIdentifier()));
+        }
+      }
+    }
+
+    if (errorNotificationArg.isPresent()) {
+      LinkedList<String> addrs = errorNotificationArg.getValues();
+      for (String addr : addrs) {
+        if (!StaticUtils.isEmailAddress(addr)) {
+          throw new ArgumentException(ERR_TASKTOOL_INVALID_EMAIL_ADDRESS.get(
+                  addr, errorNotificationArg.getLongIdentifier()));
+        }
+      }
+    }
+
+    if (failedDependencyActionArg.isPresent()) {
+
+      if (!dependencyArg.isPresent()) {
+        throw new ArgumentException(ERR_TASKTOOL_FDA_WITH_NO_DEPENDENCY.get());
+      }
+
+      String fda = failedDependencyActionArg.getValue();
+      if (null == FailedDependencyAction.fromString(fda)) {
+        Set fdaValSet = EnumSet.allOf(FailedDependencyAction.class);
+        throw new ArgumentException(ERR_TASKTOOL_INVALID_FDA.get(fda,
+                        StaticUtils.collectionToString(fdaValSet, ",")));
+      }
+    }
   }
 
   /**
@@ -166,6 +275,51 @@
   }
 
   /**
+   * {@inheritDoc}
+   */
+  public List<String> getDependencyIds() {
+    if (dependencyArg.isPresent()) {
+      return dependencyArg.getValues();
+    } else {
+      return Collections.emptyList();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public FailedDependencyAction getFailedDependencyAction() {
+    FailedDependencyAction fda = null;
+    if (failedDependencyActionArg.isPresent()) {
+      String fdaString = failedDependencyActionArg.getValue();
+      fda = FailedDependencyAction.fromString(fdaString);
+    }
+    return fda;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public List<String> getNotifyUponCompletionEmailAddresses() {
+    if (completionNotificationArg.isPresent()) {
+      return completionNotificationArg.getValues();
+    } else {
+      return Collections.emptyList();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public List<String> getNotifyUponErrorEmailAddresses() {
+    if (errorNotificationArg.isPresent()) {
+      return errorNotificationArg.getValues();
+    } else {
+      return Collections.emptyList();
+    }
+  }
+
+  /**
    * Either invokes initiates this tool's local action or schedule this
    * tool using the tasks interface based on user input.
    *
@@ -181,7 +335,7 @@
                         PrintStream out, PrintStream err) {
     int ret;
 
-    if (argParser.argumentsPresent())
+    if (processAsTask())
     {
       if (initializeServer)
       {
@@ -275,4 +429,8 @@
     return ret;
   }
 
+  private boolean processAsTask() {
+    return argParser.connectionArgumentsPresent();
+  }
+
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/StaticUtils.java b/opendj-sdk/opends/src/server/org/opends/server/util/StaticUtils.java
index e944ad7..ebb7be3 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/StaticUtils.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/StaticUtils.java
@@ -52,6 +52,8 @@
 import java.util.StringTokenizer;
 import java.util.Date;
 import java.util.TimeZone;
+import java.util.Collection;
+import java.util.Iterator;
 
 import org.opends.messages.Message;
 import org.opends.messages.MessageBuilder;
@@ -3321,6 +3323,29 @@
   }
 
   /**
+   * Creates a string representation of the elements in the
+   * <code>collection</code> separated by <code>separator</code>.
+   *
+   * @param collection to print
+   * @param separator to use between elements
+   *
+   * @return String representing the collection
+   */
+  static public String collectionToString(Collection<?> collection,
+                                          String separator)
+  {
+    StringBuilder sb = new StringBuilder();
+    for (Iterator<?> iter = collection.iterator(); iter.hasNext();) {
+      sb.append(iter.next());
+      if (iter.hasNext()) {
+        sb.append(separator);
+      }
+    }
+    return sb.toString();
+  }
+
+
+  /**
    * Retrieves an array list containing the contents of the provided array.
    *
    * @param  stringArray  The string array to convert to an array list.
@@ -4036,5 +4061,20 @@
     return timeStr;
   }
 
+  /**
+   * Indicates whether or not a string represents a syntactically correct
+   * email address.
+   *
+   * @param addr to validate
+   * @return boolean where <code>true</code> indicates that the string is a
+   *         syntactically correct email address
+   */
+  public static boolean isEmailAddress(String addr) {
+
+    // This just does basic syntax checking.  Perhaps we
+    // might want to be stricter about this.
+    return addr != null && addr.contains("@") && addr.contains(".");
+
+  }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java b/opendj-sdk/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java
index 0d404e5..d5b1e06 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/args/LDAPConnectionArgumentParser.java
@@ -134,7 +134,7 @@
    * @return true if the user wants to perform a remote operation;
    *         false otherwise
    */
-  public boolean argumentsPresent() {
+  public boolean connectionArgumentsPresent() {
     return args != null && args.argumentsPresent();
   }
 

--
Gitblit v1.10.0