From c7149b39417ba099ad2d6cd6b841bdc2e66d2cef Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 23 Jan 2014 18:01:40 +0000
Subject: [PATCH] Migrate AddressMask class to opendj-core.

---
 opendj-config-maven-plugin/src/main/resources/config/stylesheets/property-types/ip-address-mask.xsl |    2 
 /dev/null                                                                                           |   35 ---
 opendj-config/src/main/java/org/forgerock/opendj/config/PropertyValueVisitor.java                   |    2 
 opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java                        |  252 +++++++++++++++++++++++++
 opendj-config/src/main/java/org/forgerock/opendj/config/IPAddressMaskPropertyDefinition.java        |   10 
 opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java                                |  268 ++++++++++++--------------
 opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties                            |   10 
 7 files changed, 393 insertions(+), 186 deletions(-)

diff --git a/opendj-config-maven-plugin/src/main/resources/config/stylesheets/property-types/ip-address-mask.xsl b/opendj-config-maven-plugin/src/main/resources/config/stylesheets/property-types/ip-address-mask.xsl
index b9ece9e..474290d 100644
--- a/opendj-config-maven-plugin/src/main/resources/config/stylesheets/property-types/ip-address-mask.xsl
+++ b/opendj-config-maven-plugin/src/main/resources/config/stylesheets/property-types/ip-address-mask.xsl
@@ -29,7 +29,7 @@
     Templates for processing IP address mask properties.
   -->
   <xsl:template match="adm:ip-address-mask" mode="java-value-imports">
-    <import>org.opends.server.types.AddressMask</import>
+    <import>org.forgerock.opendj.ldap.AddressMask</import>
   </xsl:template>
   <xsl:template match="adm:ip-address-mask" mode="java-value-type">
     <xsl:value-of select="'AddressMask'" />
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/IPAddressMaskPropertyDefinition.java b/opendj-config/src/main/java/org/forgerock/opendj/config/IPAddressMaskPropertyDefinition.java
index 46ee1c7..b2ad5fb 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/IPAddressMaskPropertyDefinition.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/IPAddressMaskPropertyDefinition.java
@@ -22,17 +22,17 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.config;
 
-import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.forgerock.opendj.ldap.AddressMask;
 import org.forgerock.util.Reject;
 
 import java.util.EnumSet;
 
-import org.opends.server.types.AddressMask;
-
 /**
  * IP address mask property definition.
  */
@@ -100,8 +100,8 @@
         Reject.ifNull(value);
 
         try {
-            return AddressMask.decode(value);
-        } catch (ConfigException e) {
+            return AddressMask.valueOf(value);
+        } catch (LocalizedIllegalArgumentException e) {
             // TODO: it would be nice to throw the cause.
             throw PropertyException.illegalPropertyValueException(this, value);
         }
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyValueVisitor.java b/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyValueVisitor.java
index fdf3af9..1bb3350 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyValueVisitor.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyValueVisitor.java
@@ -28,10 +28,10 @@
 
 import java.net.InetAddress;
 
+import org.forgerock.opendj.ldap.AddressMask;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.opends.server.authorization.dseecompat.Aci;
-import org.opends.server.types.AddressMask;
 
 /**
  * A visitor of property values, in the style of the visitor design pattern.
diff --git a/opendj-config/src/main/java/org/opends/server/types/package-info.java b/opendj-config/src/main/java/org/opends/server/types/package-info.java
deleted file mode 100644
index 4782891..0000000
--- a/opendj-config/src/main/java/org/opends/server/types/package-info.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 2006-2008 Sun Microsystems, Inc.
- */
-/**
- * Contains implementations for a number of Directory Server data
- * types.  Most, but not necessarily all, of these data types may be
- * considered part of the public API for use when extending the
- * Directory Server.  Please refer to the official documentation for
- * authoritative information on what classes are considered part of
- * the public API.
- */
-package org.opends.server.types;
-
diff --git a/opendj-config/src/main/java/org/opends/server/types/AddressMask.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java
similarity index 71%
rename from opendj-config/src/main/java/org/opends/server/types/AddressMask.java
rename to opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java
index 8cd2fc3..ed511e1 100644
--- a/opendj-config/src/main/java/org/opends/server/types/AddressMask.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java
@@ -22,11 +22,11 @@
  *
  *
  *      Copyright 2006-2009 Sun Microsystems, Inc.
