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.server.schema;
021    
022    
023    import java.io.Serializable;
024    import java.util.Comparator;
025    
026    import javax.naming.NamingException;
027    
028    import org.apache.directory.server.schema.registries.ComparatorRegistry;
029    
030    
031    /**
032     * A serializable wrapper around a Comparator which uses delayed initialization
033     * of the underlying wrapped comparator which is JIT resolved from a static
034     * global registry.
035     *
036     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037     * @version $Rev: 777279 $
038     */
039    public class SerializableComparator<E> implements Comparator<E>, Serializable
040    {
041        private static final long serialVersionUID = 3257566226288162870L;
042    
043        /** the system global Comparator registry */
044        private static ComparatorRegistry registry;
045        /** the OID of the matchingRule for this comparator */
046        private String matchingRuleOid;
047        /** the transient wrapped comparator */
048        private transient Comparator<E> wrapped;
049    
050    
051        // ------------------------------------------------------------------------
052        // S T A T I C   M E T H O D S
053        // ------------------------------------------------------------------------
054    
055        /**
056         * Sets the global Comparator registry for comparator lookups.
057         *
058         * @param registry the comparator registry to use for Comparator lookups
059         */
060        public static void setRegistry( ComparatorRegistry registry )
061        {
062            SerializableComparator.registry = registry;
063        }
064    
065    
066        // ------------------------------------------------------------------------
067        // C O N T R U C T O R S
068        // ------------------------------------------------------------------------
069    
070    
071        public SerializableComparator( String matchingRuleOid )
072        {
073            this.matchingRuleOid = matchingRuleOid;
074        }
075    
076    
077        // ------------------------------------------------------------------------
078        // C O M P A R A T O R   I M P L E M E N T A T I O N S
079        // ------------------------------------------------------------------------
080    
081        /**
082         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
083         */
084        @SuppressWarnings("unchecked")
085        public int compare( E o1, E o2 )
086        {
087            if ( wrapped == null )
088            {
089                try
090                {
091                    wrapped = (Comparator<E>)registry.lookup( matchingRuleOid );
092                }
093                catch ( NamingException e )
094                {
095                    throw new RuntimeException( "Matching rule not found: " + matchingRuleOid );
096                }
097            }
098    
099            return wrapped.compare( o1, o2 );
100        }
101    }