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: 881198 $
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        public String getBeforeUri() {
055            return beforeUri;
056        }
057    
058        public String getAfterUri() {
059            return afterUri;
060        }
061    
062        public String getAfterFinallyUri() {
063            return afterFinallyUri;
064        }
065    
066        @Override
067        public String getShortName() {
068            return "aop";
069        }
070    
071        @Override
072        public String getLabel() {
073            return "aop";
074        }
075    
076        @Override
077        public Processor createProcessor(final RouteContext routeContext) throws Exception {
078            // either before or after must be provided
079            if (beforeUri == null && afterUri == null && afterFinallyUri == null) {
080                throw new IllegalArgumentException("At least one of before, after or afterFinally must be provided on: " + this);
081            }
082    
083            // use a pipeline to assemble the before and target processor
084            // and the after if not afterFinally
085            Collection<ProcessorDefinition> pipe = new ArrayList<ProcessorDefinition>();
086    
087            Processor finallyProcessor = null;
088    
089            if (beforeUri != null) {
090                pipe.add(new ToDefinition(beforeUri));
091            }
092            pipe.addAll(getOutputs());
093    
094            if (afterUri != null) {
095                pipe.add(new ToDefinition(afterUri));
096            } else if (afterFinallyUri != null) {
097                finallyProcessor = new ToDefinition(afterFinallyUri).createProcessor(routeContext);
098            }
099    
100            Processor tryProcessor = createOutputsProcessor(routeContext, pipe);
101    
102            // the AOP processor is based on TryProcessor so we do not have any catches
103            return new AOPProcessor(tryProcessor, null, finallyProcessor);
104        }
105    
106        /**
107         * Uses a AOP around.
108         *
109         * @param beforeUri the uri of the before endpoint
110         * @param afterUri  the uri of the after endpoint
111         * @return the builder
112         */
113        public AOPDefinition around(String beforeUri, String afterUri) {
114            this.beforeUri = beforeUri;
115            this.afterUri = afterUri;
116            this.afterFinallyUri = null;
117            return this;
118        }
119    
120        /**
121         * Uses a AOP around with after being invoked in a finally block
122         *
123         * @param beforeUri the uri of the before endpoint
124         * @param afterUri  the uri of the after endpoint
125         * @return the builder
126         */
127        public AOPDefinition aroundFinally(String beforeUri, String afterUri) {
128            this.beforeUri = beforeUri;
129            this.afterUri = null;
130            this.afterFinallyUri = afterUri;
131            return this;
132        }
133    
134        /**
135         * Uses a AOP before.
136         *
137         * @param beforeUri the uri of the before endpoint
138         * @return the builder
139         */
140        public AOPDefinition before(String beforeUri) {
141            this.beforeUri = beforeUri;
142            this.afterUri = null;
143            this.afterFinallyUri = null;
144            return this;
145        }
146    
147        /**
148         * Uses a AOP after.
149         *
150         * @param afterUri  the uri of the after endpoint
151         * @return the builder
152         */
153        public AOPDefinition after(String afterUri) {
154            this.beforeUri = null;
155            this.afterUri = afterUri;
156            this.afterFinallyUri = null;
157            return this;
158        }
159    
160        /**
161         * Uses a AOP after with after being invoked in a finally block.
162         *
163         * @param afterUri  the uri of the after endpoint
164         * @return the builder
165         */
166        public AOPDefinition afterFinally(String afterUri) {
167            this.beforeUri = null;
168            this.afterUri = null;
169            this.afterFinallyUri = afterUri;
170            return this;
171        }
172    }