KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > webservice > handler > HandlerChainBaseImpl


1 /**
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.webservice.handler;
8
9 // $Id: HandlerChainBaseImpl.java,v 1.8.2.2 2005/04/22 11:28:31 tdiesler Exp $
10

11 import org.jboss.axis.AxisFault;
12 import org.jboss.axis.Constants;
13 import org.jboss.axis.message.SOAPElementAxisImpl;
14 import org.jboss.logging.Logger;
15
16 import javax.xml.namespace.QName JavaDoc;
17 import javax.xml.rpc.JAXRPCException JavaDoc;
18 import javax.xml.rpc.handler.Handler JavaDoc;
19 import javax.xml.rpc.handler.HandlerChain JavaDoc;
20 import javax.xml.rpc.handler.HandlerInfo JavaDoc;
21 import javax.xml.rpc.handler.MessageContext JavaDoc;
22 import javax.xml.rpc.handler.soap.SOAPMessageContext JavaDoc;
23 import javax.xml.soap.SOAPEnvelope JavaDoc;
24 import javax.xml.soap.SOAPException JavaDoc;
25 import javax.xml.soap.SOAPHeader JavaDoc;
26 import javax.xml.soap.SOAPHeaderElement JavaDoc;
27 import javax.xml.soap.SOAPPart JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.ListIterator JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.Set JavaDoc;
37
38 /**
39  * Represents a list of handlers. All elements in the
40  * HandlerChain are of the type javax.xml.rpc.handler.Handler.
41  * <p/>
42  * Abstracts the policy and mechanism for the invocation of the registered handlers.
43  *
44  * @author Thomas.Diesler@jboss.org
45  * @since 06-May-2004
46  */

