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.ArrayList; 020 import java.util.Iterator; 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.XmlElementRef; 027 import javax.xml.bind.annotation.XmlRootElement; 028 029 import org.apache.camel.Predicate; 030 import org.apache.camel.Processor; 031 import org.apache.camel.builder.ExpressionClause; 032 import org.apache.camel.processor.OnCompletionProcessor; 033 import org.apache.camel.spi.RouteContext; 034 035 /** 036 * Represents an XML <onCompletion/> element 037 * 038 * @version $Revision: 775059 $ 039 */ 040 @XmlRootElement(name = "onCompletion") 041 @XmlAccessorType(XmlAccessType.FIELD) 042 public class OnCompletionDefinition extends ProcessorDefinition<ProcessorDefinition> { 043 044 @XmlAttribute(required = false) 045 private Boolean onCompleteOnly = Boolean.TRUE; 046 @XmlAttribute(required = false) 047 private Boolean onFailureOnly = Boolean.TRUE; 048 @XmlElement(name = "onWhen", required = false) 049 private WhenDefinition onWhen; 050 @XmlElementRef 051 private List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>(); 052 053 public OnCompletionDefinition() { 054 } 055 056 @Override 057 public String toString() { 058 return "Synchronize[" + getOutputs() + "]"; 059 } 060 061 @Override 062 public String getShortName() { 063 return "onCompletion"; 064 } 065 066 @Override 067 public String getLabel() { 068 return "onCompletion"; 069 } 070 071 @Override 072 public Processor createProcessor(RouteContext routeContext) throws Exception { 073 Processor childProcessor = createOutputsProcessor(routeContext); 074 075 Predicate when = null; 076 if (onWhen != null) { 077 when = onWhen.getExpression().createPredicate(routeContext); 078 } 079 080 return new OnCompletionProcessor(childProcessor, onCompleteOnly, onFailureOnly, when); 081 } 082 083 /** 084 * Removes all existing {@link org.apache.camel.model.OnCompletionDefinition} from the defintion. 085 * <p/> 086 * This is used to let route scoped <tt>onCompletion</tt> overrule any global <tt>onCompletion</tt>. 087 * Hence we remove all existing as they are global. 088 * 089 * @param definition the parent defintion that is the route 090 */ 091 @SuppressWarnings("unchecked") 092 public void removeAllOnCompletionDefinition(ProcessorDefinition definition) { 093 for (Iterator<ProcessorDefinition> it = definition.getOutputs().iterator(); it.hasNext();) { 094 ProcessorDefinition out = it.next(); 095 if (out instanceof OnCompletionDefinition) { 096 it.remove(); 097 } 098 } 099 } 100 101 @Override 102 public ProcessorDefinition<? extends ProcessorDefinition> end() { 103 // pop parent block, as we added outself as block to parent when synchronized was defined in the route 104 getParent().popBlock(); 105 return super.end(); 106 } 107 108 /** 109 * Will only synchronize when the {@link org.apache.camel.Exchange} completed succesfully (no errors). 110 * 111 * @return the builder 112 */ 113 public OnCompletionDefinition onCompleteOnly() { 114 // must define return type as OutputDefinition and not this type to avoid end user being able 115 // to invoke onFailureOnly/onCompleteOnly more than once 116 setOnCompleteOnly(Boolean.TRUE); 117 setOnFailureOnly(Boolean.FALSE); 118 return this; 119 } 120 121 /** 122 * Will only synchronize when the {@link org.apache.camel.Exchange} ended with failure (exception or FAULT message). 123 * 124 * @return the builder 125 */ 126 public OnCompletionDefinition onFailureOnly() { 127 // must define return type as OutputDefinition and not this type to avoid end user being able 128 // to invoke onFailureOnly/onCompleteOnly more than once 129 setOnCompleteOnly(Boolean.FALSE); 130 setOnFailureOnly(Boolean.TRUE); 131 return this; 132 } 133 134 /** 135 * Sets an additional predicate that should be true before the onCompletion is triggered. 136 * <p/> 137 * To be used for fine grained controlling whether a completion callback should be invoked or not 138 * 139 * @param predicate predicate that determines true or false 140 * @return the builder 141 */ 142 public OnCompletionDefinition onWhen(Predicate predicate) { 143 setOnWhen(new WhenDefinition(predicate)); 144 return this; 145 } 146 147 /** 148 * Creates an expression to configure an additional predicate that should be true before the 149 * onCompletion is triggered. 150 * <p/> 151 * To be used for fine grained controlling whether a completion callback should be invoked or not 152 * 153 * @return the expression clause to configure 154 */ 155 public ExpressionClause<OnCompletionDefinition> onWhen() { 156 onWhen = new WhenDefinition(); 157 ExpressionClause<OnCompletionDefinition> clause = new ExpressionClause<OnCompletionDefinition>(this); 158 onWhen.setExpression(clause); 159 return clause; 160 } 161 162 163 public List<ProcessorDefinition> getOutputs() { 164 return outputs; 165 } 166 167 public void setOutputs(List<ProcessorDefinition> outputs) { 168 this.outputs = outputs; 169 } 170 171 public Boolean getOnCompleteOnly() { 172 return onCompleteOnly; 173 } 174 175 public void setOnCompleteOnly(Boolean onCompleteOnly) { 176 this.onCompleteOnly = onCompleteOnly; 177 } 178 179 public Boolean getOnFailureOnly() { 180 return onFailureOnly; 181 } 182 183 public void setOnFailureOnly(Boolean onFailureOnly) { 184 this.onFailureOnly = onFailureOnly; 185 } 186 187 public WhenDefinition getOnWhen() { 188 return onWhen; 189 } 190 191 public void setOnWhen(WhenDefinition onWhen) { 192 this.onWhen = onWhen; 193 } 194 195 }