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 java.util.HashSet; 024import java.util.Set; 025 026import org.apache.directory.api.ldap.model.constants.SchemaConstants; 027import org.apache.directory.api.ldap.model.schema.SyntaxChecker; 028import org.apache.directory.api.util.Chars; 029import org.apache.directory.api.util.Strings; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033 034/** 035 * A SyntaxChecker which verifies that a value is a delivery method 036 * according to RFC 4517. 037 * 038 * From RFC 4517 & RFC 4512: 039 * 040 * DeliveryMethod = pdm *( WSP DOLLAR WSP pdm ) 041 * 042 * pdm = "any" | "mhs" | "physical" | "telex" | "teletex" | 043 * "g3fax" | "g4fax" | "ia5" | "videotex" | "telephone" 044 * 045 * WSP = 0*SPACE ; zero or more " " 046 * DOLLAR = %x24 ; dollar sign ("$") 047 * SPACE = %x20 ; space (" ") 048 * 049 * 050 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 051 */ 052@SuppressWarnings("serial") 053public class DeliveryMethodSyntaxChecker extends SyntaxChecker 054{ 055 /** A logger for this class */ 056 private static final Logger LOG = LoggerFactory.getLogger( DeliveryMethodSyntaxChecker.class ); 057 058 private static final String[] PDMS = 059 { 060 "any", "mhs", "physical", "telex", "teletex", 061 "g3fax", "g4fax", "ia5", "videotex", "telephone" 062 }; 063 064 /** The Set which contains the delivery methods */ 065 private static final Set<String> DELIVERY_METHODS = new HashSet<String>(); 066 067 /** Initialization of the delivery methods set */ 068 static 069 { 070 for ( String country : PDMS ) 071 { 072 DELIVERY_METHODS.add( country ); 073 } 074 } 075 076 077 /** 078 * 079 * Creates a new instance of DeliveryMethodSyntaxChecker. 080 * 081 */ 082 public DeliveryMethodSyntaxChecker() 083 { 084 super( SchemaConstants.DELIVERY_METHOD_SYNTAX ); 085 } 086 087 088 /** 089 * 090 * Check if the string contains a delivery method which has 091 * not already been found. 092 * 093 * @param strValue The string we want to look into for a PDM 094 * @param pos The current position in the string 095 * @param pdms The set containing all the PDM 096 * @return if a Prefered Delivery Method is found in the given string, returns 097 * its position, otherwise, returns -1 098 */ 099 private int isPdm( String strValue, int start, Set<String> pdms ) 100 { 101 int pos = start; 102 103 while ( Chars.isAlphaDigit( strValue, pos ) ) 104 { 105 pos++; 106 } 107 108 // No ascii string, this is not a delivery method 109 if ( pos == start ) 110 { 111 return -1; 112 } 113 114 String pdm = strValue.substring( start, pos ); 115 116 if ( !DELIVERY_METHODS.contains( pdm ) ) 117 { 118 // The delivery method is unknown 119 return -1; 120 } 121 else 122 { 123 if ( pdms.contains( pdm ) ) 124 { 125 // The delivery method has already been found 126 return -1; 127 } 128 else 129 { 130 pdms.add( pdm ); 131 return pos; 132 } 133 } 134 } 135 136 137 /** 138 * {@inheritDoc} 139 */ 140 public boolean isValidSyntax( Object value ) 141 { 142 String strValue = null; 143 144 if ( value == null ) 145 { 146 LOG.debug( "Syntax invalid for 'null'" ); 147 return false; 148 } 149 150 if ( value instanceof String ) 151 { 152 strValue = ( String ) value; 153 } 154 else if ( value instanceof byte[] ) 155 { 156 strValue = Strings.utf8ToString( ( byte[] ) value ); 157 } 158 else 159 { 160 strValue = value.toString(); 161 } 162 163 if ( strValue.length() == 0 ) 164 { 165 LOG.debug( "Syntax invalid for '{}'", value ); 166 return false; 167 } 168 169 // We will get the first delivery method 170 int length = strValue.length(); 171 int pos = 0; 172 Set<String> pmds = new HashSet<String>(); 173 174 if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1 ) 175 { 176 LOG.debug( "Syntax invalid for '{}'", value ); 177 return false; 178 } 179 180 // We have found at least the first pmd, 181 // now iterate through the other ones. We may have 182 // SP* '$' SP* before each pmd. 183 while ( pos < length ) 184 { 185 // Skip spaces 186 while ( Strings.isCharASCII( strValue, pos, ' ' ) ) 187 { 188 pos++; 189 } 190 191 if ( !Strings.isCharASCII( strValue, pos, '$' ) ) 192 { 193 // A '$' was expected 194 LOG.debug( "Syntax invalid for '{}'", value ); 195 return false; 196 } 197 else 198 { 199 pos++; 200 } 201 202 // Skip spaces 203 while ( Strings.isCharASCII( strValue, pos, ' ' ) ) 204 { 205 pos++; 206 } 207 208 if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1 ) 209 { 210 LOG.debug( "Syntax invalid for '{}'", value ); 211 return false; 212 } 213 } 214 215 LOG.debug( "Syntax valid for '{}'", value ); 216 return true; 217 } 218}