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 }