From 89ab562d7cbddf5263289b223c5088eb9cd366f8 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 14 Mar 2014 16:04:01 +0000
Subject: [PATCH] OPENDJ-1308 Migrate schema support
---
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java | 57 +++
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactoryTest.java | 234 ++++++++++++
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java | 116 +----
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleTest.java | 39 +-
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java | 627 +++++++++++++-------------------
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java | 11
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java | 19 +
7 files changed, 624 insertions(+), 479 deletions(-)
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
index 850506b..65ab9fd 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
@@ -35,7 +35,6 @@
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.Syntax;
-import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
/**
* This class provides default implementation of MatchingRule. A
@@ -99,21 +98,13 @@
throws DecodeException
{
final ByteString assertionValue = normalizeAssertionValue(value);
- return new Assertion()
+ return new NotImplementedAssertion()
{
-
@Override
public ConditionResult matches(ByteSequence attributeValue)
{
return valuesMatch(attributeValue, assertionValue);
}
-
- @Override
- public <T> T createIndexQuery(IndexQueryFactory<T> factory)
- throws DecodeException
- {
- throw new RuntimeException("Not implemented");
- }
};
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java
new file mode 100644
index 0000000..f9451cf
--- /dev/null
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java
@@ -0,0 +1,57 @@
+/*
+ * 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 2014 ForgeRock AS
+ */
+package org.opends.server.api;
+
+import org.forgerock.opendj.ldap.Assertion;
+import org.forgerock.opendj.ldap.ByteSequence;
+import org.forgerock.opendj.ldap.ConditionResult;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
+
+/**
+ * Avoids repeating again and again the same code when
+ * Assertion.createIndexQuery() is not implemented.
+ * <p>
+ * To be removed once we switch the schema to the SDK.
+ */
+public class NotImplementedAssertion implements Assertion
+{
+
+ /** {@inheritDoc} */
+ @Override
+ public ConditionResult matches(ByteSequence normalizedAttributeValue)
+ {
+ throw new RuntimeException("Not implemented");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ throw new RuntimeException("Not implemented");
+ }
+
+}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
index 5e4bd99..fdf3ded 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
@@ -24,7 +24,9 @@
*/
package org.opends.server.schema;
+import org.forgerock.opendj.ldap.*;
import org.opends.server.api.AbstractMatchingRule;
+import org.opends.server.api.NotImplementedAssertion;
import org.opends.server.api.OrderingMatchingRule;
/**
@@ -50,4 +52,21 @@
return null;
}
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(final ByteSequence value)
+ throws DecodeException
+ {
+ final ByteString assertionValue = normalizeAssertionValue(value);
+ return new NotImplementedAssertion()
+ {
+ @Override
+ public ConditionResult matches(ByteSequence attributeValue)
+ {
+ return ConditionResult.valueOf(
+ compareValues(assertionValue, attributeValue) < 0);
+ }
+ };
+ }
+
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
index f1f2ec4..7eb2d85 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
@@ -33,6 +33,7 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
@@ -41,7 +42,6 @@
import org.opends.server.admin.std.meta.CollationMatchingRuleCfgDefn.MatchingRuleType;
import org.opends.server.admin.std.server.CollationMatchingRuleCfg;
import org.opends.server.api.*;
-import org.forgerock.opendj.config.server.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
@@ -369,8 +369,7 @@
// If it comes here we don't need to verify MatchingRuleType; it
// should be okay as its syntax is verified by the admin framework.
// Iterate over the collations and verify if the format is okay.
- // Also,
- // verify if the locale is allowed by the JVM.
+ // Also, verify if the locale is allowed by the JVM.
for (String collation : configuration.getCollation())
{
CollationMapper mapper = new CollationMapper(collation);
@@ -404,6 +403,18 @@
+ private Collection<String> copyNames(MatchingRule matchingRule)
+ {
+ Collection<String> defaultNames = new HashSet<String>();
+ if (matchingRule != null)
+ {
+ defaultNames.addAll(matchingRule.getNames());
+ }
+ return defaultNames;
+ }
+
+
+
/**
* Creates Less-than Matching Rule.
*
@@ -420,20 +431,11 @@
String oid = mapper.getNumericOID() + ".1";
String lTag = mapper.getLanguageTag();
- Collection<String> names = new HashSet<String>();
- MatchingRule matchingRule = getMatchingRule(oid);
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- names.add(name);
- }
- }
-
+ Collection<String> names = copyNames(getMatchingRule(oid));
names.add(lTag + ".lt");
names.add(lTag + ".1");
- matchingRule =
+ MatchingRule matchingRule =
new CollationLessThanMatchingRule(oid, names, locale);
addMatchingRule(oid, matchingRule);
}
@@ -456,20 +458,11 @@
String oid = mapper.getNumericOID() + ".2";
String lTag = mapper.getLanguageTag();
- Collection<String> names = new HashSet<String>();
- MatchingRule matchingRule = getMatchingRule(oid);
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- names.add(name);
- }
- }
-
+ Collection<String> names = copyNames(getMatchingRule(oid));
names.add(lTag + ".lte");
names.add(lTag + ".2");
- matchingRule =
+ MatchingRule matchingRule =
new CollationLessThanOrEqualToMatchingRule(oid, names, locale);
addMatchingRule(oid, matchingRule);
}
@@ -496,38 +489,19 @@
String lTag = mapper.getLanguageTag();
String nOID = mapper.getNumericOID();
- MatchingRule matchingRule = getMatchingRule(nOID);
- Collection<String> defaultNames = new HashSet<String>();
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- defaultNames.add(name);
- }
- }
-
+ Collection<String> defaultNames = copyNames(getMatchingRule(nOID));
defaultNames.add(lTag);
- matchingRule =
- new CollationEqualityMatchingRule(nOID,
- defaultNames, locale);
+ MatchingRule matchingRule =
+ new CollationEqualityMatchingRule(nOID, defaultNames, locale);
addMatchingRule(nOID, matchingRule);
- Collection<String> names = new HashSet<String>();
// Register OID.3 as the equality matching rule.
String OID = mapper.getNumericOID() + ".3";
- MatchingRule equalityMatchingRule = getMatchingRule(OID);
- if (equalityMatchingRule != null)
- {
- for (String name : equalityMatchingRule.getNames())
- {
- names.add(name);
- }
- }
-
+ Collection<String> names = copyNames(getMatchingRule(OID));
names.add(lTag + ".eq");
names.add(lTag + ".3");
- equalityMatchingRule =
+ MatchingRule equalityMatchingRule =
new CollationEqualityMatchingRule(OID, names, locale);
addMatchingRule(OID, equalityMatchingRule);
}
@@ -550,21 +524,12 @@
String oid = mapper.getNumericOID() + ".4";
String lTag = mapper.getLanguageTag();
- Collection<String> names = new HashSet<String>();
- MatchingRule matchingRule = getMatchingRule(oid);
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- names.add(name);
- }
- }
-
+ Collection<String> names = copyNames(getMatchingRule(oid));
names.add(lTag + ".gte");
names.add(lTag + ".4");
- matchingRule =
- new CollationGreaterThanOrEqualToMatchingRule(oid, names,
- locale);
+
+ MatchingRule matchingRule =
+ new CollationGreaterThanOrEqualToMatchingRule(oid, names, locale);
addMatchingRule(oid, matchingRule);
}
@@ -586,19 +551,11 @@
String oid = mapper.getNumericOID() + ".5";
String lTag = mapper.getLanguageTag();
- Collection<String> names = new HashSet<String>();
- MatchingRule matchingRule = getMatchingRule(oid);
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- names.add(name);
- }
- }
-
+ Collection<String> names = copyNames(getMatchingRule(oid));
names.add(lTag + ".gt");
names.add(lTag + ".5");
- matchingRule =
+
+ MatchingRule matchingRule =
new CollationGreaterThanMatchingRule(oid, names, locale);
addMatchingRule(oid, matchingRule);
}
@@ -621,18 +578,11 @@
String oid = mapper.getNumericOID() + ".6";
String lTag = mapper.getLanguageTag();
- Collection<String> names = new HashSet<String>();
- MatchingRule matchingRule = getMatchingRule(oid);
- if (matchingRule != null)
- {
- for (String name : matchingRule.getNames())
- {
- names.add(name);
- }
- }
+ Collection<String> names = copyNames(getMatchingRule(oid));
names.add(lTag + ".sub");
names.add(lTag + ".6");
- matchingRule =
+
+ MatchingRule matchingRule =
new CollationSubstringMatchingRule(oid, names, locale);
addMatchingRule(oid, matchingRule);
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
index 3451b06..87033b3 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
@@ -24,8 +24,6 @@
* Copyright 2009 Sun Microsystems, Inc.
* Portions Copyright 2011-2014 ForgeRock AS
*/
-
-
package org.opends.server.schema;
import java.nio.ByteBuffer;
@@ -33,6 +31,8 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
@@ -43,7 +43,6 @@
import org.forgerock.opendj.ldap.spi.IndexingOptions;
import org.opends.server.admin.std.server.MatchingRuleCfg;
import org.opends.server.api.*;
-import org.forgerock.opendj.config.server.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -56,8 +55,6 @@
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.TimeThread.*;
-
-
/**
* This class acts as a factory for time-based matching rules.
*/
@@ -67,27 +64,23 @@
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
- //Greater-than RelativeTimeMatchingRule.
+ /** Greater-than RelativeTimeMatchingRule. */
private MatchingRule greaterThanRTMRule;
-
- //Less-than RelativeTimeMatchingRule.
+ /** Less-than RelativeTimeMatchingRule. */
private MatchingRule lessThanRTMRule;
-
- //PartialDayAndTimeMatchingRule.
+ /** PartialDayAndTimeMatchingRule. */
private MatchingRule partialDTMatchingRule;
-
- //A Collection of matching rules managed by this factory.
+ /** A Collection of matching rules managed by this factory. */
private Set<MatchingRule> matchingRules;
-
private static final TimeZone TIME_ZONE_UTC_OBJ =
TimeZone.getTimeZone(TIME_ZONE_UTC);
- //Constants for generating keys.
+ /** Constants for generating keys. */
private static final char SECOND = 's';
private static final char MINUTE = 'm';
private static final char HOUR = 'h';
@@ -96,9 +89,7 @@
private static final char YEAR = 'Y';
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public void initializeMatchingRule(MatchingRuleCfg configuration)
throws ConfigException, InitializationException
@@ -114,9 +105,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<MatchingRule> getMatchingRules()
{
@@ -131,9 +120,7 @@
private abstract class TimeBasedMatchingRule extends AbstractMatchingRule
implements ExtensibleMatchingRule
{
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getDescription()
{
@@ -143,9 +130,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getSyntaxOID()
{
@@ -154,9 +139,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ByteString normalizeAttributeValue(ByteSequence value)
throws DecodeException
@@ -198,19 +181,17 @@
* This value was generated using the <CODE>serialver</CODE> command-line
* utility included with the Java SDK.
*/
- private static final long serialVersionUID = -3501812894473163490L;
+ private static final long serialVersionUID = -3501812894473163490L;
- /**
- * Indexer associated with this instance.
- */
- protected ExtensibleIndexer indexer;
+ /**
+ * Indexer associated with this instance.
+ */
+ protected ExtensibleIndexer indexer;
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ByteString normalizeAssertionValue(ByteSequence value)
throws DecodeException
@@ -257,55 +238,14 @@
long week = 0;
boolean containsTimeUnit = false;
- long number = 0;
+ int number = 0;
for(; index<value.length(); index++)
{
byte b = value.byteAt(index);
if(isDigit((char)b))
{
- switch (value.byteAt(index))
- {
- case '0':
- number = (number * 10);
- break;
-
- case '1':
- number = (number * 10) + 1;
- break;
-
- case '2':
- number = (number * 10) + 2;
- break;
-
- case '3':
- number = (number * 10) + 3;
- break;
-
- case '4':
- number = (number * 10) + 4;
- break;
-
- case '5':
- number = (number * 10) + 5;
- break;
-
- case '6':
- number = (number * 10) + 6;
- break;
-
- case '7':
- number = (number * 10) + 7;
- break;
-
- case '8':
- number = (number * 10) + 8;
- break;
-
- case '9':
- number = (number * 10) + 9;
- break;
- }
+ number = multiplyByTenThenAddUnits(number, b);
}
else
{
@@ -317,7 +257,7 @@
}
else
{
- switch(value.byteAt(index))
+ switch(b)
{
case 's':
second = number;
@@ -335,8 +275,7 @@
week = number;
break;
default:
- message = WARN_ATTR_INVALID_RELATIVE_TIME_ASSERTION_FORMAT.
- get(value,(char)value.byteAt(index));
+ message = WARN_ATTR_INVALID_RELATIVE_TIME_ASSERTION_FORMAT.get(value, (char) b);
}
}
if(message !=null)
@@ -345,11 +284,8 @@
logger.error(message);
throw DecodeException.error(message);
}
- else
- {
- containsTimeUnit = true;
- number = 0;
- }
+ containsTimeUnit = true;
+ number = 0;
}
}
@@ -362,15 +298,12 @@
long delta = (second + minute*60 + hour*3600 + day*24*3600 +
week*7*24*3600)*1000 ;
long now = getTime();
- return signed?ByteString.valueOf(now-delta):
- ByteString.valueOf(now+delta);
+ return ByteString.valueOf(signed ? now - delta : now + delta);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public int compareValues(ByteSequence value1, ByteSequence value2)
{
@@ -379,9 +312,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public int compare(byte[] arg0, byte[] arg1)
{
@@ -390,9 +321,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<ExtensibleIndexer> getIndexers(
IndexingOptions indexingOptions)
@@ -401,7 +330,7 @@
{
indexer = new RelativeTimeExtensibleIndexer(this);
}
- return Collections.singletonList(indexer);
+ return Collections.singletonList(indexer);
}
}
@@ -414,7 +343,7 @@
private final class RelativeTimeGTOrderingMatchingRule
extends RelativeTimeOrderingMatchingRule
{
- //All the names for this matching rule.
+ /** All the names for this matching rule. */
private final List<String> names;
@@ -436,9 +365,7 @@
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<String> getNames()
{
@@ -447,9 +374,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getOID()
{
@@ -458,9 +383,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ConditionResult valuesMatch(ByteSequence attributeValue,
ByteSequence assertionValue)
@@ -469,18 +392,37 @@
return ConditionResult.valueOf(ret > 0);
}
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(final ByteSequence value)
+ throws DecodeException
+ {
+ final ByteString assertionValue = normalizeAssertionValue(value);
+ return new Assertion()
+ {
+ @Override
+ public ConditionResult matches(ByteSequence attributeValue)
+ {
+ return valuesMatch(attributeValue, assertionValue);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ assertionValue, ByteString.empty(), false, false);
+ }
+ };
+ }
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public <T> T createIndexQuery(ByteSequence assertionValue,
IndexQueryFactory<T> factory) throws DecodeException
{
- return factory.createRangeMatchQuery(indexer
- .getExtensibleIndexID(), normalizeAssertionValue(assertionValue),
- ByteString.empty(), false, false);
+ return getAssertion(assertionValue).createIndexQuery(factory);
}
}
@@ -493,7 +435,7 @@
private final class RelativeTimeLTOrderingMatchingRule
extends RelativeTimeOrderingMatchingRule
{
- //All the names for this matching rule.
+ /** All the names for this matching rule. */
private final List<String> names;
@@ -516,9 +458,7 @@
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<String> getNames()
{
@@ -527,9 +467,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getOID()
{
@@ -538,9 +476,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ConditionResult valuesMatch(ByteSequence attributeValue,
ByteSequence assertionValue)
@@ -549,17 +485,36 @@
return ConditionResult.valueOf(ret < 0);
}
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(final ByteSequence value)
+ throws DecodeException
+ {
+ final ByteString assertionValue = normalizeAssertionValue(value);
+ return new Assertion()
+ {
+ @Override
+ public ConditionResult matches(ByteSequence attributeValue)
+ {
+ return valuesMatch(attributeValue, assertionValue);
+ }
- /**
- * {@inheritDoc}
- */
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ ByteString.empty(), assertionValue, false, false);
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
@Override
public <T> T createIndexQuery(ByteSequence assertionValue,
IndexQueryFactory<T> factory) throws DecodeException
{
- return factory.createRangeMatchQuery(indexer
- .getExtensibleIndexID(), ByteString.empty(),
- normalizeAssertionValue(assertionValue),false, false);
+ return getAssertion(assertionValue).createIndexQuery(factory);
}
}
@@ -594,9 +549,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getExtensibleIndexID()
{
@@ -605,9 +558,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public final void createKeys(Schema schema, ByteSequence value2,
IndexingOptions options, Collection<ByteString> keys)
@@ -632,16 +583,14 @@
private final class PartialDateAndTimeMatchingRule
extends TimeBasedMatchingRule
{
- /**
- * Indexer associated with this instance.
- */
- private ExtensibleIndexer indexer;
-
-
-
/**
- * {@inheritDoc}
+ * Indexer associated with this instance.
*/
+ private ExtensibleIndexer indexer;
+
+
+
+ /** {@inheritDoc} */
@Override
public String getOID()
{
@@ -650,9 +599,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<String> getNames()
{
@@ -661,9 +608,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public ByteString normalizeAssertionValue(ByteSequence value)
throws DecodeException
@@ -684,13 +629,15 @@
into a format to be recognized by the compare routine. The normalized
value is actually the format of : smhDMY.
*/
- int second = -1;
- int minute = -1;
- int hour = -1;
- int date = 0;
- int year = 0;
+ final int initDate = 0;
+ final int initVal = -1;
+ int second = initVal;
+ int minute = initVal;
+ int hour = initVal;
+ int date = initDate;
+ int month = initVal;
+ int year = initDate;
int number = 0;
- int month = -1;
int length = value.length();
for(int index=0; index<length; index++)
@@ -698,56 +645,15 @@
byte b = value.byteAt(index);
if(isDigit((char)b))
{
- switch (value.byteAt(index))
- {
- case '0':
- number = (number * 10);
- break;
-
- case '1':
- number = (number * 10) + 1;
- break;
-
- case '2':
- number = (number * 10) + 2;
- break;
-
- case '3':
- number = (number * 10) + 3;
- break;
-
- case '4':
- number = (number * 10) + 4;
- break;
-
- case '5':
- number = (number * 10) + 5;
- break;
-
- case '6':
- number = (number * 10) + 6;
- break;
-
- case '7':
- number = (number * 10) + 7;
- break;
-
- case '8':
- number = (number * 10) + 8;
- break;
-
- case '9':
- number = (number * 10) + 9;
- break;
- }
+ number = multiplyByTenThenAddUnits(number, b);
}
else
{
LocalizableMessage message = null;
- switch(value.byteAt(index))
+ switch(b)
{
case 's':
- if(second >0)
+ if (second != initVal)
{
message = WARN_ATTR_DUPLICATE_SECOND_ASSERTION_FORMAT.get(value, date);
}
@@ -757,7 +663,7 @@
}
break;
case 'm':
- if(minute >0)
+ if (minute != initVal)
{
message = WARN_ATTR_DUPLICATE_MINUTE_ASSERTION_FORMAT.get(value, date);
}
@@ -767,7 +673,7 @@
}
break;
case 'h':
- if(hour >0)
+ if (hour != initVal)
{
message = WARN_ATTR_DUPLICATE_HOUR_ASSERTION_FORMAT.get(value, date);
}
@@ -781,7 +687,7 @@
{
message = WARN_ATTR_INVALID_DATE_ASSERTION_FORMAT.get(value, number);
}
- else if(date > 0)
+ else if (date != initDate)
{
message = WARN_ATTR_DUPLICATE_DATE_ASSERTION_FORMAT.get(value, date);
}
@@ -791,11 +697,11 @@
}
break;
case 'M':
- if(number == 0)
+ if (number == 0)
{
message = WARN_ATTR_INVALID_MONTH_ASSERTION_FORMAT.get(value, number);
}
- else if(month > 0)
+ else if (month != initVal)
{
message = WARN_ATTR_DUPLICATE_MONTH_ASSERTION_FORMAT.get(value, month);
}
@@ -809,7 +715,7 @@
{
message = WARN_ATTR_INVALID_YEAR_ASSERTION_FORMAT.get(value, number);
}
- else if(year >0)
+ else if (year != initDate)
{
message = WARN_ATTR_DUPLICATE_YEAR_ASSERTION_FORMAT.get(value, year);
}
@@ -819,133 +725,45 @@
}
break;
default:
- message = WARN_ATTR_INVALID_PARTIAL_TIME_ASSERTION_FORMAT.
- get(value,(char)value.byteAt(index));
+ message = WARN_ATTR_INVALID_PARTIAL_TIME_ASSERTION_FORMAT.get(value, (char) b);
}
if(message !=null)
{
logger.error(message);
throw DecodeException.error(message);
}
- else
- {
- number = 0;
- }
+ number = 0;
}
}
+ month = toCalendarMonth(month, value);
+
//Validate year, month , date , hour, minute and second in that order.
- if(year < 0)
+ // -1 values are allowed when these values have not been provided
+ if (year < 0)
{
//A future date is allowed.
- LocalizableMessage message = WARN_ATTR_INVALID_YEAR_ASSERTION_FORMAT.get(value, year);
- logger.warn(message);
- throw DecodeException.error(message);
+ logAndThrow(WARN_ATTR_INVALID_YEAR_ASSERTION_FORMAT.get(value, year));
+ }
+ if (isDateInvalid(date, month, year))
+ {
+ logAndThrow(WARN_ATTR_INVALID_DATE_ASSERTION_FORMAT.get(value, date));
+ }
+ if (hour < initVal || hour > 23)
+ {
+ logAndThrow(WARN_ATTR_INVALID_HOUR_ASSERTION_FORMAT.get(value, hour));
+ }
+ if (minute < initVal || minute > 59)
+ {
+ logAndThrow(WARN_ATTR_INVALID_MINUTE_ASSERTION_FORMAT.get(value, minute));
+ }
+ if (second < initVal || second > 60) // Consider leap seconds.
+ {
+ logAndThrow(WARN_ATTR_INVALID_SECOND_ASSERTION_FORMAT.get(value, second));
}
- switch(month)
- {
- case -1:
- //just allow this.
- break;
- case 1:
- month = Calendar.JANUARY;
- break;
- case 2:
- month = Calendar.FEBRUARY;
- break;
- case 3:
- month = Calendar.MARCH;
- break;
- case 4:
- month = Calendar.APRIL;
- break;
- case 5:
- month = Calendar.MAY;
- break;
- case 6:
- month = Calendar.JUNE;
- break;
- case 7:
- month = Calendar.JULY;
- break;
- case 8:
- month = Calendar.AUGUST;
- break;
- case 9:
- month = Calendar.SEPTEMBER;
- break;
- case 10:
- month = Calendar.OCTOBER;
- break;
- case 11:
- month = Calendar.NOVEMBER;
- break;
- case 12:
- month = Calendar.DECEMBER;
- break;
- default:
- LocalizableMessage message = WARN_ATTR_INVALID_MONTH_ASSERTION_FORMAT.get(value, month);
- logger.warn(message);
- throw DecodeException.error(message);
- }
-
- boolean invalidDate = false;
- switch(date)
- {
- case 29:
- if(month == Calendar.FEBRUARY && year%4 !=0)
- {
- invalidDate = true;
- }
- break;
- case 31:
- if(month != -1 && month != Calendar.JANUARY && month!= Calendar.MARCH
- && month != Calendar.MAY && month != Calendar.JULY
- && month != Calendar.AUGUST && month != Calendar.OCTOBER
- && month != Calendar.DECEMBER)
- {
- invalidDate = true;
- }
- break;
- default:
- if(!(date >=0 && date <=31))
- {
- invalidDate = true;
- }
- }
- if(invalidDate)
- {
- LocalizableMessage message = WARN_ATTR_INVALID_DATE_ASSERTION_FORMAT.get(value, date);
- logger.warn(message);
- throw DecodeException.error(message);
- }
-
- if(!(hour >=-1 && hour <=23))
- {
- LocalizableMessage message = WARN_ATTR_INVALID_HOUR_ASSERTION_FORMAT.get(value, date);
- logger.warn(message);
- throw DecodeException.error(message);
- }
-
- if(!(minute >=-1 && minute <=59))
- {
- LocalizableMessage message = WARN_ATTR_INVALID_MINUTE_ASSERTION_FORMAT.get(value, date);
- logger.warn(message);
- throw DecodeException.error(message);
- }
-
- if(!(second >=-1 && second <=60)) //Consider leap seconds.
- {
- LocalizableMessage message = WARN_ATTR_INVALID_SECOND_ASSERTION_FORMAT.get(value, date);
- logger.warn(message);
- throw DecodeException.error(message);
- }
-
- /**
- * Since we reached here we have a valid assertion value. Construct
- * a normalized value in the order: SECOND MINUTE HOUR DATE MONTH YEAR.
- */
+ // Since we reached here we have a valid assertion value.
+ // Construct a normalized value in the order: SECOND MINUTE HOUR DATE MONTH YEAR.
ByteBuffer bb = ByteBuffer.allocate(6*4);
bb.putInt(second);
bb.putInt(minute);
@@ -956,20 +774,90 @@
return ByteString.wrap(bb.array());
}
+ private void logAndThrow(LocalizableMessage message) throws DecodeException
+ {
+ logger.warn(message);
+ throw DecodeException.error(message);
+ }
+ private boolean isDateInvalid(int date, int month, int year)
+ {
+ switch (date)
+ {
+ case 29:
+ return month == Calendar.FEBRUARY && !isLeapYear(year);
+ case 30:
+ return month == Calendar.FEBRUARY;
+ case 31:
+ return month != -1 && month != Calendar.JANUARY
+ && month != Calendar.MARCH && month != Calendar.MAY
+ && month != Calendar.JULY && month != Calendar.AUGUST
+ && month != Calendar.OCTOBER && month != Calendar.DECEMBER;
+ default:
+ return date < 0 || date > 31;
+ }
+ }
- /**
- * {@inheritDoc}
- */
+ private boolean isLeapYear(int year)
+ {
+ if (year % 400 == 0)
+ {
+ return true;
+ }
+ if (year % 100 == 0)
+ {
+ return false;
+ }
+ return year % 4 == 0;
+ }
+
+ private int toCalendarMonth(int month, ByteSequence value) throws DecodeException
+ {
+ switch (month)
+ {
+ case -1:
+ // just allow this.
+ return -1;
+ case 1:
+ return Calendar.JANUARY;
+ case 2:
+ return Calendar.FEBRUARY;
+ case 3:
+ return Calendar.MARCH;
+ case 4:
+ return Calendar.APRIL;
+ case 5:
+ return Calendar.MAY;
+ case 6:
+ return Calendar.JUNE;
+ case 7:
+ return Calendar.JULY;
+ case 8:
+ return Calendar.AUGUST;
+ case 9:
+ return Calendar.SEPTEMBER;
+ case 10:
+ return Calendar.OCTOBER;
+ case 11:
+ return Calendar.NOVEMBER;
+ case 12:
+ return Calendar.DECEMBER;
+ default:
+ LocalizableMessage message = WARN_ATTR_INVALID_MONTH_ASSERTION_FORMAT.get(value, month);
+ logger.warn(message);
+ throw DecodeException.error(message);
+ }
+ }
+
+ /** {@inheritDoc} */
@Override
public ConditionResult valuesMatch(ByteSequence attributeValue,
ByteSequence assertionValue)
{
- long timeInMS = ((ByteString)attributeValue).toLong();
- //Build the information from the attribute value.
+ // Build the information from the attribute value.
GregorianCalendar cal = new GregorianCalendar(TIME_ZONE_UTC_OBJ);
cal.setLenient(false);
- cal.setTimeInMillis(timeInMS);
+ cal.setTimeInMillis(((ByteString) attributeValue).toLong());
int second = cal.get(Calendar.SECOND);
int minute = cal.get(Calendar.MINUTE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
@@ -977,7 +865,6 @@
int month = cal.get(Calendar.MONTH);
int year = cal.get(Calendar.YEAR);
-
//Build the information from the assertion value.
ByteBuffer bb = ByteBuffer.wrap(assertionValue.toByteArray());
int assertSecond = bb.getInt(0);
@@ -987,10 +874,10 @@
int assertMonth = bb.getInt(16);
int assertYear = bb.getInt(20);
+ // All the non-zero and non -1 values should match.
if ((assertSecond != -1 && assertSecond != second)
|| (assertMinute != -1 && assertMinute != minute)
|| (assertHour != -1 && assertHour != hour)
- // All the non-zero values should match.
|| (assertDate != 0 && assertDate != date)
|| (assertMonth != -1 && assertMonth != month)
|| (assertYear != 0 && assertYear != year))
@@ -1002,9 +889,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public Collection<ExtensibleIndexer> getIndexers(
IndexingOptions indexingOptions)
@@ -1018,9 +903,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public <T> T createIndexQuery(ByteSequence assertionValue,
IndexQueryFactory<T> factory) throws DecodeException
@@ -1035,52 +918,41 @@
int assertDate = bb.getInt(12);
int assertMonth = bb.getInt(16);
int assertYear = bb.getInt(20);
- List<T> queries = new ArrayList<T>();
+ List<T> queries = new ArrayList<T>();
if(assertSecond >= 0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertSecond,SECOND)));
+ queries.add(createExactMatchQuery(factory, assertSecond, SECOND));
}
-
if(assertMinute >=0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertMinute,MINUTE)));
+ queries.add(createExactMatchQuery(factory, assertMinute, MINUTE));
}
-
if(assertHour >=0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertHour,HOUR)));
+ queries.add(createExactMatchQuery(factory, assertHour, HOUR));
}
-
if(assertDate >0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertDate,DATE)));
+ queries.add(createExactMatchQuery(factory, assertDate, DATE));
}
-
if(assertMonth >=0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertMonth,MONTH)));
+ queries.add(createExactMatchQuery(factory, assertMonth, MONTH));
}
-
if(assertYear > 0)
{
- queries.add(factory.createExactMatchQuery(
- indexer.getExtensibleIndexID(),
- getKey(assertYear,YEAR)));
+ queries.add(createExactMatchQuery(factory, assertYear, YEAR));
}
return factory.createIntersectionQuery(queries);
}
+ private <T> T createExactMatchQuery(IndexQueryFactory<T> factory,
+ int assertionValue, char type)
+ {
+ return factory.createExactMatchQuery(
+ indexer.getExtensibleIndexID(), getKey(assertionValue, type));
+ }
/**
@@ -1135,6 +1007,33 @@
}
}
+ private int multiplyByTenThenAddUnits(int number, byte b)
+ {
+ switch (b)
+ {
+ case '0':
+ return number * 10;
+ case '1':
+ return number * 10 + 1;
+ case '2':
+ return number * 10 + 2;
+ case '3':
+ return number * 10 + 3;
+ case '4':
+ return number * 10 + 4;
+ case '5':
+ return number * 10 + 5;
+ case '6':
+ return number * 10 + 6;
+ case '7':
+ return number * 10 + 7;
+ case '8':
+ return number * 10 + 8;
+ case '9':
+ return number * 10 + 9;
+ }
+ return number;
+ }
/**
@@ -1143,7 +1042,7 @@
private final class PartialDateAndTimeExtensibleIndexer extends
ExtensibleIndexer
{
- // The partial date and Time matching Rule.
+ /** The partial date and Time matching Rule. */
private final PartialDateAndTimeMatchingRule matchingRule;
@@ -1162,9 +1061,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public void createKeys(Schema schema, ByteSequence value,
IndexingOptions options, Collection<ByteString> keys)
@@ -1181,9 +1078,7 @@
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public String getExtensibleIndexID()
{
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactoryTest.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactoryTest.java
new file mode 100644
index 0000000..b68e5a7
--- /dev/null
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactoryTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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 2014 ForgeRock AS
+ */
+package org.opends.server.schema;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import org.forgerock.opendj.ldap.Assertion;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.ConditionResult;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.opends.server.admin.std.server.CollationMatchingRuleCfg;
+import org.opends.server.admin.std.server.MatchingRuleCfg;
+import org.opends.server.api.MatchingRule;
+import org.opends.server.util.TimeThread;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@SuppressWarnings("javadoc")
+public class TimeBasedMatchingRuleFactoryTest extends SchemaTestCase
+{
+
+ private static final String LESS_THAN_RELATIVE_TIME = "relativeTimeLTOrderingMatch";
+ private static final String GREATER_THAN_RELATIVE_TIME = "relativeTimeGTOrderingMatch";
+ private static final String PARTIAL_DATE_AND_TIME = "partialDateAndTimeMatchingRule";
+
+ @DataProvider
+ public Iterator<Object[]> validAssertionValuesDataProvider()
+ {
+ final SimpleDateFormat generalizedTimeFormatter = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+ final Calendar cal = TimeThread.getCalendar();
+ final Date nowDate = cal.getTime();
+ final String nowGT = generalizedTimeFormatter.format(nowDate);
+ cal.add(Calendar.MONTH, 1);
+ final Date oneMonthAheadDate = cal.getTime();
+ final String oneMonthAheadGT = generalizedTimeFormatter.format(oneMonthAheadDate);
+
+ final Collection<Object[]> results = new LinkedList<Object[]>(Arrays.asList(new Object[][] {
+ { LESS_THAN_RELATIVE_TIME, /* now + */"1"/* s */, oneMonthAheadGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now + */"1"/* s */, oneMonthAheadGT, ConditionResult.TRUE },
+ { LESS_THAN_RELATIVE_TIME, /* now */"+1s", oneMonthAheadGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now */"+1s", oneMonthAheadGT, ConditionResult.TRUE },
+ { LESS_THAN_RELATIVE_TIME, /* now */"+1m", oneMonthAheadGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now */"+1m", oneMonthAheadGT, ConditionResult.TRUE },
+ { LESS_THAN_RELATIVE_TIME, /* now */"+1h", oneMonthAheadGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now */"+1h", oneMonthAheadGT, ConditionResult.TRUE },
+ { LESS_THAN_RELATIVE_TIME, /* now */"-30d", nowGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now */"-30d", nowGT, ConditionResult.TRUE },
+ { LESS_THAN_RELATIVE_TIME, /* now */"-30w", nowGT, ConditionResult.FALSE },
+ { GREATER_THAN_RELATIVE_TIME, /* now */"-30w", nowGT, ConditionResult.TRUE },
+ // 29th of months and leap years
+ { PARTIAL_DATE_AND_TIME, "2012Y03M29D", "20120329120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y02M29D", "20120229120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2000Y02M29D", "20000229120000Z", ConditionResult.TRUE },
+ // Generalized time implementation does not allow leap seconds
+ // because Java does not support them. Apparently, it never will support them:
+ // @see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4272347
+ // leap seconds are allowed, even though no formula exists to validate them
+ { PARTIAL_DATE_AND_TIME, "2012Y06M30D23h59m60s", "20120630235959Z", ConditionResult.FALSE },
+ // no match
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20111231235930Z", ConditionResult.FALSE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20121031235930Z", ConditionResult.FALSE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20121230235930Z", ConditionResult.FALSE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20121231225930Z", ConditionResult.FALSE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20121231235830Z", ConditionResult.FALSE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D23h59m30s", "20121231235829Z", ConditionResult.FALSE },
+ // 30th of months
+ { PARTIAL_DATE_AND_TIME, "1982Y09M30D", "19820930120000Z", ConditionResult.TRUE },
+ // 31st of months
+ { PARTIAL_DATE_AND_TIME, "2012Y01M31D", "20120131120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y03M31D", "20120331120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y05M31D", "20120531120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y07M31D", "20120731120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y08M31D", "20120831120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y10M31D", "20121031120000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M31D", "20121231120000Z", ConditionResult.TRUE },
+ // Only single time units
+ { PARTIAL_DATE_AND_TIME, "2012Y", "20121231123000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12M", "20121231123000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y31D", "20121231123000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y12h", "20121231123000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y30m", "20121231123000Z", ConditionResult.TRUE },
+ { PARTIAL_DATE_AND_TIME, "2012Y0s", "20121231123000Z", ConditionResult.TRUE },
+ }));
+ addPartialDateAndTimeData(results, nowDate, oneMonthAheadDate);
+ return results.iterator();
+ }
+
+ private void addPartialDateAndTimeData(Collection<Object[]> results, Date... dates)
+ {
+ final SimpleDateFormat ptFormatterUpToSeconds = new SimpleDateFormat("yyyy'Y'MM'M'dd'D'HH'h'mm'm'ss's'");
+ final SimpleDateFormat ptFormatterUpToMinutes = new SimpleDateFormat("yyyy'Y'MM'M'dd'D'HH'h'mm'm'");
+ final SimpleDateFormat ptFormatterUpToHours = new SimpleDateFormat("yyyy'Y'MM'M'dd'D'HH'h'");
+ final SimpleDateFormat gtFormatterUpToSeconds = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+ final SimpleDateFormat gtFormatterUpToMinutes = new SimpleDateFormat("yyyyMMddHHmm'Z'");
+ final SimpleDateFormat gtFormatterUpToHours = new SimpleDateFormat("yyyyMMddHH'Z'");
+
+ for (Date date : dates)
+ {
+ String ptUpToSeconds = ptFormatterUpToSeconds.format(date);
+ String gtUpToSeconds = gtFormatterUpToSeconds.format(date);
+ results.add(new Object[] { PARTIAL_DATE_AND_TIME, ptUpToSeconds, gtUpToSeconds, ConditionResult.TRUE });
+ String ptUpToMinutes = ptFormatterUpToMinutes.format(date);
+ String gtUpToMinutes = gtFormatterUpToMinutes.format(date);
+ results.add(new Object[] { PARTIAL_DATE_AND_TIME, ptUpToMinutes, gtUpToMinutes, ConditionResult.TRUE });
+ String ptUpToHours = ptFormatterUpToHours.format(date);
+ String gtUpToHours = gtFormatterUpToHours.format(date);
+ results.add(new Object[] { PARTIAL_DATE_AND_TIME, ptUpToHours, gtUpToHours, ConditionResult.TRUE });
+ }
+ }
+
+ @DataProvider
+ public Object[][] invalidAssertionValuesDataProvider()
+ {
+ final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHH");
+ final Calendar cal = TimeThread.getCalendar();
+ final String now = dateFormatter.format(cal.getTime()) + "Z";
+
+ return new Object[][] {
+ // { LESS_THAN_RELATIVE_TIME, "", now, null },
+ { LESS_THAN_RELATIVE_TIME, "bla", now, null },
+ { LESS_THAN_RELATIVE_TIME, /* now */"-30b", now, null },
+ { LESS_THAN_RELATIVE_TIME, /* now */"-30ms", now, null },
+
+ // { PARTIAL_DATE_AND_TIME, "", now, null },
+ { PARTIAL_DATE_AND_TIME, "bla", now, null },
+ // invalid time unit values
+ { PARTIAL_DATE_AND_TIME, "-1Y03M11D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "0Y03M11D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y-1M11D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y0M11D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y13M11D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M-1D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M0D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y13M32D12h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D-1h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D24h48m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h-1m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h60m32s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h48m-1s", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h48m61s", now, null },
+ // duplicate each time unit
+ { PARTIAL_DATE_AND_TIME, "1Y2014Y03M11D12h", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y1M03M11D12h", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M1D11D12h", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D1h12h", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h1m48m", now, null },
+ { PARTIAL_DATE_AND_TIME, "2014Y03M11D12h48m1s32s", now, null },
+ // February and non leap years
+ { PARTIAL_DATE_AND_TIME, "2014Y02M29D", now, null },
+ { PARTIAL_DATE_AND_TIME, "1800Y02M29D", now, null },
+ { PARTIAL_DATE_AND_TIME, "2000Y02M30D", now, null },
+ { PARTIAL_DATE_AND_TIME, "2000Y02M31D", now, null },
+ // 31st of months
+ { PARTIAL_DATE_AND_TIME, "2012Y04M31D", now, null },
+ { PARTIAL_DATE_AND_TIME, "2012Y06M31D", now, null },
+ { PARTIAL_DATE_AND_TIME, "2012Y09M31D", now, null },
+ { PARTIAL_DATE_AND_TIME, "2012Y11M31D", now, null },
+ };
+ }
+
+ @Test(dataProvider = "validAssertionValuesDataProvider")
+ public void testValidAssertionValues(String matchingRuleName,
+ String assertionValue, String attributeValue,
+ ConditionResult expectedResult) throws Exception
+ {
+ final MatchingRule rule = getMatchingRule(matchingRuleName);
+
+ Assertion assertion = rule.getAssertion(ByteString.valueOf(assertionValue));
+ ByteString normalizedAttributeValue =
+ rule.normalizeAttributeValue(ByteString.valueOf(attributeValue));
+ assertThat(assertion.matches(normalizedAttributeValue)).isEqualTo(expectedResult);
+ }
+
+ @Test(dataProvider = "invalidAssertionValuesDataProvider",
+ expectedExceptions = DecodeException.class)
+ public void testInvalidAssertionValues(String matchingRuleName,
+ String assertionValue, String attributeValue,
+ ConditionResult expectedResult) throws Exception
+ {
+ testValidAssertionValues(matchingRuleName, assertionValue, attributeValue, expectedResult);
+ }
+
+ private MatchingRule getMatchingRule(String matchingRuleName) throws Exception
+ {
+ final Collection<MatchingRule> mRules = getMatchingRules();
+ assertThat(mRules).hasSize(3);
+ for (MatchingRule mRule : mRules)
+ {
+ if (mRule.getNameOrOID().equals(matchingRuleName))
+ {
+ return mRule;
+ }
+ }
+ fail("Could not find a matching rule named '" + matchingRuleName + "'");
+ return null;
+ }
+
+ private Collection<MatchingRule> getMatchingRules() throws Exception
+ {
+ final TimeBasedMatchingRuleFactory factory =
+ new TimeBasedMatchingRuleFactory();
+ final MatchingRuleCfg cfg = mock(CollationMatchingRuleCfg.class);
+ factory.initializeMatchingRule(cfg);
+ final Collection<MatchingRule> mRules = factory.getMatchingRules();
+ verifyNoMoreInteractions(cfg);
+ return mRules;
+ }
+}
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleTest.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleTest.java
index fec76c3..af1633b 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleTest.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/schema/TimeBasedMatchingRuleTest.java
@@ -31,6 +31,7 @@
import java.util.List;
import java.util.TimeZone;
+import org.assertj.core.api.Assertions;
import org.forgerock.opendj.ldap.*;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.MatchingRule;
@@ -107,7 +108,7 @@
"objectclasses: ( testoc-oid NAME 'testOC' SUP top AUXILIARY MUST test-time)",
"objectclasses: ( testoc2-oid NAME 'testOC2' SUP top AUXILIARY MUST test-date)"
);
- assertTrue(resultCode == 0);
+ assertEquals(0, resultCode);
}
@@ -222,7 +223,8 @@
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- assertTrue(entries.size()==3 && dnFoundInEntryList(entries,user3,user4,user5));
+ Assertions.assertThat(entries).hasSize(3);
+ assertTrue(dnFoundInEntryList(entries, user3, user4, user5));
}
finally
{
@@ -479,30 +481,27 @@
};
}
-
-
-//validate if the args are found in the entries list.
- private boolean dnFoundInEntryList( List<SearchResultEntry> entries,DN ... dns)
+ // validate if the args are found in the entries list.
+ private boolean dnFoundInEntryList(List<SearchResultEntry> entries, DN... dns)
{
- for(DN dn: dns)
+ for (DN dn : dns)
{
- boolean found = false;
- for(SearchResultEntry entry: entries)
- {
- System.out.println("dn from the current entry is " + entry.getName());
- if(entry.getName().equals(dn))
- {
- found = true;
- }
- }
- if(!found)
- {
- return false;
- }
+ assertTrue(find(entries, dn), "Could not find dn " + dn + " in list " + entries);
}
return true;
}
+ private boolean find(List<SearchResultEntry> entries, DN dn)
+ {
+ for (SearchResultEntry entry : entries)
+ {
+ if (entry.getName().equals(dn))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
//Creates the entries.
private void populateEntries() throws Exception
--
Gitblit v1.10.0