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 */ 020package org.apache.directory.api.ldap.model.schema.syntaxCheckers; 021 022 023import org.apache.directory.api.i18n.I18n; 024import org.apache.directory.api.ldap.model.constants.SchemaConstants; 025import org.apache.directory.api.ldap.model.schema.SyntaxChecker; 026import org.apache.directory.api.util.Strings; 027 028 029/** 030 * A SyntaxChecker which verifies that a value is a DSAQualitySyntax according to 031 * http://tools.ietf.org/id/draft-ietf-asid-ldapv3-attributes-03.txt, par 5.2.2.2 : 032 * <pre> 033 * <DsaQualitySyntax> ::= <DSAKeyword> [ '#' <description> ] 034 * 035 * <DSAKeyword> ::= 'DEFUNCT' | 'EXPERIMENTAL' | 'BEST-EFFORT' | 036 * 'PILOT-SERVICE' | 'FULL-SERVICE' 037 * 038 * <description> ::= encoded as a PrintableString 039 * </pre> 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043@SuppressWarnings("serial") 044public final class DsaQualitySyntaxSyntaxChecker extends SyntaxChecker 045{ 046 /** 047 * A static instance of DsaQualitySyntaxSyntaxChecker 048 */ 049 public static final DsaQualitySyntaxSyntaxChecker INSTANCE = 050 new DsaQualitySyntaxSyntaxChecker( SchemaConstants.DSA_QUALITY_SYNTAX ); 051 052 /** 053 * A static Builder for this class 054 */ 055 public static final class Builder extends SCBuilder<DsaQualitySyntaxSyntaxChecker> 056 { 057 /** 058 * The Builder constructor 059 */ 060 private Builder() 061 { 062 super( SchemaConstants.DSA_QUALITY_SYNTAX ); 063 } 064 065 066 /** 067 * Create a new instance of DsaQualitySyntaxSyntaxChecker 068 * @return A new instance of DsaQualitySyntaxSyntaxChecker 069 */ 070 @Override 071 public DsaQualitySyntaxSyntaxChecker build() 072 { 073 return new DsaQualitySyntaxSyntaxChecker( oid ); 074 } 075 } 076 077 078 /** 079 * Creates a new instance of DSAQualitySyntaxSyntaxChecker. 080 * 081 * @param oid The OID to use for this SyntaxChecker 082 */ 083 private DsaQualitySyntaxSyntaxChecker( String oid ) 084 { 085 super( oid ); 086 } 087 088 089 /** 090 * @return An instance of the Builder for this class 091 */ 092 public static Builder builder() 093 { 094 return new Builder(); 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public boolean isValidSyntax( Object value ) 103 { 104 String strValue; 105 106 if ( value == null ) 107 { 108 if ( LOG.isDebugEnabled() ) 109 { 110 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, "null" ) ); 111 } 112 113 return false; 114 } 115 116 if ( value instanceof String ) 117 { 118 strValue = ( String ) value; 119 } 120 else if ( value instanceof byte[] ) 121 { 122 strValue = Strings.utf8ToString( ( byte[] ) value ); 123 } 124 else 125 { 126 strValue = value.toString(); 127 } 128 129 if ( strValue.length() < 7 ) 130 { 131 if ( LOG.isDebugEnabled() ) 132 { 133 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 134 } 135 136 return false; 137 } 138 139 String remaining; 140 141 switch ( strValue.charAt( 0 ) ) 142 { 143 case 'B': 144 if ( !strValue.startsWith( "BEST-EFFORT" ) ) 145 { 146 if ( LOG.isDebugEnabled() ) 147 { 148 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 149 } 150 151 return false; 152 } 153 154 remaining = strValue.substring( "BEST-EFFORT".length() ); 155 break; 156 157 case 'D': 158 if ( !strValue.startsWith( "DEFUNCT" ) ) 159 { 160 if ( LOG.isDebugEnabled() ) 161 { 162 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 163 } 164 165 return false; 166 } 167 168 remaining = strValue.substring( "DEFUNCT".length() ); 169 break; 170 171 case 'E': 172 if ( !strValue.startsWith( "EXPERIMENTAL" ) ) 173 { 174 if ( LOG.isDebugEnabled() ) 175 { 176 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 177 } 178 179 return false; 180 } 181 182 remaining = strValue.substring( "EXPERIMENTAL".length() ); 183 break; 184 185 case 'F': 186 if ( !strValue.startsWith( "FULL-SERVICE" ) ) 187 { 188 if ( LOG.isDebugEnabled() ) 189 { 190 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 191 } 192 193 return false; 194 } 195 196 remaining = strValue.substring( "FULL-SERVICE".length() ); 197 break; 198 199 case 'P': 200 if ( !strValue.startsWith( "PILOT-SERVICE" ) ) 201 { 202 if ( LOG.isDebugEnabled() ) 203 { 204 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 205 } 206 207 return false; 208 } 209 210 remaining = strValue.substring( "PILOT-SERVICE".length() ); 211 break; 212 213 default: 214 if ( LOG.isDebugEnabled() ) 215 { 216 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 217 } 218 219 return false; 220 } 221 222 // Now, we might have a description separated from the keyword by a '#' 223 // but this is optional 224 if ( remaining.length() == 0 ) 225 { 226 if ( LOG.isDebugEnabled() ) 227 { 228 LOG.debug( I18n.msg( I18n.MSG_04489_SYNTAX_VALID, value ) ); 229 } 230 231 return true; 232 } 233 234 if ( remaining.charAt( 0 ) != '#' ) 235 { 236 // We were expecting a '#' 237 if ( LOG.isDebugEnabled() ) 238 { 239 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 240 } 241 242 return false; 243 } 244 245 // Check that the description is a PrintableString 246 boolean result = Strings.isPrintableString( remaining.substring( 1 ) ); 247 248 if ( LOG.isDebugEnabled() ) 249 { 250 if ( result ) 251 { 252 LOG.debug( I18n.msg( I18n.MSG_04489_SYNTAX_VALID, value ) ); 253 } 254 else 255 { 256 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) ); 257 } 258 } 259 260 return result; 261 } 262}