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.ArrayList;
020import java.util.Collection;
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.Processor;
027import org.apache.camel.processor.AOPProcessor;
028import org.apache.camel.spi.Metadata;
029import org.apache.camel.spi.RouteContext;
030
031/**
032 * Does processing before and/or after the route is completed
033 *
034 * @deprecated will be removed in the future. You can for example use {@link Processor} and
035 * {@link org.apache.camel.spi.InterceptStrategy} to do AOP in Camel.
036 * @version 
037 */
038@Metadata(label = "configuration")
039@XmlRootElement(name = "aop")
040@XmlAccessorType(XmlAccessType.FIELD)
041@Deprecated
042public class AOPDefinition extends OutputDefinition<AOPDefinition> {
043    @XmlAttribute
044    private String beforeUri;
045    @XmlAttribute
046    private String afterUri;
047    @XmlAttribute
048    private String afterFinallyUri;
049
050    public AOPDefinition() {
051    }
052
053    @Override
054    public String toString() {
055        return "AOP[" + getOutputs() + "]";
056    }
057
058    public String getBeforeUri() {
059        return beforeUri;
060    }
061
062    /**
063     * Endpoint to call in AOP before.
064     */
065    public void setBeforeUri(String beforeUri) {
066        this.beforeUri = beforeUri;
067    }
068
069    public String getAfterUri() {
070        return afterUri;
071    }
072
073    /**
074     * Endpoint to call in AOP after.
075     * <p/>
076     * The difference between after and afterFinally is that afterFinally is invoked from a finally block
077     * so it will always be invoked no matter what, eg also in case of an exception occur.
078     */
079    public void setAfterUri(String afterUri) {
080        this.afterUri = afterUri;
081    }
082
083    public String getAfterFinallyUri() {
084        return afterFinallyUri;
085    }
086
087    /**
088     * Endpoint to call in AOP after finally.
089     * <p/>
090     * The difference between after and afterFinally is that afterFinally is invoked from a finally block
091     * so it will always be invoked no matter what, eg also in case of an exception occur.
092     */
093    public void setAfterFinallyUri(String afterFinallyUri) {
094        this.afterFinallyUri = afterFinallyUri;
095    }
096
097    @Override
098    public String getLabel() {
099        return "aop";
100    }
101
102    @Override
103    public Processor createProcessor(final RouteContext routeContext) throws Exception {
104        // either before or after must be provided
105        if (beforeUri == null && afterUri == null && afterFinallyUri == null) {
106            throw new IllegalArgumentException("At least one of before, after or afterFinally must be provided on: " + this);
107        }
108
109        // use a pipeline to assemble the before and target processor
110        // and the after if not afterFinally
111        Collection<ProcessorDefinition<?>> pipe = new ArrayList<ProcessorDefinition<?>>();
112
113        Processor finallyProcessor = null;
114
115        if (beforeUri != null) {
116            pipe.add(new ToDefinition(beforeUri));
117        }
118        pipe.addAll(getOutputs());
119
120        if (afterUri != null) {
121            pipe.add(new ToDefinition(afterUri));
122        } else if (afterFinallyUri != null) {
123            finallyProcessor = createProcessor(routeContext, new ToDefinition(afterFinallyUri));
124        }
125
126        Processor tryProcessor = createOutputsProcessor(routeContext, pipe);
127
128        // the AOP processor is based on TryProcessor so we do not have any catches
129        return new AOPProcessor(tryProcessor, null, finallyProcessor);
130    }
131
132    /**
133     * Uses a AOP around.
134     *
135     * @param beforeUri the uri of the before endpoint
136     * @param afterUri  the uri of the after endpoint
137     * @return the builder
138     */
139    public AOPDefinition around(String beforeUri, String afterUri) {
140        this.beforeUri = beforeUri;
141        this.afterUri = afterUri;
142        this.afterFinallyUri = null;
143        return this;
144    }
145
146    /**
147     * Uses a AOP around with after being invoked in a finally block
148     *
149     * @param beforeUri the uri of the before endpoint
150     * @param afterUri  the uri of the after endpoint
151     * @return the builder
152     */
153    public AOPDefinition aroundFinally(String beforeUri, String afterUri) {
154        this.beforeUri = beforeUri;
155        this.afterUri = null;
156        this.afterFinallyUri = afterUri;
157        return this;
158    }
159
160    /**
161     * Uses a AOP before.
162     *
163     * @param beforeUri the uri of the before endpoint
164     * @return the builder
165     */
166    public AOPDefinition before(String beforeUri) {
167        this.beforeUri = beforeUri;
168        this.afterUri = null;
169        this.afterFinallyUri = null;
170        return this;
171    }
172
173    /**
174     * Uses a AOP after.
175     *
176     * @param afterUri  the uri of the after endpoint
177     * @return the builder
178     */
179    public AOPDefinition after(String afterUri) {
180        this.beforeUri = null;
181        this.afterUri = afterUri;
182        this.afterFinallyUri = null;
183        return this;
184    }
185
186    /**
187     * Uses a AOP after with after being invoked in a finally block.
188     *
189     * @param afterUri  the uri of the after endpoint
190     * @return the builder
191     */
192    public AOPDefinition afterFinally(String afterUri) {
193        this.beforeUri = null;
194        this.afterUri = null;
195        this.afterFinallyUri = afterUri;
196        return this;
197    }
198}