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 * http://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 org.apache.directory.api.i18n.I18n; 024import org.apache.directory.api.ldap.model.exception.LdapException; 025import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 026import org.apache.directory.api.ldap.model.name.Dn; 027import org.apache.directory.api.ldap.model.schema.LdapComparator; 028import org.apache.directory.api.ldap.model.schema.SchemaManager; 029 030 031/** 032 * A comparator that sorts OIDs based on their numeric id value. Needs a 033 * OidRegistry to properly do it's job. Public method to set the oid 034 * registry will be used by the server after instantiation in deserialization. 035 * 036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 037 */ 038public class UniqueMemberComparator extends LdapComparator<String> 039{ 040 /** The serial version UID */ 041 private static final long serialVersionUID = 2L; 042 043 /** A reference to the schema manager */ 044 private SchemaManager schemaManager; 045 046 047 /** 048 * The IntegerComparator constructor. Its OID is the IntegerOrderingMatch matching 049 * rule OID. 050 * 051 * @param oid The Comparator's OID 052 */ 053 public UniqueMemberComparator( String oid ) 054 { 055 super( oid ); 056 } 057 058 059 /** 060 * {@inheritDoc} 061 */ 062 public int compare( String dnstr1, String dnstr2 ) 063 { 064 int dash1 = dnstr1.lastIndexOf( '#' ); 065 int dash2 = dnstr2.lastIndexOf( '#' ); 066 067 if ( ( dash1 == -1 ) && ( dash2 == -1 ) ) 068 { 069 // no UID part 070 try 071 { 072 Dn dn1 = getDn( dnstr1 ); 073 Dn dn2 = getDn( dnstr2 ); 074 075 if ( dn1.equals( dn2 ) ) 076 { 077 return 0; 078 } 079 else 080 { 081 return -1; 082 } 083 } 084 catch ( LdapInvalidDnException ne ) 085 { 086 return -1; 087 } 088 } 089 else 090 { 091 // Now, check that we don't have another '#' 092 if ( dnstr1.indexOf( '#' ) != dash1 ) 093 { 094 // Yes, we have one : this is not allowed, it should have been 095 // escaped. 096 return -1; 097 } 098 099 if ( dnstr2.indexOf( '#' ) != dash1 ) 100 { 101 // Yes, we have one : this is not allowed, it should have been 102 // escaped. 103 return 1; 104 } 105 106 Dn dn1; 107 Dn dn2; 108 109 // This is an UID if the '#' is immediatly 110 // followed by a BitString, except if the '#' is 111 // on the last position 112 String uid1 = dnstr1.substring( dash1 + 1 ); 113 114 if ( dash1 > 0 ) 115 { 116 try 117 { 118 dn1 = new Dn( dnstr1.substring( 0, dash1 ) ); 119 } 120 catch ( LdapException ne ) 121 { 122 return -1; 123 } 124 } 125 else 126 { 127 return -1; 128 } 129 130 // This is an UID if the '#' is immediatly 131 // followed by a BitString, except if the '#' is 132 // on the last position 133 String uid2 = dnstr2.substring( dash2 + 1 ); 134 135 if ( dash2 > 0 ) 136 { 137 try 138 { 139 dn2 = new Dn( dnstr1.substring( 0, dash2 ) ); 140 } 141 catch ( LdapException ne ) 142 { 143 return 1; 144 } 145 } 146 else 147 { 148 return 1; 149 } 150 151 if ( dn1.equals( dn2 ) ) 152 { 153 return uid1.compareTo( uid2 ); 154 } 155 156 return -1; 157 } 158 } 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override 165 public void setSchemaManager( SchemaManager schemaManager ) 166 { 167 this.schemaManager = schemaManager; 168 } 169 170 171 /** 172 * Get the DN from the given object 173 * 174 * @param obj The object containing a DN (either as an instance of Dn or as a String) 175 * @return A Dn instance 176 * @throws LdapInvalidDnException If the Dn is invalid 177 */ 178 public Dn getDn( Object obj ) throws LdapInvalidDnException 179 { 180 Dn dn; 181 182 if ( obj instanceof Dn ) 183 { 184 dn = ( Dn ) obj; 185 186 dn = dn.isSchemaAware() ? dn : dn.apply( schemaManager ); 187 } 188 else if ( obj instanceof String ) 189 { 190 dn = new Dn( schemaManager, ( String ) obj ); 191 } 192 else 193 { 194 throw new IllegalStateException( I18n.err( I18n.ERR_04218, obj == null ? null : obj.getClass() ) ); 195 } 196 197 return dn; 198 } 199}