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