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.HashSet;
24  import java.util.Set;
25  
26  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
27  import org.apache.directory.api.util.Strings;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  
32  /**
33   * A SyntaxChecker which verifies that a value is a facsimile TelephoneNumber according 
34   * to ITU recommendation E.123 for the Telephone number part, and from RFC 4517, par. 
35   * 3.3.11 :
36   * 
37   * fax-number       = telephone-number *( DOLLAR fax-parameter )
38   * telephone-number = PrintableString
39   * fax-parameter    = "twoDimensional" |
40   *                    "fineResolution" |
41   *                    "unlimitedLength" |
42   *                    "b4Length" |
43   *                    "a3Width" |
44   *                    "b4Width" |
45   *                    "uncompressed"
46   *
47   * 
48   * If needed, and to allow more syntaxes, a list of regexps has been added
49   * which can be initialized to other values
50   * 
51   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52   */
53  @SuppressWarnings("serial")
54  public class FacsimileTelephoneNumberSyntaxChecker extends TelephoneNumberSyntaxChecker
55  {
56      /** A logger for this class */
57      private static final Logger LOG = LoggerFactory.getLogger( FacsimileTelephoneNumberSyntaxChecker.class );
58  
59      /** Fax parameters possible values */
60      private static final String TWO_DIMENSIONAL = "twoDimensional";
61      private static final String FINE_RESOLUTION = "fineResolution";
62      private static final String UNLIMITED_LENGTH = "unlimitedLength";
63      private static final String B4_LENGTH = "b4Length";
64      private static final String A3_LENGTH = "a3Width";
65      private static final String B4_WIDTH = "b4Width";
66      private static final String UNCOMPRESSED = "uncompressed";
67  
68      /** A set which contaons all the possible fax parameters values */
69      private static Set<String> faxParameters = new HashSet<String>();
70  
71      /** Initialization of the fax parameters set of values */
72      static
73      {
74          faxParameters.add( Strings.toLowerCase( TWO_DIMENSIONAL ) );
75          faxParameters.add( Strings.toLowerCase( FINE_RESOLUTION ) );
76          faxParameters.add( Strings.toLowerCase( UNLIMITED_LENGTH ) );
77          faxParameters.add( Strings.toLowerCase( B4_LENGTH ) );
78          faxParameters.add( Strings.toLowerCase( A3_LENGTH ) );
79          faxParameters.add( Strings.toLowerCase( B4_WIDTH ) );
80          faxParameters.add( Strings.toLowerCase( UNCOMPRESSED ) );
81      }
82  
83  
84      /**
85       * Creates a new instance of TelephoneNumberSyntaxChecker.
86       */
87      public FacsimileTelephoneNumberSyntaxChecker()
88      {
89          super();
90          setOid( SchemaConstants.FACSIMILE_TELEPHONE_NUMBER_SYNTAX );
91      }
92  
93  
94      /**
95       * {@inheritDoc}
96       */
97      public boolean isValidSyntax( Object value )
98      {
99          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 }