/*
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2009 Sun Microsystems, Inc.
* Portions Copyright 2011 ForgeRock AS
*/
/**
* This class acts as a factory for time-based matching rules.
*/
public final class TimeBasedMatchingRuleFactory
extends MatchingRuleFactory<MatchingRuleCfg>
{
//Greater-than RelativeTimeMatchingRule.
//Less-than RelativeTimeMatchingRule.
//PartialDayAndTimeMatchingRule.
//A Collection of matching rules managed by this factory.
//Constants for generating keys.
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
}
/**
* This class defines a matching rule which is used for time-based searches.
*/
implements ExtensibleMatchingRule
{
/**
* {@inheritDoc}
*/
{
//There is no standard definition.
return null;
}
/**
* {@inheritDoc}
*/
{
return SYNTAX_GENERALIZED_TIME_OID;
}
/**
* {@inheritDoc}
*/
throws DirectoryException
{
try
{
}
catch (DirectoryException de)
{
switch (DirectoryServer.getSyntaxEnforcementPolicy())
{
case REJECT:
throw de;
case WARN:
return value.toByteString();
default:
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.
*/
/**
* Indexer associated with this instance.
*/
/**
* {@inheritDoc}
*/
throws DirectoryException
{
/**
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;
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;
long number = 0;
{
if(isDigit((char)b))
{
{
case '0':
break;
case '1':
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
case '6':
break;
case '7':
break;
case '8':
break;
case '9':
break;
}
}
else
{
if(containsTimeUnit)
{
//We already have time unit found by now.
}
else
{
{
case 's':
break;
case 'm':
break;
case 'h':
break;
case 'd':
break;
case 'w':
break;
default:
message =
}
}
{
//Log the message and throw an exception.
throw new DirectoryException(
}
else
{
containsTimeUnit = true;
number = 0;
}
}
}
if(!containsTimeUnit)
{
//There was no time unit so assume it is seconds.
}
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
{
indexer = new RelativeTimeExtensibleIndexer(this);
}
}
}
/**
* 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.
/**
* 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.
*/
{
}
/**
* {@inheritDoc}
*/
{
return EXT_OMR_RELATIVE_TIME_GT_NAME;
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
return EXT_OMR_RELATIVE_TIME_GT_OID;
}
/**
* {@inheritDoc}
*/
{
if (ret > 0)
{
return ConditionResult.TRUE;
}
else
{
return ConditionResult.FALSE;
}
}
/**
* {@inheritDoc}
*/
{
ByteString.empty(), false, false);
}
}
/**
* 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.
/**
* 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.
*/
{
}
/**
* {@inheritDoc}
*/
{
return EXT_OMR_RELATIVE_TIME_LT_NAME;
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
return EXT_OMR_RELATIVE_TIME_LT_OID;
}
/**
* {@inheritDoc}
*/
{
if (ret < 0)
{
return ConditionResult.TRUE;
}
else
{
return ConditionResult.FALSE;
}
}
/**
* {@inheritDoc}
*/
{
normalizeAssertionValue(assertionValue),false, false);
}
}
/**
* 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
{
/**
* The Extensible Matching Rule.
*/
/**
* Creates a new instance of RelativeTimeExtensibleIndexer.
*
* @param matchingRule The relative time Matching Rule.
*/
private RelativeTimeExtensibleIndexer(
{
this.matchingRule = matchingRule;
}
/**
* {@inheritDoc}
*/
{
return EXTENSIBLE_INDEXER_ID_DEFAULT;
}
/**
* {@inheritDoc}
*/
{
try
{
}
catch (DirectoryException de)
{
//don't do anything.
}
}
/**
* {@inheritDoc}
*/
{
{
{
}
{
}
}
}
/**
* {@inheritDoc}
*/
{
return RELATIVE_TIME_INDEX_NAME;
}
}
/**
* This class performs the partial date and time matching capabilities.
*/
private final class PartialDateAndTimeMatchingRule
extends TimeBasedMatchingRule
implements ExtensibleMatchingRule
{
/**
* Indexer associated with this instance.
*/
/**
* {@inheritDoc}
*/
{
return EXT_PARTIAL_DATE_TIME_NAME;
}
/**
* {@inheritDoc}
*/
{
return EXT_PARTIAL_DATE_TIME_OID;
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
throws DirectoryException
{
/**
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.
*/
int second = -1;
int minute = -1;
int hour = -1;
int date = 0;
int year = 0;
int number = 0;
int month = -1;
{
if(isDigit((char)b))
{
{
case '0':
break;
case '1':
break;
case '2':
break;
case '3':
break;
case '4':
break;
case '5':
break;
case '6':
break;
case '7':
break;
case '8':
break;
case '9':
break;
}
}
else
{
{
case 's':
if(second >0)
{
message =
}
else
{
}
break;
case 'm':
if(minute >0)
{
message =
}
else
{
}
break;
case 'h':
if(hour >0)
{
message =
}
else
{
}
break;
case 'D':
if(number == 0)
{
message =
}
else if(date > 0)
{
message =
}
else
{
}
break;
case 'M':
if(number == 0)
{
message =
}
else if(month > 0)
{
message =
}
else
{
}
break;
case 'Y':
if(number == 0)
{
message =
}
else if(year >0)
{
}
else
{
}
break;
default:
message =
}
{
throw new DirectoryException(
}
else
{
number = 0;
}
}
}
//Validate year, month , date , hour, minute and second in that order.
if(year < 0)
{
//A future date is allowed.
throw new DirectoryException(
}
switch(month)
{
case -1:
//just allow this.
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
default:
throw new DirectoryException(
}
boolean invalidDate = false;
switch(date)
{
case 29:
{
invalidDate = true;
}
break;
case 31:
{
invalidDate = true;
}
break;
default:
{
invalidDate = true;
}
}
if(invalidDate)
{
throw new DirectoryException(
}
{
throw new DirectoryException(
}
{
throw new DirectoryException(
}
{
throw new DirectoryException(
}
/**
* Since we reached here we have a valid assertion value. Construct
* a normalized value in the order: SECOND MINUTE HOUR DATE MONTH YEAR.
*/
}
/**
* {@inheritDoc}
*/
{
//Build the information from the attribute value.
cal.setLenient(false);
//Build the information from the assertion value.
{
return ConditionResult.FALSE;
}
{
return ConditionResult.FALSE;
}
{
return ConditionResult.FALSE;
}
//All the non-zero values should match.
{
return ConditionResult.FALSE;
}
{
return ConditionResult.FALSE;
}
{
return ConditionResult.FALSE;
}
return ConditionResult.TRUE;
}
/**
* {@inheritDoc}
*/
{
{
indexer = new PartialDateAndTimeExtensibleIndexer(this);
}
}
/**
* {@inheritDoc}
*/
{
//Build the information from the assertion value.
if(assertSecond >= 0)
{
}
if(assertMinute >=0)
{
}
if(assertHour >=0)
{
}
if(assertDate >0)
{
}
if(assertMonth >=0)
{
}
if(assertYear > 0)
{
}
}
/**
* 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.
*/
{
long timeInMS = 0L;
try
{
}
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.
if (second >=0)
{
}
if(minute >=0)
{
}
if(hour >=0)
{
}
//Insert date.
if(date > 0)
{
}
//Insert month.
if(month >=0)
{
}
if(year > 0)
{
}
}
{
return builder.toByteString();
}
}
/**
* Extensible Indexer class for Partial Date and Time Matching rules.
*/
private final class PartialDateAndTimeExtensibleIndexer extends
{
// The partial date and Time matching Rule.
/**
* Creates a new instance of PartialDateAndTimeExtensibleIndexer.
*
* @param matchingRule
* The PartialDateAndTime Rule.
*/
private PartialDateAndTimeExtensibleIndexer(
{
this.matchingRule = matchingRule;
}
/**
* {@inheritDoc}
*/
{
}
/**
* {@inheritDoc}
*/
{
{
{
}
{
}
}
}
/**
* {@inheritDoc}
*/
{
return PARTIAL_DATE_TIME_INDEX_NAME;
}
/**
* {@inheritDoc}
*/
{
return EXTENSIBLE_INDEXER_ID_DEFAULT;
}
}
}