From bdc6c07cd4dcf69bcad12949b4c1aa6924f57a26 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 28 Nov 2013 15:04:58 +0000
Subject: [PATCH] OpenDJ 3 : config framework

---
 opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java          |   39 +
 opendj-admin/src/main/java/org/opends/server/types/InitializationException.java |   68 ++
 opendj-admin/src/main/resources/stylesheets/serverMO.xsl                        |    2 
 opendj-admin/src/main/java/org/opends/server/api/ConfigChangeListener.java      |   81 ++
 opendj-admin/src/main/java/org/opends/server/types/ConfigChangeResult.java      |  192 ++++++
 opendj-admin/src/main/java/org/opends/server/config/ConfigException.java        |   77 ++
 opendj-admin/src/main/java/org/opends/server/api/ConfigAddListener.java         |   62 ++
 opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java  |   41 +
 opendj-admin/src/main/java/org/opends/server/types/AddressMask.java             |  516 +++++++++++++++++
 opendj-admin/src/main/java/org/opends/server/types/DirectoryException.java      |  253 ++++++++
 opendj-admin/src/main/java/org/opends/server/types/OpenDsException.java         |  124 ++++
 opendj-admin/src/main/java/org/opends/server/api/ConfigDeleteListener.java      |   80 ++
 opendj-admin/src/main/java/org/opends/server/types/IdentifiedException.java     |   80 ++
 opendj-admin/src/main/java/org/opends/server/types/LDAPException.java           |  181 ++++++
 14 files changed, 1,795 insertions(+), 1 deletions(-)

