From 3e15deec52ab7eb4bdd76b51c1c496935987d656 Mon Sep 17 00:00:00 2001
From: sin <sin@localhost>
Date: Wed, 15 Jul 2009 15:34:06 +0000
Subject: [PATCH] Issue 4116 :Provide implementation for regex syntax
---
opends/src/server/org/opends/server/types/Schema.java | 43 ++
opends/src/server/org/opends/server/core/SchemaConfigManager.java | 287 ++++++++--------
opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java | 327 +++++++++++++++---
opends/src/messages/messages/schema.properties | 9
opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java | 287 ++++++++++++----
opends/src/server/org/opends/server/backends/SchemaBackend.java | 60 +-
6 files changed, 707 insertions(+), 306 deletions(-)
diff --git a/opends/src/messages/messages/schema.properties b/opends/src/messages/messages/schema.properties
index 35e5641..3e18ae2 100644
--- a/opends/src/messages/messages/schema.properties
+++ b/opends/src/messages/messages/schema.properties
@@ -1001,4 +1001,11 @@
MILD_WARN_ATTR_SYNTAX_LDAPSYNTAX_UNKNOWN_EXT_306=The provided value "%s" \
could not be parsed as an ldap syntax because it contains an unrecognized \
extension %s at position %d
-
+MILD_WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_VALUE_307=The provided value \
+ "%s" cannot be parsed as a valid regex syntax because it does not match \
+ the pattern "%s"
+MILD_WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_NO_PATTERN_308=The provided value "%s" \
+ could not be parsed as a regex syntax because it does not contain a regex pattern
+MILD_WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN_309=The provided value \
+ "%s" could not be parsed as a regex syntax because the provided regex \
+ pattern "%s" is invalid
diff --git a/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opends/src/server/org/opends/server/backends/SchemaBackend.java
index a69218f..9912785 100644
--- a/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -397,8 +397,9 @@
LinkedHashSet<String> newDCRs = new LinkedHashSet<String>();
LinkedHashSet<String> newDSRs = new LinkedHashSet<String>();
LinkedHashSet<String> newMRUs = new LinkedHashSet<String>();
+ LinkedHashSet<String> newLSDs = new LinkedHashSet<String>();
Schema.genConcatenatedSchema(newATs, newOCs, newNFs, newDCRs, newDSRs,
- newMRUs);
+ newMRUs,newLSDs);
// Next, generate lists of elements from the previous concatenated schema.
// If there isn't a previous concatenated schema, then use the base
@@ -449,8 +450,9 @@
LinkedHashSet<String> oldDCRs = new LinkedHashSet<String>();
LinkedHashSet<String> oldDSRs = new LinkedHashSet<String>();
LinkedHashSet<String> oldMRUs = new LinkedHashSet<String>();
+ LinkedHashSet<String> oldLSDs = new LinkedHashSet<String>();
Schema.readConcatenatedSchema(concatFilePath, oldATs, oldOCs, oldNFs,
- oldDCRs, oldDSRs, oldMRUs);
+ oldDCRs, oldDSRs, oldMRUs,oldLSDs);
// Create a list of modifications and add any differences between the old
// and new schema into them.
@@ -465,6 +467,8 @@
mods);
Schema.compareConcatenatedSchema(oldMRUs, newMRUs, matchingRuleUsesType,
mods);
+ Schema.compareConcatenatedSchema(oldLSDs, newLSDs, ldapSyntaxesType,
+ mods);
if (! mods.isEmpty())
{
DirectoryServer.setOfflineSchemaChanges(mods);
@@ -3472,12 +3476,36 @@
// Start with an empty schema entry.
Entry schemaEntry = createEmptySchemaEntry();
+ /**
+ * Add all of the ldap syntax descriptions to the schema entry. We do
+ * this only for the real part of the ldapsyntaxes attribute. The real part
+ * is read and write to/from the schema files.
+ */
+ LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
+ for (LDAPSyntaxDescription ldapSyntax :
+ schema.getLdapSyntaxDescriptions().values())
+ {
+ if(schemaFile.equals(ldapSyntax.getSchemaFile()))
+ {
+ values.add(AttributeValues.create(ldapSyntaxesType,
+ ldapSyntax.getDefinition()));
+ }
+ }
+
+ if (! values.isEmpty())
+ {
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
+ AttributeBuilder builder = new AttributeBuilder(ldapSyntaxesType);
+ builder.addAll(values);
+ attrList.add(builder.toAttribute());
+ schemaEntry.putAttribute(ldapSyntaxesType, attrList);
+ }
// Add all of the appropriate attribute types to the schema entry. We need
// to be careful of the ordering to ensure that any superior types in the
// same file are written before the subordinate types.
HashSet<AttributeType> addedTypes = new HashSet<AttributeType>();
- LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
+ values = new LinkedHashSet<AttributeValue>();
for (AttributeType at : schema.getAttributeTypes().values())
{
if (schemaFile.equals(at.getSchemaFile()))
@@ -3616,32 +3644,6 @@
}
- /**
- * Add all of the ldap syntax descriptions to the schema entry. We do
- * this only for the real part of the ldapsyntaxes attribute. The real part
- * is read and write to/from the schema files.
- */
- values = new LinkedHashSet<AttributeValue>();
- for (LDAPSyntaxDescription ldapSyntax :
- schema.getLdapSyntaxDescriptions().values())
- {
- if(schemaFile.equals(ldapSyntax.getSchemaFile()))
- {
- values.add(AttributeValues.create(ldapSyntaxesType,
- ldapSyntax.getDefinition()));
- }
- }
-
- if (! values.isEmpty())
- {
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- AttributeBuilder builder = new AttributeBuilder(ldapSyntaxesType);
- builder.addAll(values);
- attrList.add(builder.toAttribute());
- schemaEntry.putAttribute(attributeTypesType, attrList);
- }
-
-
if (schemaFile.equals(FILE_USER_SCHEMA_ELEMENTS))
{
Map<String, Attribute> attributes = schema.getExtraAttributes();
diff --git a/opends/src/server/org/opends/server/core/SchemaConfigManager.java b/opends/src/server/org/opends/server/core/SchemaConfigManager.java
index 7aec8fb..186a1bd 100644
--- a/opends/src/server/org/opends/server/core/SchemaConfigManager.java
+++ b/opends/src/server/org/opends/server/core/SchemaConfigManager.java
@@ -526,6 +526,47 @@
// Get the attributeTypes attribute from the entry.
LinkedList<Modification> mods = new LinkedList<Modification>();
+ //parse the syntaxes first because attributes rely on these.
+ LDAPSyntaxDescriptionSyntax ldapSyntax;
+ try
+ {
+ ldapSyntax = (LDAPSyntaxDescriptionSyntax) schema.getSyntax(
+ SYNTAX_LDAP_SYNTAX_OID);
+ if (ldapSyntax == null)
+ {
+ ldapSyntax = new LDAPSyntaxDescriptionSyntax();
+ ldapSyntax.initializeSyntax(null);
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ ldapSyntax = new LDAPSyntaxDescriptionSyntax();
+ ldapSyntax.initializeSyntax(null);
+ }
+
+ AttributeType ldapSyntaxAttrType =
+ schema.getAttributeType(ATTR_LDAP_SYNTAXES_LC);
+ if (ldapSyntaxAttrType == null)
+ {
+ ldapSyntaxAttrType =
+ DirectoryServer.getDefaultAttributeType(ATTR_LDAP_SYNTAXES,
+ ldapSyntax);
+ }
+
+ List<Attribute> ldapSyntaxList = entry.getAttribute(ldapSyntaxAttrType);
+ if ((ldapSyntaxList != null) && (! ldapSyntaxList.isEmpty()))
+ {
+ for (Attribute a : ldapSyntaxList)
+ {
+ mods.add(new Modification(ModificationType.ADD, a));
+ }
+ }
+
AttributeTypeSyntax attrTypeSyntax;
try
{
@@ -773,47 +814,6 @@
}
}
- // Get the ldapsyntaxes attribute from the entry.
- LDAPSyntaxDescriptionSyntax ldapSyntax;
- try
- {
- ldapSyntax = (LDAPSyntaxDescriptionSyntax) schema.getSyntax(
- SYNTAX_LDAP_SYNTAX_OID);
- if (ldapSyntax == null)
- {
- ldapSyntax = new LDAPSyntaxDescriptionSyntax();
- ldapSyntax.initializeSyntax(null);
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- ldapSyntax = new LDAPSyntaxDescriptionSyntax();
- ldapSyntax.initializeSyntax(null);
- }
-
- AttributeType ldapSyntaxAttrType =
- schema.getAttributeType(ATTR_LDAP_SYNTAXES_LC);
- if (ldapSyntaxAttrType == null)
- {
- ldapSyntaxAttrType =
- DirectoryServer.getDefaultAttributeType(ATTR_LDAP_SYNTAXES,
- ldapSyntax);
- }
-
- List<Attribute> ldapSyntaxList = entry.getAttribute(ldapSyntaxAttrType);
- if ((ldapSyntaxList != null) && (! ldapSyntaxList.isEmpty()))
- {
- for (Attribute a : ldapSyntaxList)
- {
- mods.add(new Modification(ModificationType.ADD, a));
- }
- }
-
// Loop on all the attribute of the schema entry to
// find the extra attribute that shoule be loaded in the Schema.
for (Attribute attribute : entry.getAttributes())
@@ -824,6 +824,104 @@
}
}
+
+
+ // Parse the ldapsyntaxes definitions if there are any.
+ if (ldapSyntaxList != null)
+ {
+ for (Attribute a : ldapSyntaxList)
+ {
+ for (AttributeValue v : a)
+ {
+ LDAPSyntaxDescription syntaxDescription = null;
+ try
+ {
+ syntaxDescription = LDAPSyntaxDescriptionSyntax.decodeLDAPSyntax(
+ v.getValue(),schema,false);
+ syntaxDescription.setExtraProperty(
+ SCHEMA_PROPERTY_FILENAME, (String) null);
+ syntaxDescription.setSchemaFile(schemaFile);
+ }
+ catch (DirectoryException de)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, de);
+ }
+
+ Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_LDAP_SYNTAX.get(
+ schemaFile,
+ de.getMessageObject());
+
+ if (failOnError)
+ {
+ throw new ConfigException(message, de);
+ }
+ else
+ {
+ logError(message);
+ continue;
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_LDAP_SYNTAX.get(
+ schemaFile,
+ v.getValue().toString() + ": " + getExceptionMessage(e));
+
+ if (failOnError)
+ {
+ throw new ConfigException(message, e);
+ }
+ else
+ {
+ logError(message);
+ continue;
+ }
+ }
+
+ // Register it with the schema. We will allow duplicates, with the
+ // later definition overriding any earlier definition, but we want
+ // to trap them and log a warning.
+ try
+ {
+ schema.registerLdapSyntaxDescription(
+ syntaxDescription, failOnError);
+ }
+ catch (DirectoryException de)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, de);
+ }
+
+ Message message = WARN_CONFIG_SCHEMA_CONFLICTING_LDAP_SYNTAX.get(
+ schemaFile, de.getMessageObject());
+ logError(message);
+
+ try
+ {
+ schema.registerLdapSyntaxDescription(syntaxDescription, true);
+ }
+ catch (Exception e)
+ {
+ // This should never happen.
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ }
+ }
+
+ }
+ }
+ }
+
// Parse the attribute type definitions if there are any.
if (attrList != null)
{
@@ -1386,101 +1484,6 @@
}
}
-
- // Parse the ldapsyntaxes definitions if there are any.
- if (ldapSyntaxList != null)
- {
- for (Attribute a : ldapSyntaxList)
- {
- for (AttributeValue v : a)
- {
- LDAPSyntaxDescription syntaxDescription = null;
- try
- {
- syntaxDescription = LDAPSyntaxDescriptionSyntax.decodeLDAPSyntax(
- v.getValue(),schema,false);
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_LDAP_SYNTAX.get(
- schemaFile,
- de.getMessageObject());
-
- if (failOnError)
- {
- throw new ConfigException(message, de);
- }
- else
- {
- logError(message);
- continue;
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = WARN_CONFIG_SCHEMA_CANNOT_PARSE_LDAP_SYNTAX.get(
- schemaFile,
- v.getValue().toString() + ": " + getExceptionMessage(e));
-
- if (failOnError)
- {
- throw new ConfigException(message, e);
- }
- else
- {
- logError(message);
- continue;
- }
- }
-
- // Register it with the schema. We will allow duplicates, with the
- // later definition overriding any earlier definition, but we want
- // to trap them and log a warning.
- try
- {
- schema.registerLdapSyntaxDescription(
- syntaxDescription, failOnError);
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- Message message = WARN_CONFIG_SCHEMA_CONFLICTING_LDAP_SYNTAX.get(
- schemaFile, de.getMessageObject());
- logError(message);
-
- try
- {
- schema.registerLdapSyntaxDescription(syntaxDescription, true);
- }
- catch (Exception e)
- {
- // This should never happen.
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
- }
-
- }
- }
- }
-
-
return mods;
}
@@ -1509,12 +1512,12 @@
attributeOid.equals("1.3.6.1.4.1.1466.101.120.16") ||
attributeOid.equals("attributetypes-oid") ||
attributeOid.equals("objectclasses-oid") ||
- attributeOid.equals("matchingRules-oid") ||
- attributeOid.equals("matchingRuleUse-oid") ||
- attributeOid.equals("NameFormDescription-oid") ||
- attributeOid.equals("dITContentRules-oid") ||
- attributeOid.equals("dITStructureRules") ||
- attributeOid.equals("ldapSyntaxes-oid")
+ attributeOid.equals("matchingrules-oid") ||
+ attributeOid.equals("matchingruleuse-oid") ||
+ attributeOid.equals("nameformdescription-oid") ||
+ attributeOid.equals("ditcontentrules-oid") ||
+ attributeOid.equals("ditstructurerules-oid") ||
+ attributeOid.equals("ldapsyntaxes-oid")
)
{
diff --git a/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java b/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
index e0a4f74..0a890fd 100644
--- a/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
+++ b/opends/src/server/org/opends/server/schema/LDAPSyntaxDescriptionSyntax.java
@@ -29,6 +29,8 @@
+import java.util.regex.Pattern;
+
import org.opends.server.admin.std.server.AttributeSyntaxCfg;
import org.opends.server.api.ApproximateMatchingRule;
import org.opends.server.api.AttributeSyntax;
@@ -496,8 +498,7 @@
String oid = oidBuffer.toString();
String description = descriptionBuffer.toString();
StringBuilder extBuffer = new StringBuilder();
- //Attribute syntax which will sustitute the syntax with oid.
- AttributeSyntax subSyntax = null;
+ LDAPSyntaxDescriptionSyntax syntax = null;
pos = readTokenName(valueStr, extBuffer, pos);
String lowerTokenName = toLowerCase(extBuffer.toString());
@@ -507,7 +508,7 @@
StringBuilder woidBuffer = new StringBuilder();
pos = readQuotedString(lowerStr, woidBuffer, pos);
String syntaxOID = woidBuffer.toString();
- subSyntax = schema.getSyntax(syntaxOID);
+ AttributeSyntax subSyntax = schema.getSyntax(syntaxOID);
if(subSyntax == null)
{
Message message = WARN_ATTR_SYNTAX_ATTRTYPE_UNKNOWN_SYNTAX.get(
@@ -515,6 +516,33 @@
throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
message);
}
+ syntax = new SubstitutionSyntax(subSyntax,description,oid);
+ }
+ else if(lowerTokenName.equals("x-pattern"))
+ {
+ StringBuilder regexBuffer = new StringBuilder();
+ pos = readQuotedString(valueStr, regexBuffer, pos);
+ String regex = regexBuffer.toString();
+ if(regex == null)
+ {
+ Message message = WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_NO_PATTERN.get(
+ valueStr);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message);
+ }
+
+ try
+ {
+ Pattern pattern = Pattern.compile(regex);
+ syntax = new RegexSyntax(pattern,description,oid);
+ }
+ catch(Exception e)
+ {
+ Message message = WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_PATTERN.get
+ (valueStr,regex);
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ message);
+ }
}
else
{
@@ -557,16 +585,8 @@
}
}
- LDAPSyntaxDescription syntaxDesc = null;
//Since we reached here it means everything is OK.
- if(subSyntax !=null)
- {
- //A SubstitutionSyntax is requested.
- syntaxDesc = new LDAPSyntaxDescription(valueStr,
- new SubstitutionSyntax(subSyntax,description,oid),
- description,null);
- }
- return syntaxDesc;
+ return new LDAPSyntaxDescription(valueStr,syntax,description,null);
}
@@ -920,7 +940,7 @@
- /**
+ /**
* {@inheritDoc}
*/
@Override
@@ -966,67 +986,250 @@
- /**
- * Retrieves the default equality matching rule that will be used for
- * attributes with this syntax.
- *
- * @return The default equality matching rule that will be used for
- * attributes with this syntax, or <CODE>null</CODE> if equality
- * matches will not be allowed for this type by default.
- */
- @Override
- public EqualityMatchingRule getEqualityMatchingRule()
- {
- return subSyntax.getEqualityMatchingRule();
+ /**
+ * Retrieves the default equality matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default equality matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if equality
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public EqualityMatchingRule getEqualityMatchingRule()
+ {
+ return subSyntax.getEqualityMatchingRule();
+ }
+
+
+
+ /**
+ * Retrieves the default ordering matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default ordering matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if ordering
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public OrderingMatchingRule getOrderingMatchingRule()
+ {
+ return subSyntax.getOrderingMatchingRule();
+ }
+
+
+
+ /**
+ * Retrieves the default substring matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default substring matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if substring
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public SubstringMatchingRule getSubstringMatchingRule()
+ {
+ return subSyntax.getSubstringMatchingRule();
+ }
+
+
+
+ /**
+ * Retrieves the default approximate matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default approximate matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if approximate
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public ApproximateMatchingRule getApproximateMatchingRule()
+ {
+ return subSyntax.getApproximateMatchingRule();
+ }
}
/**
- * Retrieves the default ordering matching rule that will be used for
- * attributes with this syntax.
- *
- * @return The default ordering matching rule that will be used for
- * attributes with this syntax, or <CODE>null</CODE> if ordering
- * matches will not be allowed for this type by default.
+ * This class provides a regex mechanism where a new syntax and its
+ * corresponding matching rules can be created on-the-fly. A regex
+ * syntax is an LDAPSyntaxDescriptionSyntax with X-PATTERN extension.
*/
- @Override
- public OrderingMatchingRule getOrderingMatchingRule()
+ private static class RegexSyntax extends
+ LDAPSyntaxDescriptionSyntax
{
- return subSyntax.getOrderingMatchingRule();
- }
+ // The Pattern associated with the regex.
+ private Pattern pattern;
+
+ // The description of this syntax.
+ private String description;
+
+ //The oid of this syntax.
+ private String oid;
+
+ //The equality matching rule.
+ private EqualityMatchingRule equalityMatchingRule;
+
+ //The substring matching rule.
+ private SubstringMatchingRule substringMatchingRule;
+
+ //The ordering matching rule.
+ private OrderingMatchingRule orderingMatchingRule;
+
+ //The approximate matching rule.
+ private ApproximateMatchingRule approximateMatchingRule;
+
+
+ //Creates a new instance of this syntax.
+ private RegexSyntax(Pattern pattern,
+ String description,
+ String oid)
+ {
+ super();
+ this.pattern = pattern;
+ this.description = description;
+ this.oid = oid;
+ }
- /**
- * Retrieves the default substring matching rule that will be used for
- * attributes with this syntax.
- *
- * @return The default substring matching rule that will be used for
- * attributes with this syntax, or <CODE>null</CODE> if substring
- * matches will not be allowed for this type by default.
- */
- @Override
- public SubstringMatchingRule getSubstringMatchingRule()
- {
- return subSyntax.getSubstringMatchingRule();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getSyntaxName()
+ {
+ // There is no name for a regex syntax.
+ return null;
+ }
- /**
- * Retrieves the default approximate matching rule that will be used for
- * attributes with this syntax.
- *
- * @return The default approximate matching rule that will be used for
- * attributes with this syntax, or <CODE>null</CODE> if approximate
- * matches will not be allowed for this type by default.
- */
- @Override
- public ApproximateMatchingRule getApproximateMatchingRule()
- {
- return subSyntax.getApproximateMatchingRule();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getOID()
+ {
+ return oid;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getDescription()
+ {
+ return description;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean valueIsAcceptable(ByteSequence value,
+ MessageBuilder invalidReason)
+ {
+ String strValue = value.toString();
+ boolean matches = pattern.matcher(strValue).matches();
+ if(!matches)
+ {
+ Message message = WARN_ATTR_SYNTAX_LDAPSYNTAX_REGEX_INVALID_VALUE.get(
+ strValue,pattern.pattern());
+ invalidReason.append(message);
+ }
+ return matches;
+ }
+
+
+
+ /**
+ * Retrieves the default equality matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default equality matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if equality
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public EqualityMatchingRule getEqualityMatchingRule()
+ {
+ if(equalityMatchingRule == null)
+ {
+ //This has already been verified.
+ equalityMatchingRule =
+ DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
+ }
+ return equalityMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default ordering matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default ordering matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if ordering
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public OrderingMatchingRule getOrderingMatchingRule()
+ {
+ if(orderingMatchingRule == null)
+ {
+ orderingMatchingRule =
+ DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
+ }
+ return orderingMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default substring matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default substring matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if substring
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public SubstringMatchingRule getSubstringMatchingRule()
+ {
+ if(substringMatchingRule == null)
+ {
+ substringMatchingRule =
+ DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
+ }
+ return substringMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default approximate matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default approximate matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if approximate
+ * matches will not be allowed for this type by default.
+ */
+ @Override
+ public ApproximateMatchingRule getApproximateMatchingRule()
+ {
+ if(approximateMatchingRule == null)
+ {
+ approximateMatchingRule =
+ DirectoryServer.getApproximateMatchingRule(
+ AMR_DOUBLE_METAPHONE_OID);
+ }
+ return approximateMatchingRule;
+ }
}
}
-
diff --git a/opends/src/server/org/opends/server/types/Schema.java b/opends/src/server/org/opends/server/types/Schema.java
index 011280f..e5a3f22 100644
--- a/opends/src/server/org/opends/server/types/Schema.java
+++ b/opends/src/server/org/opends/server/types/Schema.java
@@ -3386,9 +3386,11 @@
new LinkedHashSet<String>();
LinkedHashSet<String> matchingRuleUses =
new LinkedHashSet<String>();
+ LinkedHashSet<String> ldapSyntaxes =
+ new LinkedHashSet<String>();
genConcatenatedSchema(attributeTypes, objectClasses, nameForms,
ditContentRules, ditStructureRules,
- matchingRuleUses);
+ matchingRuleUses,ldapSyntaxes);
File configFile = new File(DirectoryServer.getConfigFile());
@@ -3459,6 +3461,15 @@
writer.newLine();
}
+
+ for (String line : ldapSyntaxes)
+ {
+ writer.write(ATTR_LDAP_SYNTAXES);
+ writer.write(": ");
+ writer.write(line);
+ writer.newLine();
+ }
+
writer.close();
if (concatFile.exists())
@@ -3506,6 +3517,9 @@
* @param matchingRuleUses The set into which to place the
* matching rule uses read from the
* schema files.
+ * @param ldapSyntaxes The set into which to place the
+ * ldap syntaxes read from the
+ * schema files.
*
* @throws IOException If a problem occurs while reading the
* schema file elements.
@@ -3516,7 +3530,8 @@
LinkedHashSet<String> nameForms,
LinkedHashSet<String> ditContentRules,
LinkedHashSet<String> ditStructureRules,
- LinkedHashSet<String> matchingRuleUses)
+ LinkedHashSet<String> matchingRuleUses,
+ LinkedHashSet<String> ldapSyntaxes)
throws IOException
{
// Get a sorted list of the files in the schema directory.
@@ -3641,6 +3656,12 @@
ATTR_MATCHING_RULE_USE.length()+1).trim();
matchingRuleUses.add(value);
}
+ else if(lowerLine.startsWith(ATTR_LDAP_SYNTAXES_LC))
+ {
+ value = line.substring(
+ ATTR_LDAP_SYNTAXES.length()+1).trim();
+ ldapSyntaxes.add(value);
+ }
}
}
}
@@ -3671,6 +3692,9 @@
* @param matchingRuleUses The set into which to place the
* matching rule uses read from the
* concatenated schema file.
+ * @param ldapSyntaxes The set into which to place the
+ * ldap syntaxes read from the
+ * concatenated schema file.
*
* @throws IOException If a problem occurs while reading the
* schema file elements.
@@ -3681,7 +3705,8 @@
LinkedHashSet<String> nameForms,
LinkedHashSet<String> ditContentRules,
LinkedHashSet<String> ditStructureRules,
- LinkedHashSet<String> matchingRuleUses)
+ LinkedHashSet<String> matchingRuleUses,
+ LinkedHashSet<String> ldapSyntaxes)
throws IOException
{
BufferedReader reader =
@@ -3730,6 +3755,12 @@
ATTR_MATCHING_RULE_USE.length()+1).trim();
matchingRuleUses.add(value);
}
+ else if (lowerLine.startsWith(ATTR_LDAP_SYNTAXES_LC))
+ {
+ value = line.substring(
+ ATTR_LDAP_SYNTAXES.length()+1).trim();
+ ldapSyntaxes.add(value);
+ }
}
reader.close();
@@ -3957,6 +3988,12 @@
extensibleMatchingRules = null;
}
+ if(ldapSyntaxDescriptions != null)
+ {
+ ldapSyntaxDescriptions.clear();
+ ldapSyntaxDescriptions = null;
+ }
+
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
index ce6efae..e7fabb7 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/schema/LDAPSyntaxTest.java
@@ -32,6 +32,7 @@
import java.util.List;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.AttributeSyntax;
+import org.opends.server.core.AddOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
@@ -40,6 +41,7 @@
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.DereferencePolicy;
+import org.opends.server.types.Entry;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
@@ -136,71 +138,70 @@
/**
* Tests whether an implemented syntax can't be substituted by another.
*/
- @Test()
- public void testSubstitutionSyntaxForInvalidSubstitution() throws Exception
- {
+ @Test()
+ public void testSubstitutionSyntaxForInvalidSubstitution() throws Exception
+ {
+ try
+ {
+ //Test if we can substitute a directory string syntax by itself.
+ int resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "add: ldapsyntaxes",
+ "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 " +
+ "DESC 'Replacing DirectorySyntax' " +
+ " X-SUBST '1.3.6.1.4.1.1466.115.121.1.15' )");
- try
- {
- //Test if we can substitute a directory string syntax by itself.
- int resultCode = TestCaseUtils.applyModifications(true,
- "dn: cn=schema",
- "changetype: modify",
- "add: ldapsyntaxes",
- "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 " +
- "DESC 'Replacing DirectorySyntax' " +
- " X-SUBST '1.3.6.1.4.1.1466.115.121.1.15' )");
+ //This is not expected to happen
+ assertFalse(resultCode==0);
- //This is not expected to happen
- assertFalse(resultCode==0);
+ //Test if we can substitute a directory string syntax by an undefined.
+ resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "add: ldapsyntaxes",
+ "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 " +
+ "DESC 'Replacing DirectorySyntax' " +
+ " X-SUBST '1.1.1' )");
- //Test if we can substitute a directory string syntax by an undefined.
- resultCode = TestCaseUtils.applyModifications(true,
- "dn: cn=schema",
- "changetype: modify",
- "add: ldapsyntaxes",
- "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 " +
- "DESC 'Replacing DirectorySyntax' " +
- " X-SUBST '1.1.1' )");
-
- //This is not expected to happen
- assertFalse(resultCode==0);
+ //This is not expected to happen
+ assertFalse(resultCode==0);
- //Test if we can substitute a core syntax with a user-defined
- //syntax
- addSubtitutionSyntax();
- //Replace the IA5Stringsyntax with the custom syntax we just created.
- resultCode = TestCaseUtils.applyModifications(true,
- "dn: cn=schema",
- "changetype: modify",
- "add: ldapsyntaxes",
- "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 " +
- "DESC 'Replacing DirectorySyntax' " +
- " X-SUBST '9.9.9' )");
+ //Test if we can substitute a core syntax with a user-defined
+ //syntax
+ addSubtitutionSyntax();
+ //Replace the IA5Stringsyntax with the custom syntax we just created.
+ resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "add: ldapsyntaxes",
+ "ldapsyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 " +
+ "DESC 'Replacing DirectorySyntax' " +
+ " X-SUBST '9.9.9' )");
- //This is not expected to happen
- assertFalse(resultCode==0);
- }
- finally
- {
+ //This is not expected to happen
+ assertFalse(resultCode==0);
+ }
+ finally
+ {
deleteSubstitutionSyntax();
- }
- }
+ }
+ }
- /**
+ /**
* Tests whether both the virtual and the newly added real substitution
* sytanx are available when a search is made for ldapsyntaxes attribute.
*
* @throws java.lang.Exception
*/
- @Test()
- public void testSubstitutionSyntaxSearch() throws Exception
- {
- try
- {
+ @Test()
+ public void testSubstitutionSyntaxSearch() throws Exception
+ {
+ try
+ {
addSubtitutionSyntax();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
@@ -230,9 +231,9 @@
assertNotNull(e);
Attribute attr = e.getAttribute("ldapsyntaxes").get(0);
Iterator<AttributeValue> iter = attr.iterator();
-
+
//There are other ways of doing it but we will extract the OID
- //from the attribute values and then check to see if our
+ //from the attribute values and then check to see if our
//OID is found in the result set or not.
List<String> syntaxList = new ArrayList<String>();
while(iter.hasNext())
@@ -241,21 +242,21 @@
//parse the OIDs.
syntaxList.add(getOIDFromLdapSyntax(val.toString()));
}
-
+
assertTrue(syntaxList.size() ==
DirectoryServer.getAttributeSyntaxSet().size() ) ;
- //Check if we find our OID.
+ //Check if we find our OID.
assertTrue(syntaxList.contains("9.9.9"));
//DirectoryString.
assertTrue(syntaxList.contains("1.3.6.1.4.1.1466.115.121.1.15"));
//IA5String.
assertTrue(syntaxList.contains("1.3.6.1.4.1.1466.115.121.1.26"));
- }
- finally
- {
- deleteSubstitutionSyntax();
- }
- }
+ }
+ finally
+ {
+ deleteSubstitutionSyntax();
+ }
+ }
@@ -265,6 +266,7 @@
*
* @throws java.lang.Exception
*/
+ @Test()
public void testSubsitutionSyntaxAddValues() throws Exception
{
try
@@ -298,6 +300,109 @@
}
+
+ /**
+ * Tests whether it is possible to add values after a regex syntax
+ * has been added.
+ *
+ * @throws java.lang.Exception
+ */
+ @Test()
+ public void testRegexSyntaxAddValues() throws Exception
+ {
+ try
+ {
+ addRegexSyntax();
+ TestCaseUtils.initializeTestBackend(true);
+
+ //This addition should fail because it doesn't match the pattern.
+ Entry entry = TestCaseUtils.makeEntry(
+ "dn: cn=syntax-test,o=test",
+ "objectclass: person",
+ "objectclass: testOC",
+ "cn: syntax-test",
+ "sn: xyz",
+ "test-attr-regex: invalid regex");
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ AddOperation addOperation = conn.processAdd(entry.getDN(),
+ entry.getObjectClasses(),
+ entry.getUserAttributes(),
+ entry.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(),
+ ResultCode.INVALID_ATTRIBUTE_SYNTAX);
+
+ //This addition should go through.
+ TestCaseUtils.addEntry(
+ "dn: cn=syntax-test,o=test",
+ "objectclass: person",
+ "objectclass: testOC",
+ "cn: syntax-test",
+ "sn: xyz",
+ "test-attr-regex: host:0.0.0");
+ }
+ finally
+ {
+ deleteRegexSyntax();
+ }
+ }
+
+
+
+ /**
+ * Tests the search using regex syntax.
+ *
+ * @throws java.lang.Exception
+ */
+ @Test()
+ public void testRegexSyntaxSearch() throws Exception
+ {
+ try
+ {
+ addRegexSyntax();
+ //This addition should go through.
+ TestCaseUtils.addEntry(
+ "dn: cn=test,o=test",
+ "objectclass: person",
+ "objectclass: testOC",
+ "cn: test",
+ "sn: xyz",
+ "test-attr-regex: host:0.0.0");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ InternalSearchOperation searchOperation =
+ new InternalSearchOperation(
+ conn,
+ InternalClientConnection.nextOperationID(),
+ InternalClientConnection.nextMessageID(),
+ null,
+ ByteString.valueOf("cn=test,o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ false,
+ LDAPFilter.decode("test-attr-regex=host:0.0.0"),
+ null, null);
+
+ searchOperation.run();
+ assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
+ List<SearchResultEntry> entries = searchOperation.getSearchEntries();
+ SearchResultEntry e = entries.get(0);
+ //An entry must be returned.
+ assertNotNull(e);
+ }
+ finally
+ {
+ deleteRegexSyntax();
+ }
+ }
+
+
+
//Parses the OID from the syntax defitions.
private String getOIDFromLdapSyntax(String valueStr)
{
@@ -319,18 +424,9 @@
}
int oidStartPos = pos;
- boolean lastWasPeriod = false;
while ((pos < length) && ((c = valueStr.charAt(pos)) != ' ')
&& (c = valueStr.charAt(pos)) != ')')
{
- if (c == '.')
- {
- lastWasPeriod = true;
- }
- else
- {
- lastWasPeriod = false;
- }
pos++;
}
return valueStr.substring(oidStartPos, pos);
@@ -366,4 +462,57 @@
assertTrue(resultCode==0);
}
+
+
+ //Adds a regex syntax to the schema.
+ private void addRegexSyntax() throws Exception
+ {
+ //Add the substitution syntax for an unimplemented syntax.
+ int resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "add: ldapsyntaxes",
+ "ldapSyntaxes: ( 1.1.1 DESC 'Host and Port in the format of HOST:PORT' " +
+ "X-PATTERN '^[a-z-A-Z]+:[0-9.]+\\d$' )");
+ assertTrue(resultCode==0);
+
+ resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "add: attributetypes",
+ "attributetypes: ( test-attr-oid NAME 'test-attr-regex' SYNTAX 1.1.1 )",
+ "-",
+ "add: objectclasses",
+ "objectclasses: ( oc-oid NAME 'testOC' SUP top AUXILIARY MUST test-attr-regex)"
+ );
+ assertTrue(resultCode == 0);
+ }
+
+
+
+ //Deletes the regex syntax from the schema.
+ private void deleteRegexSyntax() throws Exception
+ {
+ //delete the substitution syntax.
+ int resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "delete: objectclasses",
+ "objectclasses: ( oc-oid NAME 'testOC' SUP top AUXILIARY MUST test-attr-regex)",
+ "-",
+ "delete: attributetypes",
+ "attributetypes: ( test-attr-oid NAME 'test-attr-regex' SYNTAX 1.1.1 )"
+ );
+
+ assertTrue(resultCode==0);
+
+ resultCode = TestCaseUtils.applyModifications(true,
+ "dn: cn=schema",
+ "changetype: modify",
+ "delete: ldapsyntaxes",
+ "ldapSyntaxes: ( 1.1.1 DESC 'Host and Port in the format of HOST:PORT' " +
+ "X-PATTERN '^[a-z-A-Z]+:[0-9.]+\\d$' )");
+
+ assertTrue(resultCode==0);
+ }
}
--
Gitblit v1.10.0