- *      Portions copyright 2011-2013 ForgeRock AS
+ *      Portions copyright 2011-2014 ForgeRock AS
  */
-package org.opends.server.types;
+package org.forgerock.opendj.ldap;
 
-import static com.forgerock.opendj.ldap.ProtocolMessages.*;
+import static com.forgerock.opendj.ldap.CoreMessages.*;
 
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -34,13 +34,11 @@
 import java.util.BitSet;
 import java.util.Collection;
 
-import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 
 /**
- * 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.
+ * An address mask 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 {
     /**
@@ -62,34 +60,20 @@
     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.
+     * Returns {@code true} if an address matches any of the provided address
+     * masks.
      *
      * @param address
-     *            The address to check.
+     *            The address.
      * @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.
+     * @return {@code true} if an address matches any of the provided address
+     *         masks.
      */
-    public static boolean maskListContains(final InetAddress address, final Collection<AddressMask> masks) {
+    public static boolean matchesAny(final Collection<AddressMask> masks, final InetAddress address) {
         if (address != null) {
             for (final AddressMask mask : masks) {
-                if (mask.match(address)) {
+                if (mask.matches(address)) {
                     return true;
                 }
             }
@@ -97,6 +81,19 @@
         return false;
     }
 
+    /**
+     * Parses the provided string as an address mask.
+     *
+     * @param mask
+     *            The address mask string to be parsed.
+     * @return The parsed address mask.
+     * @throws LocalizedIllegalArgumentException
+     *             If the provided string cannot be decoded as an address mask.
+     */
+    public static AddressMask valueOf(final String mask) {
+        return new AddressMask(mask);
+    }
+
     // Array that holds each component of a hostname.
     private String[] hostName;
 
@@ -115,15 +112,7 @@
     // 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 {
+    private AddressMask(final String rule) {
         determineRuleType(rule);
         switch (ruleType) {
         case IPv6:
@@ -149,71 +138,13 @@
     }
 
     /**
-     * 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.
+     * Returns {@code true} if this address mask matches the provided address.
      *
      * @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.
+     *            The address.
+     * @return {@code true} if this address mask matches the provided address.
      */
-    private boolean match(final InetAddress address) {
+    public boolean matches(final InetAddress address) {
         boolean ret = false;
 
         switch (ruleType) {
@@ -245,6 +176,61 @@
     }
 
     /**
+     * Returns the string representation of this address mask.
+     *
+     * @return The 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 LocalizedIllegalArgumentException
+     *             If the rule type cannot be determined from the rule string.
+     */
+    private void determineRuleType(final String ruleString) {
+
+        // Rule ending with '.' is invalid'
+        if (ruleString.endsWith(".")) {
+            throw genericDecodeError();
+        } 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;
+            }
+        }
+    }
+
+    /**
      * Try to match remote client address using prefix mask and rule mask.
      *
      * @param remoteMask
@@ -309,7 +295,8 @@
      */
     private boolean matchPattern(final String remoteHostName) {
         final int len = remoteHostName.length() - hostPattern.length();
-        return len > 0 && remoteHostName.regionMatches(true, len, hostPattern, 0, hostPattern.length());
+        return len > 0
+                && remoteHostName.regionMatches(true, len, hostPattern, 0, hostPattern.length());
     }
 
     /**
@@ -324,7 +311,7 @@
             this.prefixMask[i] = (byte) 0xff;
             prefix -= 8;
         }
-        this.prefixMask[i] = (byte) ((0xff) << (8 - prefix));
+        this.prefixMask[i] = (byte) (0xff << 8 - prefix);
     }
 
     /**
@@ -335,7 +322,7 @@
      *            The rule string containing all wildcards.
      */
     private void processAllWilds(final String rule) {
-        final String []s = rule.split("\\.", -1);
+        final String[] s = rule.split("\\.", -1);
         if (s.length == IN4ADDRSZ) {
             for (int i = 0; i < IN4ADDRSZ; i++) {
                 wildCard.set(i);
@@ -349,15 +336,14 @@
      *
      * @param rule
      *            The rule string.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the rule string is not a valid host name.
      */
-    private void processHost(final String rule) throws ConfigException {
+    private void processHost(final String rule) {
         // Note that '*' is valid in host rule
-        final String []s = rule.split("^[0-9a-zA-z-.*]+");
+        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);
+            throw genericDecodeError();
         }
         hostName = rule.split("\\.", -1);
     }
@@ -368,15 +354,14 @@
      *
      * @param rule
      *            The rule string to examine.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the rule string is not a valid host pattern rule.
      */
-    private void processHostPattern(final String rule) throws ConfigException {
+    private void processHostPattern(final String rule) {
         // quick check for invalid chars like " "
-        final String []s = rule.split("^[0-9a-zA-z-.]+");
+        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);
+            throw genericDecodeError();
         }
         hostPattern = rule;
     }
@@ -387,15 +372,15 @@
      *
      * @param rule
      *            The rule string containing the IPv4 rule.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the rule string is not a valid IPv4 rule.
      */
-    private void processIpv4(final String rule) throws ConfigException {
+    private void processIpv4(final String rule) {
         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]);
+        processIPv4Subnet(s.length == 0 ? rule : s[0]);
     }
 
     /**
@@ -404,16 +389,15 @@
      *
      * @param subnet
      *            The subnet string part of the rule.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the subnet string is not a valid IPv4 subnet string.
      */
-    private void processIPv4Subnet(final String subnet) throws ConfigException {
+    private void processIPv4Subnet(final String subnet) {
         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);
+                throw genericDecodeError();
             }
             for (int i = 0; i < IN4ADDRSZ; i++) {
                 final String quad = s[i].trim();
@@ -422,16 +406,14 @@
                 } 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);
+                    if (val < 0 || val > 0xff) {
+                        throw genericDecodeError();
                     }
                     ruleMask[i] = (byte) (val & 0xff);
                 }
             }
         } catch (final NumberFormatException nfex) {
-            final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
-            throw new ConfigException(message);
+            throw genericDecodeError();
         }
     }
 
