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.model.language.ExpressionDefinition;
029    import org.apache.camel.processor.SortProcessor;
030    import org.apache.camel.spi.RouteContext;
031    import org.apache.camel.util.ObjectHelper;
032    
033    import static org.apache.camel.builder.ExpressionBuilder.bodyExpression;
034    
035    /**
036     * Represents an XML <sort/> element
037     */
038    @XmlRootElement(name = "sort")
039    @XmlAccessorType(XmlAccessType.FIELD)
040    public class SortDefinition<T> extends NoOutputExpressionNode {
041        @XmlTransient
042        private Comparator<? super T> comparator;
043        @XmlAttribute
044        private String comparatorRef;
045    
046        public SortDefinition() {
047        }
048    
049        public SortDefinition(Expression expression) {
050            setExpression(new ExpressionDefinition(expression));
051        }
052    
053        public SortDefinition(Expression expression, Comparator<? super T> comparator) {
054            this(expression);
055            this.comparator = comparator;
056        }
057    
058        @Override
059        public String toString() {
060            return "sort[" + getExpression() + " by: " + (comparatorRef != null ? "ref:" + comparatorRef : comparator) + "]";
061        }
062        
063        @Override
064        public String getLabel() {
065            return "sort[" + getExpression() + "]";
066        }
067    
068        @Override
069        public String getShortName() {
070            return "sort";
071        }
072    
073        @Override
074        @SuppressWarnings("unchecked")
075        public Processor createProcessor(RouteContext routeContext) throws Exception {
076            // lookup in registry
077            if (ObjectHelper.isNotEmpty(comparatorRef)) {
078                comparator = routeContext.getCamelContext().getRegistry().lookup(comparatorRef, Comparator.class);
079            }
080    
081            // if no comparator then default on to string representation
082            if (comparator == null) {
083                comparator = new Comparator<T>() {
084                    public int compare(T o1, T o2) {
085                        return ObjectHelper.compare(o1, o2);
086                    }
087                };
088            }
089    
090            // if no expression provided then default to body expression
091            Expression exp;
092            if (getExpression() == null) {
093                exp = bodyExpression();
094            } else {
095                exp = getExpression().createExpression(routeContext);
096            }
097            return new SortProcessor<T>(exp, getComparator());
098        }
099    
100        public Comparator<? super T> getComparator() {
101            return comparator;
102        }
103    
104        public void setComparator(Comparator<T> comparator) {
105            this.comparator = comparator;
106        }
107    
108        public String getComparatorRef() {
109            return comparatorRef;
110        }
111    
112        public void setComparatorRef(String comparatorRef) {
113            this.comparatorRef = comparatorRef;
114        }
115    
116        /**
117         * Sets the comparator to use for sorting
118         *
119         * @param comparator  the comparator to use for sorting
120         * @return the builder
121         */
122        public SortDefinition<T> comparator(Comparator<T> comparator) {
123            setComparator(comparator);
124            return this;
125        }
126    
127        /**
128         * Sets a reference to lookup for the comparator to use for sorting
129         *
130         * @param ref reference for the comparator
131         * @return the builder
132         */
133        public SortDefinition<T> comparatorRef(String ref) {
134            setComparatorRef(ref);
135            return this;
136        }
137    }