001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.model;
018    
019    import java.util.Comparator;
020    import javax.xml.bind.annotation.XmlAccessType;
021    import javax.xml.bind.annotation.XmlAccessorType;
022    import javax.xml.bind.annotation.XmlAttribute;
023    import javax.xml.bind.annotation.XmlRootElement;
024    import javax.xml.bind.annotation.XmlTransient;
025    
026    import org.apache.camel.Expression;
027    import org.apache.camel.Processor;
028    import org.apache.camel.processor.SortProcessor;
029    import org.apache.camel.spi.RouteContext;
030    import org.apache.camel.util.ObjectHelper;
031    
032    import static org.apache.camel.builder.ExpressionBuilder.bodyExpression;
033    
034    /**
035     * Represents an XML <sort/> element
036     */
037    @XmlRootElement(name = "sort")
038    @XmlAccessorType(XmlAccessType.FIELD)
039    public class SortDefinition<T> extends NoOutputExpressionNode {
040        @XmlTransient
041        private Comparator<? super T> comparator;
042        @XmlAttribute
043        private String comparatorRef;
044    
045        public SortDefinition() {
046        }
047    
048        public SortDefinition(Expression expression) {
049            setExpression(ExpressionNodeHelper.toExpressionDefinition(expression));
050        }
051    
052        public SortDefinition(Expression expression, Comparator<? super T> comparator) {
053            this(expression);
054            this.comparator = comparator;
055        }
056    
057        @Override
058        public String toString() {
059            return "sort[" + getExpression() + " by: " + (comparatorRef != null ? "ref:" + comparatorRef : comparator) + "]";
060        }
061        
062        @Override
063        public String getLabel() {
064            return "sort[" + getExpression() + "]";
065        }
066    
067        @Override
068        public String getShortName() {
069            return "sort";
070        }
071    
072        @Override
073        @SuppressWarnings("unchecked")
074        public Processor createProcessor(RouteContext routeContext) throws Exception {
075            // lookup in registry
076            if (ObjectHelper.isNotEmpty(comparatorRef)) {
077                comparator = routeContext.getCamelContext().getRegistry().lookupByNameAndType(comparatorRef, Comparator.class);
078            }
079    
080            // if no comparator then default on to string representation
081            if (comparator == null) {
082                comparator = new Comparator<T>() {
083                    public int compare(T o1, T o2) {
084                        return ObjectHelper.compare(o1, o2);
085                    }
086                };
087            }
088    
089            // if no expression provided then default to body expression
090            Expression exp;
091            if (getExpression() == null) {
092                exp = bodyExpression();
093            } else {
094                exp = getExpression().createExpression(routeContext);
095            }
096            return new SortProcessor<T>(exp, getComparator());
097        }
098    
099        public Comparator<? super T> getComparator() {
100            return comparator;
101        }
102    
103        public void setComparator(Comparator<T> comparator) {
104            this.comparator = comparator;
105        }
106    
107        public String getComparatorRef() {
108            return comparatorRef;
109        }
110    
111        public void setComparatorRef(String comparatorRef) {
112            this.comparatorRef = comparatorRef;
113        }
114    
115        /**
116         * Sets the comparator to use for sorting
117         *
118         * @param comparator  the comparator to use for sorting
119         * @return the builder
120         */
121        public SortDefinition<T> comparator(Comparator<T> comparator) {
122            setComparator(comparator);
123            return this;
124        }
125    
126        /**
127         * Sets a reference to lookup for the comparator to use for sorting
128         *
129         * @param ref reference for the comparator
130         * @return the builder
131         */
132        public SortDefinition<T> comparatorRef(String ref) {
133            setComparatorRef(ref);
134            return this;
135        }
136    }