Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/SimpleChain.java


1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.axis ;
18  
19  import org.apache.axis.components.logger.LogFactory;
20  import org.apache.axis.handlers.BasicHandler;
21  import org.apache.axis.strategies.InvocationStrategy;
22  import org.apache.axis.strategies.WSDLGenStrategy;
23  import org.apache.axis.utils.Messages;
24  import org.apache.commons.logging.Log;
25  import org.w3c.dom.Document;
26  import org.w3c.dom.Element;
27  
28  import javax.xml.namespace.QName;
29  import java.util.Enumeration;
30  import java.util.Vector;
31  
32  /**
33   * A Simple Chain is a 'composite' Handler in that it aggregates a collection
34   * of Handlers and also acts as a Handler which delegates its operations to
35   * the collection.
36   * <p>
37   * A Simple Chain initially has no Handlers. Handlers may be added until the
38   * chain is invoke()d after which Handlers may not be added (and any attempt
39   * to do so will throw an exception).
40   *
41   * @author Doug Davis (dug@us.ibm.com)
42   * @author Glyn Normington (norm@uk.ibm.com)
43   */
44  public class SimpleChain extends BasicHandler implements Chain {
45      private static Log log =
46          LogFactory.getLog(SimpleChain.class.getName());
47  
48      protected Vector handlers = new Vector();
49      protected boolean invoked = false;
50  
51      private String CAUGHTFAULT_PROPERTY =
52              "org.apache.axis.SimpleChain.caughtFaultInResponse";
53  
54      public void init() {
55          for ( int i = 0 ; i < handlers.size() ; i++ )
56              ((Handler) handlers.elementAt( i )).init();
57      }
58  
59      public void cleanup() {
60          for ( int i = 0 ; i < handlers.size() ; i++ )
61              ((Handler) handlers.elementAt( i )).cleanup();
62      }
63  
64      private static final HandlerIterationStrategy iVisitor =
65          new InvocationStrategy();
66  
67      private static final HandlerIterationStrategy wsdlVisitor =
68          new WSDLGenStrategy();
69  
70      /**
71       * Iterate over the chain invoking each handler.  If there's a fault
72       * then call 'onFault' for each completed handler in reverse order, then
73       * rethrow the exception.
74       *
75       * @throws AxisFault if there was a fault with any of the handlers
76       */
77      public void invoke(MessageContext msgContext) throws AxisFault {
78          if (log.isDebugEnabled()) {
79              log.debug("Enter: SimpleChain::invoke");
80          }
81  
82         invoked = true;
83          doVisiting(msgContext, iVisitor);
84  
85          if (log.isDebugEnabled()) {
86              log.debug("Exit: SimpleChain::invoke");
87          }
88     }
89  
90      /**
91       * Iterate over the chain letting each handler have a crack at
92       * contributing to a WSDL description.
93       *
94       * @param msgContext  the <code>MessageContext</code> to write the WSDL
95       *              out to
96       * @throws AxisFault  if there was a problem writing the WSDL
97       */
98      public void generateWSDL(MessageContext msgContext) throws AxisFault {
99          if (log.isDebugEnabled()) {
100             log.debug("Enter: SimpleChain::generateWSDL");
101         }
102 
103         invoked = true;
104         doVisiting(msgContext, wsdlVisitor);
105 
106         if (log.isDebugEnabled()) {
107             log.debug("Exit: SimpleChain::generateWSDL");
108         }
109     }
110 
111     private void doVisiting(MessageContext msgContext,
112                             HandlerIterationStrategy visitor) throws AxisFault {
113         int i = 0 ;
114         try {
115             Enumeration enumeration = handlers.elements();
116             while (enumeration.hasMoreElements()) {
117                 Handler h = (Handler)enumeration.nextElement();
118                 visitor.visit(h, msgContext);
119                 i++;
120             }
121         } catch( AxisFault f ) {
122             // Something went wrong.  If we haven't already put this fault
123             // into the MessageContext's response message, do so and make sure
124             // we only do it once.  This allows onFault() methods to safely
125             // set headers and such in the response message without them
126             // getting stomped.
127             if (!msgContext.isPropertyTrue(CAUGHTFAULT_PROPERTY)) {
128                 // Attach the fault to the response message; enabling access to the
129                 // fault details while inside the handler onFault methods.
130                 Message respMsg = new Message(f);
131                 msgContext.setResponseMessage(respMsg);
132                 msgContext.setProperty(CAUGHTFAULT_PROPERTY, Boolean.TRUE);
133             }
134             while( --i >= 0 )
135                 ((Handler) handlers.elementAt( i )).onFault( msgContext );
136             throw f;
137         }
138     }
139 
140     /**
141      * Notify the handlers in this chain because some handler
142      * later on has faulted - in reverse order. If any handlers
143      * have been added since we visited the chain, they will get
144      * notified too!
145      *
146      * @param msgContext the context to process
147      */
148     public void onFault(MessageContext msgContext) {
149         if (log.isDebugEnabled()) {
150             log.debug("Enter: SimpleChain::onFault");
151         }
152 
153         for ( int i = handlers.size()-1 ; i >= 0 ; i-- )
154             ((Handler) handlers.elementAt( i )).onFault( msgContext );
155 
156         if (log.isDebugEnabled()) {
157             log.debug("Exit: SimpleChain::onFault");
158         }
159     }
160 
161     public boolean canHandleBlock(QName qname) {
162         for ( int i = 0 ; i < handlers.size() ; i++ )
163             if ( ((Handler) handlers.elementAt( i )).canHandleBlock(qname) )
164                 return( true );
165         return( false );
166     }
167 
168     public void addHandler(Handler handler) {
169         if (handler == null)
170             throw new InternalException(
171                 Messages.getMessage("nullHandler00",
172                                      "SimpleChain::addHandler"));
173 
174         if (invoked)
175             throw new InternalException(
176               Messages.getMessage("addAfterInvoke00",
177                                    "SimpleChain::addHandler"));
178 
179         handlers.add( handler );
180     }
181 
182     public boolean contains(Handler handler) {
183         return( handlers.contains( handler ));
184     }
185 
186     public Handler[] getHandlers() {
187         if (handlers.size() == 0)
188             return null;
189 
190         Handler [] ret = new Handler[handlers.size()];
191         return( (Handler[]) handlers.toArray(ret) );
192     }
193 
194     public Element getDeploymentData(Document doc) {
195         if (log.isDebugEnabled()) {
196             log.debug( Messages.getMessage("enter00",
197                                             "SimpleChain::getDeploymentData") );
198         }
199 
200         Element  root = doc.createElementNS("", "chain" );
201 
202         StringBuffer str = new StringBuffer();
203         int i = 0;
204         while (i < handlers.size()) {
205             if ( i != 0 ) str.append(",");
206             Handler h = (Handler) handlers.elementAt(i);
207             str.append( h.getName() );
208             i++;
209         }
210         if (i > 0) {
211             root.setAttribute( "flow", str.toString() );
212         }
213 
214         if ( options != null ) {
215             Enumeration e = options.keys();
216             while ( e.hasMoreElements() ) {
217                 String k = (String) e.nextElement();
218                 Object v = options.get(k);
219                 Element e1 = doc.createElementNS("", "option");
220                 e1.setAttribute( "name", k );
221                 e1.setAttribute( "value", v.toString() );
222                 root.appendChild( e1 );
223             }
224         }
225 
226         if (log.isDebugEnabled()) {
227             log.debug("Exit: SimpleChain::getDeploymentData");
228         }
229 
230         return( root );
231     }
232 }