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.syntaxes;
021
022
023 import java.util.HashSet;
024 import java.util.Set;
025
026 import org.apache.directory.shared.ldap.constants.SchemaConstants;
027 import org.apache.directory.shared.ldap.schema.AbstractSyntaxChecker;
028 import org.apache.directory.shared.ldap.util.StringTools;
029
030
031 /**
032 * A SyntaxChecker which verifies that a value is a DSEType according to
033 * http://tools.ietf.org/id/draft-ietf-asid-ldapv3-attributes-03.txt, par 6.2.1.5 :
034 *
035 * <DSEType> ::= '(' <sp>* <DSEBit> <sp>* <DSEBitList> ')'
036 * <DSEBitList> ::= '$' <sp>* <DSEBit> <sp>* <DSEBitList> | e
037 * <DSEBit> ::= 'root' | 'glue' | 'cp' | 'entry' | 'alias' | 'subr' |
038 * 'nssr' | 'supr' | 'xr' | 'admPoint' | 'subentry' |
039 * 'shadow' | 'zombie' | 'immSupr' | 'rhob' | 'sa'
040 *
041 *
042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043 * @version $Rev$
044 */
045 public class DSETypeSyntaxChecker extends AbstractSyntaxChecker
046 {
047 /** The DSE BITS keywords */
048 private static final String[] DSE_BITS_STRINGS =
049 {
050 "root", "glue", "cp", "entry", "alias", "subr",
051 "nssr", "supr", "xr", "admPoint", "subentry",
052 "shadow", "zombie", "immSupr", "rhob", "sa"
053 };
054
055
056 /** The Set which contains the DESBits */
057 private static final Set<String> DSE_BITS = new HashSet<String>();
058
059 /** Initialization of the country set */
060 static
061 {
062 for ( String country:DSE_BITS_STRINGS )
063 {
064 DSE_BITS.add( country );
065 }
066 }
067
068
069 /**
070 *
071 * Creates a new instance of DSETypeSyntaxChecker.
072 *
073 */
074 public DSETypeSyntaxChecker()
075 {
076 super( SchemaConstants.DSE_TYPE_SYNTAX );
077 }
078
079 /**
080 *
081 * Creates a new instance of DSETypeSyntaxChecker.
082 *
083 * @param oid the oid to associate with this new SyntaxChecker
084 *
085 */
086 protected DSETypeSyntaxChecker( String oid )
087 {
088 super( oid );
089 }
090
091
092 /* (non-Javadoc)
093 * @see org.apache.directory.shared.ldap.schema.SyntaxChecker#isValidSyntax(java.lang.Object)
094 */
095 public boolean isValidSyntax( Object value )
096 {
097 String strValue = null;
098
099 if ( value == null )
100 {
101 return false;
102 }
103
104 if ( value instanceof String )
105 {
106 strValue = ( String ) value;
107 }
108 else if ( value instanceof byte[] )
109 {
110 strValue = StringTools.utf8ToString( ( byte[] ) value );
111 }
112 else
113 {
114 strValue = value.toString();
115 }
116
117 // We must have at least '(cp)', '(xr)' or '(ca)'
118 if ( strValue.length() < 4 )
119 {
120 return false;
121 }
122
123 // Check the opening and closing parenthesis
124 if ( ( strValue.charAt( 0 ) != '(' ) ||
125 ( strValue.charAt( strValue.length() - 1 ) != ')' ) )
126 {
127 return false;
128 }
129
130 Set<String> keywords = new HashSet<String>();
131 int len = strValue.length() - 1;
132 boolean needKeyword = true;
133
134 //
135 for ( int i = 1; i < len; /* */ )
136 {
137 // Skip spaces
138 while ( ( i < len ) && ( strValue.charAt( i ) == ' ' ) )
139 {
140 i++;
141 }
142
143 int pos = i;
144
145 // Search for a keyword
146 while ( ( i < len ) && StringTools.isAlphaASCII( strValue, pos ) )
147 {
148 pos++;
149 }
150
151 if ( pos == i )
152 {
153 // No keyword : error
154 return false;
155 }
156
157 String keyword = strValue.substring( i, pos );
158 i = pos;
159
160 if ( !DSE_BITS.contains( keyword ) )
161 {
162 // Unkown keyword
163 return false;
164 }
165
166 // Check that the keyword has not been met
167 if ( keywords.contains( keyword ) )
168 {
169 return false;
170 }
171
172 keywords.add( keyword );
173 needKeyword = false;
174
175 // Skip spaces
176 while ( ( i < len ) && ( strValue.charAt( i ) == ' ' ) )
177 {
178 i++;
179 }
180
181 // Do we have another keyword ?
182 if ( ( i < len) && ( strValue.charAt( i ) == '$' ) )
183 {
184 // yes
185 i++;
186 needKeyword = true;
187 continue;
188 }
189 }
190
191 // We are done
192 return !needKeyword;
193 }
194 }