| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.server.core.shared; |
| |
| |
| import java.util.Comparator; |
| import java.util.TreeSet; |
| |
| import org.apache.directory.api.ldap.model.entry.Attribute; |
| import org.apache.directory.api.ldap.model.entry.Entry; |
| import org.apache.directory.api.ldap.model.entry.Value; |
| import org.apache.directory.api.ldap.model.exception.LdapException; |
| import org.apache.directory.api.ldap.model.schema.AttributeType; |
| import org.apache.directory.api.ldap.model.schema.LdapComparator; |
| import org.apache.directory.api.ldap.model.schema.MatchingRule; |
| import org.apache.directory.api.ldap.model.schema.SchemaManager; |
| |
| /** |
| * A comparator to sort the entries as per <a href="http://tools.ietf.org/html/rfc2891">RFC 2891</a> |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| class SortedEntryComparator implements Comparator<Entry> |
| { |
| |
| /** the attribute's type */ |
| private AttributeType type; |
| |
| /** comparator used for comparing the values of the given attribute type */ |
| private Comparator comparator; |
| |
| /** flag to indicate if the attribute type is multivalued */ |
| private boolean multivalued; |
| |
| /** flag for indicating the order of sorting */ |
| private boolean reverse; |
| |
| /** flag to indicate if the attribute is human readable or binary */ |
| private boolean hr; |
| |
| |
| /** |
| * |
| * Creates a new instance of SortedEntryComparator. |
| * |
| * @param at the attribute's type |
| * @param mrOid the OID or name of the matchingrule |
| * @param reverse flag to indicate the sort order |
| */ |
| public SortedEntryComparator( AttributeType at, String mrule, boolean reverse, SchemaManager schemaManager ) throws LdapException |
| { |
| this.type = at; |
| this.reverse = reverse; |
| |
| if ( !at.isSingleValued() ) |
| { |
| multivalued = true; |
| } |
| |
| hr = at.getSyntax().isHumanReadable(); |
| |
| if( mrule != null ) |
| { |
| comparator = schemaManager.lookupComparatorRegistry( mrule ); |
| } |
| else |
| { |
| MatchingRule mr = at.getOrdering(); |
| |
| if( mr == null ) |
| { |
| mr = at.getEquality(); |
| } |
| |
| comparator = schemaManager.lookupComparatorRegistry( mr.getOid() ); |
| } |
| |
| ( ( LdapComparator ) comparator ).setSchemaManager( schemaManager ); |
| } |
| |
| |
| @Override |
| public int compare( Entry entry1, Entry entry2 ) |
| { |
| Attribute at1 = entry1.get( type ); |
| |
| Attribute at2 = entry2.get( type ); |
| |
| // as per section 2.2 of the spec null values are considered larger |
| if ( at1 == null ) |
| { |
| return ( reverse ? -1 : 1 ); |
| } |
| else if ( at2 == null ) |
| { |
| return ( reverse ? 1 : -1 ); |
| } |
| |
| Object o1 = null; |
| Object o2 = null; |
| |
| if ( multivalued ) |
| { |
| TreeSet ts = new TreeSet( comparator ); |
| |
| o1 = sortAndGetFirst( at1, ts ); |
| |
| ts.clear(); |
| o2 = sortAndGetFirst( at2, ts ); |
| } |
| else |
| { |
| Value<?> v1 = at1.get(); |
| Value<?> v2 = at2.get(); |
| |
| if ( hr ) |
| { |
| o1 = v1.getString(); |
| o2 = v2.getString(); |
| } |
| else |
| { |
| o1 = v1.getBytes(); |
| o2 = v2.getBytes(); |
| } |
| } |
| |
| if( o1 == null || o2 == null ) |
| { |
| System.out.println(""); |
| } |
| int c = 1; |
| |
| if ( reverse ) |
| { |
| c = comparator.compare( o2, o1 ); |
| } |
| else |
| { |
| c = comparator.compare( o1, o2 ); |
| } |
| |
| if ( c == 0 ) |
| { |
| return 1; |
| } |
| |
| return c; |
| } |
| |
| |
| /** |
| * sorts the values of an attribute and picks the least value |
| * |
| * @param at the attribute |
| * @param ts the TreeSet for sorting |
| * @return the least value among the values of the attribute |
| */ |
| private Object sortAndGetFirst( Attribute at, TreeSet ts ) |
| { |
| for ( Value v : at ) |
| { |
| if ( hr ) |
| { |
| ts.add( v.getString() ); |
| } |
| else |
| { |
| ts.add( v.getBytes() ); |
| } |
| } |
| |
| return ts.first(); |
| } |
| } |