@@ -441,17 +423,16 @@
      *
      * @param rule
      *            The rule string containing the IPv6 rule.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the rule string is not a valid IPv6 rule.
      */
-    private void processIPv6(final String rule) throws ConfigException {
+    private void processIPv6(final String rule) {
         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);
+            throw genericDecodeError();
         }
         if (addr instanceof Inet6Address) {
             this.ruleType = RuleType.IPv6;
@@ -465,8 +446,7 @@
              * the rule has a prefix.
              */
             if (s.length == 2) {
-                final LocalizableMessage message = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
-                throw new ConfigException(message);
+                throw genericDecodeError();
             }
             this.ruleMask = addr.getAddress();
             this.ruleType = RuleType.IPv4;
@@ -483,33 +463,35 @@
      * @param maxPrefix
      *            The max value the prefix can be.
      * @return The prefix integer value.
-     * @throws ConfigException
+     * @throws LocalizedIllegalArgumentException
      *             If the string array and prefix are not valid.
      */
-    private int processPrefix(final String[] s, final int maxPrefix) throws ConfigException {
+    private int processPrefix(final String[] s, final int maxPrefix) {
         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);
+            if (s.length < 1 || s.length > 2) {
+                throw genericDecodeError();
             } 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);
+                    throw new LocalizedIllegalArgumentException(
+                            ERR_ADDRESSMASK_WILDCARD_DECODE_ERROR.get());
                 }
                 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);
