View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.model.schema.syntaxCheckers;
21  
22  
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.regex.Pattern;
26  import java.util.regex.PatternSyntaxException;
27  
28  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
29  import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
30  import org.apache.directory.api.util.Strings;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  
34  
35  /**
36   * A SyntaxChecker which verifies that a value is a TelephoneNumber according to ITU
37   * recommendation E.123 (which is quite vague ...).
38   * 
39   * A valid Telephone number respect more or less this syntax :
40   * 
41   * " *[+]? *((\([0-9- ]+\))|[0-9- ]+)+"
42   * 
43   * If needed, and to allow more syntaxes, a list of regexps has been added
44   * which can be initialized to other values
45   * 
46   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
47   */
48  @SuppressWarnings("serial")
49  public class TelephoneNumberSyntaxChecker extends SyntaxChecker
50  {
51      /** A logger for this class */
52      private static final Logger LOG = LoggerFactory.getLogger( TelephoneNumberSyntaxChecker.class );
53  
54      /** Other regexps to extend the initial one */
55      private List<String> regexps;
56  
57      /** Other regexp to extend the initial one, compiled */
58      private List<Pattern> compiledREs;
59  
60      /** The default pattern used to check a TelephoneNumber */
61      private static final String DEFAULT_REGEXP = "^ *[+]? *((\\([0-9- ,;#*]+\\))|[0-9- ,;#*]+)+$";
62  
63      /** The compiled default pattern */
64      private Pattern defaultPattern = Pattern.compile( DEFAULT_REGEXP );
65  
66      /** A flag set when only the default regexp should be tested */
67      protected boolean defaultMandatory = false;
68  
69  
70      /**
71       * Creates a new instance of TelephoneNumberSyntaxChecker.
72       */
73      public TelephoneNumberSyntaxChecker()
74      {
75          super( SchemaConstants.TELEPHONE_NUMBER_SYNTAX );
76      }
77  
78  
79      /**
80       * Add a new valid regexp for a Telephone number
81       * @param regexp The new regexp to check
82       */
83      public void addRegexp( String regexp )
84      {
85          if ( defaultMandatory )
86          {
87              return;
88          }
89  
90          try
91          {
92              Pattern compiledRE = Pattern.compile( regexp );
93  
94              if ( regexps == null )
95              {
96                  regexps = new ArrayList<String>();
97                  compiledREs = new ArrayList<Pattern>();
98              }
99  
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 }