47 public abstract class HandlerChainBaseImpl implements HandlerChain JavaDoc
48 {
49    private static Logger log = Logger.getLogger(HandlerChainBaseImpl.class);
50
51    public static final int STATE_DOES_NOT_EXIST = 0;
52    public static final int STATE_CREATED = 1;
53    public static final int STATE_READY = 2;
54    public static final int STATE_DESTROYED = 3;
55
56    // The List<Entry> objects
57
protected ArrayList JavaDoc handlers = new ArrayList JavaDoc();
58    // The roles associated with the handler chain
59
protected HashSet JavaDoc roles = new HashSet JavaDoc();
60    // The index of the first handler that returned false during processing
61
protected int falseIndex = -1;
62    // The state of this handler chain
63
protected int state;
64
65    /**
66     * Constructs a handler chain with the given handlers infos
67     */

68    public HandlerChainBaseImpl(List JavaDoc infos, Set JavaDoc roles)
69    {
70       log.debug("Create a handler chain for roles: " + roles);
71       addHandlersToChain(infos, roles);
72    }
73
74    /**
75     * Initialize the a handler chain with the given handlers infos
76     *
77     * @throws javax.xml.rpc.JAXRPCException If any error during initialization
78     */

79    private void addHandlersToChain(List JavaDoc infos, Set JavaDoc roleSet)
80    {
81       try
82       {
83          if (infos != null)
84          {
85             for (int i = 0; i < infos.size(); i++)
86             {
87                HandlerInfo JavaDoc info = (HandlerInfo JavaDoc)infos.get(i);
88                HandlerWrapper handler = new HandlerWrapper((Handler JavaDoc)info.getHandlerClass().newInstance());
89                handlers.add(new Entry(handler, info));
90             }
91          }
92          if (roleSet != null)
93          {
94             roles.addAll(roleSet);
95          }
96       }
97       catch (Exception JavaDoc e)
98       {
99          throw new JAXRPCException JavaDoc("Cannot initialize handler chain", e);
100       }
101
102       // set state to created
103
state = STATE_CREATED;
104    }
105
106    /**
107     * Get the state of this handler chain
108     */

109    public int getState()
110    {
111       return state;
112    }
113
114    /**
115     * Initializes the configuration for a HandlerChain.
116     *
117     * @param config Configuration for the initialization of this handler chain
118     * @throws javax.xml.rpc.JAXRPCException If any error during initialization
119     */

120    public void init(Map JavaDoc config)
121    {
122       log.debug("init: [config=" + config + "]");
123       for (int i = 0; i < handlers.size(); i++)
124       {
125          Entry entry = (Entry)handlers.get(i);
126          entry.handler.init(entry.info);
127       }
128
129       // set state to ready
130
state = STATE_READY;
131    }
132
133    /**
134     * Indicates the end of lifecycle for a HandlerChain.
135     *
136     * @throws javax.xml.rpc.JAXRPCException If any error during destroy
137     */

138    public void destroy()
139    {
140       log.debug("destroy");
141       for (int i = 0; i < handlers.size(); i++)
142       {
143          Entry entry = (Entry)handlers.get(i);
144          entry.handler.destroy();
145       }
146       handlers.clear();
147
148       // set state to destroyed
149
state = STATE_DESTROYED;
150    }
151
152    /**
153     * Gets SOAP actor roles registered for this HandlerChain at this SOAP node. The returned array includes the
154     * special SOAP actor next.
155     *
156     * @return SOAP Actor roles as URIs
157     */

158    public String JavaDoc[] getRoles()
159    {
160       String JavaDoc[] arr = new String JavaDoc[roles.size()];
161       roles.toArray(arr);
162       return arr;
163    }
164
165    /**
166     * Sets SOAP Actor roles for this HandlerChain. This specifies the set of roles in which this HandlerChain is to act
167     * for the SOAP message processing at this SOAP node. These roles assumed by a HandlerChain must be invariant during
168     * the processing of an individual SOAP message through the HandlerChain.
169     * <p/>
170     * A HandlerChain always acts in the role of the special SOAP actor next. Refer to the SOAP specification for the
171     * URI name for this special SOAP actor. There is no need to set this special role using this method.
172     *
173     * @param soapActorNames URIs for SOAP actor name
174     */

175    public void setRoles(String JavaDoc[] soapActorNames)
176    {
177       List JavaDoc newRoles = Arrays.asList(soapActorNames);
178       log.debug("setRoles: " + newRoles);
179
180       roles.clear();
181       roles.addAll(newRoles);
182    }
183
184    /**
185     * Initiates the request processing for this handler chain.
186     *
187     * @param msgContext MessageContext parameter provides access to the request SOAP message.
188     * @return Returns true if all handlers in chain have been processed. Returns false if a handler in the chain returned false from its handleRequest method.
189     * @throws javax.xml.rpc.JAXRPCException if any processing error happens
190     */

191    public boolean handleRequest(MessageContext JavaDoc msgContext)
192    {
193       boolean doNext = true;
194
195       log.debug("Enter: doHandleRequest");
196
197       // Replace handlers that did not survive the previous call
198
replaceDirtyHandlers();
199
200       int handlerIndex = 0;
201       Handler JavaDoc currHandler = null;
202       try
203       {
204          for (; doNext && handlerIndex < handlers.size(); handlerIndex++)
205          {
206             String JavaDoc lastMessageTrace = null;
207             if (log.isTraceEnabled())
208             {
209                org.jboss.axis.MessageContext msgCtx = (org.jboss.axis.MessageContext)msgContext;
210                SOAPPart JavaDoc soapPart = msgCtx.getRequestMessage().getSOAPPart();
211                lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
212             }
213
214             currHandler = ((Entry)handlers.get(handlerIndex)).getHandler();
215             log.debug("Handle request: " + currHandler);
216             doNext = currHandler.handleRequest(msgContext);
217
218             if (log.isTraceEnabled())
219             {
220                org.jboss.axis.MessageContext msgCtx = (org.jboss.axis.MessageContext)msgContext;
221                SOAPPart JavaDoc soapPart = msgCtx.getRequestMessage().getSOAPPart();
222                lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
223             }
224          }
225       }
226       catch (RuntimeException JavaDoc e)
227       {
228          log.error("RuntimeException in request handler", e);
229          doNext = false;
230          throw e;
231       }
232       finally
233       {
234          // we start at this index in the response chain
235
if (doNext == false)
236             falseIndex = handlerIndex;
237
238          log.debug("Exit: doHandleRequest with status: " + doNext);
239       }
240
241       return doNext;
242    }
243
244    /**
245     * Initiates the response processing for this handler chain.
246     * <p/>
247     * In this implementation, the response handler chain starts processing from the same Handler
248     * instance (that returned false) and goes backward in the execution sequence.
249     *
250     * @return Returns true if all handlers in chain have been processed.
251     * Returns false if a handler in the chain returned false from its handleResponse method.
252     * @throws javax.xml.rpc.JAXRPCException if any processing error happens
253     */

254    public boolean handleResponse(MessageContext JavaDoc msgContext)
255    {
256       boolean doNext = true;
257
258       log.debug("Enter: handleResponse");
259
260       int handlerIndex = handlers.size() - 1;
261       if (falseIndex != -1)
262          handlerIndex = falseIndex;
263
264       Handler JavaDoc currHandler = null;
265       try
266       {
267          for (; doNext && handlerIndex >= 0; handlerIndex--)
268          {
269             String JavaDoc lastMessageTrace = null;
270             if (log.isTraceEnabled())
271             {
272                org.jboss.axis.MessageContext msgCtx = (org.jboss.axis.MessageContext)msgContext;
273                SOAPPart JavaDoc soapPart = msgCtx.getResponseMessage().getSOAPPart();
274                lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
275             }
276
277             currHandler = ((Entry)handlers.get(handlerIndex)).getHandler();
278             log.debug("Handle response: " + currHandler);
279             doNext = currHandler.handleResponse(msgContext);
280
281             if (log.isTraceEnabled())
282             {
283                org.jboss.axis.MessageContext msgCtx = (org.jboss.axis.MessageContext)msgContext;
284                SOAPPart JavaDoc soapPart = msgCtx.getResponseMessage().getSOAPPart();
285                lastMessageTrace = traceSOAPPart(soapPart, lastMessageTrace);
286             }
287          }
288       }
289       catch (RuntimeException JavaDoc rte)
290       {
291          log.error("RuntimeException in response handler", rte);
292          doNext = false;
293          throw rte;
294       }
295       finally
296       {
297          // we start at this index in the fault chain
298
if (doNext == false)
299             falseIndex = handlerIndex;
300
301          log.debug("Exit: handleResponse with status: " + doNext);
302       }
303
304       return doNext;
305    }
306
307    /**
308     * Initiates the SOAP fault processing for this handler chain.
309     * <p/>
310     * In this implementation, the fault handler chain starts processing from the same Handler
311     * instance (that returned false) and goes backward in the execution sequence.
312     *
313     * @return Returns true if all handlers in chain have been processed.
314     * Returns false if a handler in the chain returned false from its handleFault method.
315     * @throws javax.xml.rpc.JAXRPCException if any processing error happens
316     */

317    public boolean handleFault(MessageContext JavaDoc msgContext)
318    {
319       boolean doNext = true;
320
321       int handlerIndex = handlers.size() - 1;
322       if (falseIndex != -1)
323          handlerIndex = falseIndex;
324
325       Handler JavaDoc currHandler = null;
326       for (; doNext && handlerIndex >= 0; handlerIndex--)
327       {
328          currHandler = ((Entry)handlers.get(handlerIndex)).getHandler();
329          log.debug("Handle fault: " + currHandler);
330          doNext = currHandler.handleFault(msgContext);
331       }
332
333       return doNext;
334    }
335
336    /**
337     * Trace the SOAPPart, do nothing if the String representation is equal to the last one.
338     */

339    protected String JavaDoc traceSOAPPart(SOAPPart JavaDoc soapPart, String JavaDoc lastMessageTrace)
340    {
341       try
342       {
343          SOAPEnvelope JavaDoc env = soapPart.getEnvelope();
344          String JavaDoc envAsString = ((SOAPElementAxisImpl)env).getAsStringFromInternal();
345          if (envAsString.equals(lastMessageTrace) == false)
346          {
347             log.trace(envAsString);
348             lastMessageTrace = envAsString;
349          }
350          return lastMessageTrace;
351       }
352       catch (SOAPException JavaDoc e)
353       {
354          log.error("Cannot get SOAPEnvelope", e);
355          return null;
356       }
357    }
358
359    /**
360     * Replace handlers that did not survive the previous call
361     */

362    protected void replaceDirtyHandlers()
363    {
364       for (int i = 0; i < handlers.size(); i++)
365       {
366          Entry entry = (Entry)handlers.get(i);
367          if (entry.handler.getState() == HandlerWrapper.DOES_NOT_EXIST)
368          {
369             log.debug("Replacing dirty handler: " + entry.handler);
370             try
371             {
372                HandlerWrapper handler = new HandlerWrapper((Handler JavaDoc)entry.info.getHandlerClass().newInstance());
373                entry.handler = handler;
374                handler.init(entry.info);
375             }
376             catch (Exception JavaDoc e)
377             {
378                log.error("Cannot create handler instance for: " + entry.info);
379             }
380          }
381       }
382    }
383
384    /**
385     * Get the handler at the requested position
386     */

387    protected Handler JavaDoc getHandlerAt(int pos)
388    {
389       if (pos < 0 || handlers.size() <= pos)
390          throw new IllegalArgumentException JavaDoc("No handler at position: " + pos);
391
392       Entry entry = (Entry)handlers.get(pos);
393       return entry.handler;
394    }
395
396    /**
397     * Check if there are mustUnderstand headers that were not processed
398     */

399    protected void checkMustUnderstand(MessageContext JavaDoc msgContext)
400    {
401       String JavaDoc errorMsg = null;
402
403       try
404       {
405          SOAPMessageContext JavaDoc msgCtx = (SOAPMessageContext JavaDoc)msgContext;
406          SOAPPart JavaDoc soapPart = msgCtx.getMessage().getSOAPPart();
407          SOAPHeader JavaDoc soapHeader = soapPart.getEnvelope().getHeader();
408          if (soapHeader != null)
409          {
410             Iterator JavaDoc it = soapHeader.examineAllHeaderElements();
411             while (errorMsg == null && it.hasNext())
412             {
413                SOAPHeaderElement JavaDoc headerElement = (SOAPHeaderElement JavaDoc)it.next();
414                if (headerElement.getMustUnderstand() == true)
415                {
416                   QName JavaDoc headerName = new QName JavaDoc(headerElement.getNamespaceURI(), headerElement.getLocalName());
417
418                   String JavaDoc actor = headerElement.getActor();
419                   if (actor == null || Constants.URI_SOAP11_NEXT_ACTOR.equals(actor))
420                   {
421                      errorMsg = "Unprocessed mustUnderstand header " + headerName;
422                      break;
423                   }
424
425                   if (actor != null && roles.contains(actor))
426                   {
427                      Iterator JavaDoc itHandlers = handlers.iterator();
428                      while (itHandlers.hasNext())
429                      {
430                         Entry entry = (Entry)itHandlers.next();
431                         Handler JavaDoc handler = entry.getHandler();
432
433                         // Check if this handler should have processed this header element
434
List JavaDoc headers = Arrays.asList(handler.getHeaders());
435                         if (headers.contains(headerName))
436                         {
437                            errorMsg = "Unprocessed mustUnderstand header " + headerName;
438                            break;
439                         }
440                      }
441                   }
442                }
443             }
444          }
445       }
446       catch (SOAPException JavaDoc e)
447       {
448          log.error("Cannot check mustUnderstand for headers", e);
449       }
450
451       if (errorMsg != null)
452       {
453          AxisFault fault = new AxisFault(errorMsg);
454          fault.setFaultCode(Constants.FAULT_MUSTUNDERSTAND);
455          throw new JAXRPCException JavaDoc(fault);
456       }
457    }
458
459    /**
460     * An entry in the handler list
461     */

462    private class Entry
463    {
464       private HandlerWrapper handler;
465       private HandlerInfo JavaDoc info;
466
467       public Entry(HandlerWrapper handler, HandlerInfo JavaDoc info)
468       {
469          this.handler = handler;
470          this.info = info;
471       }
472
473       public Handler JavaDoc getHandler()
474       {
475          return handler;
476       }
477
478       public HandlerInfo JavaDoc getInfo()
479       {
480          return info;
481       }
482    }
483
484    // java.util.List interface ****************************************************************************************
485

486    public boolean remove(Object JavaDoc o)
487    {
488       return handlers.remove(o);
489    }
490
491    public boolean containsAll(Collection JavaDoc c)
492    {
493       return handlers.containsAll(c);
494    }
495
496    public boolean removeAll(Collection JavaDoc c)
497    {
498       return handlers.removeAll(c);
499    }
500
501    public boolean retainAll(Collection JavaDoc c)
502    {
503       return handlers.retainAll(c);
504    }
505
506    public int hashCode()
507    {
508       return handlers.hashCode();
509    }
510
511    public boolean equals(Object JavaDoc o)
512    {
513       return handlers.equals(o);
514    }
515
516    public Iterator JavaDoc iterator()
517    {
518       return handlers.iterator();
519    }
520
521    public List JavaDoc subList(int fromIndex, int toIndex)
522    {
523       return handlers.subList(fromIndex, toIndex);
524    }
525
526    public ListIterator JavaDoc listIterator()
527    {
528       return handlers.listIterator();
529    }
530
531    public ListIterator JavaDoc listIterator(int index)
532    {
533       return handlers.listIterator(index);
534    }
535
536    public int size()
537    {
538       return handlers.size();
539    }
540
541    public void clear()
542    {
543       handlers.clear();
544    }
545
546    public boolean isEmpty()
547    {
548       return handlers.isEmpty();
549    }
550
551    public Object JavaDoc[] toArray()
552    {
553       return handlers.toArray();
554    }
555
556    public Object JavaDoc get(int index)
557    {
558       return handlers.get(index);
559    }
560
561    public Object JavaDoc remove(int index)
562    {
563       return handlers.remove(index);
564    }
565
566    public void add(int index, Object JavaDoc element)
567    {
568       handlers.add(index, element);
569    }
570
571    public int indexOf(Object JavaDoc elem)
572    {
573       return handlers.indexOf(elem);
574    }
575
576    public int lastIndexOf(Object JavaDoc elem)
577    {
578       return handlers.lastIndexOf(elem);
579    }
580
581    public boolean add(Object JavaDoc o)
582    {
583       return handlers.add(o);
584    }
585
586    public boolean contains(Object JavaDoc elem)
587    {
588       return handlers.contains(elem);
589    }
590
591    public boolean addAll(int index, Collection JavaDoc c)
592    {
593       return handlers.addAll(index, c);
594    }
595
596    public boolean addAll(Collection JavaDoc c)
597    {
598       return handlers.addAll(c);
599    }
600
601    public Object JavaDoc set(int index, Object JavaDoc element)
602    {
603       return handlers.set(index, element);
604    }
605
606    public Object JavaDoc[] toArray(Object JavaDoc[] a)
607    {
608       return handlers.toArray(a);
609    }
610 }
611
Popular Tags