+            if (prefix < 0 || prefix > maxPrefix) {
+                throw new LocalizedIllegalArgumentException(ERR_ADDRESSMASK_PREFIX_DECODE_ERROR
+                        .get());
             }
         } catch (final NumberFormatException nfex) {
-            final LocalizableMessage msg = ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get();
-            throw new ConfigException(msg);
+            throw genericDecodeError();
         }
         return prefix;
     }
+
+    private LocalizedIllegalArgumentException genericDecodeError() {
+        return new LocalizedIllegalArgumentException(ERR_ADDRESSMASK_FORMAT_DECODE_ERROR.get());
+    }
 }
diff --git a/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties b/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
index 9e0eecf..c30b968 100755
--- a/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
+++ b/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
@@ -22,7 +22,7 @@
 #
 #
 #      Copyright 2010 Sun Microsystems, Inc.
-#      Portions copyright 2011-2013 ForgeRock AS
+#      Portions copyright 2011-2014 ForgeRock AS
 #
 ERR_ATTR_SYNTAX_UNKNOWN_APPROXIMATE_MATCHING_RULE=Unable to retrieve \
  approximate matching rule %s used as the default for the %s attribute syntax. \
@@ -1548,3 +1548,11 @@
 ERR_ENTRY_GENERATOR_EXCEPTION_DURING_PARSE=An error occurred while \
  attempting to parse the template file:  %s
 ERR_ENTRY_GENERATOR_MISSING_TEMPLATE_FILE=Unexpected error when initializing config : no template file provided as input
