001    /*
002    Copyright (c) 1996-2012, Damon Hart-Davis
003    All rights reserved.
004    
005    Redistribution and use in source and binary forms, with or without
006    modification, are permitted provided that the following conditions are
007    met:
008    
009      * Redistributions of source code must retain the above copyright
010        notice, this list of conditions and the following disclaimer.
011    
012      * Redistributions in binary form must reproduce the above copyright
013        notice, this list of conditions and the following disclaimer in the
014        documentation and/or other materials provided with the
015        distribution.
016    
017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028    */
029    package org.hd.d.pg2k.webSvr.exhibit;
030    
031    import org.hd.d.pg2k.svrCore.AllExhibitProperties;
032    import org.hd.d.pg2k.svrCore.Name;
033    
034    /**Wraps a sorter to make an expression (for a FilterBean).
035     * Sorters must be Serializable so that expressions can
036     * be persisted.  They must not attempt to cache any reference,
037     * direct or indirect, to a DataSourceBean.
038     * <p>
039     * Sorter objects must be immutable and the sort() method must be
040     * idempotent.
041     * <p>
042     * TODO: do object validation on deserialisation
043     */
044    public final class SortExpr extends Expr
045                                implements java.io.Serializable
046        {
047        /**The sort we apply here; never null. */
048        private final SortIF sorter;
049    
050        /**Construct us with the upstream expression.
051         * If the upstream expression is null this is the first
052         * element in the expression pipeline.
053         */
054        public SortExpr(final Expr _upstream, final SortIF _sorter)
055            {
056            super(_upstream);
057            if(_sorter == null) { throw new IllegalArgumentException(); }
058            sorter = _sorter;
059            }
060    
061        /**Evaluate this expression applying our sort.
062         * Given the upstream expression, compute its results and
063         * then compute ours on it.
064         * <p>
065         * We return a set of names, possibly empty.
066         * <p>
067         * The result array contains no duplicates nor nulls
068         * (providing the input is similarly well-behaved)
069         * and is never null itself.
070         * <p>
071         * Designed to be overridden and have super() called to
072         * collect upstream results...  By itself returns all
073         * the exhibits untouched, ie is a null filter/sorter.
074         * <p>
075         * The result may be the input array sorted in place to avoid
076         * copying, or may be a new array possibly smaller than the
077         * input array; this may perform filtering or other operations
078         * that needs to operate on the whole (current) set of exhibits
079         * at once.
080         */
081        @Override
082        public Name.ExhibitFull[] eval(final AllExhibitProperties aep, final Name.ExhibitFull[] in)
083            {
084            // Chose our input.
085            final Name.ExhibitFull input[] = super.eval(aep, in);
086            // Sort in situ or into a new array.
087            return(sorter.sort(aep, input));
088            }
089    
090        /**Hash depends on underlying expression and this sorter. */
091        @Override
092        public int hashCode()
093            {
094            return((super.hashCode() << 7) + sorter.hashCode());
095            }
096    
097        /**Equality depends on underlying expression and this sorter. */
098        @Override
099        public boolean equals(final Object obj)
100            {
101            if(!(obj instanceof SortExpr)) { return(false); }
102            final SortExpr other = (SortExpr) obj;
103            if(!sorter.equals(other.sorter)) { return(false); }
104            return(super.equals(obj));
105            }
106    
107    
108        /**Unique Serialisation class ID generated by http://random.hd.org/. */
109        private static final long serialVersionUID = -7947761366290611963L;
110        }