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 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(); 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") ) { 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; } } } 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; } } } 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); } }