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.ArrayList; 024import java.util.List; 025import java.util.regex.Pattern; 026import java.util.regex.PatternSyntaxException; 027 028import org.apache.directory.api.ldap.model.constants.SchemaConstants; 029import org.apache.directory.api.ldap.model.schema.SyntaxChecker; 030import org.apache.directory.api.util.Strings; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034 035/** 036 * A SyntaxChecker which verifies that a value is a TelephoneNumber according to ITU 037 * recommendation E.123 (which is quite vague ...). 038 * 039 * A valid Telephone number respect more or less this syntax : 040 * 041 * " *[+]? *((\([0-9- ]+\))|[0-9- ]+)+" 042 * 043 * If needed, and to allow more syntaxes, a list of regexps has been added 044 * which can be initialized to other values 045 * 046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 047 */ 048@SuppressWarnings("serial") 049public class TelephoneNumberSyntaxChecker extends SyntaxChecker 050{ 051 /** A logger for this class */ 052 private static final Logger LOG = LoggerFactory.getLogger( TelephoneNumberSyntaxChecker.class ); 053 054 /** Other regexps to extend the initial one */ 055 private List<String> regexps; 056 057 /** Other regexp to extend the initial one, compiled */ 058 private List<Pattern> compiledREs; 059 060 /** The default pattern used to check a TelephoneNumber */ 061 private static final String DEFAULT_REGEXP = "^ *[+]? *((\\([0-9- ,;#*]+\\))|[0-9- ,;#*]+)+$"; 062 063 /** The compiled default pattern */ 064 private Pattern defaultPattern = Pattern.compile( DEFAULT_REGEXP ); 065 066 /** A flag set when only the default regexp should be tested */ 067 protected boolean defaultMandatory = false; 068 069 070 /** 071 * Creates a new instance of TelephoneNumberSyntaxChecker. 072 */ 073 public TelephoneNumberSyntaxChecker() 074 { 075 super( SchemaConstants.TELEPHONE_NUMBER_SYNTAX ); 076 } 077 078 079 /** 080 * Add a new valid regexp for a Telephone number 081 * @param regexp The new regexp to check 082 */ 083 public void addRegexp( String regexp ) 084 { 085 if ( defaultMandatory ) 086 { 087 return; 088 } 089 090 try 091 { 092 Pattern compiledRE = Pattern.compile( regexp ); 093 094 if ( regexps == null ) 095 { 096 regexps = new ArrayList<String>(); 097 compiledREs = new ArrayList<Pattern>(); 098 } 099 100 regexps.add( regexp ); 101 compiledREs.add( compiledRE ); 102 } 103 catch ( PatternSyntaxException pse ) 104 { 105 return; 106 } 107 } 108 109 110 /** 111 * Set the defaut regular expression for the Telephone number 112 * 113 * @param regexp the default regular expression. 114 */ 115 public void setDefaultRegexp( String regexp ) 116 { 117 try 118 { 119 defaultPattern = Pattern.compile( regexp ); 120 121 defaultMandatory = true; 122 regexps = null; 123 compiledREs = null; 124 } 125 catch ( PatternSyntaxException pse ) 126 { 127 return; 128 } 129 } 130 131 132 /** 133 * {@inheritDoc} 134 */ 135 public boolean isValidSyntax( Object value ) 136 { 137 String strValue = null; 138 139 if ( value == null ) 140 { 141 LOG.debug( "Syntax invalid for 'null'" ); 142 return false; 143 } 144 145 if ( value instanceof String ) 146 { 147 strValue = ( String ) value; 148 } 149 else if ( value instanceof byte[] ) 150 { 151 strValue = Strings.utf8ToString( ( byte[] ) value ); 152 } 153 else 154 { 155 strValue = value.toString(); 156 } 157 158 if ( strValue.length() == 0 ) 159 { 160 LOG.debug( "Syntax invalid for '{}'", value ); 161 return false; 162 } 163 164 // We will use a regexp to check the TelephoneNumber. 165 if ( defaultMandatory ) 166 { 167 // We have a unique regexp to check, the default one 168 boolean result = defaultPattern.matcher( strValue ).matches(); 169 170 if ( result ) 171 { 172 LOG.debug( "Syntax valid for '{}'", value ); 173 } 174 else 175 { 176 LOG.debug( "Syntax invalid for '{}'", value ); 177 } 178 179 return result; 180 } 181 else 182 { 183 if ( defaultPattern.matcher( strValue ).matches() ) 184 { 185 LOG.debug( "Syntax valid for '{}'", value ); 186 return true; 187 } 188 else 189 { 190 if ( compiledREs == null ) 191 { 192 LOG.debug( "Syntax invalid for '{}'", value ); 193 return false; 194 } 195 196 // The default is not enough, let's try 197 // the other regexps 198 for ( Pattern pattern : compiledREs ) 199 { 200 if ( pattern.matcher( strValue ).matches() ) 201 { 202 LOG.debug( "Syntax valid for '{}'", value ); 203 return true; 204 } 205 } 206 207 LOG.debug( "Syntax invalid for '{}'", value ); 208 return false; 209 } 210 } 211 } 212}