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 * https://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.comparators; 021 022 023import java.io.Serializable; 024import java.math.BigInteger; 025 026import org.apache.directory.api.i18n.I18n; 027import org.apache.directory.api.ldap.model.entry.Value; 028import org.apache.directory.api.ldap.model.exception.LdapException; 029import org.apache.directory.api.ldap.model.schema.LdapComparator; 030import org.apache.directory.api.ldap.model.schema.normalizers.NumericNormalizer; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034 035/** 036 * A class for the integerOrderingMatch matchingRule (RFC 4517, par. 4.2.20) 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 */ 040public class IntegerComparator extends LdapComparator<Object> implements Serializable 041{ 042 /** The serial version UID */ 043 private static final long serialVersionUID = 2L; 044 045 /** A logger for this class */ 046 private static final Logger LOG = LoggerFactory.getLogger( IntegerComparator.class ); 047 048 049 /** 050 * The IntegerComparator constructor. Its OID is the IntegerOrderingMatch matching 051 * rule OID. 052 * 053 * @param oid The Comparator's OID 054 */ 055 public IntegerComparator( String oid ) 056 { 057 super( oid ); 058 } 059 060 061 /** 062 * {@inheritDoc} 063 */ 064 @Override 065 public int compare( Object v1, Object v2 ) 066 { 067 // The value can be a String, a Value or a Long 068 if ( v1 == null ) 069 { 070 if ( v2 == null ) 071 { 072 return 0; 073 } 074 else 075 { 076 return -1; 077 } 078 } 079 else if ( v2 == null ) 080 { 081 return 1; 082 } 083 084 if ( v1 instanceof String ) 085 { 086 return compare( ( String ) v1, ( String ) v2 ); 087 } 088 else if ( v1 instanceof Value ) 089 { 090 return compare( ( ( Value ) v1 ).getString(), ( ( Value ) v2 ).getString() ); 091 } 092 else 093 { 094 return Long.compare( ( Long ) v1, ( Long ) v2 ); 095 } 096 } 097 098 099 /** 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}