+ERR_ADDRESSMASK_PREFIX_DECODE_ERROR=Cannot decode the provided \
+ address mask prefix because an invalid value was specified. The permitted \
+ values for IPv4are 0 to32 and for IPv6 0 to128
+ERR_ADDRESSMASK_WILDCARD_DECODE_ERROR=Cannot decode the provided \
+ address mask because an prefix mask was specified with an wild card "*" match \
+ character
+ERR_ADDRESSMASK_FORMAT_DECODE_ERROR=Cannot decode the provided \
+ address mask because the it has an invalid format
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java
new file mode 100644
index 0000000..de5d493
--- /dev/null
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java
@@ -0,0 +1,252 @@
+/*
+ * 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 2006-2008 Sun Microsystems, Inc.
+ *      Portions copyright 2011-2014 ForgeRock AS
+ */
+package org.forgerock.opendj.ldap;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class AddressMaskTestCase extends SdkTestCase {
+
+    /* These are all valid rules -- should all pass. */
+    @DataProvider(name = "validRules")
+    public Object[][] validData() {
+        return new Object[][] { { "129.34.55.67" }, { "129.*.78.55" }, { ".central.sun.com" },
+            { "foo.central.sun.com" }, { "foo.*.sun.*" }, { "128.*.*.*" }, { "129.45.23.67/22" },
+            { "128.33.23.21/32" }, { "*.*.*.*" }, { "129.45.67.34/0" }, { "foo.com" }, { "foo" } };
+    }
+
+    @DataProvider(name = "invalidRules")
+    public Object[][] invalidData() {
+        return new Object[][] { { "129.*.900.67" }, { "129.67" }, { "   " },
+            { "129.56.78.90/2000" }, { "677.777.AG.BC" }, { "/34" }, { "234.12.12.*/31" },
+            { "234.12.12.90/" }, { "129.34.56.78/-100" }, { "129" }, { "129.34.-90.67" },
+            { "129.**.56.67" }, { "foo bar.com" }, { "12foo.example.com" }, { "123.45." },
+            { ".central.sun day.com" }, { "129.34.45.45/4/3/" } };
+    }
+
+    @DataProvider(name = "toStringRule")
+    public Object[][] toStringData() {
+        return new Object[][] { { "129.35.45.66/12" } };
+    }
+
+    @Test(dataProvider = "validRules")
+    public void testValidDecode(String mask) {
+        AddressMask.valueOf(mask);
+    }
+
+    @Test(expectedExceptions = LocalizedIllegalArgumentException.class,
+            dataProvider = "invalidRules")
+    public void testInvalidDecode(String mask) throws Exception {
+        AddressMask.valueOf(mask);
+    }
+
+    @DataProvider(name = "matchRules")
+    public Object[][] ruleMatchData() {
+        // @Checkstyle:off
+        return new Object[][] { {
+            //Rules
+            new String[] { "129.56.*.22", //1
+                "*.domain.com", //2
+                "foo.example.com", //3
+                "126.67.89.90", //4
+                "90.89.78.67/30", //5
+                ".test.com", //6
+                "128.153.147.32/21", //7
+                "128.153.146.32/26", //8
+                "90.89.78.67/26" }, //9
+            //Addresses
+            new String[] { "128.153.147.45", //rule 7
+                "128.153.146.60", //rule 8
+                "148.45.45.46", //host
+                "129.56.78.22", //rule 1
+                "148.45.45.47", //host
+                "148.45.45.48", //host
+                "90.89.78.65" }, //rule 5
+            //Hostnames
+            new String[] { "some.host.name", //addr
+                "some.host.name", //addr
+                "foo.example.com", //rule 3
+                "some.host.name", //addr
+                "foo.test.com", //rule 6
+                "foo.domain.com", //rule 2
+                "some.host.name" //addr
+            } } };
+        // @Checkstyle:on
+    }
+
+    @DataProvider(name = "noMatchRules")
+    public Object[][] ruleNoMatchData() {
+        // @Checkstyle:off
+        return new Object[][] { {
+            // Rule to not match
+            new String[] { "129.56.*.22", //1
+                "*.domain.com", //2
+                "foo.example.com", //3
+                "126.67.89.90", //4
+                "90.89.78.67/30", //5
+                ".test.com", //6
+                "128.153.147.32/21", //7
+                "128.153.146.32/26", //8
+                "90.89.78.67/26" }, //9
+            //Addresses
+            new String[] { "128.153.140.45", "128.153.143.255", "148.45.45.46", "126.56.78.22",
+                "148.45.45.47", "148.45.45.48", "90.89.78.128", "148.45.45.49" },
+            //Hostnames
+            new String[] { "some.host.name", "some.host.name", "foo.examplee.com",
+                "some.host.name", "foo.ttest.com", "foo.domain.comm", "some.host.name", "f.e.c",
+                "foo.domain.cm" } } };
+        // @Checkstyle:on
+    }
+
+    @DataProvider(name = "matchWCRules")
+    public Object[][] ruleMatchWCData() {
+        // @Checkstyle:off
+        return new Object[][] { {
+            //Rules
+            new String[] { "*.*.*", "*.*.*.*" },
+            //Addresses
+            new String[] { "129.34.45.12", "129.34.45.13" },
+            //Hostnames
+            new String[] { "some.host.name", "some.host.name" } } };
+        // @Checkstyle:on
+    }
+
+    @Test(dataProvider = "matchRules")
+    public void testMatch(String[] rules, String[] addrs, String[] hostNames) throws Exception {
+        assertTrue(match(rules, addrs, hostNames));
+    }
+
+    @Test(dataProvider = "matchWCRules")
+    public void testWildCardMatch(String[] rules, String[] addrs, String[] hostNames)
+            throws Exception {
+        assertTrue(match(rules, addrs, hostNames));
+    }
+
+    @Test(dataProvider = "noMatchRules")
+    public void testNoMatch(String[] rules, String[] addrs, String[] hostNames) throws Exception {
+        assertFalse(match(rules, addrs, hostNames));
+    }
+
+    @Test(dataProvider = "toStringRule")
+    public void testToString(String rule) {
+        AddressMask m = AddressMask.valueOf(rule);
+        assertEquals(rule, m.toString());
+    }
+
+    @Test
+    public void testNullMatch() {
+        AddressMask m = AddressMask.valueOf("*.*.*.*");
+        assertFalse(AddressMask.matchesAny(Arrays.asList(m), null));
+    }
+
+    private boolean match(String[] rules, String[] addrs, String[] hostNames)
+            throws UnknownHostException {
+        int i = 0;
+        Collection<AddressMask> m = new ArrayList<AddressMask>(rules.length);
+        for (i = 0; i < rules.length; i++) {
+            m.add(AddressMask.valueOf(rules[i]));
+        }
+        for (int j = 0; j < addrs.length; j++) {
+            InetAddress addr =
+                    InetAddress.getByAddress(hostNames[j], InetAddress.getByName(addrs[j])
+                            .getAddress());
+            if (!AddressMask.matchesAny(m, addr)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*
+     * IPV6 data and tests.
+     */
+
+    //Invalid IPv6 expressions.
+    @DataProvider(name = "invalid6Rules")
+    public Object[][] inValid6Data() {
+        return new Object[][] { { "2001:feca:ba23:cd1f:dcb1:1010:9234:4088///124" },
+            { "2001:feca:ba23:cd1f:dcb1:1010:9234:4088?124" },
+            { "2001:fecz:ba23:cd1f:dcb1:1010:9234:4088/124" },
+            { "2001:fecd:ba23:cd1ff:dcb1:1010:9234:4088/46" }, { "0:0:0:0:0:ffff:101..45.75.219" },
+            { "0:0:0:0:0:0:101.45.75.700" }, { "1080::8:800:200C:417A/500" },
+            { "1080::8:800:*:417A/66" }, { "2001:fecd:ba23:cd1ff:dcb1:1010:202.45.66.20" }, };
+    }
+
+    //Valid IPv6 expressions.
+    @DataProvider(name = "valid6Rules")
+    public Object[][] valid6Data() {
+        return new Object[][] { { "2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124" },
+            { "2001:fecd:ba23:cd1f:dcb1:1010:9234:4088" },
+            { "[2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45" }, { "::/128" }, { "::1/128" },
+            { "::" }, { "0:0:0:0:0:ffff:101.45.75.219" }, { "1080::8:800:200C:417A" },
+            { "0:0:0:0:0:0:101.45.75.219" }, { "::101.45.75.219" } };
+    }
+
+    @DataProvider(name = "match6Rules")
+    public Object[][] ruleMatch6Data() {
+        // @Checkstyle:off
+        return new Object[][] { {
+            //IPV6 Rules
+            new String[] { "[12ab:0:0:cd30::]/60", "::ffff:72.56.78.9", "::", "42ab:0:0:dd30::" },
+            //IPv6 Addresses
+            new String[] { "12ab:0:0:cd3f:0000:0000:23DC:DC30", "72.56.78.9", "::",
+                "42ab:0000:0000:dd30:0000:0000:0000:0000" },
+            //ignored Hostnames
+            new String[] { "ignored.host.name", "ignored.host.name", "ignored.host.name",
+                "ignored.host.name" } } };
+        // @Checkstyle:on
+    }
+
+    @Test(dataProvider = "valid6Rules")
+    public void testValid6Decode(String mask) {
+        AddressMask.valueOf(mask);
+    }
+
+    @Test(expectedExceptions = LocalizedIllegalArgumentException.class,
+            dataProvider = "invalid6Rules")
+    public void testInvalid6Decode(String mask) {
+        AddressMask.valueOf(mask);
+    }
+
+    @Test(dataProvider = "match6Rules")
+    public void testMatch6(String[] rules, String[] addrs, String[] hostNames)
+            throws UnknownHostException {
+        assertTrue(match(rules, addrs, hostNames));
+    }
+}

--
Gitblit v1.10.0