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   *    http://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.server.schema;
21  
22  
23  import java.util.Comparator;
24  
25  import javax.naming.Name;
26  import javax.naming.NamingException;
27  
28  import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
29  import org.apache.directory.server.schema.registries.Registries;
30  import org.apache.directory.shared.ldap.name.LdapDN;
31  
32  
33  /**
34   * A comparator for the uniqueMember match
35   * 
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   * @version $Rev$
38   */
39  public class NameAndOptionalUIDComparator implements Comparator
40  {
41      // @TODO you'll need this to fix the way normalization is done
42      private AttributeTypeRegistry attrRegistry;
43      
44      
45      public NameAndOptionalUIDComparator( AttributeTypeRegistry attrRegistry )
46      {
47          this.attrRegistry = attrRegistry;
48      }
49      
50      
51      public NameAndOptionalUIDComparator()
52      {
53      }
54  
55      
56      public void setRegistries( Registries registries )
57      {
58          attrRegistry = registries.getAttributeTypeRegistry();
59      }
60      
61      /**
62       * Comparing two uniqueMember is a matter of following this algorithm:
63       * - if they are only DN, then the values should be equal
64       * - otherwise, both element should contain the same DN and 
65       *   * if they both have an UID, they should be equals.
66       */
67      public int compare( Object obj0, Object obj1 )
68      {
69          String dnstr0 = null;
70          String dnstr1 = null;
71          
72          if ( ( obj0 instanceof String ) && ( obj1 instanceof String) )
73          {
74              dnstr0 = (String)obj0;
75              dnstr1 = (String)obj1;
76              
77              int dash0 = dnstr0.lastIndexOf( '#' );
78              int dash1 = dnstr1.lastIndexOf( '#' );
79              
80              if ( ( dash0 == -1 ) && ( dash1 == -1 ) )
81              {
82                  // no UID part
83                  try
84                  {
85                      return getDn( dnstr0 ).compareTo( getDn ( dnstr1 ) );
86                  }
87                  catch ( NamingException ne )
88                  {
89                      return -1;
90                  }
91              }
92              else
93              {
94                  // Now, check that we don't have another '#'
95                  if ( dnstr0.indexOf( '#' ) != dash0 )
96                  {
97                      // Yes, we have one : this is not allowed, it should have been
98                      // escaped.
99                      return -1;
100                 }
101                 
102                 if ( dnstr1.indexOf( '#' ) != dash0 )
103                 {
104                     // Yes, we have one : this is not allowed, it should have been
105                     // escaped.
106                     return 1;
107                 }
108                 
109                 LdapDN dn0 = null;
110                 LdapDN dn1 = null;
111                 
112                 // This is an UID if the '#' is immediatly
113                 // followed by a BitString, except if the '#' is
114                 // on the last position
115                 String uid0 = dnstr0.substring( dash0 + 1 );
116                 
117                 if ( dash0 > 0 )
118                 {
119                     try
120                     {
121                         dn0 = new LdapDN( dnstr0.substring( 0, dash0 ) );
122                     }
123                     catch ( NamingException ne )
124                     {
125                         return -1;
126                     }
127                 }
128                 else
129                 {
130                     return -1;
131                 }
132                 
133                 // This is an UID if the '#' is immediatly
134                 // followed by a BitString, except if the '#' is
135                 // on the last position
136                 String uid1 = dnstr1.substring( dash1 + 1 );
137                 
138                 if ( dash1 > 0 )
139                 {
140                     try
141                     {
142                         dn1 = new LdapDN( dnstr0.substring( 0, dash1 ) );
143                     }
144                     catch ( NamingException ne )
145                     {
146                         return 1;
147                     }
148                 }
149                 else
150                 {
151                     return 1;
152                 }
153                 
154                 int dnComp = dn0.compareTo( dn1 );
155                 
156                 if ( dnComp != 0 )
157                 {
158                     return dnComp;
159                 }
160                 
161                 return uid0.compareTo( uid1 );
162             }
163         }
164         else
165         {
166             return -1;
167         }
168     }
169 
170 
171     public LdapDN getDn( Object obj ) throws NamingException
172     {
173         LdapDN dn = null;
174         
175         if ( obj instanceof LdapDN )
176         {
177             dn = (LdapDN)obj;
178             
179             dn = ( dn.isNormalized() ? dn : LdapDN.normalize( dn, attrRegistry.getNormalizerMapping() ) );
180         }
181         else if ( obj instanceof Name )
182         {
183             dn = new LdapDN( ( Name ) obj );
184             dn.normalize( attrRegistry.getNormalizerMapping() );
185         }
186         else if ( obj instanceof String )
187         {
188             dn = new LdapDN( ( String ) obj );
189             dn.normalize( attrRegistry.getNormalizerMapping() );
190         }
191         else
192         {
193             throw new IllegalStateException( "I do not know how to handle dn comparisons with objects of class: " 
194                 + (obj == null ? null : obj.getClass() ) );
195         }
196         
197         return dn;
198     }
199 }