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