From ec6408fb14ac5d8f3c5d889e4ccce289db08e498 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 23 Apr 2007 09:50:42 +0000
Subject: [PATCH] Fix for issue 1523 - Implement String property definition regex support.

---
 opends/resource/admin/property-types/string.xsl                                                     |    5 +
 opends/tests/unit-tests-testng/src/server/org/opends/server/admin/StringPropertyDefinitionTest.java |  108 +++++++++++++++++++++++++++
 opends/src/server/org/opends/server/admin/StringPropertyDefinition.java                             |   80 +++++++++++++++++---
 3 files changed, 181 insertions(+), 12 deletions(-)

diff --git a/opends/resource/admin/property-types/string.xsl b/opends/resource/admin/property-types/string.xsl
index ebcd145..13f32c9 100644
--- a/opends/resource/admin/property-types/string.xsl
+++ b/opends/resource/admin/property-types/string.xsl
@@ -41,5 +41,10 @@
         select="concat('      builder.setCaseInsensitive(',
                        @case-insensitive, ');&#xa;')" />
     </xsl:if>
+    <xsl:if test="adm:pattern/adm:regex">
+      <xsl:value-of
+        select="concat('      builder.setPattern(&quot;',
+                       normalize-space(adm:pattern/adm:regex), '&quot;);&#xa;')" />
+    </xsl:if>
   </xsl:template>
 </xsl:stylesheet>
diff --git a/opends/src/server/org/opends/server/admin/StringPropertyDefinition.java b/opends/src/server/org/opends/server/admin/StringPropertyDefinition.java
index 2eb20bb..7ff09e6 100644
--- a/opends/src/server/org/opends/server/admin/StringPropertyDefinition.java
+++ b/opends/src/server/org/opends/server/admin/StringPropertyDefinition.java
@@ -34,13 +34,14 @@
 import java.util.EnumSet;
 import java.util.Locale;
 import java.util.MissingResourceException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 
 
 /**
  * String property definition.
- * <p>
- * TODO: pattern matching.
  */
 public final class StringPropertyDefinition extends
     AbstractPropertyDefinition<String> {
@@ -54,10 +55,14 @@
   // case-insensitive.
   private final boolean isCaseInsensitive;
 
+  // Optional pattern which values of this property must match.
+  private final Pattern pattern;
+
 
 
   /**
-   * An interface for incrementally constructing string property definitions.
+   * An interface for incrementally constructing string property
+   * definitions.
    */
   public static class Builder extends
       AbstractBuilder<String, StringPropertyDefinition> {
@@ -66,11 +71,14 @@
     // case-insensitive.
     private boolean isCaseInsensitive = true;
 
+    // Optional pattern which values of this property must match.
+    private Pattern pattern = null;
+
 
 
     // Private constructor
-    private Builder(
-        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
+    private Builder(AbstractManagedObjectDefinition<?, ?> d,
+        String propertyName) {
       super(d, propertyName);
     }
 
@@ -91,6 +99,28 @@
 
 
     /**
+     * Set the regular expression pattern which values of this
+     * property must match. By default there is no pattern defined.
+     *
+     * @param pattern
+     *          The regular expression pattern string, or
+     *          <code>null</code> if there is no pattern.
+     * @throws PatternSyntaxException
+     *           If the provided regular expression pattern has an
+     *           invalid syntax.
+     */
+    public final void setPattern(String pattern)
+        throws PatternSyntaxException {
+      if (pattern == null) {
+        this.pattern = null;
+      } else {
+        this.pattern = Pattern.compile(pattern);
+      }
+    }
+
+
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -99,7 +129,7 @@
         EnumSet<PropertyOption> options,
         DefaultBehaviorProvider<String> defaultBehavior) {
       return new StringPropertyDefinition(d, propertyName, options,
-          defaultBehavior, isCaseInsensitive);
+          defaultBehavior, isCaseInsensitive, pattern);
     }
 
   }
@@ -128,9 +158,24 @@
       AbstractManagedObjectDefinition<?, ?> d, String propertyName,
       EnumSet<PropertyOption> options,
       DefaultBehaviorProvider<String> defaultBehavior,
