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: */package org.apache.openejb.server.axis;
017:
018: import javax.xml.rpc.JAXRPCException;
019: import javax.xml.rpc.handler.Handler;
020: import javax.xml.rpc.handler.HandlerInfo;
021: import javax.xml.rpc.handler.MessageContext;
022: import javax.xml.rpc.handler.soap.SOAPMessageContext;
023: import javax.xml.rpc.soap.SOAPFaultException;
024: import javax.xml.soap.SOAPBody;
025: import javax.xml.soap.SOAPElement;
026: import javax.xml.soap.SOAPException;
027: import javax.xml.soap.SOAPMessage;
028: import java.util.ArrayList;
029: import java.util.Iterator;
030: import java.util.LinkedList;
031: import java.util.List;
032: import java.util.Map;
033:
034: /**
035: * Implementation of HandlerChain
036: */
037: public class HandlerChainImpl extends ArrayList implements
038: javax.xml.rpc.handler.HandlerChain {
039: private String[] roles;
040: private LinkedList<Handler> invokedHandlers = new LinkedList<Handler>();
041:
042: public HandlerChainImpl(List<HandlerInfo> handlerInfos) {
043: this (handlerInfos, null);
044: }
045:
046: @SuppressWarnings({"unchecked"})
047: public HandlerChainImpl(List<HandlerInfo> handlerInfos,
048: String[] roles) {
049: this .roles = roles;
050: for (int i = 0; i < handlerInfos.size(); i++) {
051: HandlerInfo handlerInfo = handlerInfos.get(i);
052: try {
053: Handler handler = (Handler) handlerInfo
054: .getHandlerClass().newInstance();
055: handler.init(handlerInfo);
056: add(handler);
057: } catch (Exception e) {
058: throw new JAXRPCException(
059: "Unable to initialize handler class: "
060: + handlerInfo.getHandlerClass()
061: .getName(), e);
062: }
063: }
064: }
065:
066: public String[] getRoles() {
067: return roles;
068: }
069:
070: public void setRoles(String[] roles) {
071: if (roles == null) {
072: this .roles = new String[0];
073: } else {
074: this .roles = roles;
075: }
076: }
077:
078: public void init(Map map) {
079: }
080:
081: public void destroy() {
082: for (Iterator iterator = invokedHandlers.iterator(); iterator
083: .hasNext();) {
084: Handler handler = (Handler) iterator.next();
085: handler.destroy();
086: }
087: invokedHandlers.clear();
088: clear();
089: }
090:
091: public boolean handleRequest(MessageContext context) {
092: MessageSnapshot snapshot = new MessageSnapshot(context);
093: try {
094: for (int i = 0; i < size(); i++) {
095: Handler currentHandler = (Handler) get(i);
096: invokedHandlers.addFirst(currentHandler);
097: try {
098: if (!currentHandler.handleRequest(context)) {
099: return false;
100: }
101: } catch (SOAPFaultException e) {
102: throw e;
103: }
104: }
105: } finally {
106: saveChanges(context);
107: }
108:
109: if (!snapshot.equals(context)) {
110: throw new IllegalStateException(
111: "The soap message operation or arguments were illegally modified by the HandlerChain");
112: }
113: return true;
114: }
115:
116: public boolean handleResponse(MessageContext context) {
117: MessageSnapshot snapshot = new MessageSnapshot(context);
118: try {
119: for (Iterator iterator = invokedHandlers.iterator(); iterator
120: .hasNext();) {
121: Handler handler = (Handler) iterator.next();
122: if (!handler.handleResponse(context)) {
123: return false;
124: }
125: }
126: } finally {
127: saveChanges(context);
128: }
129: if (!snapshot.equals(context)) {
130: throw new IllegalStateException(
131: "The soap message operation or arguments were illegally modified by the HandlerChain");
132: }
133: return true;
134: }
135:
136: public boolean handleFault(MessageContext context) {
137: MessageSnapshot snapshot = new MessageSnapshot(context);
138: try {
139: for (Iterator iterator = invokedHandlers.iterator(); iterator
140: .hasNext();) {
141: Handler handler = (Handler) iterator.next();
142: if (!handler.handleFault(context)) {
143: return false;
144: }
145: }
146: } finally {
147: saveChanges(context);
148: }
149: if (!snapshot.equals(context)) {
150: throw new IllegalStateException(
151: "The soap message operation or arguments were illegally modified by the HandlerChain");
152: }
153: return true;
154: }
155:
156: private void saveChanges(MessageContext context) {
157: try {
158: SOAPMessage message = ((SOAPMessageContext) context)
159: .getMessage();
160: if (message != null) {
161: message.saveChanges();
162: }
163: } catch (SOAPException e) {
164: throw new RuntimeException(
165: "Unable to save changes to SOAPMessage : "
166: + e.toString());
167: }
168: }
169:
170: /**
171: * Handlers cannot:
172: * <p/>
173: * - re-target a request to a different component.
174: * - change the operation
175: * - change the message part types
176: * - change the number of message parts.
177: */
178: static class MessageSnapshot {
179: private final String operationName;
180: private final List<String> parameterNames;
181:
182: public MessageSnapshot(MessageContext soapMessage) {
183: SOAPMessage message = ((SOAPMessageContext) soapMessage)
184: .getMessage();
185: if (message == null || message.getSOAPPart() == null) {
186: operationName = null;
187: parameterNames = null;
188: } else {
189: SOAPBody body = getBody(message);
190:
191: SOAPElement operation = ((SOAPElement) body
192: .getChildElements().next());
193: this .operationName = operation.getElementName()
194: .toString();
195:
196: this .parameterNames = new ArrayList<String>();
197: for (Iterator i = operation.getChildElements(); i
198: .hasNext();) {
199: SOAPElement parameter = (SOAPElement) i.next();
200: String element = parameter.getElementName()
201: .toString();
202: parameterNames.add(element);
203: }
204: }
205: }
206:
207: private SOAPBody getBody(SOAPMessage message) {
208: try {
209: return message.getSOAPPart().getEnvelope().getBody();
210: } catch (SOAPException e) {
211: throw new RuntimeException(e);
212: }
213: }
214:
215: public boolean equals(Object obj) {
216: return (obj instanceof SOAPMessageContext)
217: && equals((SOAPMessageContext) obj);
218: }
219:
220: private boolean equals(SOAPMessageContext soapMessage) {
221: SOAPMessage message = soapMessage.getMessage();
222:
223: if (operationName == null) {
224: return message == null || message.getSOAPPart() == null;
225: }
226:
227: SOAPBody body = getBody(message);
228:
229: // Handlers can't change the operation
230: SOAPElement operation = ((SOAPElement) body
231: .getChildElements().next());
232: if (!this .operationName.equals(operation.getElementName()
233: .toString())) {
234: return false;
235: }
236:
237: Iterator parameters = operation.getChildElements();
238: for (Iterator i = parameterNames.iterator(); i.hasNext();) {
239: // Handlers can't remove parameters
240: if (!parameters.hasNext()) {
241: return false;
242: }
243:
244: String original = (String) i.next();
245: SOAPElement parameter = (SOAPElement) parameters.next();
246: // Handlers can't change parameter types
247: if (parameter == null
248: || !original.equals(parameter.getElementName()
249: .toString())) {
250: return false;
251: }
252: }
253:
254: // Handlers can't add parameters
255: return !parameters.hasNext();
256: }
257: }
258: }
|