001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.portlet;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.springframework.util.CollectionUtils;
023import org.springframework.util.ObjectUtils;
024
025/**
026 * Handler execution chain, consisting of handler object and any handler interceptors.
027 * Returned by HandlerMapping's {@link HandlerMapping#getHandler} method.
028 *
029 * @author Juergen Hoeller
030 * @author John A. Lewis
031 * @since 2.0
032 * @see HandlerInterceptor
033 */
034public class HandlerExecutionChain {
035
036        private final Object handler;
037
038        private HandlerInterceptor[] interceptors;
039
040        private List<HandlerInterceptor> interceptorList;
041
042
043        /**
044         * Create a new HandlerExecutionChain.
045         * @param handler the handler object to execute
046         */
047        public HandlerExecutionChain(Object handler) {
048                this(handler, (HandlerInterceptor[]) null);
049        }
050
051        /**
052         * Create a new HandlerExecutionChain.
053         * @param handler the handler object to execute
054         * @param interceptors the array of interceptors to apply
055         * (in the given order) before the handler itself executes
056         */
057        public HandlerExecutionChain(Object handler, HandlerInterceptor... interceptors) {
058                if (handler instanceof HandlerExecutionChain) {
059                        HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;
060                        this.handler = originalChain.getHandler();
061                        this.interceptorList = new ArrayList<HandlerInterceptor>();
062                        CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
063                        CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
064                }
065                else {
066                        this.handler = handler;
067                        this.interceptors = interceptors;
068                }
069        }
070
071
072        /**
073         * Return the handler object to execute.
074         * @return the handler object (may be {@code null})
075         */
076        public Object getHandler() {
077                return this.handler;
078        }
079
080        public void addInterceptor(HandlerInterceptor interceptor) {
081                initInterceptorList().add(interceptor);
082        }
083
084        public void addInterceptors(HandlerInterceptor... interceptors) {
085                if (!ObjectUtils.isEmpty(interceptors)) {
086                        CollectionUtils.mergeArrayIntoCollection(interceptors, initInterceptorList());
087                }
088        }
089
090        private List<HandlerInterceptor> initInterceptorList() {
091                if (this.interceptorList == null) {
092                        this.interceptorList = new ArrayList<HandlerInterceptor>();
093                        if (this.interceptors != null) {
094                                // An interceptor array specified through the constructor
095                                CollectionUtils.mergeArrayIntoCollection(this.interceptors, this.interceptorList);
096                        }
097                }
098                this.interceptors = null;
099                return this.interceptorList;
100        }
101
102        /**
103         * Return the array of interceptors to apply (in the given order).
104         * @return the array of HandlerInterceptors instances (may be {@code null})
105         */
106        public HandlerInterceptor[] getInterceptors() {
107                if (this.interceptors == null && this.interceptorList != null) {
108                        this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
109                }
110                return this.interceptors;
111        }
112
113
114        /**
115         * Delegates to the handler's {@code toString()}.
116         */
117        @Override
118        public String toString() {
119                Object handler = getHandler();
120                if (handler == null) {
121                        return "HandlerExecutionChain with no handler";
122                }
123                StringBuilder sb = new StringBuilder();
124                sb.append("HandlerExecutionChain with handler [").append(handler).append("]");
125                HandlerInterceptor[] interceptors = getInterceptors();
126                if (!ObjectUtils.isEmpty(interceptors)) {
127                        sb.append(" and ").append(interceptors.length).append(" interceptor");
128                        if (interceptors.length > 1) {
129                                sb.append("s");
130                        }
131                }
132                return sb.toString();
133        }
134
135}