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
020package org.apache.wiki.pages;
021
022import org.apache.log4j.Logger;
023import org.apache.wiki.util.ClassUtil;
024import org.apache.wiki.util.comparators.JavaNaturalComparator;
025
026import java.util.Arrays;
027import java.util.Comparator;
028import java.util.List;
029import java.util.Properties;
030
031/**
032 * Wrapper class for managing and using the PageNameComparator.
033 * <p>
034 * <b>Note</b> - this class is deliberately not null safe. Never call any of the methods with a null argument!
035 */
036public class PageSorter implements Comparator< String > {
037    
038    private static final Logger LOG = Logger.getLogger( PageSorter.class );
039
040    // The name of the property that specifies the desired page name comparator
041    protected static final String PROP_PAGE_NAME_COMPARATOR = "jspwiki.pageNameComparator.class";
042
043    private Comparator< String > m_comparator;
044
045    /** Default constructor uses Java "natural" ordering. */
046    public PageSorter() {
047        m_comparator = JavaNaturalComparator.DEFAULT_JAVA_COMPARATOR;
048    }
049
050    /**
051     * Construct with a particular comparator.
052     * 
053     * @param comparator the Comparator to use
054     */
055    public PageSorter( final Comparator<String> comparator ) {
056        m_comparator = comparator;
057    }
058
059    /**
060     * Compare two page names (String version).
061     * 
062     * @param pageName1 the first page name
063     * @param pageName2 the second page name
064     * @return see java.util.Comparator
065     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
066     */
067    @Override
068    public int compare( final String pageName1, final String pageName2 ) {
069        return m_comparator.compare( pageName1, pageName2 );
070    }
071
072    @Override
073    public boolean equals( final Object o ) {
074        if( !( o instanceof PageSorter ) ) {
075            return false; // Definitely not equal
076        }
077        final PageSorter that = ( PageSorter )o;
078        if( this == that || m_comparator == that.m_comparator ) {
079            return true; // Essentially the same object
080        }
081        return m_comparator.equals( that.m_comparator );
082    }
083
084    /**
085     * Called by Engine to initialise this instance. Tries to use class given by the PROP_PAGE_NAME_COMPARATOR property as the page name
086     * comparator. Uses a default comparator if this property is not set or there is any problem loading the specified class.
087     * 
088     * @param props this Engine's properties.
089     */
090    @SuppressWarnings( "unchecked" )
091    public void initialize( final Properties props ) {
092        // Default is Java natural order
093        m_comparator = JavaNaturalComparator.DEFAULT_JAVA_COMPARATOR;
094        final String className = props.getProperty( PROP_PAGE_NAME_COMPARATOR );
095        if( className != null && className.length() > 0 ) {
096            try {
097                m_comparator = ( Comparator< String > )ClassUtil.findClass( "org.apache.wiki.util.comparators", className ).newInstance();
098            } catch( final Exception e ) {
099                LOG.error( "Falling back to default \"natural\" comparator", e );
100            }
101        }
102    }
103
104    /**
105     * Sorts the specified list into ascending order based on the PageNameComparator. The actual sort is done using {@code List.sort()}.
106     * 
107     * @param nameList the page names to be sorted
108     */
109    public void sort( final List< String > nameList ) {
110        nameList.sort( m_comparator );
111    }
112
113    /**
114     * Sorts the specified array into ascending order based on the PageNameComparator. The actual sort is done using {@code Arrays.sort()}.
115     * 
116     * @param nameArray the page names to be sorted
117     */
118    public void sort( final String[] nameArray ) {
119        Arrays.sort( nameArray, m_comparator );
120    }
121
122}