001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.schema; 028 029 030 031 import org.opends.server.admin.std.server.OrderingMatchingRuleCfg; 032 import org.opends.server.api.OrderingMatchingRule; 033 import org.opends.server.config.ConfigException; 034 import org.opends.server.protocols.asn1.ASN1OctetString; 035 import org.opends.server.types.ByteString; 036 import org.opends.server.types.DirectoryException; 037 import org.opends.server.types.InitializationException; 038 039 import static org.opends.messages.SchemaMessages.*; 040 import static org.opends.server.schema.SchemaConstants.*; 041 import static org.opends.server.util.StaticUtils.*; 042 043 044 045 /** 046 * This class defines the caseExactOrderingMatch matching rule defined in X.520 047 * and referenced in RFC 4519. 048 */ 049 public class CaseExactOrderingMatchingRule 050 extends OrderingMatchingRule 051 { 052 /** 053 * The serial version identifier required to satisfy the compiler because this 054 * class implements the <CODE>java.io.Serializable</CODE> interface. This 055 * value was generated using the <CODE>serialver</CODE> command-line utility 056 * included with the Java SDK. 057 */ 058 private static final long serialVersionUID = -5904188628828913709L; 059 060 061 062 /** 063 * Creates a new instance of this caseExactOrderingMatch matching rule. 064 */ 065 public CaseExactOrderingMatchingRule() 066 { 067 super(); 068 } 069 070 071 072 /** 073 * {@inheritDoc} 074 */ 075 public void initializeMatchingRule(OrderingMatchingRuleCfg configuration) 076 throws ConfigException, InitializationException 077 { 078 // No initialization is required. 079 } 080 081 082 083 /** 084 * Retrieves the common name for this matching rule. 085 * 086 * @return The common name for this matching rule, or <CODE>null</CODE> if 087 * it does not have a name. 088 */ 089 public String getName() 090 { 091 return OMR_CASE_EXACT_NAME; 092 } 093 094 095 096 /** 097 * Retrieves the OID for this matching rule. 098 * 099 * @return The OID for this matching rule. 100 */ 101 public String getOID() 102 { 103 return OMR_CASE_EXACT_OID; 104 } 105 106 107 108 /** 109 * Retrieves the description for this matching rule. 110 * 111 * @return The description for this matching rule, or <CODE>null</CODE> if 112 * there is none. 113 */ 114 public String getDescription() 115 { 116 // There is no standard description for this matching rule. 117 return null; 118 } 119 120 121 122 /** 123 * Retrieves the OID of the syntax with which this matching rule is 124 * associated. 125 * 126 * @return The OID of the syntax with which this matching rule is associated. 127 */ 128 public String getSyntaxOID() 129 { 130 return SYNTAX_DIRECTORY_STRING_OID; 131 } 132 133 134 135 /** 136 * Retrieves the normalized form of the provided value, which is best suited 137 * for efficiently performing matching operations on that value. 138 * 139 * @param value The value to be normalized. 140 * 141 * @return The normalized version of the provided value. 142 * 143 * @throws DirectoryException If the provided value is invalid according to 144 * the associated attribute syntax. 145 */ 146 public ByteString normalizeValue(ByteString value) 147 throws DirectoryException 148 { 149 StringBuilder buffer = new StringBuilder(); 150 buffer.append(value.stringValue().trim()); 151 152 int bufferLength = buffer.length(); 153 if (bufferLength == 0) 154 { 155 if (value.value().length > 0) 156 { 157 // This should only happen if the value is composed entirely of spaces. 158 // In that case, the normalized value is a single space. 159 return new ASN1OctetString(" "); 160 } 161 else 162 { 163 // The value is empty, so it is already normalized. 164 return new ASN1OctetString(); 165 } 166 } 167 168 169 // Replace any consecutive spaces with a single space. 170 for (int pos = bufferLength-1; pos > 0; pos--) 171 { 172 if (buffer.charAt(pos) == ' ') 173 { 174 if (buffer.charAt(pos-1) == ' ') 175 { 176 buffer.delete(pos, pos+1); 177 } 178 } 179 } 180 181 return new ASN1OctetString(buffer.toString()); 182 } 183 184 185 186 /** 187 * Compares the first value to the second and returns a value that indicates 188 * their relative order. 189 * 190 * @param value1 The normalized form of the first value to compare. 191 * @param value2 The normalized form of the second value to compare. 192 * 193 * @return A negative integer if <CODE>value1</CODE> should come before 194 * <CODE>value2</CODE> in ascending order, a positive integer if 195 * <CODE>value1</CODE> should come after <CODE>value2</CODE> in 196 * ascending order, or zero if there is no difference between the 197 * values with regard to ordering. 198 */ 199 public int compareValues(ByteString value1, ByteString value2) 200 { 201 return compare(value1.value(), value2.value()); 202 } 203 204 205 206 /** 207 * Compares the contents of the provided byte arrays to determine their 208 * relative order. 209 * 210 * @param b1 The first byte array to use in the comparison. 211 * @param b2 The second byte array to use in the comparison. 212 * 213 * @return A negative integer if <CODE>b1</CODE> should come before 214 * <CODE>b2</CODE> in ascending order, a positive integer if 215 * <CODE>b1</CODE> should come after <CODE>b2</CODE> in ascending 216 * order, or zero if there is no difference between the values with 217 * regard to ordering. 218 */ 219 public int compare(byte[] b1, byte[] b2) 220 { 221 int minLength = Math.min(b1.length, b2.length); 222 223 for (int i=0; i < minLength; i++) 224 { 225 if (b1[i] == b2[i]) 226 { 227 continue; 228 } 229 else if (b1[i] < b2[i]) 230 { 231 return -1; 232 } 233 else if (b1[i] > b2[i]) 234 { 235 return 1; 236 } 237 } 238 239 if (b1.length == b2.length) 240 { 241 return 0; 242 } 243 else if (b1.length < b2.length) 244 { 245 return -1; 246 } 247 else 248 { 249 return 1; 250 } 251 } 252 } 253