001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.schema.syntaxCheckers;
021
022
023 import java.util.regex.Pattern;
024
025 import org.apache.directory.shared.ldap.constants.SchemaConstants;
026 import org.apache.directory.shared.ldap.schema.SyntaxChecker;
027 import org.apache.directory.shared.ldap.util.StringTools;
028 import org.slf4j.Logger;
029 import org.slf4j.LoggerFactory;
030
031
032 /**
033 * A SyntaxChecker which verifies that a value is a UTC time
034 * according to RFC 4517.
035 *
036 * From RFC 4517 :
037 * UTCTime = year month day hour minute [ second ] [ u-time-zone ]
038 * u-time-zone = %x5A ; "Z" | u-differential
039 * u-differential = ( MINUS | PLUS ) hour minute
040 *
041 * year = 2(%x30-39) ; "00" to "99"
042 * month = ( %x30 %x31-39 ) ; "01" (January) to "09"
043 * | ( %x31 %x30-32 ) ; "10" to "12"
044 * day = ( %x30 %x31-39 ) ; "01" to "09"
045 * | ( %x31-32 %x30-39 ) ; "10" to "29"
046 * | ( %x33 %x30-31 ) ; "30" to "31"
047 * hour = ( %x30-31 %x30-39 )
048 * | ( %x32 %x30-33 ) ; "00" to "23"
049 * minute = %x30-35 %x30-39 ; "00" to "59"
050 *
051 * second = ( %x30-35 %x30-39 ) ; "00" to "59"
052 *
053 * g-time-zone = %x5A ; "Z"
054 * | g-differential
055 * g-differential = ( MINUS / PLUS ) hour [ minute ]
056 * MINUS = %x2D ; minus sign ("-")
057 *
058 * From RFC 4512 :
059 * PLUS = %x2B ; plus sign ("+")
060 *
061 *
062 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
063 * @version $Rev$
064 */
065 public class UtcTimeSyntaxChecker extends SyntaxChecker
066 {
067 /** A logger for this class */
068 private static final Logger LOG = LoggerFactory.getLogger( UtcTimeSyntaxChecker.class );
069
070 /** The serialVersionUID */
071 private static final long serialVersionUID = 1L;
072
073 /** The GeneralizedDate pattern matching */
074 private static final String UTC_TIME_PATTERN =
075 "^\\d{2}" + // year : 00 to 99
076 "(0[1-9]|1[0-2])" + // month : 01 to 12
077 "(0[1-9]|[12]\\d|3[01])" + // day : 01 to 31
078 "([01]\\d|2[0-3])" + // hour: 00 to 23
079 "([0-5]\\d)" + // minute : 00 to 59
080 "(" +
081 "([0-5]\\d)?" + // optional second : 00 to 59
082 "(Z|([+-]([01]\\d|2[0-3])[0-5]\\d))?" + // optionnal time-zone
083 ")$";
084
085 // The regexp pattern matcher
086 private Pattern datePattern = Pattern.compile( UTC_TIME_PATTERN );
087
088 /**
089 *
090 * Creates a new instance of UtcTimeSyntaxChecker.
091 *
092 */
093 public UtcTimeSyntaxChecker()
094 {
095 super( SchemaConstants.UTC_TIME_SYNTAX );
096 }
097
098
099 /**
100 * {@inheritDoc}
101 */
102 public boolean isValidSyntax( Object value )
103 {
104 String strValue = null;
105
106 if ( value == null )
107 {
108 LOG.debug( "Syntax invalid for '{}'", value );
109 return false;
110 }
111
112 if ( value instanceof String )
113 {
114 strValue = ( String ) value;
115 }
116 else if ( value instanceof byte[] )
117 {
118 strValue = StringTools.utf8ToString( ( byte[] ) value );
119 }
120 else
121 {
122 strValue = value.toString();
123 }
124
125 // A generalized time must have a minimal length of 11
126 if ( strValue.length() < 11 )
127 {
128 LOG.debug( "Syntax invalid for '{}'", value );
129 return false;
130 }
131
132 // Start the date parsing
133 boolean result = datePattern.matcher( strValue ).find();
134
135 if ( result )
136 {
137 LOG.debug( "Syntax valid for '{}'", value );
138 }
139 else
140 {
141 LOG.debug( "Syntax invalid for '{}'", value );
142 }
143 return result;
144 }
145 }