-      boolean isCaseInsensitive) {
+      boolean isCaseInsensitive, Pattern pattern) {
     super(d, String.class, propertyName, options, defaultBehavior);
     this.isCaseInsensitive = isCaseInsensitive;
+    this.pattern = pattern;
+  }
+
+
+
+  /**
+   * Gets the optional regular expression pattern which values of this
+   * property must match.
+   *
+   * @return Returns the optional regular expression pattern which
+   *         values of this property must match, or <code>null</code>
+   *         if there is no pattern.
+   */
+  public Pattern getPattern() {
+    return pattern;
   }
 
 
@@ -181,8 +226,8 @@
   /**
    * Query whether values of this property are case-insensitive.
    *
-   * @return Returns <code>true</code> if values are case-insensitive, or
-   *         <code>false</code> otherwise.
+   * @return Returns <code>true</code> if values are
+   *         case-insensitive, or <code>false</code> otherwise.
    */
   public boolean isCaseInsensitive() {
     return isCaseInsensitive;
@@ -211,11 +256,16 @@
    * {@inheritDoc}
    */
   @Override
-  public void validateValue(String value) throws IllegalPropertyValueException {
+  public void validateValue(String value)
+      throws IllegalPropertyValueException {
     ensureNotNull(value);
 
-    // No additional validation required for now (might do pattern
-    // matching in future).
+    if (pattern != null) {
+      Matcher matcher = pattern.matcher(value);
+      if (!matcher.matches()) {
+        throw new IllegalPropertyValueException(this, value);
+      }
+    }
   }
 
 
@@ -228,6 +278,12 @@
       throws IllegalPropertyValueStringException {
     ensureNotNull(value);
 
+    try {
+      validateValue(value);
+    } catch (IllegalPropertyValueException e) {
+      throw new IllegalPropertyValueStringException(this, value);
+    }
+
     return value;
   }
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/StringPropertyDefinitionTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/StringPropertyDefinitionTest.java
new file mode 100644
index 0000000..4b74482
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/StringPropertyDefinitionTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin;
+
+
+
+import static org.testng.Assert.assertEquals;
+
+import org.opends.server.admin.std.meta.RootCfgDefn;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * StringPropertyDefinition Tester.
+ */
+public class StringPropertyDefinitionTest {
+
+  /**
+   * Tests validateValue() with valid data and no pattern.
+   */
+  @Test
+  public void testValidateValue1() {
+    StringPropertyDefinition d = getDefinition(true, null);
+    d.validateValue("abc");
+  }
+
+
+
+  /**
+   * Tests validateValue() with valid data and a pattern.
+   */
+  @Test
+  public void testValidateValue2() {
+    StringPropertyDefinition d = getDefinition(true, "^[a-z]+$");
+    d.validateValue("abc");
+  }
+
+
+
+  /**
+   * Tests validateValue() with invalid data and a pattern.
+   */
+  @Test(expectedExceptions = IllegalPropertyValueException.class)
+  public void testValidateValue3() {
+    StringPropertyDefinition d = getDefinition(true, "^[a-z]+$");
+    d.validateValue("abc123");
+  }
+
+
+
+  /**
+   * Tests decodeValue() with valid data and a pattern.
+   */
+  @Test
+  public void testDecodeValue1() {
+    StringPropertyDefinition d = getDefinition(true, "^[a-z]+$");
+    assertEquals(d.decodeValue("abc"), "abc");
+  }
+
+
+
+  /**
+   * Tests decodeValue() with invalid data and a pattern.
+   */
+  @Test(expectedExceptions = IllegalPropertyValueStringException.class)
+  public void testDecodeValue2() {
+    StringPropertyDefinition d = getDefinition(true, "^[a-z]+$");
+    d.decodeValue("abc123");
+  }
+
+
+
+  // Create a string property definition.
+  private StringPropertyDefinition getDefinition(
+      boolean isCaseInsensitive, String pattern) {
+    StringPropertyDefinition.Builder builder = StringPropertyDefinition
+        .createBuilder(RootCfgDefn.getInstance(), "test-property");
+    builder.setCaseInsensitive(isCaseInsensitive);
+    builder.setPattern(pattern);
+    return builder.getInstance();
+  }
+}

--
Gitblit v1.10.0