All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.model.ToDynamicDefinition Maven / Gradle / Ivy

There is a newer version: 4.7.0
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.model;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
import org.apache.camel.NoSuchLanguageException;
import org.apache.camel.Processor;
import org.apache.camel.builder.ExpressionBuilder;
import org.apache.camel.processor.SendDynamicProcessor;
import org.apache.camel.spi.Language;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.RouteContext;
import org.apache.camel.util.ObjectHelper;

/**
 * Sends the message to a dynamic endpoint
 * 

* You can specify multiple languages in the uri separated by the plus sign, such as mock:+language:xpath:/order/@uri * where mock: would be a prefix to a xpath expression. *

* For more dynamic behavior use Recipient List or * Dynamic Router EIP instead. */ @Metadata(label = "eip,endpoint,routing") @XmlRootElement(name = "toD") @XmlAccessorType(XmlAccessType.FIELD) public class ToDynamicDefinition extends NoOutputDefinition { private static final Pattern RAW_PATTERN = Pattern.compile("RAW\\([^\\)]+\\)"); @XmlAttribute @Metadata(required = "true") private String uri; @XmlAttribute private ExchangePattern pattern; @XmlAttribute private Integer cacheSize; @XmlAttribute private Boolean ignoreInvalidEndpoint; public ToDynamicDefinition() { } public ToDynamicDefinition(String uri) { this.uri = uri; } @Override public Processor createProcessor(RouteContext routeContext) throws Exception { ObjectHelper.notEmpty(uri, "uri", this); Expression exp = createExpression(routeContext); SendDynamicProcessor processor = new SendDynamicProcessor(uri, exp); processor.setCamelContext(routeContext.getCamelContext()); processor.setPattern(pattern); if (cacheSize != null) { processor.setCacheSize(cacheSize); } if (ignoreInvalidEndpoint != null) { processor.setIgnoreInvalidEndpoint(ignoreInvalidEndpoint); } return processor; } protected Expression createExpression(RouteContext routeContext) { List list = new ArrayList(); String[] parts = safeSplitRaw(uri); for (String part : parts) { // the part may have optional language to use, so you can mix languages String value = ObjectHelper.after(part, "language:"); if (value != null) { String before = ObjectHelper.before(value, ":"); String after = ObjectHelper.after(value, ":"); if (before != null && after != null) { // maybe its a language, must have language: as prefix try { Language partLanguage = routeContext.getCamelContext().resolveLanguage(before); if (partLanguage != null) { Expression exp = partLanguage.createExpression(after); list.add(exp); continue; } } catch (NoSuchLanguageException e) { // ignore } } } // fallback and use simple language Language lan = routeContext.getCamelContext().resolveLanguage("simple"); Expression exp = lan.createExpression(part); list.add(exp); } Expression exp; if (list.size() == 1) { exp = list.get(0); } else { exp = ExpressionBuilder.concatExpression(list); } return exp; } @Override public String toString() { return "DynamicTo[" + getLabel() + "]"; } // Fluent API // ------------------------------------------------------------------------- /** * Sets the optional {@link ExchangePattern} used to invoke this endpoint */ public ToDynamicDefinition pattern(ExchangePattern pattern) { setPattern(pattern); return this; } /** * Sets the maximum size used by the {@link org.apache.camel.impl.ConsumerCache} which is used to cache and reuse producers. * * @param cacheSize the cache size, use 0 for default cache size, or -1 to turn cache off. * @return the builder */ public ToDynamicDefinition cacheSize(int cacheSize) { setCacheSize(cacheSize); return this; } /** * Ignore the invalidate endpoint exception when try to create a producer with that endpoint * * @return the builder */ public ToDynamicDefinition ignoreInvalidEndpoint() { setIgnoreInvalidEndpoint(true); return this; } // Properties // ------------------------------------------------------------------------- public String getUri() { return uri; } /** * The uri of the endpoint to send to. The uri can be dynamic computed using the {@link org.apache.camel.language.simple.SimpleLanguage} expression. */ public void setUri(String uri) { this.uri = uri; } public ExchangePattern getPattern() { return pattern; } public void setPattern(ExchangePattern pattern) { this.pattern = pattern; } public Integer getCacheSize() { return cacheSize; } public void setCacheSize(Integer cacheSize) { this.cacheSize = cacheSize; } public Boolean getIgnoreInvalidEndpoint() { return ignoreInvalidEndpoint; } public void setIgnoreInvalidEndpoint(Boolean ignoreInvalidEndpoint) { this.ignoreInvalidEndpoint = ignoreInvalidEndpoint; } // Utilities // ------------------------------------------------------------------------- private static class Pair { int left; int right; Pair(int left, int right) { this.left = left; this.right = right; } } private static List checkRAW(String s) { Matcher matcher = RAW_PATTERN.matcher(s); List answer = new ArrayList(); // Check all occurrences while (matcher.find()) { answer.add(new Pair(matcher.start(), matcher.end() - 1)); } return answer; } private static boolean isRaw(int index, Listpairs) { for (Pair pair : pairs) { if (index < pair.left) { return false; } else { if (index >= pair.left) { if (index <= pair.right) { return true; } else { continue; } } } } return false; } /** * We need to split the string safely for each + sign, but avoid splitting within RAW(...). */ private static String[] safeSplitRaw(String s) { List list = new ArrayList<>(); if (!s.contains("+")) { // no plus sign so there is only one part, so no need to split list.add(s); } else { // there is a plus sign so we need to split in a safe manner List rawPairs = checkRAW(s); StringBuilder sb = new StringBuilder(); char chars[] = s.toCharArray(); for (int i = 0; i < chars.length; i++) { char ch = chars[i]; if (ch != '+' || isRaw(i, rawPairs)) { sb.append(ch); } else { list.add(sb.toString()); sb.setLength(0); } } // any leftover? if (sb.length() > 0) { list.add(sb.toString()); sb.setLength(0); } } return list.toArray(new String[list.size()]); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy