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