From 4cb8262e95fde77e6a0d2c84f1aa118e3b1ee850 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 06 Nov 2014 14:50:48 +0000
Subject: [PATCH] OPENDJ-1591 CR-5092 Switch server to SDK matching rules
---
opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java | 1043 ---------------------------------------------------------
1 files changed, 8 insertions(+), 1,035 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java b/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
index 4fe25be..c712214 100644
--- a/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
+++ b/opendj3-server-dev/src/server/org/opends/server/schema/TimeBasedMatchingRuleFactory.java
@@ -26,47 +26,17 @@
*/
package org.opends.server.schema;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
-import java.util.GregorianCalendar;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
-import java.util.TimeZone;
-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;
-import org.forgerock.opendj.ldap.ConditionResult;
-import org.forgerock.opendj.ldap.DecodeException;
-import org.forgerock.opendj.ldap.schema.Schema;
-import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
-import org.forgerock.opendj.ldap.spi.IndexingOptions;
+import org.forgerock.opendj.ldap.schema.CoreSchema;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.opends.server.admin.std.server.MatchingRuleCfg;
-import org.opends.server.api.AbstractMatchingRule;
-import org.opends.server.api.ExtensibleIndexer;
-import org.opends.server.api.ExtensibleMatchingRule;
-import org.opends.server.api.MatchingRule;
import org.opends.server.api.MatchingRuleFactory;
-import org.opends.server.api.OrderingMatchingRule;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
-import org.opends.server.util.StaticUtils;
-
-import static org.opends.messages.SchemaMessages.*;
-import static org.opends.server.schema.GeneralizedTimeSyntax.*;
-import static org.opends.server.schema.SchemaConstants.*;
-import static org.opends.server.util.ServerConstants.*;
-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.
@@ -75,49 +45,23 @@
extends MatchingRuleFactory<MatchingRuleCfg>
{
- private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
-
- /** Greater-than RelativeTimeMatchingRule. */
- private MatchingRule greaterThanRTMRule;
-
- /** Less-than RelativeTimeMatchingRule. */
- private MatchingRule lessThanRTMRule;
-
- /** PartialDayAndTimeMatchingRule. */
- private MatchingRule partialDTMatchingRule;
-
/** 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. */
- private static final char SECOND = 's';
- private static final char MINUTE = 'm';
- private static final char HOUR = 'h';
- private static final char MONTH = 'M';
- private static final char DATE = 'D';
- private static final char YEAR = 'Y';
-
-
/** {@inheritDoc} */
@Override
public void initializeMatchingRule(MatchingRuleCfg configuration)
throws ConfigException, InitializationException
{
matchingRules = new HashSet<MatchingRule>();
- greaterThanRTMRule = new RelativeTimeGTOrderingMatchingRule();
- matchingRules.add(greaterThanRTMRule);
- lessThanRTMRule = new RelativeTimeLTOrderingMatchingRule();
- matchingRules.add(lessThanRTMRule);
- partialDTMatchingRule = new PartialDateAndTimeMatchingRule();
- matchingRules.add(partialDTMatchingRule);
+ // relative time greater than
+ matchingRules.add(CoreSchema.getInstance().getMatchingRule("1.3.6.1.4.1.26027.1.4.5"));
+ // relative time less than
+ matchingRules.add(CoreSchema.getInstance().getMatchingRule("1.3.6.1.4.1.26027.1.4.6"));
+ // partial date and time
+ matchingRules.add(CoreSchema.getInstance().getMatchingRule("1.3.6.1.4.1.26027.1.4.7"));
}
-
-
/** {@inheritDoc} */
@Override
public Collection<MatchingRule> getMatchingRules()
@@ -125,975 +69,4 @@
return Collections.unmodifiableCollection(matchingRules);
}
-
-
- /**
- * This class defines a matching rule which is used for time-based searches.
- */
- private abstract class TimeBasedMatchingRule extends AbstractMatchingRule
- implements ExtensibleMatchingRule
- {
- /** {@inheritDoc} */
- @Override
- public String getDescription()
- {
- //There is no standard definition.
- return null;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_GENERALIZED_TIME_OID;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public ByteString normalizeAttributeValue(ByteSequence value)
- throws DecodeException
- {
- try
- {
- long timestamp = decodeGeneralizedTimeValue(value);
- return ByteString.valueOf(timestamp);
- }
- catch (DirectoryException de)
- {
- switch (DirectoryServer.getSyntaxEnforcementPolicy())
- {
- case REJECT:
- throw DecodeException.error(de.getMessageObject(), de);
-
- case WARN:
- logger.error(de.getMessageObject());
- break;
- }
- return value.toByteString();
- }
- }
- }
-
-
-
- /**
- * This class defines a matching rule which matches the relative time for
- * time-based searches.
- */
- private abstract class RelativeTimeOrderingMatchingRule
- extends TimeBasedMatchingRule
- implements OrderingMatchingRule
- {
- /**
- * The serial version identifier required to satisfy the compiler because
- * this class implements the <CODE>java.io.Serializable</CODE> interface.
- * This value was generated using the <CODE>serialver</CODE> command-line
- * utility included with the Java SDK.
- */
- private static final long serialVersionUID = -3501812894473163490L;
-
-
-
- /**
- * Indexer associated with this instance.
- */
- protected ExtensibleIndexer indexer;
-
-
- /** {@inheritDoc} */
- @Override
- public ByteString normalizeAssertionValue(ByteSequence value)
- throws DecodeException
- {
- /**
- An assertion value may contain one of the following:
- s = second
- m = minute
- h = hour
- d = day
- w = week
-
- An example assertion is OID:=(-)1d, where a '-' means that the user
- intends to search only the expired events. In this example we are
- searching for an event expired 1 day back.
-
- Use this method to parse, validate and normalize the assertion value
- into a format to be recognized by the valuesMatch routine. This method
- takes the assertion value, adds/substracts it to/from the current time
- and calculates a time which will be used as a relative time by inherited
- rules.
- */
-
- int index = 0;
- boolean signed = false;
- byte firstByte = value.byteAt(0);
-
- if(firstByte == '-')
- {
- //Turn the sign on to go back in past.
- signed = true;
- index = 1;
- }
- else if(firstByte == '+')
- {
- //'+" is not required but we won't reject it either.
- index = 1;
- }
-
- long second = 0;
- long minute = 0;
- long hour = 0;
- long day = 0;
- long week = 0;
-
- boolean containsTimeUnit = false;
- int number = 0;
-
- for(; index<value.length(); index++)
- {
- byte b = value.byteAt(index);
- if(isDigit((char)b))
- {
- number = multiplyByTenThenAddUnits(number, b);
- }
- else
- {
- LocalizableMessage message = null;
- if(containsTimeUnit)
- {
- //We already have time unit found by now.
- message = WARN_ATTR_CONFLICTING_ASSERTION_FORMAT.get(value);
- }
- else
- {
- switch(b)
- {
- case 's':
- second = number;
- break;
- case 'm':
- minute = number;
- break;
- case 'h':
- hour = number;
- break;
- case 'd':
- day = number;
- break;
- case 'w':
- week = number;
- break;
- default:
- message = WARN_ATTR_INVALID_RELATIVE_TIME_ASSERTION_FORMAT.get(value, (char) b);
- }
- }
- if(message !=null)
- {
- //Log the message and throw an exception.
- logger.error(message);
- throw DecodeException.error(message);
- }
- containsTimeUnit = true;
- number = 0;
- }
- }
-
- if(!containsTimeUnit)
- {
- //There was no time unit so assume it is seconds.
- second = number;
- }
-
- long delta = (second + minute*60 + hour*3600 + day*24*3600 +
- week*7*24*3600)*1000 ;
- long now = getTime();
- return ByteString.valueOf(signed ? now - delta : now + delta);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public int compareValues(ByteSequence value1, ByteSequence value2)
- {
- return value1.compareTo(value2);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public int compare(byte[] arg0, byte[] arg1)
- {
- return StaticUtils.compare(arg0, arg1);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public Collection<ExtensibleIndexer> getIndexers()
- {
- if(indexer == null)
- {
- indexer = new RelativeTimeExtensibleIndexer(this);
- }
- return Collections.singletonList(indexer);
- }
- }
-
-
-
- /**
- * This class defines a matching rule which calculates the "greater-than"
- * relative time for time-based searches.
- */
- private final class RelativeTimeGTOrderingMatchingRule
- extends RelativeTimeOrderingMatchingRule
- {
- /** All the names for this matching rule. */
- private final List<String> names;
-
-
-
- /**
- * The serial version identifier required to satisfy the compiler because
- * this class implements the <CODE>java.io.Serializable</CODE> interface.
- * This value was generated using the <CODE>serialver</CODE> command-line
- * utility included with the Java SDK.
- */
- private static final long serialVersionUID = 7247241496402474136L;
-
-
- RelativeTimeGTOrderingMatchingRule()
- {
- names = new ArrayList<String>();
- names.add(EXT_OMR_RELATIVE_TIME_GT_NAME);
- names.add(EXT_OMR_RELATIVE_TIME_GT_ALT_NAME);
- }
-
-
- /** {@inheritDoc} */
- @Override
- public Collection<String> getNames()
- {
- return Collections.unmodifiableList(names);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getOID()
- {
- return EXT_OMR_RELATIVE_TIME_GT_OID;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public ConditionResult valuesMatch(ByteSequence attributeValue,
- ByteSequence assertionValue)
- {
- int ret = compareValues(attributeValue, assertionValue);
- 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} */
- @Override
- public <T> T createIndexQuery(ByteSequence assertionValue,
- IndexQueryFactory<T> factory) throws DecodeException
- {
- return getAssertion(assertionValue).createIndexQuery(factory);
- }
- }
-
-
-
- /**
- * This class defines a matching rule which calculates the "less-than"
- * relative time for time-based searches.
- */
- private final class RelativeTimeLTOrderingMatchingRule
- extends RelativeTimeOrderingMatchingRule
- {
- /** All the names for this matching rule. */
- private final List<String> names;
-
-
-
- /**
- * The serial version identifier required to satisfy the compiler because
- * this class implements the <CODE>java.io.Serializable</CODE> interface.
- * This value was generated using the <CODE>serialver</CODE> command-line
- * utility included with the Java SDK.
- */
- private static final long serialVersionUID = -5122459830973558441L;
-
-
-
- RelativeTimeLTOrderingMatchingRule()
- {
- names = new ArrayList<String>();
- names.add(EXT_OMR_RELATIVE_TIME_LT_NAME);
- names.add(EXT_OMR_RELATIVE_TIME_LT_ALT_NAME);
- }
-
-
- /** {@inheritDoc} */
- @Override
- public Collection<String> getNames()
- {
- return Collections.unmodifiableList(names);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getOID()
- {
- return EXT_OMR_RELATIVE_TIME_LT_OID;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public ConditionResult valuesMatch(ByteSequence attributeValue,
- ByteSequence assertionValue)
- {
- int ret = compareValues(attributeValue, assertionValue);
- 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(),
- ByteString.empty(), assertionValue, false, false);
- }
- };
- }
-
- /** {@inheritDoc} */
- @Override
- public <T> T createIndexQuery(ByteSequence assertionValue,
- IndexQueryFactory<T> factory) throws DecodeException
- {
- return getAssertion(assertionValue).createIndexQuery(factory);
- }
- }
-
-
-
- /**
- * Extensible Indexer class for Relative Time Matching rules which share
- * the same index. This Indexer is shared by both greater than and less than
- * Relative Time Matching Rules.
- */
- private final class RelativeTimeExtensibleIndexer extends
- ExtensibleIndexer
- {
-
- /**
- * The Extensible Matching Rule.
- */
- private final RelativeTimeOrderingMatchingRule matchingRule;
-
-
-
- /**
- * Creates a new instance of RelativeTimeExtensibleIndexer.
- *
- * @param matchingRule The relative time Matching Rule.
- */
- private RelativeTimeExtensibleIndexer(
- RelativeTimeOrderingMatchingRule matchingRule)
- {
- this.matchingRule = matchingRule;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getExtensibleIndexID()
- {
- return EXTENSIBLE_INDEXER_ID_DEFAULT;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public final void createKeys(Schema schema, ByteSequence value2,
- IndexingOptions options, Collection<ByteString> keys)
- throws DecodeException
- {
- keys.add(matchingRule.normalizeAttributeValue(value2));
- }
-
- /** {@inheritDoc} */
- @Override
- public String getIndexID()
- {
- return RELATIVE_TIME_INDEX_NAME + "." + getExtensibleIndexID();
- }
- }
-
-
-
- /**
- * This class performs the partial date and time matching capabilities.
- */
- private final class PartialDateAndTimeMatchingRule
- extends TimeBasedMatchingRule
- {
- /**
- * Indexer associated with this instance.
- */
- private ExtensibleIndexer indexer;
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getOID()
- {
- return EXT_PARTIAL_DATE_TIME_OID;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public Collection<String> getNames()
- {
- return Collections.singleton(EXT_PARTIAL_DATE_TIME_NAME);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public ByteString normalizeAssertionValue(ByteSequence value)
- throws DecodeException
- {
- /**
- An assertion value may contain one or all of the following:
- D = day
- M = month
- Y = year
- h = hour
- m = month
- s = second
-
- An example assertion is OID:=04M. In this example we are
- searching for entries corresponding to month of april.
-
- Use this method to parse, validate and normalize the assertion value
- into a format to be recognized by the compare routine. The normalized
- value is actually the format of : smhDMY.
- */
- 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 length = value.length();
- for(int index=0; index<length; index++)
- {
- byte b = value.byteAt(index);
- if(isDigit((char)b))
- {
- number = multiplyByTenThenAddUnits(number, b);
- }
- else
- {
- LocalizableMessage message = null;
- switch(b)
- {
- case 's':
- if (second != initVal)
- {
- message = WARN_ATTR_DUPLICATE_SECOND_ASSERTION_FORMAT.get(value, date);
- }
- else
- {
- second = number;
- }
- break;
- case 'm':
- if (minute != initVal)
- {
- message = WARN_ATTR_DUPLICATE_MINUTE_ASSERTION_FORMAT.get(value, date);
- }
- else
- {
- minute = number;
- }
- break;
- case 'h':
- if (hour != initVal)
- {
- message = WARN_ATTR_DUPLICATE_HOUR_ASSERTION_FORMAT.get(value, date);
- }
- else
- {
- hour = number;
- }
- break;
- case 'D':
- if(number == 0)
- {
- message = WARN_ATTR_INVALID_DATE_ASSERTION_FORMAT.get(value, number);
- }
- else if (date != initDate)
- {
- message = WARN_ATTR_DUPLICATE_DATE_ASSERTION_FORMAT.get(value, date);
- }
- else
- {
- date = number;
- }
- break;
- case 'M':
- if (number == 0)
- {
- message = WARN_ATTR_INVALID_MONTH_ASSERTION_FORMAT.get(value, number);
- }
- else if (month != initVal)
- {
- message = WARN_ATTR_DUPLICATE_MONTH_ASSERTION_FORMAT.get(value, month);
- }
- else
- {
- month = number;
- }
- break;
- case 'Y':
- if(number == 0)
- {
- message = WARN_ATTR_INVALID_YEAR_ASSERTION_FORMAT.get(value, number);
- }
- else if (year != initDate)
- {
- message = WARN_ATTR_DUPLICATE_YEAR_ASSERTION_FORMAT.get(value, year);
- }
- else
- {
- year = number;
- }
- break;
- default:
- message = WARN_ATTR_INVALID_PARTIAL_TIME_ASSERTION_FORMAT.get(value, (char) b);
- }
- if(message !=null)
- {
- logger.error(message);
- throw DecodeException.error(message);
- }
- number = 0;
- }
- }
-
- month = toCalendarMonth(month, value);
-
- //Validate year, month , date , hour, minute and second in that order.
- // -1 values are allowed when these values have not been provided
- if (year < 0)
- {
- //A future date is allowed.
- 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));
- }
-
- // 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);
- bb.putInt(hour);
- bb.putInt(date);
- bb.putInt(month);
- bb.putInt(year);
- 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;
- }
- }
-
- 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)
- {
- // Build the information from the attribute value.
- GregorianCalendar cal = new GregorianCalendar(TIME_ZONE_UTC_OBJ);
- cal.setLenient(false);
- 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);
- int date = cal.get(Calendar.DATE);
- 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);
- int assertMinute = bb.getInt(4);
- int assertHour = bb.getInt(8);
- int assertDate = bb.getInt(12);
- 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)
- || (assertDate != 0 && assertDate != date)
- || (assertMonth != -1 && assertMonth != month)
- || (assertYear != 0 && assertYear != year))
- {
- return ConditionResult.FALSE;
- }
- return ConditionResult.TRUE;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public Collection<ExtensibleIndexer> getIndexers()
- {
- if(indexer == null)
- {
- indexer = new PartialDateAndTimeExtensibleIndexer(this);
- }
- return Collections.singletonList(indexer);
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public <T> T createIndexQuery(ByteSequence assertionValue,
- IndexQueryFactory<T> factory) throws DecodeException
- {
- //Build the information from the assertion value.
- byte[] arr = normalizeAssertionValue(assertionValue).toByteArray();
- ByteBuffer bb = ByteBuffer.wrap(arr);
-
- int assertSecond = bb.getInt(0);
- int assertMinute = bb.getInt(4);
- int assertHour = bb.getInt(8);
- int assertDate = bb.getInt(12);
- int assertMonth = bb.getInt(16);
- int assertYear = bb.getInt(20);
-
- List<T> queries = new ArrayList<T>();
- if(assertSecond >= 0)
- {
- queries.add(createExactMatchQuery(factory, assertSecond, SECOND));
- }
- if(assertMinute >=0)
- {
- queries.add(createExactMatchQuery(factory, assertMinute, MINUTE));
- }
- if(assertHour >=0)
- {
- queries.add(createExactMatchQuery(factory, assertHour, HOUR));
- }
- if(assertDate >0)
- {
- queries.add(createExactMatchQuery(factory, assertDate, DATE));
- }
- if(assertMonth >=0)
- {
- queries.add(createExactMatchQuery(factory, assertMonth, MONTH));
- }
- if(assertYear > 0)
- {
- 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));
- }
-
-
- /**
- * Decomposes an attribute value into a set of partial date and time index
- * keys.
- *
- * @param attValue
- * The normalized attribute value
- * @param set
- * A set into which the keys will be inserted.
- */
- private void timeKeys(ByteSequence attributeValue, Collection<ByteString> keys)
- {
- long timeInMS = 0L;
- try
- {
- timeInMS = decodeGeneralizedTimeValue(attributeValue);
- }
- catch(DirectoryException de)
- {
- //If the schema check is on this should never reach here. If not then we
- //would return from here.
- return;
- }
- //Build the information from the attribute value.
- GregorianCalendar cal = new GregorianCalendar(TIME_ZONE_UTC_OBJ);
- cal.setTimeInMillis(timeInMS);
- addKeyIfNotZero(keys, cal, Calendar.SECOND, SECOND);
- addKeyIfNotZero(keys, cal, Calendar.MINUTE, MINUTE);
- addKeyIfNotZero(keys, cal, Calendar.HOUR_OF_DAY, HOUR);
- addKeyIfNotZero(keys, cal, Calendar.DATE, DATE);
- addKeyIfNotZero(keys, cal, Calendar.MONTH, MONTH);
- addKeyIfNotZero(keys, cal, Calendar.YEAR, YEAR);
- }
-
- private void addKeyIfNotZero(Collection<ByteString> keys,
- GregorianCalendar cal, int calField, char type)
- {
- int value = cal.get(calField);
- if (value >= 0)
- {
- keys.add(getKey(value, type));
- }
- }
-
- private ByteString getKey(int value, char type)
- {
- ByteStringBuilder builder = new ByteStringBuilder();
- builder.append(type);
- builder.append(value);
- return builder.toByteString();
- }
- }
-
- 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;
- }
-
-
- /**
- * Extensible Indexer class for Partial Date and Time Matching rules.
- */
- private final class PartialDateAndTimeExtensibleIndexer extends
- ExtensibleIndexer
- {
- /** The partial date and Time matching Rule. */
- private final PartialDateAndTimeMatchingRule matchingRule;
-
-
-
- /**
- * Creates a new instance of PartialDateAndTimeExtensibleIndexer.
- *
- * @param matchingRule
- * The PartialDateAndTime Rule.
- */
- private PartialDateAndTimeExtensibleIndexer(
- PartialDateAndTimeMatchingRule matchingRule)
- {
- this.matchingRule = matchingRule;
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public void createKeys(Schema schema, ByteSequence value,
- IndexingOptions options, Collection<ByteString> keys)
- {
- matchingRule.timeKeys(value, keys);
- }
-
- /** {@inheritDoc} */
- @Override
- public String getIndexID()
- {
- return PARTIAL_DATE_TIME_INDEX_NAME + "." + getExtensibleIndexID();
- }
-
-
-
- /** {@inheritDoc} */
- @Override
- public String getExtensibleIndexID()
- {
- return EXTENSIBLE_INDEXER_ID_DEFAULT;
- }
- }
}
--
Gitblit v1.10.0