001: /*
002: * (C) Copyright 2000 - 2005 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019:
020: package com.nabhinc.ws.server;
021:
022: import java.io.IOException;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import com.nabhinc.ws.core.UnavailableException;
028: import com.nabhinc.ws.core.WebServiceException;
029:
030: /**
031: * Represents a chain of interceptors associated with a Web service
032: * request. A new instance of this class is created for every service
033: * request.
034: *
035: * @author Padmanabh Dabke
036: * (c) 2005 Nabh Information Systems, Inc. All Rights Reserved.
037: */
038: public class InterceptorChain {
039: /**
040: * Logger
041: */
042: private Log wsicLogger = LogFactory.getLog(InterceptorChain.class);
043:
044: /**
045: * Position of the interceptor being invoked.
046: */
047: private int wsicCurrentPosition = 0;
048:
049: /**
050: * Interceptor array
051: */
052: private InterceptorInfo[] wsicInterceptors = null;
053:
054: /**
055: * Constructs a new interceptor chain consisting of
056: * supplied interceptors
057: *
058: * @param interceptors Array of interceptors that constitute the chain
059: */
060: public InterceptorChain(InterceptorInfo[] interceptors) {
061: wsicInterceptors = interceptors;
062: }
063:
064: /**
065: * Workhorse method in the interceptor chaining mechanism. It invokes
066: * the next interceptor in the chain. If the current interceptor is
067: * the last one, it invokes the Web service method. If an interceptor
068: * throws and exception and it is marked critical, it fails the
069: * method invocation. Otherwise, it simply logs the occurance and
070: * continues
071: * @param reqInfo Current request info
072: * @throws WebServiceException
073: * @throws IOException
074: */
075: public void doIntercept(RequestInfo reqInfo)
076: throws WebServiceException, IOException {
077: if (wsicCurrentPosition < wsicInterceptors.length) {
078: InterceptorInfo currentIntInfo = wsicInterceptors[wsicCurrentPosition++];
079: Interceptor currentInterceptor = currentIntInfo.interceptor;
080: if (currentInterceptor == null) {
081: if (currentIntInfo.isCritical) {
082: wsicLogger.error("Critical interceptor "
083: + currentIntInfo.name + " is not loaded.");
084: throw new WebServiceException(
085: "Critical interceptor is not loaded.");
086: } else {
087: wsicLogger.error("Non-critical interceptor "
088: + currentIntInfo.name + " is not loaded.");
089: }
090: }
091: try {
092: currentInterceptor.intercept(reqInfo, this );
093: } catch (WebServiceException ex) {
094: throw ex;
095: } catch (Throwable ex) {
096: handleInternalInterceptorException(currentIntInfo,
097: reqInfo, ex);
098: }
099: } else {
100: // Time to invoke the real method
101:
102: try {
103: reqInfo.result = reqInfo.serviceInfo.webService
104: .invoke(reqInfo);
105: } catch (UnavailableException ex) {
106: handleUnavailableException(reqInfo.serviceInfo, ex);
107: } catch (WebServiceException ex) {
108: throw ex;
109: } catch (Throwable ex) {
110: handleInternalWebServiceException(reqInfo.serviceInfo,
111: ex);
112: }
113: /*
114: try {
115: reqInfo.result = reqInfo.serviceInfo.webService.invoke(reqInfo);
116: //reqInfo.result = reqInfo.method.invoke(reqInfo.serviceInfo.webService.getServiceInstance(),
117: // reqInfo.arguments);
118: } catch (UnavailableException e) {
119: reqInfo.serviceInfo.loadError = e;
120: reqInfo.serviceInfo.status = WebServiceServerConstants.LOAD_STATUS_METHOD_INVOCATION_ERROR;
121: reqInfo.error = e;
122: } catch (WebServiceException e) {
123: reqInfo.error = e.getCause();
124: } catch (Throwable t) {
125: reqInfo.serviceInfo.status = WebServiceServerConstants.LOAD_STATUS_METHOD_INVOCATION_ERROR;
126: reqInfo.serviceInfo.loadError = t;
127: reqInfo.error = t;
128: }
129: */
130: }
131: }
132:
133: /**
134: * Get position of the current interceptor.
135: * @return Current interceptor position
136: */
137: public int getCurrentPosition() {
138: return wsicCurrentPosition;
139: }
140:
141: /**
142: * Set current interceptor position.
143: * @param pos New current position
144: */
145: public void setCurrentPosition(int pos) {
146: wsicCurrentPosition = pos;
147: }
148:
149: private void handleInternalInterceptorException(
150: InterceptorInfo currentIntInfo, RequestInfo reqInfo,
151: Throwable t) throws WebServiceException, IOException {
152: currentIntInfo.loadError = t;
153: currentIntInfo.status = WebServiceServerConstants.LOAD_STATUS_METHOD_INVOCATION_ERROR;
154: currentIntInfo.interceptor.destroy();
155: currentIntInfo.interceptor = null;
156: if (currentIntInfo.isCritical) {
157: wsicLogger.error("Critical interceptor "
158: + currentIntInfo.name + " failed.", t);
159: throw new UnavailableException(
160: "Critical interceptor threw exception.");
161: } else {
162: wsicLogger.error("Non-critical interceptor "
163: + currentIntInfo.name + " failed.", t);
164: doIntercept(reqInfo);
165: }
166:
167: }
168:
169: private void handleInternalWebServiceException(
170: WebServiceInfo wsInfo, Throwable t)
171: throws WebServiceException, IOException {
172: wsInfo.loadError = t;
173: wsInfo.status = WebServiceServerConstants.LOAD_STATUS_METHOD_INVOCATION_ERROR;
174: wsInfo.webService.destroy();
175: wsInfo.webService = null;
176: wsicLogger.error("Web service " + wsInfo.name + " failed.", t);
177: throw new UnavailableException("Internal exception.", t);
178:
179: }
180:
181: private void handleUnavailableException(WebServiceInfo wsInfo,
182: UnavailableException t) throws WebServiceException,
183: IOException {
184: wsInfo.loadError = t;
185: wsInfo.status = WebServiceServerConstants.LOAD_STATUS_METHOD_INVOCATION_ERROR;
186: wsInfo.webService.destroy();
187: wsInfo.webService = null;
188: wsicLogger.error("Web service " + wsInfo.name + " failed.", t);
189: throw t;
190:
191: }
192:
193: }
|