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.util.Strings; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031 032/** 033 * A SyntaxChecker which verifies that a value is a facsimile TelephoneNumber according 034 * to ITU recommendation E.123 for the Telephone number part, and from RFC 4517, par. 035 * 3.3.11 : 036 * 037 * fax-number = telephone-number *( DOLLAR fax-parameter ) 038 * telephone-number = PrintableString 039 * fax-parameter = "twoDimensional" | 040 * "fineResolution" | 041 * "unlimitedLength" | 042 * "b4Length" | 043 * "a3Width" | 044 * "b4Width" | 045 * "uncompressed" 046 * 047 * 048 * If needed, and to allow more syntaxes, a list of regexps has been added 049 * which can be initialized to other values 050 * 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 */ 053@SuppressWarnings("serial") 054public class FacsimileTelephoneNumberSyntaxChecker extends TelephoneNumberSyntaxChecker 055{ 056 /** A logger for this class */ 057 private static final Logger LOG = LoggerFactory.getLogger( FacsimileTelephoneNumberSyntaxChecker.class ); 058 059 /** Fax parameters possible values */ 060 private static final String TWO_DIMENSIONAL = "twoDimensional"; 061 private static final String FINE_RESOLUTION = "fineResolution"; 062 private static final String UNLIMITED_LENGTH = "unlimitedLength"; 063 private static final String B4_LENGTH = "b4Length"; 064 private static final String A3_LENGTH = "a3Width"; 065 private static final String B4_WIDTH = "b4Width"; 066 private static final String UNCOMPRESSED = "uncompressed"; 067 068 /** A set which contaons all the possible fax parameters values */ 069 private static Set<String> faxParameters = new HashSet<String>(); 070 071 /** Initialization of the fax parameters set of values */ 072 static 073 { 074 faxParameters.add( Strings.toLowerCase( TWO_DIMENSIONAL ) ); 075 faxParameters.add( Strings.toLowerCase( FINE_RESOLUTION ) ); 076 faxParameters.add( Strings.toLowerCase( UNLIMITED_LENGTH ) ); 077 faxParameters.add( Strings.toLowerCase( B4_LENGTH ) ); 078 faxParameters.add( Strings.toLowerCase( A3_LENGTH ) ); 079 faxParameters.add( Strings.toLowerCase( B4_WIDTH ) ); 080 faxParameters.add( Strings.toLowerCase( UNCOMPRESSED ) ); 081 } 082 083 084 /** 085 * Creates a new instance of TelephoneNumberSyntaxChecker. 086 */ 087 public FacsimileTelephoneNumberSyntaxChecker() 088 { 089 super(); 090 setOid( SchemaConstants.FACSIMILE_TELEPHONE_NUMBER_SYNTAX ); 091 } 092 093 094 /** 095 * {@inheritDoc} 096 */ 097 public boolean isValidSyntax( Object value ) 098 { 099 String strValue = null; 100 101 if ( value == null ) 102 { 103 LOG.debug( "Syntax invalid for 'null'" ); 104 return false; 105 } 106 107 if ( value instanceof String ) 108 { 109 strValue = ( String ) value; 110 } 111 else if ( value instanceof byte[] ) 112 { 113 strValue = Strings.utf8ToString( ( byte[] ) value ); 114 } 115 else 116 { 117 strValue = value.toString(); 118 } 119 120 if ( strValue.length() == 0 ) 121 { 122 LOG.debug( "Syntax invalid for '{}'", value ); 123 return false; 124 } 125 126 // The facsimile telephone number might be composed 127 // of two parts separated by a '$'. 128 int dollarPos = strValue.indexOf( '$' ); 129 130 if ( dollarPos == -1 ) 131 { 132 // We have no fax-parameter : check the Telephone number 133 boolean result = super.isValidSyntax( strValue ); 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 144 return result; 145 } 146 147 // First check the telephone number if the '$' is not at the first position 148 if ( dollarPos > 0 ) 149 { 150 if ( !super.isValidSyntax( strValue.substring( 0, dollarPos - 1 ) ) ) 151 { 152 LOG.debug( "Syntax invalid for '{}'", value ); 153 return false; 154 } 155 156 // Now, try to validate the fax-parameters : we may 157 // have more than one, so we will store the seen params 158 // in a set to check that we don't have the same param twice 159 Set<String> paramsSeen = new HashSet<String>(); 160 161 while ( dollarPos > 0 ) 162 { 163 String faxParam = null; 164 int newDollar = strValue.indexOf( '$', dollarPos + 1 ); 165 166 if ( newDollar == -1 ) 167 { 168 faxParam = strValue.substring( dollarPos + 1 ); 169 } 170 else 171 { 172 faxParam = strValue.substring( dollarPos + 1, newDollar ); 173 } 174 175 if ( faxParam.length() == 0 ) 176 { 177 // Not allowed 178 LOG.debug( "Syntax invalid for '{}'", value ); 179 return false; 180 } 181 182 // Relax a little bit the syntax by lowercasing the param 183 faxParam = Strings.toLowerCase( faxParam ); 184 185 if ( !faxParameters.contains( faxParam ) ) 186 { 187 // This parameter is not in the possible set 188 LOG.debug( "Syntax invalid for '{}'", value ); 189 return false; 190 } 191 else if ( paramsSeen.contains( faxParam ) ) 192 { 193 // We have the same parameters twice... 194 LOG.debug( "Syntax invalid for '{}'", value ); 195 return false; 196 } 197 else 198 { 199 // It's a correct param, let's add it to the seen 200 // params. 201 paramsSeen.add( faxParam ); 202 } 203 204 dollarPos = newDollar; 205 } 206 207 LOG.debug( "Syntax valid for '{}'", value ); 208 return true; 209 } 210 211 // We must have a valid telephone number ! 212 LOG.debug( "Syntax invalid for '{}'", value ); 213 return false; 214 } 215}