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.Collections; 020import java.util.List; 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlAttribute; 024import javax.xml.bind.annotation.XmlRootElement; 025 026import org.apache.camel.Expression; 027import org.apache.camel.Processor; 028import org.apache.camel.model.language.ExpressionDefinition; 029import org.apache.camel.model.language.HeaderExpression; 030import org.apache.camel.processor.RoutingSlip; 031import org.apache.camel.spi.Metadata; 032import org.apache.camel.spi.RouteContext; 033 034/** 035 * Routes a message through a series of steps that are pre-determined (the slip) 036 */ 037@Metadata(label = "eip,endpoint,routing") 038@XmlRootElement(name = "routingSlip") 039@XmlAccessorType(XmlAccessType.FIELD) 040public class RoutingSlipDefinition<Type extends ProcessorDefinition<Type>> extends NoOutputExpressionNode { 041 public static final String DEFAULT_DELIMITER = ","; 042 043 @XmlAttribute @Metadata(defaultValue = ",") 044 private String uriDelimiter; 045 @XmlAttribute 046 private Boolean ignoreInvalidEndpoints; 047 @XmlAttribute 048 private Integer cacheSize; 049 050 public RoutingSlipDefinition() { 051 this((String)null, DEFAULT_DELIMITER); 052 } 053 054 public RoutingSlipDefinition(String headerName) { 055 this(headerName, DEFAULT_DELIMITER); 056 } 057 058 public RoutingSlipDefinition(String headerName, String uriDelimiter) { 059 super(new HeaderExpression(headerName)); 060 setUriDelimiter(uriDelimiter); 061 } 062 063 public RoutingSlipDefinition(Expression expression, String uriDelimiter) { 064 super(expression); 065 setUriDelimiter(uriDelimiter); 066 } 067 068 public RoutingSlipDefinition(Expression expression) { 069 this(expression, DEFAULT_DELIMITER); 070 } 071 072 @Override 073 public String toString() { 074 return "RoutingSlip[" + getExpression() + "]"; 075 } 076 077 @Override 078 public String getLabel() { 079 return "routingSlip[" + getExpression() + "]"; 080 } 081 082 @Override 083 public Processor createProcessor(RouteContext routeContext) throws Exception { 084 Expression expression = getExpression().createExpression(routeContext); 085 String delimiter = getUriDelimiter() != null ? getUriDelimiter() : DEFAULT_DELIMITER; 086 087 RoutingSlip routingSlip = new RoutingSlip(routeContext.getCamelContext(), expression, delimiter); 088 if (getIgnoreInvalidEndpoints() != null) { 089 routingSlip.setIgnoreInvalidEndpoints(getIgnoreInvalidEndpoints()); 090 } 091 if (getCacheSize() != null) { 092 routingSlip.setCacheSize(getCacheSize()); 093 } 094 return routingSlip; 095 } 096 097 @Override 098 public List<ProcessorDefinition<?>> getOutputs() { 099 return Collections.emptyList(); 100 } 101 102 /** 103 * Expression to define the routing slip, which defines which endpoints to route the message in a pipeline style. 104 * Notice the expression is evaluated once, if you want a more dynamic style, then the dynamic router eip is a better choice. 105 */ 106 @Override 107 public void setExpression(ExpressionDefinition expression) { 108 // override to include javadoc what the expression is used for 109 super.setExpression(expression); 110 } 111 112 public void setUriDelimiter(String uriDelimiter) { 113 this.uriDelimiter = uriDelimiter; 114 } 115 116 public String getUriDelimiter() { 117 return uriDelimiter; 118 } 119 120 public void setIgnoreInvalidEndpoints(Boolean ignoreInvalidEndpoints) { 121 this.ignoreInvalidEndpoints = ignoreInvalidEndpoints; 122 } 123 124 public Boolean getIgnoreInvalidEndpoints() { 125 return ignoreInvalidEndpoints; 126 } 127 128 public Integer getCacheSize() { 129 return cacheSize; 130 } 131 132 public void setCacheSize(Integer cacheSize) { 133 this.cacheSize = cacheSize; 134 } 135 136 // Fluent API 137 // ------------------------------------------------------------------------- 138 139 @Override 140 @SuppressWarnings("unchecked") 141 public Type end() { 142 // allow end() to return to previous type so you can continue in the DSL 143 return (Type) super.end(); 144 } 145 146 /** 147 * Ignore the invalidate endpoint exception when try to create a producer with that endpoint 148 * 149 * @return the builder 150 */ 151 public RoutingSlipDefinition<Type> ignoreInvalidEndpoints() { 152 setIgnoreInvalidEndpoints(true); 153 return this; 154 } 155 156 /** 157 * Sets the uri delimiter to use 158 * 159 * @param uriDelimiter the delimiter 160 * @return the builder 161 */ 162 public RoutingSlipDefinition<Type> uriDelimiter(String uriDelimiter) { 163 setUriDelimiter(uriDelimiter); 164 return this; 165 } 166 167 /** 168 * Sets the maximum size used by the {@link org.apache.camel.impl.ProducerCache} which is used 169 * to cache and reuse producers when using this recipient list, when uris are reused. 170 * 171 * @param cacheSize the cache size, use <tt>0</tt> for default cache size, or <tt>-1</tt> to turn cache off. 172 * @return the builder 173 */ 174 public RoutingSlipDefinition<Type> cacheSize(int cacheSize) { 175 setCacheSize(cacheSize); 176 return this; 177 } 178 179}