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   *    https://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.comparators;
21  
22  
23  import java.io.Serializable;
24  import java.math.BigInteger;
25  
26  import org.apache.directory.api.i18n.I18n;
27  import org.apache.directory.api.ldap.model.entry.Value;
28  import org.apache.directory.api.ldap.model.exception.LdapException;
29  import org.apache.directory.api.ldap.model.schema.LdapComparator;
30  import org.apache.directory.api.ldap.model.schema.normalizers.NumericNormalizer;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  
34  
35  /**
36   * A class for the integerOrderingMatch matchingRule (RFC 4517, par. 4.2.20)
37   * 
38   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
39   */
40  public class IntegerComparator extends LdapComparator<Object> implements Serializable
41  {
42      /** The serial version UID */
43      private static final long serialVersionUID = 2L;
44  
45      /** A logger for this class */
46      private static final Logger LOG = LoggerFactory.getLogger( IntegerComparator.class );
47  
48  
49      /**
50       * The IntegerComparator constructor. Its OID is the IntegerOrderingMatch matching
51       * rule OID.
52       * 
53       * @param oid The Comparator's OID
54       */
55      public IntegerComparator( String oid )
56      {
57          super( oid );
58      }
59  
60  
61      /**
62       * {@inheritDoc}
63       */
64      @Override
65      public int compare( Object v1, Object v2 )
66      {
67          // The value can be a String, a Value or a Long
68          if ( v1 == null )
69          {
70              if ( v2 == null )
71              {
72                  return 0;
73              }
74              else
75              {
76                  return -1;
77              }
78          }
79          else if ( v2 == null )
80          {
81              return 1;
82          }
83          
84          if ( v1 instanceof String )
85          {
86              return compare( ( String ) v1, ( String ) v2 );
87          }
88          else if ( v1 instanceof Value )
89          {
90              return compare( ( ( Value ) v1 ).getString(), ( ( Value ) v2 ).getString() ); 
91          }
92          else 
93          {
94              return Long.compare( ( Long ) v1, ( Long ) v2 );
95          }
96      }
97  
98  
99      /**
100      * Implementation of the Compare method
101      * 
102      * @param backendValue The stored value
103      * @param assertValue The provided value
104      * @return <tt>0</tt> if the values are equal, <tt>-1</tt> if the provided value is below
105      * the stored value, <tt>+1</tt> otherwise
106      */
107     private int compare( String backendValue, String assertValue )
108     {
109         if ( LOG.isDebugEnabled() )
110         {
111             LOG.debug( I18n.msg( I18n.MSG_13746_COMPARING_INTEGER, backendValue, assertValue ) );
112         }
113 
114         // First, shortcut the process by comparing
115         // references. If they are equals, then o1 and o2
116         // reference the same object
117         if ( backendValue == assertValue )
118         {
119             return 0;
120         }
121 
122         // Then, deal with one of o1 or o2 being null
123         // Both can't be null, because then they would
124         // have been caught by the previous test
125         if ( ( backendValue == null ) || ( assertValue == null ) )
126         {
127             return backendValue == null ? -1 : 1;
128         }
129 
130         // Both objects must be stored as String for numeric.
131         // But we need to normalize the values first.
132         NumericNormalizer normalizer = new NumericNormalizer();
133         
134         try
135         {
136             backendValue = normalizer.normalize( backendValue );
137         }
138         catch ( LdapException le )
139         {
140             throw new IllegalArgumentException( I18n.err( I18n.ERR_13724_INVALID_VALUE, backendValue ), le );
141         }
142         try
143         {
144             assertValue = normalizer.normalize( assertValue );
145         }
146         catch ( LdapException le )
147         {
148             throw new IllegalArgumentException( I18n.err( I18n.ERR_13724_INVALID_VALUE, assertValue ), le );
149         }
150         
151         try
152         {
153             // First try with longs
154             Long l1 = Long.valueOf( backendValue );
155             Long l2 = Long.valueOf( assertValue );
156             
157             return l1.compareTo( l2 );
158         }
159         catch ( NumberFormatException nfe )
160         {
161             // Ok, try with BigIntegers
162             BigInteger b1 = new BigInteger( backendValue );
163             BigInteger b2 = new BigInteger( assertValue );
164     
165             return b1.compareTo( b2 );
166         }
167     }
168 }