1 /******************************************************************************
3 * Copyright (c) 2003 Novell Inc. www.novell.com
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 *******************************************************************************/
24 // Novell.Directory.Ldap.LdapCompareAttrNames.cs
27 // Sunil Kumar (Sunilk@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
33 using Novell
.Directory
.Ldap
.Utilclass
;
35 namespace Novell
.Directory
.Ldap
39 /// <summary> Compares Ldap entries based on attribute name.
41 /// An object of this class defines ordering when sorting LdapEntries,
42 /// usually from search results. When using this Comparator, LdapEntry objects
43 /// are sorted by the attribute names(s) passed in on the
44 /// constructor, in ascending or descending order. The object is typically
45 /// supplied to an implementation of the collection interfaces such as
46 /// java.util.TreeSet which performs sorting.
48 /// Comparison is performed via locale-sensitive Java String comparison,
49 /// which may not correspond to the Ldap ordering rules by which an Ldap server
53 public class LdapCompareAttrNames
: System
.Collections
.IComparer
55 private void InitBlock()
57 // location = Locale.getDefault();
58 location
=System
.Globalization
.CultureInfo
.CurrentCulture
;
59 collator
= System
.Globalization
.CultureInfo
.CurrentCulture
.CompareInfo
;
61 /// <summary> Returns the locale to be used for sorting, if a locale has been
64 /// If locale is null, a basic String.compareTo method is used for
65 /// collation. If non-null, a locale-specific collation is used.
68 /// <returns> The locale if one has been specified
70 /// <summary> Sets the locale to be used for sorting.
73 /// <param name="locale"> The locale to be used for sorting.
75 virtual public System
.Globalization
.CultureInfo Locale
79 //currently supports only English local.
85 collator
= value.CompareInfo
;
90 private System
.String
[] sortByNames
; //names to to sort by.
91 private bool[] sortAscending
; //true if sorting ascending
92 private System
.Globalization
.CultureInfo location
;
93 private System
.Globalization
.CompareInfo collator
;
95 /// <summary> Constructs an object that sorts results by a single attribute, in
99 /// <param name="attrName"> Name of an attribute by which to sort.
102 public LdapCompareAttrNames(System
.String attrName
)
105 sortByNames
= new System
.String
[1];
106 sortByNames
[0] = attrName
;
107 sortAscending
= new bool[1];
108 sortAscending
[0] = true;
111 /// <summary> Constructs an object that sorts results by a single attribute, in
112 /// either ascending or descending order.
115 /// <param name="attrName"> Name of an attribute to sort by.
118 /// <param name="ascendingFlag"> True specifies ascending order; false specifies
119 /// descending order.
121 public LdapCompareAttrNames(System
.String attrName
, bool ascendingFlag
)
124 sortByNames
= new System
.String
[1];
125 sortByNames
[0] = attrName
;
126 sortAscending
= new bool[1];
127 sortAscending
[0] = ascendingFlag
;
131 /// <summary> Constructs an object that sorts by one or more attributes, in the
132 /// order provided, in ascending order.
134 /// Note: Novell eDirectory allows sorting by one attribute only. The
135 /// direcctory server must also be configured to index the specified
139 /// <param name="attrNames"> Array of names of attributes to sort by.
142 public LdapCompareAttrNames(System
.String
[] attrNames
)
145 sortByNames
= new System
.String
[attrNames
.Length
];
146 sortAscending
= new bool[attrNames
.Length
];
147 for (int i
= 0; i
< attrNames
.Length
; i
++)
149 sortByNames
[i
] = attrNames
[i
];
150 sortAscending
[i
] = true;
154 /// <summary> Constructs an object that sorts by one or more attributes, in the
155 /// order provided, in either ascending or descending order for each
158 /// Note: Novell eDirectory supports only ascending sort order (A,B,C ...)
159 /// and allows sorting only by one attribute. The directory server must be
160 /// configured to index this attribute.
163 /// <param name="attrNames"> Array of names of attributes to sort by.
166 /// <param name="ascendingFlags"> Array of flags, one for each attrName, where
167 /// true specifies ascending order and false specifies
168 /// descending order. An LdapException is thrown if
169 /// the length of ascendingFlags is not greater than
170 /// or equal to the length of attrNames.
173 /// <exception> LdapException A general exception which includes an error
174 /// message and an Ldap error code.
177 public LdapCompareAttrNames(System
.String
[] attrNames
, bool[] ascendingFlags
)
180 if (attrNames
.Length
!= ascendingFlags
.Length
)
182 throw new LdapException(ExceptionMessages
.UNEQUAL_LENGTHS
, LdapException
.INAPPROPRIATE_MATCHING
, (System
.String
) null);
183 //"Length of attribute Name array does not equal length of Flags array"
185 sortByNames
= new System
.String
[attrNames
.Length
];
186 sortAscending
= new bool[ascendingFlags
.Length
];
187 for (int i
= 0; i
< attrNames
.Length
; i
++)
189 sortByNames
[i
] = attrNames
[i
];
190 sortAscending
[i
] = ascendingFlags
[i
];
194 /// <summary> Compares the the attributes of the first LdapEntry to the second.
195 /// Only the values of the attributes named at the construction of this
196 /// object will be compared. Multi-valued attributes compare on the first
200 /// <param name="object1"> Target entry for comparison.
203 /// <param name="object2"> Entry to be compared to.
206 /// <returns> Negative value if the first entry is less than the second and
207 /// positive if the first is greater than the second. Zero is returned if all
208 /// attributes to be compared are the same.
210 public virtual int Compare(System
.Object object1
, System
.Object object2
)
212 LdapEntry entry1
= (LdapEntry
) object1
;
213 LdapEntry entry2
= (LdapEntry
) object2
;
214 LdapAttribute one
, two
;
215 System
.String
[] first
; //multivalued attributes are ignored.
216 System
.String
[] second
; //we just use the first element
218 if (collator
== null)
220 //using default locale
221 collator
= System
.Globalization
.CultureInfo
.CurrentCulture
.CompareInfo
;
226 //while first and second are equal
227 one
= entry1
.getAttribute(sortByNames
[i
]);
228 two
= entry2
.getAttribute(sortByNames
[i
]);
229 if ((one
!= null) && (two
!= null))
231 first
= one
.StringValueArray
;
232 second
= two
.StringValueArray
;
233 compare
= collator
.Compare(first
[0], second
[0]);
235 //We could also use the other multivalued attributes to break ties.
236 //one of the entries was null
241 //one is greater than two
242 else if (two
!= null)
244 //one is lesser than two
246 compare
= 0; //tie - break it with the next attribute name
251 while ((compare
== 0) && (i
< sortByNames
.Length
));
253 if (sortAscending
[i
- 1])
255 // return the normal ascending comparison.
260 // negate the comparison for a descending comparison.
265 /// <summary> Determines if this comparator is equal to the comparator passed in.
267 /// This will return true if the comparator is an instance of
268 /// LdapCompareAttrNames and compares the same attributes names in the same
272 /// <returns> true the comparators are equal
274 public override bool Equals(System
.Object comparator
)
276 if (!(comparator
is LdapCompareAttrNames
))
280 LdapCompareAttrNames comp
= (LdapCompareAttrNames
) comparator
;
282 // Test to see if the attribute to compare are the same length
283 if ((comp
.sortByNames
.Length
!= this.sortByNames
.Length
) || (comp
.sortAscending
.Length
!= this.sortAscending
.Length
))
288 // Test to see if the attribute names and sorting orders are the same.
289 for (int i
= 0; i
< this.sortByNames
.Length
; i
++)
291 if (comp
.sortAscending
[i
] != this.sortAscending
[i
])
293 if (!comp
.sortByNames
[i
].ToUpper().Equals(this.sortByNames
[i
].ToUpper()))