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.Collection;
021    import javax.xml.bind.annotation.XmlAccessType;
022    import javax.xml.bind.annotation.XmlAccessorType;
023    import javax.xml.bind.annotation.XmlAttribute;
024    import javax.xml.bind.annotation.XmlRootElement;
025    
026    import org.apache.camel.Processor;
027    import org.apache.camel.processor.AOPProcessor;
028    import org.apache.camel.spi.RouteContext;
029    
030    /**
031     * Represents an XML <aop/> element
032     *
033     * @version $Revision: 794544 $
034     */
035    @XmlRootElement(name = "aop")
036    @XmlAccessorType(XmlAccessType.FIELD)
037    public class AOPDefinition extends OutputDefinition<ProcessorDefinition> {
038    
039        @XmlAttribute(required = false)
040        private String beforeUri;
041        @XmlAttribute(required = false)
042        private String afterUri;
043        @XmlAttribute(required = false)
044        private String afterFinallyUri;
045    
046        public AOPDefinition() {
047        }
048    
049        @Override
050        public String toString() {
051            return "AOP[" + getOutputs() + "]";
052        }
053    
054        @Override
055        public String getShortName() {
056            return "aop";
057        }
058    
059        @Override
060        public String getLabel() {
061            return "aop";
062        }
063    
064        @Override
065        public Processor createProcessor(final RouteContext routeContext) throws Exception {
066            // either before or after must be provided
067            if (beforeUri == null && afterUri == null && afterFinallyUri == null) {
068                throw new IllegalArgumentException("At least one of before, after or afterFinally must be provided on: " + this);
069            }
070    
071            // use a pipeline to assemble the before and target processor
072            // and the after if not afterFinally
073            Collection<ProcessorDefinition> pipe = new ArrayList<ProcessorDefinition>();
074    
075            Processor finallyProcessor = null;
076    
077            if (beforeUri != null) {
078                pipe.add(new SendDefinition(beforeUri));
079            }
080            pipe.addAll(getOutputs());
081    
082            if (afterUri != null) {
083                pipe.add(new SendDefinition(afterUri));
084            } else if (afterFinallyUri != null) {
085                finallyProcessor = new SendDefinition(afterFinallyUri).createProcessor(routeContext);
086            }
087    
088            Processor tryProcessor = createOutputsProcessor(routeContext, pipe);
089    
090            // the AOP processor is based on TryProcessor so we do not have any catches
091            return new AOPProcessor(tryProcessor, null, finallyProcessor);
092        }
093    
094        /**
095         * Uses a AOP around.
096         *
097         * @param beforeUri the uri of the before endpoint
098         * @param afterUri  the uri of the after endpoint
099         * @return the builder
100         */
101        public AOPDefinition around(String beforeUri, String afterUri) {
102            this.beforeUri = beforeUri;
103            this.afterUri = afterUri;
104            this.afterFinallyUri = null;
105            return this;
106        }
107    
108        /**
109         * Uses a AOP around with after being invoked in a finally block
110         *
111         * @param beforeUri the uri of the before endpoint
112         * @param afterUri  the uri of the after endpoint
113         * @return the builder
114         */
115        public AOPDefinition aroundFinally(String beforeUri, String afterUri) {
116            this.beforeUri = beforeUri;
117            this.afterUri = null;
118            this.afterFinallyUri = afterUri;
119            return this;
120        }
121    
122        /**
123         * Uses a AOP before.
124         *
125         * @param beforeUri the uri of the before endpoint
126         * @return the builder
127         */
128        public AOPDefinition before(String beforeUri) {
129            this.beforeUri = beforeUri;
130            this.afterUri = null;
131            this.afterFinallyUri = null;
132            return this;
133        }
134    
135        /**
136         * Uses a AOP after.
137         *
138         * @param afterUri  the uri of the after endpoint
139         * @return the builder
140         */
141        public AOPDefinition after(String afterUri) {
142            this.beforeUri = null;
143            this.afterUri = afterUri;
144            this.afterFinallyUri = null;
145            return this;
146        }
147    
148        /**
149         * Uses a AOP after with after being invoked in a finally block.
150         *
151         * @param afterUri  the uri of the after endpoint
152         * @return the builder
153         */
154        public AOPDefinition afterFinally(String afterUri) {
155            this.beforeUri = null;
156            this.afterUri = null;
157            this.afterFinallyUri = afterUri;
158            return this;
159        }
160    
161    }