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.Collections;
020    import java.util.Comparator;
021    import java.util.List;
022    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlAttribute;
025    import javax.xml.bind.annotation.XmlElement;
026    import javax.xml.bind.annotation.XmlRootElement;
027    import javax.xml.bind.annotation.XmlTransient;
028    
029    import org.apache.camel.Expression;
030    import org.apache.camel.Processor;
031    import org.apache.camel.processor.SortProcessor;
032    import org.apache.camel.spi.RouteContext;
033    import org.apache.camel.util.ObjectHelper;
034    import static org.apache.camel.builder.ExpressionBuilder.bodyExpression;
035    
036    /**
037     * Represents an XML <sort/> element
038     */
039    @XmlRootElement(name = "sort")
040    @XmlAccessorType(XmlAccessType.FIELD)
041    public class SortDefinition extends OutputDefinition<SortDefinition> {
042        @XmlTransient
043        private Comparator<Object> comparator;
044        @XmlAttribute(required = false)
045        private String comparatorRef;
046        @XmlElement(name = "expression", required = false)
047        private ExpressionSubElementDefinition expression;
048    
049        public SortDefinition() {
050        }
051    
052        public SortDefinition(Expression expression) {
053            setExpression(expression);
054        }
055    
056        public SortDefinition(Expression expression, Comparator<Object> comparator) {
057            this(expression);
058            this.comparator = comparator;
059        }
060    
061        @Override
062        public String toString() {
063            return "sort[" + getExpression() + " by: " + (comparatorRef != null ? "ref:" + comparatorRef : comparator) + "]";
064        }
065    
066        @Override
067        public String getShortName() {
068            return "sort";
069        }
070    
071        @Override
072        @SuppressWarnings("unchecked")
073        public Processor createProcessor(RouteContext routeContext) throws Exception {
074            // lookup in registry
075            if (ObjectHelper.isNotEmpty(comparatorRef)) {
076                comparator = routeContext.getCamelContext().getRegistry().lookup(comparatorRef, Comparator.class);
077            }
078    
079            // if no comparator then default on to string representation
080            if (comparator == null) {
081                comparator = new Comparator<Object>() {
082                    public int compare(Object o1, Object o2) {
083                        return ObjectHelper.compare(o1, o2);
084                    }
085                };
086            }
087    
088            // if no expression provided then default to body expression
089            if (getExpression() == null) {
090                setExpression(bodyExpression());
091            }
092    
093            Expression exp = expression.getExpression();
094            // fallback to the type when its been initialized from JAXB using camel-spring
095            if (exp == null) {
096                exp = expression.getExpressionType();
097            }
098            return new SortProcessor(exp, getComparator());
099        }
100    
101        @Override
102        @SuppressWarnings("unchecked")
103        public List<ProcessorDefinition> getOutputs() {
104            return Collections.EMPTY_LIST;
105        }
106    
107        public Comparator<Object> getComparator() {
108            return comparator;
109        }
110    
111        public void setComparator(Comparator<Object> comparator) {
112            this.comparator = comparator;
113        }
114    
115        public String getComparatorRef() {
116            return comparatorRef;
117        }
118    
119        public void setComparatorRef(String comparatorRef) {
120            this.comparatorRef = comparatorRef;
121        }
122    
123        public ExpressionSubElementDefinition getExpression() {
124            return expression;
125        }
126    
127        public void setExpression(Expression expression) {
128            this.expression = new ExpressionSubElementDefinition(expression);
129        }
130    
131        public void setExpression(ExpressionSubElementDefinition expression) {
132            this.expression = expression;
133        }
134    
135        /**
136         * Sets the comparator to use for sorting
137         *
138         * @param comparator  the comparator to use for sorting
139         * @return the builder
140         */
141        public SortDefinition comparator(Comparator<Object> comparator) {
142            setComparator(comparator);
143            return this;
144        }
145    
146        /**
147         * Sets a reference to lookup for the comparator to use for sorting
148         *
149         * @param ref reference for the comparator
150         * @return the builder
151         */
152        public SortDefinition comparatorRef(String ref) {
153            setComparatorRef(ref);
154            return this;
155        }
156    }