diff --git a/opendj-admin/src/main/java/org/opends/server/api/ConfigAddListener.java b/opendj-admin/src/main/java/org/opends/server/api/ConfigAddListener.java
new file mode 100644
index 0000000..ecb27f1
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/api/ConfigAddListener.java
@@ -0,0 +1,62 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.api;
+
+import org.opends.server.types.ConfigChangeResult;
+
+/**
+ * This interface defines the methods that a Directory Server component should
+ * implement if it wishes to be able to receive notification of new entries
+ * added below a configuration entry.
+ */
+public interface ConfigAddListener {
+    /**
+     * Indicates whether the configuration entry that will result from a
+     * proposed add is acceptable to this add listener.
+     *
+     * @param configEntry
+     *            The configuration entry that will result from the requested
+     *            add.
+     * @param unacceptableReason
+     *            A buffer to which this method can append a human-readable
+     *            message explaining why the proposed entry is not acceptable.
+     * @return {@code true} if the proposed entry contains an acceptable
+     *         configuration, or {@code false} if it does not.
+     */
+    public boolean configAddIsAcceptable(ConfigEntry configEntry, MessageBuilder unacceptableReason);
+
+    /**
+     * Attempts to apply a new configuration based on the provided added entry.
+     *
+     * @param configEntry
+     *            The new configuration entry that contains the configuration to
+     *            apply.
+     * @return Information about the result of processing the configuration
+     *         change.
+     */
+    public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry);
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/api/ConfigChangeListener.java b/opendj-admin/src/main/java/org/opends/server/api/ConfigChangeListener.java
new file mode 100644
index 0000000..8200ffe
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/api/ConfigChangeListener.java
@@ -0,0 +1,81 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.api;
+
+
+
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.messages.MessageBuilder;
+
+
+/**
+ * This interface defines the methods that a Directory Server
+ * component should implement if it wishes to be able to receive
+ * notification of changes to a configuration entry.
+ */
+@org.opends.server.types.PublicAPI(
+     stability=org.opends.server.types.StabilityLevel.VOLATILE,
+     mayInstantiate=false,
+     mayExtend=true,
+     mayInvoke=false)
+public interface ConfigChangeListener
+{
+  /**
+   * Indicates whether the configuration entry that will result from a
+   * proposed modification is acceptable to this change listener.
+   *
+   * @param  configEntry         The configuration entry that will
+   *                             result from the requested update.
+   * @param  unacceptableReason  A buffer to which this method can
+   *                             append a human-readable message
+   *                             explaining why the proposed change is
+   *                             not acceptable.
+   *
+   * @return  {@code true} if the proposed entry contains an
+   *          acceptable configuration, or {@code false} if it does
+   *          not.
+   */
+  public boolean configChangeIsAcceptable(ConfigEntry configEntry,
+                      MessageBuilder unacceptableReason);
+
+
+
+  /**
+   * Attempts to apply a new configuration to this Directory Server
+   * component based on the provided changed entry.
+   *
+   * @param  configEntry  The configuration entry that containing the
+   *                      updated configuration for this component.
+   *
+   * @return  Information about the result of processing the
+   *          configuration change.
+   */
+  public ConfigChangeResult applyConfigurationChange(
+                                 ConfigEntry configEntry);
+}
+
diff --git a/opendj-admin/src/main/java/org/opends/server/api/ConfigDeleteListener.java b/opendj-admin/src/main/java/org/opends/server/api/ConfigDeleteListener.java
new file mode 100644
index 0000000..ea13246
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/api/ConfigDeleteListener.java
@@ -0,0 +1,80 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.api;
+
+
+
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.messages.MessageBuilder;
+
+
+/**
+ * This interface defines the methods that a Directory Server
+ * component should implement if it wishes to be able to receive
+ * notification if entries below a configuration entry are removed.
+ */
+@org.opends.server.types.PublicAPI(
+     stability=org.opends.server.types.StabilityLevel.VOLATILE,
+     mayInstantiate=false,
+     mayExtend=true,
+     mayInvoke=false)
+public interface ConfigDeleteListener
+{
+  /**
+   * Indicates whether it is acceptable to remove the provided
+   * configuration entry.
+   *
+   * @param  configEntry         The configuration entry that will be
+   *                             removed from the configuration.
+   * @param  unacceptableReason  A buffer to which this method can
+   *                             append a human-readable message
+   *                             explaining why the proposed delete is
+   *                             not acceptable.
+   *
+   * @return  {@code true} if the proposed entry may be removed from
+   *          the configuration, or {@code false} if not.
+   */
+  public boolean configDeleteIsAcceptable(ConfigEntry configEntry,
+                      MessageBuilder unacceptableReason);
+
+
+
+  /**
+   * Attempts to apply a new configuration based on the provided
+   * deleted entry.
+   *
+   * @param  configEntry  The new configuration entry that has been
+   *                      deleted.
+   *
+   * @return  Information about the result of processing the
+   *          configuration change.
+   */
+  public ConfigChangeResult applyConfigurationDelete(
+                                 ConfigEntry configEntry);
+}
+
diff --git a/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java
new file mode 100644
index 0000000..0cb5eb4
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java
@@ -0,0 +1,41 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2010-2013 ForgeRock AS
+ */
+package org.opends.server.authorization.dseecompat;
+
+/**
+ * The Aci class represents ACI strings.
+ */
+public class Aci implements Comparable<Aci>
+{
+    // TODO : to complete when implementing Aci support.
+
+    @Override
+    public int compareTo(Aci o) {
+        throw new RuntimeException("This class is not implemented");
+    }
+ }
diff --git a/opendj-admin/src/main/java/org/opends/server/config/ConfigException.java b/opendj-admin/src/main/java/org/opends/server/config/ConfigException.java
new file mode 100644
index 0000000..ac64a1a
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/config/ConfigException.java
@@ -0,0 +1,77 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.config;
+
+import org.forgerock.i18n.LocalizableException;
+import org.forgerock.i18n.LocalizableMessage;
+
+/**
+ * Thrown during the course of interactions with the Directory Server
+ * configuration.
+ */
+public final class ConfigException extends Exception implements LocalizableException {
+
+    private static final long serialVersionUID = -540463620272921157L;
+
+    private final LocalizableMessage message;
+
+    /**
+     * Returns the message that explains the problem that occurred.
+     *
+     * @return LocalizableMessage of the problem
+     */
+    public LocalizableMessage getMessageObject() {
+        return message;
+    }
+
+    /**
+     * Creates a new configuration exception with the provided message.
+     *
+     * @param message
+     *            The message to use for this configuration exception.
+     */
+    public ConfigException(LocalizableMessage message) {
+        super(message.toString());
+        this.message = message;
+    }
+
+    /**
+     * Creates a new configuration exception with the provided message and
+     * underlying cause.
+     *
+     * @param message
+     *            The message to use for this configuration exception.
+     * @param cause
+     *            The underlying cause that triggered this configuration
+     *            exception.
+     */
+    public ConfigException(LocalizableMessage message, Throwable cause) {
+        super(message.toString(), cause);
+        this.message = message;
+    }
+
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
new file mode 100644
index 0000000..a312f73
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -0,0 +1,39 @@
+/*
+ * 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 legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 legal-notices/CDDLv1_0.txt.
+ * 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 2013 ForgeRock AS.
+ */
+package org.opends.server.core;
+
+import org.forgerock.opendj.ldap.schema.AttributeType;
+
+/**
+ *  TODO : this is a stub
+ */
+public class DirectoryServer {
+
+    public static AttributeType getAttributeType(String name, boolean b) {
+        throw new RuntimeException("Not implemented");
+    }
+
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/AddressMask.java b/opendj-admin/src/main/java/org/opends/server/types/AddressMask.java
new file mode 100644
index 0000000..46a6cd2
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/AddressMask.java
@@ -0,0 +1,516 @@
+/*
+ * 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 2006-2009 Sun Microsystems, Inc.
+ *      Portions copyright 2011-2013 ForgeRock AS
+ */
+package org.opends.server.types;
+
+import static com.forgerock.opendj.ldap.ProtocolMessages.*;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.BitSet;
+import java.util.Collection;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.opends.server.config.ConfigException;
+
+/**
+ * This class defines an address mask, which can be used to perform efficient
+ * comparisons against IP addresses to determine whether a particular IP address
+ * is in a given range.
+ */
+public final class AddressMask {
+    /**
+     * Types of rules we have. IPv4 - ipv4 rule IPv6 - ipv6 rule (begin with '['
+     * or contains an ':'). HOST - hostname match (foo.sun.com) HOSTPATTERN -
+     * host pattern match (begin with '.') ALLWILDCARD - *.*.*.* (first HOST is
+     * applied then ipv4)
+     */
+    enum RuleType {
+        ALLWILDCARD, HOST, HOSTPATTERN, IPv4, IPv6
+    }
+
+    // IPv4 values for number of bytes and max CIDR prefix
+    private static final int IN4ADDRSZ = 4;
+    private static final int IPV4MAXPREFIX = 32;
+
+    // IPv6 values for number of bytes and max CIDR prefix
+    private static final int IN6ADDRSZ = 16;
+    private static final int IPV6MAXPREFIX = 128;
+
+    /**
+     * Decodes the provided string as an address mask.
+     *
+     * @param maskString
+     *            The string to decode as an address mask.
+     * @return AddressMask The address mask decoded from the provided string.
+     * @throws ConfigException
+     *             If the provided string cannot be decoded as an address mask.
+     */
+
+    public static AddressMask decode(final String maskString) throws ConfigException {
+        return new AddressMask(maskString);
+    }
+
+    /**
+     * Indicates whether provided address matches one of the address masks in
+     * the provided collection.
+     *
+     * @param address
+     *            The address to check.
+     * @param masks
+     *            A collection of address masks to check.
+     * @return <CODE>true</CODE> if the provided address matches one of the
+     *         given address masks, or <CODE>false</CODE> if it does not.
+     */
+    public static boolean maskListContains(final InetAddress address, final Collection<AddressMask> masks) {
+        if (address != null) {
+            for (final AddressMask mask : masks) {
+                if (mask.match(address)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // Array that holds each component of a hostname.
+    private String[] hostName;
+
+    // Holds a hostname pattern (ie, rule that begins with '.');'
+    private String hostPattern;
+
+    // Holds binary representations of rule and mask respectively.
+    private byte[] ruleMask, prefixMask;
+
+    // Holds string passed into the constructor.
+    private final String ruleString;
+
+    // Type of rule determined
+    private RuleType ruleType;
+
+    // Bit array that holds wildcard info for above binary arrays.
+    private final BitSet wildCard = new BitSet();
+
+    /**
+     * Address mask constructor.
+     *
+     * @param rule
+     *            The rule string to process.
+     * @throws ConfigException
+     *             If the rule string is not valid.
+     */
+    private AddressMask(final String rule) throws ConfigException {
+        determineRuleType(rule);
+        switch (ruleType) {
+        case IPv6:
+            processIPv6(rule);
+            break;
+
+        case IPv4:
+            processIpv4(rule);
+            break;
+
+        case HOST:
+            processHost(rule);
+            break;
+
+        case HOSTPATTERN:
+            processHostPattern(rule);
+            break;
+
+        case ALLWILDCARD:
+            processAllWilds(rule);
+        }
+        ruleString = rule;
+    }
+
+    /**
+     * Retrieves a string representation of this address mask.
+     *
+     * @return A string representation of this address mask.
+     */
+    @Override
+    public String toString() {
+        return ruleString;
+    }
+
+    /**
+     * Try to determine what type of rule string this is. See RuleType above for
+     * valid types.
+     *
+     * @param ruleString
+     *            The rule string to be examined.
+     * @throws ConfigException
+     *             If the rule type cannot be determined from the rule string.
+     */
+    private void determineRuleType(final String ruleString) throws ConfigException {
+
+        // Rule ending with '.' is invalid'
+        if (ruleString.endsWith(".")) {
+            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(message);
+        } else if (ruleString.startsWith(".")) {
+            ruleType = RuleType.HOSTPATTERN;
+        } else if (ruleString.startsWith("[") || (ruleString.indexOf(':') != -1)) {
+            ruleType = RuleType.IPv6;
+        } else {
+            int wildCount = 0;
+            final String[] s = ruleString.split("\\.", -1);
+            /*
+             * Try to figure out how many wildcards and if the rule is hostname
+             * (can't begin with digit) or ipv4 address. Default to IPv4
+             * ruletype.
+             */
+            ruleType = RuleType.HOST;
+            for (final String value : s) {
+                if (value.equals("*")) {
+                    wildCount++;
+                    continue;
+                }
+                // Looks like an ipv4 address
+                if (Character.isDigit(value.charAt(0))) {
+                    ruleType = RuleType.IPv4;
+                    break;
+                }
+            }
+            // All wildcards (*.*.*.*)
+            if (wildCount == s.length) {
+                ruleType = RuleType.ALLWILDCARD;
+            }
+        }
+    }
+
+    /**
+     * Main match function that determines which rule-type match function to
+     * use.
+     *
+     * @param address
+     *            The address to check.
+     * @return <CODE>true</CODE>if one of the match functions found a match or
+     *         <CODE>false</CODE>if not.
+     */
+    private boolean match(final InetAddress address) {
+        boolean ret = false;
+
+        switch (ruleType) {
+        case IPv6:
+        case IPv4:
+            // this Address mask is an IPv4 rule
+            ret = matchAddress(address.getAddress());
+            break;
+
+        case HOST:
+            // HOST rule use hostname
+            ret = matchHostName(address.getHostName());
+            break;
+
+        case HOSTPATTERN:
+            // HOSTPATTERN rule
+            ret = matchPattern(address.getHostName());
+            break;
+
+        case ALLWILDCARD:
+            // first try ipv4 addr match, then hostname
+            ret = matchAddress(address.getAddress());
+            if (!ret) {
+                ret = matchHostName(address.getHostName());
+            }
+            break;
+        }
+        return ret;
+    }
+
+    /**
+     * Try to match remote client address using prefix mask and rule mask.
+     *
+     * @param remoteMask
+     *            The byte array with remote client address.
+     * @return <CODE>true</CODE> if remote client address matches or
+     *         <CODE>false</CODE>if not.
+     */
+    private boolean matchAddress(final byte[] remoteMask) {
+        if (ruleType == RuleType.ALLWILDCARD) {
+            return true;
+        }
+        if (prefixMask == null) {
+            return false;
+        }
+        if (remoteMask.length != prefixMask.length) {
+            return false;
+        }
+        for (int i = 0; i < prefixMask.length; i++) {
+            if (!wildCard.get(i)) {
+                if ((ruleMask[i] & prefixMask[i]) != (remoteMask[i] & prefixMask[i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Try to match remote client host name against rule host name.
+     *
+     * @param remoteHostName
+     *            The remote host name string.
+     * @return <CODE>true</CODE>if the remote client host name matches
+     *         <CODE>false</CODE> if it does not.
+     */
+    private boolean matchHostName(final String remoteHostName) {
+        final String[] s = remoteHostName.split("\\.", -1);
+        if (s.length != hostName.length) {
+            return false;
+        }
+        if (ruleType == RuleType.ALLWILDCARD) {
+            return true;
+        }
+        for (int i = 0; i < s.length; i++) {
+            if (!hostName[i].equals("*")) // skip if wildcard
+            {
+                if (!s[i].equalsIgnoreCase(hostName[i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Try to match remote host name string against the pattern rule.
+     *
+     * @param remoteHostName
+     *            The remote client host name.
+     * @return <CODE>true</CODE>if the remote host name matches or
+     *         <CODE>false</CODE>if not.
+     */
+    private boolean matchPattern(final String remoteHostName) {
+        final int len = remoteHostName.length() - hostPattern.length();
+        return len > 0 && remoteHostName.regionMatches(true, len, hostPattern, 0, hostPattern.length());
+    }
+
+    /**
+     * Build the prefix mask of prefix len bits set in the array.
+     *
+     * @param prefix
+     *            The len of the prefix to use.
+     */
+    private void prefixMask(int prefix) {
+        int i;
+        for (i = 0; prefix > 8; i++) {
+            this.prefixMask[i] = (byte) 0xff;
+            prefix -= 8;
+        }
+        this.prefixMask[i] = (byte) ((0xff) << (8 - prefix));
+    }
+
+    /**
+     * The rule string is all wildcards. Set both address wildcard bitmask and
+     * hostname wildcard array.
+     *
+     * @param rule
+     *            The rule string containing all wildcards.
+     */
+    private void processAllWilds(final String rule) {
+        final String s[] = rule.split("\\.", -1);
+        if (s.length == IN4ADDRSZ) {
+            for (int i = 0; i < IN4ADDRSZ; i++) {
+                wildCard.set(i);
+            }
+        }
+        hostName = rule.split("\\.", -1);
+    }
+
+    /**
+     * Examine rule string and build a hostname string array of its parts.
+     *
+     * @param rule
+     *            The rule string.
+     * @throws ConfigException
+     *             If the rule string is not a valid host name.
+     */
+    private void processHost(final String rule) throws ConfigException {
+        // Note that '*' is valid in host rule
+        final String s[] = rule.split("^[0-9a-zA-z-.*]+");
+        if (s.length > 0) {
+            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(message);
+        }
+        hostName = rule.split("\\.", -1);
+    }
+
+    /**
+     * Examine the rule string of a host pattern and set the host pattern from
+     * the rule.
+     *
+     * @param rule
+     *            The rule string to examine.
+     * @throws ConfigException
+     *             If the rule string is not a valid host pattern rule.
+     */
+    private void processHostPattern(final String rule) throws ConfigException {
+        // quick check for invalid chars like " "
+        final String s[] = rule.split("^[0-9a-zA-z-.]+");
+        if (s.length > 0) {
+            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(message);
+        }
+        hostPattern = rule;
+    }
+
+    /**
+     * The rule string is an IPv4 rule. Build both the prefix mask array and
+     * rule mask from the string.
+     *
+     * @param rule
+     *            The rule string containing the IPv4 rule.
+     * @throws ConfigException
+     *             If the rule string is not a valid IPv4 rule.
+     */
+    private void processIpv4(final String rule) throws ConfigException {
+        final String[] s = rule.split("/", -1);
+        this.ruleMask = new byte[IN4ADDRSZ];
+        this.prefixMask = new byte[IN4ADDRSZ];
+        prefixMask(processPrefix(s, IPV4MAXPREFIX));
+        processIPv4Subnet((s.length == 0) ? rule : s[0]);
+    }
+
+    /**
+     * Examine the subnet part of a rule string and build a byte array
+     * representation of it.
+     *
+     * @param subnet
+     *            The subnet string part of the rule.
+     * @throws ConfigException
+     *             If the subnet string is not a valid IPv4 subnet string.
+     */
+    private void processIPv4Subnet(final String subnet) throws ConfigException {
+        final String[] s = subnet.split("\\.", -1);
+        try {
+            // Make sure we have four parts
+            if (s.length != IN4ADDRSZ) {
+                final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+                throw new ConfigException(message);
+            }
+            for (int i = 0; i < IN4ADDRSZ; i++) {
+                final String quad = s[i].trim();
+                if (quad.equals("*")) {
+                    wildCard.set(i); // see wildcard mark bitset
+                } else {
+                    final long val = Integer.parseInt(quad);
+                    // must be between 0-255
+                    if ((val < 0) || (val > 0xff)) {
+                        final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+                        throw new ConfigException(message);
+                    }
+                    ruleMask[i] = (byte) (val & 0xff);
+                }
+            }
+        } catch (final NumberFormatException nfex) {
+            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(message);
+        }
+    }
+
+    /**
+     * The rule string is an IPv6 rule. Build both the prefix mask array and
+     * rule mask from the string.
+     *
+     * @param rule
+     *            The rule string containing the IPv6 rule.
+     * @throws ConfigException
+     *             If the rule string is not a valid IPv6 rule.
+     */
+    private void processIPv6(final String rule) throws ConfigException {
+        final String[] s = rule.split("/", -1);
+        InetAddress addr;
+        try {
+            addr = InetAddress.getByName(s[0]);
+        } catch (final UnknownHostException ex) {
+            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(message);
+        }
+        if (addr instanceof Inet6Address) {
+            this.ruleType = RuleType.IPv6;
+            final Inet6Address addr6 = (Inet6Address) addr;
+            this.ruleMask = addr6.getAddress();
+            this.prefixMask = new byte[IN6ADDRSZ];
+            prefixMask(processPrefix(s, IPV6MAXPREFIX));
+        } else {
+            /*
+             * The address might be an IPv4-compat address. Throw an error if
+             * the rule has a prefix.
+             */
+            if (s.length == 2) {
+                final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+                throw new ConfigException(message);
+            }
+            this.ruleMask = addr.getAddress();
+            this.ruleType = RuleType.IPv4;
+            this.prefixMask = new byte[IN4ADDRSZ];
+            prefixMask(processPrefix(s, IPV4MAXPREFIX));
+        }
+    }
+
+    /**
+     * Examine rule string for correct prefix usage.
+     *
+     * @param s
+     *            The string array with rule string add and prefix strings.
+     * @param maxPrefix
+     *            The max value the prefix can be.
+     * @return The prefix integer value.
+     * @throws ConfigException
+     *             If the string array and prefix are not valid.
+     */
+    private int processPrefix(final String[] s, final int maxPrefix) throws ConfigException {
+        int prefix = maxPrefix;
+        try {
+            // can only have one prefix value and a subnet string
+            if ((s.length < 1) || (s.length > 2)) {
+                final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+                throw new ConfigException(message);
+            } else if (s.length == 2) {
+                // can't have wildcard with a prefix
+                if (s[0].indexOf('*') > -1) {
+                    final LocalizableMessage message = ERR_ADDRESSMASK_WILDCARD_DECODE_ERROR.get();
+                    throw new ConfigException(message);
+                }
+                prefix = Integer.parseInt(s[1]);
+            }
+            // must be between 0-maxprefix
+            if ((prefix < 0) || (prefix > maxPrefix)) {
+                final LocalizableMessage message = ERR_ADDRESSMASK_PREFIX_DECODE_ERROR.get();
+                throw new ConfigException(message);
+            }
+        } catch (final NumberFormatException nfex) {
+            final LocalizableMessage msg = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
+            throw new ConfigException(msg);
+        }
+        return prefix;
+    }
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/ConfigChangeResult.java b/opendj-admin/src/main/java/org/opends/server/types/ConfigChangeResult.java
new file mode 100644
index 0000000..0a1e0bf
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/ConfigChangeResult.java
@@ -0,0 +1,192 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.ResultCode;
+
+/**
+ * This class defines a data structure that can be used to hold information
+ * about the result of processing a configuration change.
+ */
+public final class ConfigChangeResult {
+    // A set of messages describing the changes that were made, any
+    // action that may be required, or any problems that were
+    // encountered.
+    private List<LocalizableMessage> messages;
+
+    // Indicates whether one or more of the changes requires
+    // administrative action in order to take effect.
+    private boolean adminActionRequired;
+
+    // The result code to return to the client from this configuration
+    // change.
+    private ResultCode resultCode;
+
+    /**
+     * Creates a new config change result object with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this config change result.
+     * @param adminActionRequired
+     *            Indicates whether administrative action is required for one or
+     *            more of the changes to take effect.
+     */
+    public ConfigChangeResult(ResultCode resultCode, boolean adminActionRequired) {
+        this.resultCode = resultCode;
+        this.adminActionRequired = adminActionRequired;
+        this.messages = new ArrayList<LocalizableMessage>();
+    }
+
+    /**
+     * Creates a new config change result object with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this config change result.
+     * @param adminActionRequired
+     *            Indicates whether administrative action is required for one or
+     *            more of the changes to take effect.
+     * @param messages
+     *            A set of messages that provide additional information about
+     *            the change processing.
+     */
+    public ConfigChangeResult(ResultCode resultCode, boolean adminActionRequired, List<LocalizableMessage> messages) {
+        this.resultCode = resultCode;
+        this.adminActionRequired = adminActionRequired;
+        this.messages = messages;
+    }
+
+    /**
+     * Retrieves the result code for this config change result.
+     *
+     * @return The result code for this config change result.
+     */
+    public ResultCode getResultCode() {
+        return resultCode;
+    }
+
+    /**
+     * Specifies the result code for this config change result.
+     *
+     * @param resultCode
+     *            The result code for this config change result.
+     */
+    public void setResultCode(ResultCode resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    /**
+     * Indicates whether administrative action is required before one or more of
+     * the changes will take effect.
+     *
+     * @return <CODE>true</CODE> if one or more of the configuration changes
+     *         require administrative action to take effect, or
+     *         <CODE>false</CODE> if not.
+     */
+    public boolean adminActionRequired() {
+        return adminActionRequired;
+    }
+
+    /**
+     * Specifies whether administrative action is required before one or more of
+     * the changes will take effect.
+     *
+     * @param adminActionRequired
+     *            Specifies whether administrative action is required before one
+     *            or more of the changes will take effect.
+     */
+    public void setAdminActionRequired(boolean adminActionRequired) {
+        this.adminActionRequired = adminActionRequired;
+    }
+
+    /**
+     * Retrieves the set of messages that provide explanation for the processing
+     * of the configuration changes. This list may be modified by the caller.
+     *
+     * @return The set of messages that provide explanation for the processing
+     *         of the configuration changes.
+     */
+    public List<LocalizableMessage> getMessages() {
+        return messages;
+    }
+
+    /**
+     * Adds the provided message to the set of messages for this config change
+     * result.
+     *
+     * @param message
+     *            The message to add to the set of messages for this config
+     *            change result.
+     */
+    public void addMessage(LocalizableMessage message) {
+        messages.add(message);
+    }
+
+    /**
+     * Retrieves a string representation of this config change result.
+     *
+     * @return A string representation of this config change result.
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        toString(buffer);
+        return buffer.toString();
+    }
+
+    /**
+     * Appends a string representation of this config change result to the
+     * provided buffer.
+     *
+     * @param buffer
+     *            The buffer to which the information should be appended.
+     */
+    public void toString(StringBuilder buffer) {
+        buffer.append("ConfigChangeResult(result=");
+        buffer.append(resultCode.toString());
+        buffer.append(", adminActionRequired=");
+        buffer.append(adminActionRequired);
+        buffer.append(", messages={");
+
+        if (!messages.isEmpty()) {
+            Iterator<LocalizableMessage> iterator = messages.iterator();
+
+            LocalizableMessage firstMessage = iterator.next();
+            buffer.append(firstMessage);
+
+            while (iterator.hasNext()) {
+                buffer.append(",");
+                buffer.append(iterator.next());
+            }
+        }
+
+        buffer.append("})");
+    }
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/DirectoryException.java b/opendj-admin/src/main/java/org/opends/server/types/DirectoryException.java
new file mode 100644
index 0000000..a18a332
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/DirectoryException.java
@@ -0,0 +1,253 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2013 ForgeRock AS
+ */
+package org.opends.server.types;
+
+import java.util.List;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.ResultCode;
+
+/**
+ * This class defines an exception that may be thrown if a problem occurs in the
+ * Directory Server.
+ */
+public final class DirectoryException extends IdentifiedException {
+    /**
+     * The serial version identifier required to satisfy the compiler because
+     * this class extends <CODE>java.lang.Exception</CODE>, which implements the
+     * <CODE>java.io.Serializable</CODE> interface. This value was generated
+     * using the <CODE>serialver</CODE> command-line utility included with the
+     * Java SDK.
+     */
+    private static final long serialVersionUID = 2615453139798417203L;
+
+    /** The matched DN returned to the client for this directory exception. */
+    private final DN matchedDN;
+
+    /** The set of referral URLs for this directory exception. */
+    private final List<String> referralURLs;
+
+    /**
+     * The result code returned to the client for this directory exception.
+     * Note: for security considerations (information leak) this result code
+     * might not be the underlying reason why the directory server refused to
+     * execute the operation.
+     *
+     * @see #maskedResultCode for the underlying reason why the directory server
+     *      refused to execute the operation
+     */
+    private final ResultCode resultCode;
+
+    /**
+     * If set, this is the real message for this directory exception that cannot
+     * be returned to the client, but will be logged.
+     *
+     * @see #getMessage() for the message returned to the client
+     */
+    private LocalizableMessage maskedMessage;
+
+    /**
+     * If set, this is the real result code for this directory exception that
+     * cannot be returned to the client, but will be logged.
+     *
+     * @see #resultCode for the reason code returned to the client
+     */
+    private ResultCode maskedResultCode;
+
+    /**
+     * Creates a new directory exception with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this directory exception.
+     * @param errorMessage
+     *            The error message for this directory exception.
+     */
+    public DirectoryException(ResultCode resultCode, LocalizableMessage errorMessage) {
+        super(errorMessage);
+
+        this.resultCode = resultCode;
+        this.matchedDN = null;
+        this.referralURLs = null;
+    }
+
+    /**
+     * Creates a new directory exception with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this directory exception.
+     * @param errorMessage
+     *            The error message for this directory exception.
+     * @param cause
+     *            The exception that was caught to trigger this directory
+     *            exception.
+     */
+    public DirectoryException(ResultCode resultCode, LocalizableMessage errorMessage, Throwable cause) {
+        super(errorMessage, cause);
+
+        this.resultCode = resultCode;
+        this.matchedDN = null;
+        this.referralURLs = null;
+    }
+
+    /**
+     * Creates a new directory exception with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this directory exception.
+     * @param cause
+     *            The exception that was caught to trigger this directory
+     *            exception. The message of this exception will be set to that
+     *            of this parameter.
+     */
+    public DirectoryException(ResultCode resultCode, OpenDsException cause) {
+        super(cause.getMessageObject(), cause);
+
+        this.resultCode = resultCode;
+        this.matchedDN = null;
+        this.referralURLs = null;
+    }
+
+    /**
+     * Creates a new directory exception with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this directory exception.
+     * @param errorMessage
+     *            The error message for this directory exception.
+     * @param matchedDN
+     *            The matched DN for this directory exception.
+     * @param cause
+     *            The exception that was caught to trigger this directory
+     *            exception.
+     */
+    public DirectoryException(ResultCode resultCode, LocalizableMessage errorMessage, DN matchedDN, Throwable cause) {
+        super(errorMessage, cause);
+
+        this.resultCode = resultCode;
+        this.matchedDN = matchedDN;
+        this.referralURLs = null;
+    }
+
+    /**
+     * Creates a new directory exception with the provided information.
+     *
+     * @param resultCode
+     *            The result code for this directory exception.
+     * @param errorMessage
+     *            The error message for this directory
+     * @param matchedDN
+     *            The matched DN for this directory exception.
+     * @param referralURLs
+     *            The set of referral URLs for this directory exception.
+     * @param cause
+     *            The exception that was caught to trigger this directory
+     *            exception.
+     */
+    public DirectoryException(ResultCode resultCode, LocalizableMessage errorMessage, DN matchedDN,
+            List<String> referralURLs, Throwable cause) {
+        super(errorMessage, cause);
+
+        this.resultCode = resultCode;
+        this.matchedDN = matchedDN;
+        this.referralURLs = referralURLs;
+    }
+
+    /**
+     * Retrieves the result code for this directory exception.
+     *
+     * @return The result code for this directory exception.
+     */
+    public ResultCode getResultCode() {
+        return resultCode;
+    }
+
+    /**
+     * Retrieves the matched DN for this directory exception.
+     *
+     * @return The matched DN for this directory exception, or <CODE>null</CODE>
+     *         if there is none.
+     */
+    public DN getMatchedDN() {
+        return matchedDN;
+    }
+
+    /**
+     * Retrieves the set of referral URLs for this directory exception.
+     *
+     * @return The set of referral URLs for this directory exception, or
+     *         <CODE>null</CODE> if there are none.
+     */
+    public List<String> getReferralURLs() {
+        return referralURLs;
+    }
+
+    /**
+     * Returns the real, masked message for this directory exception that cannot
+     * be returned to the client, but will be logged.
+     *
+     * @return the real, masked message
+     * @see #getMessage() for the message returned to the client
+     */
+    public LocalizableMessage getMaskedMessage() {
+        return maskedMessage;
+    }
+
+    /**
+     * Returns the real result code for this directory exception that cannot be
+     * returned to the client, but will be logged.
+     *
+     * @return the real, masked result code
+     * @see #getResultCode() for the result code returned to the client
+     */
+    public ResultCode getMaskedResultCode() {
+        return maskedResultCode;
+    }
+
+    /**
+     * Sets the real message for this directory exception that cannot be
+     * returned to the client, but will be logged.
+     *
+     * @param maskedMessage
+     *            the real, masked message to set
+     */
+    public void setMaskedMessage(LocalizableMessage maskedMessage) {
+        this.maskedMessage = maskedMessage;
+    }
+
+    /**
+     * Sets the real result code for this directory exception that cannot be
+     * returned to the client, but will be logged.
+     *
+     * @param maskedResultCode
+     *            the real, masked result code to set
+     */
+    public void setMaskedResultCode(ResultCode maskedResultCode) {
+        this.maskedResultCode = maskedResultCode;
+    }
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/IdentifiedException.java b/opendj-admin/src/main/java/org/opends/server/types/IdentifiedException.java
new file mode 100644
index 0000000..566e009
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/IdentifiedException.java
@@ -0,0 +1,80 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+/**
+ * This class defines a base exception that should be extended by any exception
+ * that exposes a unique identifier for the associated message.
+ */
+public abstract class IdentifiedException extends OpenDsException {
+    /**
+     * Generated serialization ID.
+     */
+    private static final long serialVersionUID = 7071843225564003122L;
+
+    /**
+     * Creates a new identified exception.
+     */
+    protected IdentifiedException() {
+        super();
+    }
+
+    /**
+     * Creates a new identified exception with the provided information.
+     *
+     * @param message
+     *            The message that explains the problem that occurred.
+     */
+    protected IdentifiedException(LocalizableMessage message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new identified exception with the provided information.
+     *
+     * @param cause
+     *            The underlying cause that triggered this exception.
+     */
+    protected IdentifiedException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Creates a new identified exception with the provided information.
+     *
+     * @param message
+     *            The message that explains the problem that occurred.
+     * @param cause
+     *            The underlying cause that triggered this exception.
+     */
+    protected IdentifiedException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/InitializationException.java b/opendj-admin/src/main/java/org/opends/server/types/InitializationException.java
new file mode 100644
index 0000000..7754c72
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/InitializationException.java
@@ -0,0 +1,68 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+/**
+ * This class defines an exception that may be thrown if a problem occurs while
+ * trying to initialize a Directory Server component.
+ */
+public final class InitializationException extends IdentifiedException {
+    /**
+     * The serial version identifier required to satisfy the compiler because
+     * this class extends <CODE>java.lang.Exception</CODE>, which implements the
+     * <CODE>java.io.Serializable</CODE> interface. This value was generated
+     * using the <CODE>serialver</CODE> command-line utility included with the
+     * Java SDK.
+     */
+    private static final long serialVersionUID = -6121147544833914730L;
+
+    /**
+     * Creates a new initialization exception with the provided message.
+     *
+     * @param message
+     *            The message that explains the problem that occurred.
+     */
+    public InitializationException(LocalizableMessage message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new initialization exception with the provided message and root
+     * cause.
+     *
+     * @param message
+     *            The message that explains the problem that occurred.
+     * @param cause
+     *            The exception that was caught to trigger this exception.
+     */
+    public InitializationException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/LDAPException.java b/opendj-admin/src/main/java/org/opends/server/types/LDAPException.java
new file mode 100644
index 0000000..d976f9c
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/LDAPException.java
@@ -0,0 +1,181 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.DN;
+
+/**
+ * This class defines an exception that may be thrown if a problem occurs while
+ * interacting with an LDAP protocol element.
+ */
+public final class LDAPException extends IdentifiedException {
+    /**
+     * The serial version identifier required to satisfy the compiler because
+     * this class extends {@code java.lang.Exception}, which implements the
+     * {@code java.io.Serializable} interface. This value was generated using
+     * the {@code serialver} command-line utility included with the Java SDK.
+     */
+    private static final long serialVersionUID = -7273984376022613884L;
+
+    // The matched DN associated with this LDAP exception.
+    private final DN matchedDN;
+
+    // The LDAP result code associated with this exception.
+    private final int resultCode;
+
+    // The server-provided error message for this LDAP exception.
+    private final LocalizableMessage errorMessage;
+
+    /**
+     * Creates a new LDAP exception with the provided message.
+     *
+     * @param resultCode
+     *            The LDAP result code associated with this exception.
+     * @param message
+     *            The message that explains the problem that occurred.
+     */
+    public LDAPException(int resultCode, LocalizableMessage message) {
+        super(message);
+
+        this.resultCode = resultCode;
+
+        errorMessage = null;
+        matchedDN = null;
+    }
+
+    /**
+     * Creates a new LDAP exception with the provided message.
+     *
+     * @param resultCode
+     *            The LDAP result code associated with this exception.
+     * @param errorMessage
+     *            The server-provided error message.
+     * @param message
+     *            The message that explains the problem that occurred.
+     */
+    public LDAPException(int resultCode, LocalizableMessage errorMessage, LocalizableMessage message) {
+        super(message);
+
+        this.resultCode = resultCode;
+        this.errorMessage = errorMessage;
+
+        matchedDN = null;
+    }
+
+    /**
+     * Creates a new LDAP exception with the provided message and root cause.
+     *
+     * @param resultCode
+     *            The LDAP result code associated with this exception.
+     * @param message
+     *            The message that explains the problem that occurred.
+     * @param cause
+     *            The exception that was caught to trigger this exception.
+     */
+    public LDAPException(int resultCode, LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+
+        this.resultCode = resultCode;
+
+        errorMessage = null;
+        matchedDN = null;
+    }
+
+    /**
+     * Creates a new LDAP exception with the provided message and root cause.
+     *
+     * @param resultCode
+     *            The LDAP result code associated with this exception.
+     * @param errorMessage
+     *            The server-provided error message.
+     * @param message
+     *            The message that explains the problem that occurred.
+     * @param cause
+     *            The exception that was caught to trigger this exception.
+     */
+    public LDAPException(int resultCode, LocalizableMessage errorMessage, LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+
+        this.resultCode = resultCode;
+        this.errorMessage = errorMessage;
+
+        matchedDN = null;
+    }
+
+    /**
+     * Creates a new LDAP exception with the provided message and root cause.
+     *
+     * @param resultCode
+     *            The LDAP result code associated with this exception.
+     * @param errorMessage
+     *            The server-provided error message.
+     * @param message
+     *            The message that explains the problem that occurred.
+     * @param matchedDN
+     *            The matched DN returned by the server.
+     * @param cause
+     *            The exception that was caught to trigger this exception.
+     */
+    public LDAPException(int resultCode, LocalizableMessage errorMessage, LocalizableMessage message, DN matchedDN,
+            Throwable cause) {
+        super(message, cause);
+
+        this.resultCode = resultCode;
+        this.errorMessage = errorMessage;
+        this.matchedDN = matchedDN;
+    }
+
+    /**
+     * Retrieves the LDAP result code associated with this exception.
+     *
+     * @return The LDAP result code associated with this exception.
+     */
+    public int getResultCode() {
+        return resultCode;
+    }
+
+    /**
+     * Retrieves the server-provided error message for this exception.
+     *
+     * @return The server-provided error message for this exception, or
+     *         {@code null} if none was given.
+     */
+    public LocalizableMessage getErrorMessage() {
+        return errorMessage;
+    }
+
+    /**
+     * Retrieves the matched DN for this exception.
+     *
+     * @return The matched DN for this exception, or {@code null} if there is
+     *         none.
+     */
+    public DN getMatchedDN() {
+        return matchedDN;
+    }
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/types/OpenDsException.java b/opendj-admin/src/main/java/org/opends/server/types/OpenDsException.java
new file mode 100644
index 0000000..14f04d9
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/types/OpenDsException.java
@@ -0,0 +1,124 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.types;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+
+/**
+ * This class defines a base exception for OpenDS exceptions.
+ */
+public abstract class OpenDsException
+        extends Exception
+{
+
+  /**
+   * Generated serialization ID.
+   */
+  private static final long serialVersionUID = 7310881401563732702L;
+
+  /** LocalizableMessage that explains the problem. */
+  LocalizableMessage message;
+
+  /**
+   * Creates a new identified exception.
+   */
+  protected OpenDsException()
+  {
+    super();
+  }
+
+  /**
+   * Constructs a new instance from another
+   * <code>OpenDsException</code>.
+   * This constructor sets the message to be that of
+   * <code>cause</code>.
+   *
+   * @param cause exception whose message will be used for
+   *        this exception's message.
+   */
+  protected OpenDsException(OpenDsException cause) {
+    this(null, cause);
+  }
+
+  /**
+   * Creates a new identified exception with the provided information.
+   *
+   * @param  message  The message that explains the problem that
+   *                  occurred.
+   */
+  protected OpenDsException(LocalizableMessage message)
+  {
+    this(message, null);
+  }
+
+
+
+  /**
+   * Creates a new identified exception with the provided information.
+   *
+   * @param  cause  The underlying cause that triggered this
+   *                exception.
+   */
+  protected OpenDsException(Throwable cause)
+  {
+    this(null, cause);
+  }
+
+
+
+  /**
+   * Creates a new identified exception with the provided information.
+   *
+   * @param  message  The message that explains the problem that
+   *                  occurred.
+   * @param  cause    The underlying cause that triggered this
+   *                  exception.
+   */
+  protected OpenDsException(LocalizableMessage message, Throwable cause)
+  {
+    super(message != null ? message.toString() :
+            cause != null ? cause.getMessage() : null, cause);
+    if (message != null) {
+      this.message = message;
+    } else if (cause instanceof OpenDsException) {
+      this.message = ((OpenDsException)cause).getMessageObject();
+    }
+  }
+
+
+
+  /**
+   * Returns the message that explains the problem that occurred.
+   *
+   * @return LocalizableMessage of the problem
+   */
+  public LocalizableMessage getMessageObject() {
+    return this.message;
+  }
+}
diff --git a/opendj-admin/src/main/resources/stylesheets/serverMO.xsl b/opendj-admin/src/main/resources/stylesheets/serverMO.xsl
index a9aaf18..e2576cb 100644
--- a/opendj-admin/src/main/resources/stylesheets/serverMO.xsl
+++ b/opendj-admin/src/main/resources/stylesheets/serverMO.xsl
@@ -373,7 +373,7 @@
           </import>
         </xsl:if>
         <xsl:if test="$this-local-relations">
-          <import>org.opends.server.types.ConfigException</import>
+          <import>org.opends.server.config.ConfigException</import>
         </xsl:if>
         <xsl:if
           test="$this-local-relations/adm:one-to-zero-or-one|$this-local-relations/adm:one-to-many">

--
Gitblit v1.10.0