Source Code Cross Referenced for HandlerChainCaller.java in  » 6.0-JDK-Modules-com.sun » xml » com » sun » xml » internal » ws » handler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun » xml » com.sun.xml.internal.ws.handler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Portions Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:        package com.sun.xml.internal.ws.handler;
0026:
0027:        import com.sun.xml.internal.ws.spi.runtime.WSConnection;
0028:        import javax.xml.namespace.QName;
0029:        import javax.xml.soap.SOAPBody;
0030:        import javax.xml.soap.SOAPEnvelope;
0031:        import javax.xml.soap.SOAPException;
0032:        import javax.xml.soap.SOAPFault;
0033:        import javax.xml.soap.SOAPMessage;
0034:        import javax.xml.ws.LogicalMessage;
0035:        import javax.xml.ws.ProtocolException;
0036:        import javax.xml.ws.handler.Handler;
0037:        import javax.xml.ws.handler.LogicalHandler;
0038:        import javax.xml.ws.handler.LogicalMessageContext;
0039:        import javax.xml.ws.handler.MessageContext;
0040:        import javax.xml.ws.handler.soap.SOAPHandler;
0041:        import javax.xml.ws.handler.soap.SOAPMessageContext;
0042:        import javax.xml.ws.http.HTTPException;
0043:        import javax.xml.ws.soap.SOAPFaultException;
0044:
0045:        import java.util.ArrayList;
0046:        import java.util.HashSet;
0047:        import java.util.List;
0048:        import java.util.Set;
0049:        import java.util.logging.Level;
0050:        import java.util.logging.Logger;
0051:
0052:        import com.sun.xml.internal.ws.encoding.soap.SOAPConstants;
0053:        import com.sun.xml.internal.ws.encoding.soap.SOAP12Constants;
0054:        import com.sun.xml.internal.ws.encoding.soap.streaming.SOAP12NamespaceConstants;
0055:
0056:        /**
0057:         * The class stores the actual "chain" of handlers that is called
0058:         * during a request or response. On the client side, it is created
0059:         * by a {@link com.sun.xml.internal.ws.binding.BindingImpl} class when a
0060:         * binding provider is created. On the server side, where a Binding
0061:         * object may be passed from an outside source, the handler chain
0062:         * caller may be created by the message dispatcher classes.
0063:         *
0064:         * <p>When created, a java.util.List of Handlers is passed in. This list
0065:         * is sorted into logical and protocol handlers, so the handler order
0066:         * that is returned from getHandlerChain() may be different from the
0067:         * original that was passed in.
0068:         *
0069:         * <p>At runtime, one of the callHandlers() methods is invoked by the
0070:         * soap or xml message dispatchers, passing in a {@link HandlerContext}
0071:         * or {@link XMLHandlerContext} object along with other information
0072:         * about the current message that is required for proper handler flow.
0073:         *
0074:         * <p>Exceptions are logged in many cases here before being rethrown. This
0075:         * is to help primarily with server side handlers.
0076:         *
0077:         * <p>Currently, the handler chain caller checks for a null soap
0078:         * message context to see if the binding in use is XML/HTTP.
0079:         *
0080:         * @see com.sun.xml.internal.ws.binding.BindingImpl
0081:         * @see com.sun.xml.internal.ws.protocol.soap.client.SOAPMessageDispatcher
0082:         * @see com.sun.xml.internal.ws.protocol.soap.server.SOAPMessageDispatcher
0083:         * @see com.sun.xml.internal.ws.protocol.xml.server.XMLMessageDispatcher
0084:         *
0085:         * @author WS Development Team
0086:         */
0087:        public class HandlerChainCaller {
0088:
0089:            public static final String HANDLER_CHAIN_CALLER = "handler_chain_caller";
0090:            public static final String IGNORE_FAULT_PROPERTY = "ignore fault in message";
0091:
0092:            private static final Logger logger = Logger
0093:                    .getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain
0094:                            + ".handler");
0095:
0096:            // need request or response for Handle interface
0097:            public enum RequestOrResponse {
0098:                REQUEST, RESPONSE
0099:            }
0100:
0101:            public enum Direction {
0102:                OUTBOUND, INBOUND
0103:            }
0104:
0105:            private Set<QName> understoodHeaders;
0106:            private List<Handler> handlers; // may be logical/soap mixed
0107:
0108:            private List<LogicalHandler> logicalHandlers;
0109:            private List<SOAPHandler> soapHandlers;
0110:
0111:            private Set<String> roles;
0112:
0113:            /**
0114:             * The handlers that are passed in will be sorted into
0115:             * logical and soap handlers. During this sorting, the
0116:             * understood headers are also obtained from any soap
0117:             * handlers.
0118:             *
0119:             * @param chain A list of handler objects, which can
0120:             * be protocol or logical handlers.
0121:             */
0122:            public HandlerChainCaller(List<Handler> chain) {
0123:                if (chain == null) { // should only happen in testing
0124:                    chain = new ArrayList<Handler>();
0125:                }
0126:                handlers = chain;
0127:                logicalHandlers = new ArrayList<LogicalHandler>();
0128:                soapHandlers = new ArrayList<SOAPHandler>();
0129:                understoodHeaders = new HashSet<QName>();
0130:                sortHandlers();
0131:            }
0132:
0133:            /**
0134:             * This list may be different than the chain that is passed
0135:             * in since the logical and protocol handlers must be separated.
0136:             *
0137:             * @return The list of handlers, sorted by logical and then protocol.
0138:             */
0139:            public List<Handler> getHandlerChain() {
0140:                return handlers;
0141:            }
0142:
0143:            public boolean hasHandlers() {
0144:                return (handlers.size() != 0);
0145:            }
0146:
0147:            /**
0148:             * These are set by the SOAPBindingImpl when it creates the
0149:             * HandlerChainCaller or when new roles are set on the binding.
0150:             *
0151:             * @param roles A set of roles strings.
0152:             */
0153:            public void setRoles(Set<String> roles) {
0154:                this .roles = roles;
0155:            }
0156:
0157:            /**
0158:             * Returns the roles that were passed in by the binding
0159:             * in the case of soap binding.
0160:             */
0161:            public Set<String> getRoles() {
0162:                return roles;
0163:            }
0164:
0165:            /**
0166:             * Returns the headers understood by the handlers. This set
0167:             * is created when the handler chain caller is instantiated and
0168:             * the handlers are sorted. The set is comprised of headers
0169:             * returned from SOAPHandler.getHeaders() method calls.
0170:             *
0171:             * @return The set of all headers that the handlers declare
0172:             * that they understand.
0173:             */
0174:            public Set<QName> getUnderstoodHeaders() {
0175:                return understoodHeaders;
0176:            }
0177:
0178:            /**
0179:             * This method separates the logical and protocol handlers. When
0180:             * this method returns, the original "handlers" List has been
0181:             * resorted.
0182:             */
0183:            private void sortHandlers() {
0184:                for (Handler handler : handlers) {
0185:                    if (LogicalHandler.class.isAssignableFrom(handler
0186:                            .getClass())) {
0187:                        logicalHandlers.add((LogicalHandler) handler);
0188:                    } else if (SOAPHandler.class.isAssignableFrom(handler
0189:                            .getClass())) {
0190:                        soapHandlers.add((SOAPHandler) handler);
0191:                        Set<QName> headers = ((SOAPHandler) handler)
0192:                                .getHeaders();
0193:                        if (headers != null) {
0194:                            understoodHeaders.addAll(headers);
0195:                        }
0196:                    } else if (Handler.class.isAssignableFrom(handler
0197:                            .getClass())) {
0198:                        throw new HandlerException(
0199:                                "cannot.extend.handler.directly", handler
0200:                                        .getClass().toString());
0201:                    } else {
0202:                        throw new HandlerException("handler.not.valid.type",
0203:                                handler.getClass().toString());
0204:                    }
0205:                }
0206:                handlers.clear();
0207:                handlers.addAll(logicalHandlers);
0208:                handlers.addAll(soapHandlers);
0209:            }
0210:
0211:            /**
0212:             * Replace the message in the given message context with a
0213:             * fault message. If the context already contains a fault
0214:             * message, then return without changing it.
0215:             * Also sets the HTTP_RESPONSE_CODE in the context on Server-side.
0216:             */
0217:            private void insertFaultMessage(ContextHolder holder,
0218:                    ProtocolException exception) {
0219:                try {
0220:                    SOAPMessageContext context = holder.getSMC();
0221:                    if (context == null) { // non-soap case
0222:                        LogicalMessageContext lmc = holder.getLMC();
0223:                        LogicalMessage msg = lmc.getMessage();
0224:                        if (msg != null) {
0225:                            msg.setPayload(null);
0226:                        }
0227:                        //Set Status Code only if it is on server
0228:                        if ((Boolean) lmc
0229:                                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
0230:                            if (exception instanceof  HTTPException) {
0231:                                lmc.put(MessageContext.HTTP_RESPONSE_CODE,
0232:                                        ((HTTPException) exception)
0233:                                                .getStatusCode());
0234:                            } else {
0235:                                lmc.put(MessageContext.HTTP_RESPONSE_CODE,
0236:                                        WSConnection.INTERNAL_ERR);
0237:                            }
0238:                        }
0239:                        return;
0240:                    }
0241:                    //Set Status Code only if it is on server
0242:                    if ((Boolean) context
0243:                            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
0244:                        context.put(MessageContext.HTTP_RESPONSE_CODE,
0245:                                WSConnection.INTERNAL_ERR);
0246:                    }
0247:                    SOAPMessage message = context.getMessage();
0248:                    SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
0249:                    SOAPBody body = envelope.getBody();
0250:                    if (body.hasFault()) {
0251:                        return;
0252:                    }
0253:                    if (envelope.getHeader() != null) {
0254:                        envelope.getHeader().detachNode();
0255:                    }
0256:
0257:                    body.removeContents();
0258:                    SOAPFault fault = body.addFault();
0259:                    String envelopeNamespace = envelope.getNamespaceURI();
0260:
0261:                    if (exception instanceof  SOAPFaultException) {
0262:                        SOAPFaultException sfe = (SOAPFaultException) exception;
0263:                        SOAPFault userFault = sfe.getFault();
0264:
0265:                        QName faultCode = userFault.getFaultCodeAsQName();
0266:                        if (faultCode == null) {
0267:                            faultCode = determineFaultCode(context);
0268:                        }
0269:                        fault.setFaultCode(faultCode);
0270:
0271:                        String faultString = userFault.getFaultString();
0272:                        if (faultString == null) {
0273:                            if (sfe.getMessage() != null) {
0274:                                faultString = sfe.getMessage();
0275:                            } else {
0276:                                faultString = sfe.toString();
0277:                            }
0278:                        }
0279:                        fault.setFaultString(faultString);
0280:
0281:                        String faultActor = userFault.getFaultActor();
0282:                        if (faultActor == null) {
0283:                            faultActor = "";
0284:                        }
0285:                        fault.setFaultActor(faultActor);
0286:
0287:                        if (userFault.getDetail() != null) {
0288:                            fault.addChildElement(userFault.getDetail());
0289:                        }
0290:                    } else {
0291:                        fault.setFaultCode(determineFaultCode(context));
0292:                        if (exception.getMessage() != null) {
0293:                            fault.setFaultString(exception.getMessage());
0294:                        } else {
0295:                            fault.setFaultString(exception.toString());
0296:                        }
0297:                    }
0298:                } catch (Exception e) {
0299:                    // severe since this is from runtime and not handler
0300:                    logger
0301:                            .log(
0302:                                    Level.SEVERE,
0303:                                    "exception while creating fault message in handler chain",
0304:                                    e);
0305:                    throw new RuntimeException(e);
0306:                }
0307:            }
0308:
0309:            /**
0310:             * <p>The expectation of the rest of the code is that,
0311:             * if a ProtocolException is thrown from the handler chain,
0312:             * the message contents reflect the protocol exception.
0313:             * However, if a new ProtocolException is thrown from
0314:             * the handleFault method, then the fault should be
0315:             * ignored and the new exception should be dispatched.
0316:             *
0317:             * <p>This method simply sets a property that is checked
0318:             * by the client and server code when a ProtocolException
0319:             * is caught. The property can be checked with
0320:             * {@link MessageContextUtil#ignoreFaultInMessage}
0321:             */
0322:            private void addIgnoreFaultProperty(ContextHolder holder) {
0323:                LogicalMessageContext context = holder.getLMC();
0324:                context.put(IGNORE_FAULT_PROPERTY, Boolean.TRUE);
0325:            }
0326:
0327:            /**
0328:             * <p>Figure out if the fault code local part is client,
0329:             * server, sender, receiver, etc. This is called by
0330:             * insertFaultMessage.
0331:             *
0332:             * <p>This method should only be called when there is a ProtocolException 
0333:             * during request. Reverse the Message direction first,
0334:             * So this method can use the MESSAGE_OUTBOUND_PROPERTY
0335:             * to determine whether it is being called on the client
0336:             * or the server side. If this changes in the spec, then
0337:             * something else will need to be passed to the method 
0338:             * to determine whether the fault code is client or server.
0339:             *
0340:             * <p>For determining soap version, start checking with the
0341:             * latest version and default to soap 1.1.
0342:             */
0343:            private QName determineFaultCode(SOAPMessageContext context)
0344:                    throws SOAPException {
0345:
0346:                SOAPEnvelope envelope = context.getMessage().getSOAPPart()
0347:                        .getEnvelope();
0348:                String uri = envelope.getNamespaceURI();
0349:
0350:                // client case
0351:                if (!(Boolean) context
0352:                        .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
0353:                    if (uri.equals(SOAP12NamespaceConstants.ENVELOPE)) {
0354:                        return SOAP12Constants.FAULT_CODE_CLIENT;
0355:                    }
0356:                    return SOAPConstants.FAULT_CODE_CLIENT;
0357:                }
0358:
0359:                //server case
0360:                if (uri.equals(SOAP12NamespaceConstants.ENVELOPE)) {
0361:                    return SOAP12Constants.FAULT_CODE_SERVER;
0362:                }
0363:                return SOAPConstants.FAULT_CODE_SERVER;
0364:            }
0365:
0366:            /**
0367:             * <p>Method used to call handlers with a HandlerContext that
0368:             * may contain logical and protocol handlers. This is the
0369:             * main entry point for calling the handlers in the case
0370:             * of SOAP binding. Before calling the handlers, the
0371:             * handler chain caller will set the outbound property and
0372:             * the roles on the message context.
0373:             *
0374:             * <p>Besides the context object passed in, the other information
0375:             * is used to control handler execution and closing. See the
0376:             * handler section of the spec for the rules concering handlers
0377:             * returning false, throwing exceptions, etc.
0378:             *
0379:             * @param direction Inbound or outbound.
0380:             * @param messageType Request or response.
0381:             * @param context A soap handler context containing the message.
0382:             * @param responseExpected A boolean indicating whether or not
0383:             * a response is expected to the current message (should be false
0384:             * for responses or one-way requests).
0385:             *
0386:             * @return True in the normal case, false if a handler
0387:             * returned false. This normally means that the runtime
0388:             * should reverse direction if called during a request.
0389:             */
0390:            public boolean callHandlers(Direction direction,
0391:                    RequestOrResponse messageType, SOAPHandlerContext context,
0392:                    boolean responseExpected) {
0393:
0394:                return internalCallHandlers(direction, messageType,
0395:                        new ContextHolder(context), responseExpected);
0396:            }
0397:
0398:            /**
0399:             * Method used to call handlers with a HandlerContext that
0400:             * may contain logical handlers only. This is the
0401:             * main entry point for calling the handlers in the case
0402:             * of http binding. Before calling the handlers, the
0403:             * handler chain caller will set the outbound property on
0404:             * the message context.
0405:             *
0406:             * <p>Besides the context object passed in, the other information
0407:             * is used to control handler execution and closing. See the
0408:             * handler section of the spec for the rules concering handlers
0409:             * returning false, throwing exceptions, etc.
0410:             *
0411:             * @param direction Inbound or outbound.
0412:             * @param messageType Request or response.
0413:             * @param context A soap handler context containing the message.
0414:             * @param responseExpected A boolean indicating whether or not
0415:             * a response is expected to the current message (should be false
0416:             * for responses or one-way requests).
0417:             *
0418:             * @return True in the normal case, false if a handler
0419:             * returned false. This normally means that the runtime
0420:             * should reverse direction if called during a request.
0421:             */
0422:            public boolean callHandlers(Direction direction,
0423:                    RequestOrResponse messageType, XMLHandlerContext context,
0424:                    boolean responseExpected) {
0425:
0426:                return internalCallHandlers(direction, messageType,
0427:                        new ContextHolder(context), responseExpected);
0428:            }
0429:
0430:            /**
0431:             * Main runtime method, called internally by the callHandlers()
0432:             * methods that may be called with HandlerContext or 
0433:             * XMLHandlerContext objects.
0434:             *
0435:             * The boolean passed in is whether or not a response is required
0436:             * for the current message. See section 5.3.2. (todo: this section
0437:             * is going to change). 
0438:             *
0439:             * The callLogicalHandlers and callProtocolHandlers methods will
0440:             * take care of execution once called and return true or false or
0441:             * throw an exception.
0442:             */
0443:            private boolean internalCallHandlers(Direction direction,
0444:                    RequestOrResponse messageType, ContextHolder ch,
0445:                    boolean responseExpected) {
0446:
0447:                // set outbound property
0448:                ch.getLMC().put(MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0449:                        (direction == Direction.OUTBOUND));
0450:
0451:                // if there is as soap message context, set roles
0452:                if (ch.getSMC() != null) {
0453:                    ((SOAPMessageContextImpl) ch.getSMC()).setRoles(getRoles());
0454:                }
0455:
0456:                // call handlers
0457:                if (direction == Direction.OUTBOUND) {
0458:                    if (callLogicalHandlers(ch, direction, messageType,
0459:                            responseExpected) == false) {
0460:                        return false;
0461:                    }
0462:                    if (callProtocolHandlers(ch, direction, messageType,
0463:                            responseExpected) == false) {
0464:                        return false;
0465:                    }
0466:                } else {
0467:                    if (callProtocolHandlers(ch, direction, messageType,
0468:                            responseExpected) == false) {
0469:                        return false;
0470:                    }
0471:                    if (callLogicalHandlers(ch, direction, messageType,
0472:                            responseExpected) == false) {
0473:                        return false;
0474:                    }
0475:                }
0476:
0477:                /*
0478:                 * Close if MEP finished. Server code responsible for closing
0479:                 * handlers if it determines that an incoming request is a
0480:                 * one way message.
0481:                 */
0482:                if (!responseExpected) {
0483:                    if (messageType == RequestOrResponse.REQUEST) {
0484:                        if (direction == Direction.INBOUND) {
0485:                            closeHandlersServer(ch);
0486:                        } else {
0487:                            closeHandlersClient(ch);
0488:                        }
0489:                    } else {
0490:                        if (direction == Direction.INBOUND) {
0491:                            closeHandlersClient(ch);
0492:                        } else {
0493:                            closeHandlersServer(ch);
0494:                        }
0495:                    }
0496:                }
0497:                return true;
0498:            }
0499:
0500:            /**
0501:             * This method called by the server when an endpoint has thrown
0502:             * an exception. This method calls handleFault on the handlers
0503:             * and closes them. Because this method is called only during
0504:             * a response after the endpoint has been reached, all of the
0505:             * handlers have been called during the request and so all are
0506:             * closed.
0507:             */
0508:            public boolean callHandleFault(SOAPHandlerContext context) {
0509:                ContextHolder ch = new ContextHolder(context);
0510:                ch.getSMC().put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, true);
0511:                ((SOAPMessageContextImpl) ch.getSMC()).setRoles(getRoles());
0512:
0513:                int i = 0; // counter for logical handlers
0514:                int j = 0; // counter for protocol handlers
0515:                try {
0516:                    while (i < logicalHandlers.size()) {
0517:                        if (logicalHandlers.get(i).handleFault(ch.getLMC()) == false) {
0518:                            return false;
0519:                        }
0520:                        i++;
0521:                    }
0522:                    while (j < soapHandlers.size()) {
0523:                        if (soapHandlers.get(j).handleFault(ch.getSMC()) == false) {
0524:                            return false;
0525:                        }
0526:                        j++;
0527:                    }
0528:                } catch (RuntimeException re) {
0529:                    logger.log(Level.FINER, "exception in handler chain", re);
0530:                    throw re;
0531:                } finally {
0532:                    closeHandlersServer(ch); // this is always called on server side
0533:                }
0534:                return true;
0535:            }
0536:
0537:            /**
0538:             * This method called by the client when it sees a SOAPFault message.
0539:             * This method calls handleFault on the handlers and closes them. Because 
0540:             * this method is called only during a response, all of the handlers have 
0541:             * been called during the request and so all are closed.
0542:             */
0543:            public boolean callHandleFaultOnClient(SOAPHandlerContext context) {
0544:                ContextHolder ch = new ContextHolder(context);
0545:                ch.getSMC()
0546:                        .put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
0547:                ((SOAPMessageContextImpl) ch.getSMC()).setRoles(getRoles());
0548:
0549:                try {
0550:                    for (int i = soapHandlers.size() - 1; i >= 0; i--) {
0551:                        if (soapHandlers.get(i).handleFault(ch.getSMC()) == false) {
0552:                            return false;
0553:                        }
0554:                    }
0555:                    for (int i = logicalHandlers.size() - 1; i >= 0; i--) {
0556:                        if (logicalHandlers.get(i).handleFault(ch.getLMC()) == false) {
0557:                            return false;
0558:                        }
0559:                    }
0560:                } catch (RuntimeException re) {
0561:                    logger.log(Level.FINER, "exception in handler chain", re);
0562:                    throw re;
0563:                } finally {
0564:                    closeHandlersClient(ch);
0565:                }
0566:                return true;
0567:            }
0568:
0569:            /**
0570:             * Called from the main callHandlers() method.
0571:             * Logical message context updated before this method is called.
0572:             */
0573:            private boolean callLogicalHandlers(ContextHolder holder,
0574:                    Direction direction, RequestOrResponse type,
0575:                    boolean responseExpected) {
0576:
0577:                if (direction == Direction.OUTBOUND) {
0578:                    int i = 0;
0579:                    try {
0580:                        while (i < logicalHandlers.size()) {
0581:                            if (logicalHandlers.get(i).handleMessage(
0582:                                    holder.getLMC()) == false) {
0583:                                if (responseExpected) {
0584:                                    // reverse and call handle message
0585:                                    holder
0586:                                            .getLMC()
0587:                                            .put(
0588:                                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0589:                                                    false);
0590:                                    callLogicalHandleMessage(holder, i - 1, 0);
0591:                                }
0592:                                if (type == RequestOrResponse.RESPONSE) {
0593:                                    closeHandlersServer(holder);
0594:                                } else {
0595:                                    closeLogicalHandlers(holder, i, 0);
0596:                                }
0597:                                return false;
0598:                            }
0599:                            i++;
0600:                        }
0601:                    } catch (RuntimeException re) {
0602:                        logger.log(Level.FINER, "exception in handler chain",
0603:                                re);
0604:                        if (responseExpected && re instanceof  ProtocolException) {
0605:                            // reverse direction and handle fault
0606:                            holder.getLMC().put(
0607:                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0608:                                    false);
0609:                            insertFaultMessage(holder, (ProtocolException) re);
0610:                            if (i > 0) {
0611:                                try {
0612:                                    callLogicalHandleFault(holder, i - 1, 0);
0613:                                } catch (ProtocolException re1) {
0614:                                    addIgnoreFaultProperty(holder);
0615:                                    re = re1;
0616:                                } catch (RuntimeException re2) {
0617:                                    re = re2;
0618:                                }
0619:                            }
0620:                        }
0621:                        if (type == RequestOrResponse.RESPONSE) {
0622:                            closeHandlersServer(holder);
0623:                        } else {
0624:                            closeLogicalHandlers(holder, i, 0);
0625:                        }
0626:                        throw re;
0627:                    }
0628:                } else { // inbound case, H(x) -> H(x-1) -> ... H(1) -> H(0)
0629:                    int i = logicalHandlers.size() - 1;
0630:                    try {
0631:                        while (i >= 0) {
0632:                            if (logicalHandlers.get(i).handleMessage(
0633:                                    holder.getLMC()) == false) {
0634:
0635:                                if (responseExpected) {
0636:                                    // reverse and call handle message/response
0637:                                    holder
0638:                                            .getLMC()
0639:                                            .put(
0640:                                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0641:                                                    true);
0642:                                    callLogicalHandleMessage(holder, i + 1,
0643:                                            logicalHandlers.size() - 1);
0644:                                    callProtocolHandleMessage(holder, 0,
0645:                                            soapHandlers.size() - 1);
0646:                                }
0647:                                if (type == RequestOrResponse.RESPONSE) {
0648:                                    closeHandlersClient(holder);
0649:                                } else {
0650:                                    closeLogicalHandlers(holder, i,
0651:                                            logicalHandlers.size() - 1);
0652:                                    closeProtocolHandlers(holder, 0,
0653:                                            soapHandlers.size() - 1);
0654:                                }
0655:                                return false;
0656:                            }
0657:                            i--;
0658:                        }
0659:                    } catch (RuntimeException re) {
0660:                        logger.log(Level.FINER, "exception in handler chain",
0661:                                re);
0662:                        if (responseExpected && re instanceof  ProtocolException) {
0663:                            // reverse direction and handle fault
0664:                            holder.getLMC().put(
0665:                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0666:                                    true);
0667:                            insertFaultMessage(holder, (ProtocolException) re);
0668:
0669:                            try {
0670:                                // if i==size-1, no more logical handlers to call
0671:                                if (i == logicalHandlers.size() - 1
0672:                                        || callLogicalHandleFault(holder,
0673:                                                i + 1,
0674:                                                logicalHandlers.size() - 1)) {
0675:                                    callProtocolHandleFault(holder, 0,
0676:                                            soapHandlers.size() - 1);
0677:                                }
0678:                            } catch (ProtocolException re1) {
0679:                                addIgnoreFaultProperty(holder);
0680:                                re = re1;
0681:                            } catch (RuntimeException re2) {
0682:                                re = re2;
0683:                            }
0684:                        }
0685:                        if (type == RequestOrResponse.RESPONSE) {
0686:                            closeHandlersClient(holder);
0687:                        } else {
0688:                            closeLogicalHandlers(holder, i, logicalHandlers
0689:                                    .size() - 1);
0690:                            closeProtocolHandlers(holder, 0, soapHandlers
0691:                                    .size() - 1);
0692:                        }
0693:                        throw re;
0694:                    }
0695:                }
0696:
0697:                return true;
0698:            }
0699:
0700:            /**
0701:             * Called from the main callHandlers() method.
0702:             * SOAP message context updated before this method is called.
0703:             */
0704:            private boolean callProtocolHandlers(ContextHolder holder,
0705:                    Direction direction, RequestOrResponse type,
0706:                    boolean responseExpected) {
0707:
0708:                if (direction == Direction.OUTBOUND) {
0709:                    int i = 0;
0710:                    try {
0711:                        while (i < soapHandlers.size()) {
0712:                            if (soapHandlers.get(i).handleMessage(
0713:                                    holder.getSMC()) == false) {
0714:
0715:                                if (responseExpected) {
0716:                                    // reverse and call handle message/response
0717:                                    holder
0718:                                            .getSMC()
0719:                                            .put(
0720:                                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0721:                                                    false);
0722:                                    if (i > 0) {
0723:                                        callProtocolHandleMessage(holder,
0724:                                                i - 1, 0);
0725:                                    }
0726:                                    callLogicalHandleMessage(holder,
0727:                                            logicalHandlers.size() - 1, 0);
0728:                                }
0729:                                if (type == RequestOrResponse.RESPONSE) {
0730:                                    closeHandlersServer(holder);
0731:                                } else {
0732:                                    closeProtocolHandlers(holder, i, 0);
0733:                                    closeLogicalHandlers(holder,
0734:                                            logicalHandlers.size() - 1, 0);
0735:                                }
0736:                                return false;
0737:                            }
0738:                            i++;
0739:                        }
0740:                    } catch (RuntimeException re) {
0741:                        logger.log(Level.FINER, "exception in handler chain",
0742:                                re);
0743:                        if (responseExpected && re instanceof  ProtocolException) {
0744:                            // reverse direction and handle fault
0745:                            holder.getSMC().put(
0746:                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0747:                                    false);
0748:                            insertFaultMessage(holder, (ProtocolException) re);
0749:                            try {
0750:                                if (i == 0 || // still on first handler
0751:                                        callProtocolHandleFault(holder, i - 1,
0752:                                                0)) {
0753:                                    callLogicalHandleFault(holder,
0754:                                            logicalHandlers.size() - 1, 0);
0755:                                }
0756:                            } catch (ProtocolException re1) {
0757:                                addIgnoreFaultProperty(holder);
0758:                                re = re1;
0759:                            } catch (RuntimeException re2) {
0760:                                re = re2;
0761:                            }
0762:                        }
0763:                        if (type == RequestOrResponse.RESPONSE) {
0764:                            closeHandlersServer(holder);
0765:                        } else {
0766:                            closeProtocolHandlers(holder, i, 0);
0767:                            closeLogicalHandlers(holder,
0768:                                    logicalHandlers.size() - 1, 0);
0769:                        }
0770:                        throw re;
0771:                    }
0772:                } else { // inbound case, H(x) -> H(x-1) -> ... H(1) -> H(0)
0773:                    int i = soapHandlers.size() - 1;
0774:                    try {
0775:                        while (i >= 0) {
0776:                            if (soapHandlers.get(i).handleMessage(
0777:                                    holder.getSMC()) == false) {
0778:
0779:                                // reverse and call handle message/response
0780:                                holder
0781:                                        .getSMC()
0782:                                        .put(
0783:                                                MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0784:                                                true);
0785:                                if (responseExpected
0786:                                        && i != soapHandlers.size() - 1) {
0787:                                    callProtocolHandleMessage(holder, i + 1,
0788:                                            soapHandlers.size() - 1);
0789:                                }
0790:                                if (type == RequestOrResponse.RESPONSE) {
0791:                                    closeHandlersClient(holder);
0792:                                } else {
0793:                                    closeProtocolHandlers(holder, i,
0794:                                            soapHandlers.size() - 1);
0795:                                }
0796:                                return false;
0797:                            }
0798:                            i--;
0799:                        }
0800:                    } catch (RuntimeException re) {
0801:                        logger.log(Level.FINER, "exception in handler chain",
0802:                                re);
0803:                        if (responseExpected && re instanceof  ProtocolException) {
0804:                            // reverse direction and handle fault
0805:                            holder.getSMC().put(
0806:                                    MessageContext.MESSAGE_OUTBOUND_PROPERTY,
0807:                                    true);
0808:                            insertFaultMessage(holder, (ProtocolException) re);
0809:                            try {
0810:                                if (i < soapHandlers.size() - 1) {
0811:                                    callProtocolHandleFault(holder, i + 1,
0812:                                            soapHandlers.size() - 1);
0813:                                }
0814:                            } catch (ProtocolException re1) {
0815:                                addIgnoreFaultProperty(holder);
0816:                                re = re1;
0817:                            } catch (RuntimeException re2) {
0818:                                re = re2;
0819:                            }
0820:                        }
0821:                        if (type == RequestOrResponse.RESPONSE) {
0822:                            closeHandlersClient(holder);
0823:                        } else {
0824:                            closeProtocolHandlers(holder, i, soapHandlers
0825:                                    .size() - 1);
0826:                        }
0827:                        throw re;
0828:                    }
0829:                }
0830:                return true;
0831:            }
0832:
0833:            /**
0834:             * Method called for abnormal processing (for instance, as the
0835:             * result of a handler returning false during normal processing).
0836:             * Start and end indices are inclusive. 
0837:             */
0838:            private void callLogicalHandleMessage(ContextHolder holder,
0839:                    int start, int end) {
0840:
0841:                if (logicalHandlers.isEmpty() || start == -1
0842:                        || start == logicalHandlers.size()) {
0843:                    return;
0844:                }
0845:                callGenericHandleMessage(logicalHandlers, holder.getLMC(),
0846:                        start, end);
0847:
0848:            }
0849:
0850:            /**
0851:             * Method called for abnormal processing (for instance, as the
0852:             * result of a handler returning false during normal processing).
0853:             * Start and end indices are inclusive. 
0854:             */
0855:            private void callProtocolHandleMessage(ContextHolder holder,
0856:                    int start, int end) {
0857:
0858:                if (soapHandlers.isEmpty()) {
0859:                    return;
0860:                }
0861:                callGenericHandleMessage(soapHandlers, holder.getSMC(), start,
0862:                        end);
0863:            }
0864:
0865:            /**
0866:             * Utility method for calling handleMessage during abnormal processing(for 
0867:             * instance, as the result of a handler returning false during normal 
0868:             * processing). Start and end indices are inclusive. 
0869:             */
0870:
0871:            private <C extends MessageContext> void callGenericHandleMessage(
0872:                    List<? extends Handler> handlerList, C context, int start,
0873:                    int end) {
0874:                if (handlerList.isEmpty()) {
0875:                    return;
0876:                }
0877:                int i = start;
0878:                if (start > end) {
0879:                    try {
0880:                        while (i >= end) {
0881:                            if (handlerList.get(i).handleMessage(context) == false)
0882:                                return;
0883:                            i--;
0884:                        }
0885:                    } catch (RuntimeException re) {
0886:                        logger.log(Level.FINER, "exception in handler chain",
0887:                                re);
0888:                        throw re;
0889:                    }
0890:                } else {
0891:                    try {
0892:                        while (i <= end) {
0893:                            if (handlerList.get(i).handleMessage(context) == false)
0894:                                return;
0895:                            i++;
0896:                        }
0897:                    } catch (RuntimeException re) {
0898:                        logger.log(Level.FINER, "exception in handler chain",
0899:                                re);
0900:                        throw re;
0901:                    }
0902:                }
0903:                return;
0904:            }
0905:
0906:            /*
0907:             * Calls handleFault on the logical handlers. Indices are
0908:             * inclusive. Exceptions get passed up the chain, and an
0909:             * exception or return of 'false' ends processing.
0910:             */
0911:            private boolean callLogicalHandleFault(ContextHolder holder,
0912:                    int start, int end) {
0913:
0914:                return callGenericHandleFault(logicalHandlers, holder.getLMC(),
0915:                        start, end);
0916:            }
0917:
0918:            /**
0919:             * Calls handleFault on the protocol handlers. Indices are
0920:             * inclusive. Exceptions get passed up the chain, and an
0921:             * exception or return of 'false' ends processing.
0922:             */
0923:            private boolean callProtocolHandleFault(ContextHolder holder,
0924:                    int start, int end) {
0925:
0926:                return callGenericHandleFault(soapHandlers, holder.getSMC(),
0927:                        start, end);
0928:            }
0929:
0930:            /*
0931:             * Used by callLogicalHandleFault and callProtocolHandleFault.
0932:             */
0933:            private <C extends MessageContext> boolean callGenericHandleFault(
0934:                    List<? extends Handler> handlerList, C context, int start,
0935:                    int end) {
0936:
0937:                if (handlerList.isEmpty()) {
0938:                    return true;
0939:                }
0940:                int i = start;
0941:                if (start > end) {
0942:                    try {
0943:                        while (i >= end) {
0944:                            if (handlerList.get(i).handleFault(context) == false) {
0945:
0946:                                return false;
0947:                            }
0948:                            i--;
0949:                        }
0950:                    } catch (RuntimeException re) {
0951:                        logger.log(Level.FINER, "exception in handler chain",
0952:                                re);
0953:                        throw re;
0954:                    }
0955:                } else {
0956:                    try {
0957:                        while (i <= end) {
0958:                            if (handlerList.get(i).handleFault(context) == false) {
0959:
0960:                                return false;
0961:                            }
0962:                            i++;
0963:                        }
0964:                    } catch (RuntimeException re) {
0965:                        logger.log(Level.FINER, "exception in handler chain",
0966:                                re);
0967:                        throw re;
0968:                    }
0969:                }
0970:                return true;
0971:            }
0972:
0973:            /**
0974:             * Method that closes protocol handlers and then
0975:             * logical handlers.
0976:             */
0977:            private void closeHandlersClient(ContextHolder holder) {
0978:                closeProtocolHandlers(holder, soapHandlers.size() - 1, 0);
0979:                closeLogicalHandlers(holder, logicalHandlers.size() - 1, 0);
0980:            }
0981:
0982:            /**
0983:             * Method that closes logical handlers and then
0984:             * protocol handlers.
0985:             */
0986:            private void closeHandlersServer(ContextHolder holder) {
0987:                closeLogicalHandlers(holder, 0, logicalHandlers.size() - 1);
0988:                closeProtocolHandlers(holder, 0, soapHandlers.size() - 1);
0989:            }
0990:
0991:            /**
0992:             * This version is called by the server code once it determines
0993:             * that an incoming message is a one-way request. 
0994:             */
0995:            public void forceCloseHandlersOnServer(SOAPHandlerContext context) {
0996:                ContextHolder ch = new ContextHolder(context);
0997:                // only called after an inbound request
0998:                ch.getSMC()
0999:                        .put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
1000:                ((SOAPMessageContextImpl) ch.getSMC()).setRoles(getRoles());
1001:                closeHandlersServer(ch);
1002:            }
1003:
1004:            /**
1005:             * It is called by the client when an MU fault occurs since the handlerchain
1006:             * never gets invoked. The direction is an inbound message.
1007:             */
1008:            public void forceCloseHandlersOnClient(SOAPHandlerContext context) {
1009:                ContextHolder ch = new ContextHolder(context);
1010:
1011:                // only called after an inbound request
1012:                ch.getSMC()
1013:                        .put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
1014:                ((SOAPMessageContextImpl) ch.getSMC()).setRoles(getRoles());
1015:                closeHandlersClient(ch);
1016:            }
1017:
1018:            /**
1019:             * Version of forceCloseHandlers(HandlerContext) that is used
1020:             * by XML binding.
1021:             */
1022:            public void forceCloseHandlersOnServer(XMLHandlerContext context) {
1023:                ContextHolder ch = new ContextHolder(context);
1024:                // only called after an inbound request
1025:                ch.getLMC()
1026:                        .put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
1027:                closeHandlersServer(ch);
1028:            }
1029:
1030:            /**
1031:             * Version of forceCloseHandlers(HandlerContext) that is used
1032:             * by XML binding.
1033:             */
1034:            public void forceCloseHandlersOnClient(XMLHandlerContext context) {
1035:                ContextHolder ch = new ContextHolder(context);
1036:                // only called after an inbound request
1037:                ch.getLMC()
1038:                        .put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
1039:                closeHandlersClient(ch);
1040:            }
1041:
1042:            private void closeProtocolHandlers(ContextHolder holder, int start,
1043:                    int end) {
1044:
1045:                closeGenericHandlers(soapHandlers, holder.getSMC(), start, end);
1046:            }
1047:
1048:            private void closeLogicalHandlers(ContextHolder holder, int start,
1049:                    int end) {
1050:
1051:                closeGenericHandlers(logicalHandlers, holder.getLMC(), start,
1052:                        end);
1053:            }
1054:
1055:            /**
1056:             * Calls close on the handlers from the starting
1057:             * index through the ending index (inclusive). Made indices
1058:             * inclusive to allow both directions more easily.
1059:             */
1060:            private void closeGenericHandlers(
1061:                    List<? extends Handler> handlerList,
1062:                    MessageContext context, int start, int end) {
1063:
1064:                if (handlerList.isEmpty()) {
1065:                    return;
1066:                }
1067:                if (start > end) {
1068:                    for (int i = start; i >= end; i--) {
1069:                        try {
1070:                            handlerList.get(i).close(context);
1071:                        } catch (RuntimeException re) {
1072:                            logger.log(Level.INFO,
1073:                                    "Exception ignored during close", re);
1074:                        }
1075:                    }
1076:                } else {
1077:                    for (int i = start; i <= end; i++) {
1078:                        try {
1079:                            handlerList.get(i).close(context);
1080:                        } catch (RuntimeException re) {
1081:                            logger.log(Level.INFO,
1082:                                    "Exception ignored during close", re);
1083:                        }
1084:                    }
1085:                }
1086:            }
1087:
1088:            /**
1089:             * Used to hold the context objects that are used to get
1090:             * and set the current message.
1091:             *
1092:             * If a HandlerContext is passed in, both logical and soap
1093:             * handlers are used. If XMLHandlerContext is passed in,
1094:             * only logical handlers are assumed to be present.
1095:             */
1096:            static class ContextHolder {
1097:
1098:                boolean logicalOnly;
1099:                SOAPHandlerContext context;
1100:                XMLHandlerContext xmlContext;
1101:
1102:                ContextHolder(SOAPHandlerContext context) {
1103:                    this .context = context;
1104:                    logicalOnly = false;
1105:                }
1106:
1107:                ContextHolder(XMLHandlerContext xmlContext) {
1108:                    this .xmlContext = xmlContext;
1109:                    logicalOnly = true;
1110:                }
1111:
1112:                LogicalMessageContext getLMC() {
1113:                    return (logicalOnly ? xmlContext.getLogicalMessageContext()
1114:                            : context.getLogicalMessageContext());
1115:                }
1116:
1117:                SOAPMessageContext getSMC() {
1118:                    return (logicalOnly ? null : context
1119:                            .getSOAPMessageContext());
1120:                }
1121:            }
1122:
1123:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.