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