KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis2 > engine > AxisEngine


1 /*
2  * Copyright 2004,2005 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 package org.apache.axis2.engine;
17
18 import org.apache.axis2.context.ConfigurationContext;
19 import org.apache.axis2.context.MessageContext;
20 import org.apache.axis2.context.OperationContext;
21 import org.apache.axis2.description.OperationDescription;
22 import org.apache.axis2.description.TransportOutDescription;
23 import org.apache.axis2.om.OMAbstractFactory;
24 import org.apache.axis2.soap.*;
25 import org.apache.axis2.soap.impl.llom.SOAPProcessingException;
26 import org.apache.axis2.soap.impl.llom.soap12.SOAP12Constants;
27 import org.apache.axis2.transport.TransportSender;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import java.util.ArrayList JavaDoc;
32
33 /**
34  * There is one engine for the Server and the Client. the send() and receive()
35  * Methods are the basic operations the Sync, Async messageing are build on top.
36  */

37 public class AxisEngine {
38     /**
39      * Field log
40      */

41     private Log log = LogFactory.getLog(getClass());
42     private ConfigurationContext engineContext;
43
44     /**
45      * Constructor AxisEngine
46      */

47     public AxisEngine(ConfigurationContext engineContext) {
48         log.info("Axis Engine Started");
49         this.engineContext = engineContext;
50     }
51
52     /**
53      * This methods represents the outflow of the Axis, this could be either at the server side or the client side.
54      * Here the <code>ExecutionChain</code> is created using the Phases. The Handlers at the each Phases is ordered in
55      * deployment time by the deployment module
56      *
57      * @param context
58      * @throws AxisFault
59      * @see MessageContext
60      * @see ExecutionChain
61      * @see Phase
62      * @see Handler
63      */

64     public void send(MessageContext msgContext) throws AxisFault {
65         try {
66             verifyContextBuilt(msgContext);
67             OperationContext operationContext = msgContext.getOperationContext();
68
69             ArrayList JavaDoc phases = operationContext.getAxisOperation().getPhasesOutFlow();
70             if (msgContext.isPaused()) {
71                 resumeInvocationPhases(phases, msgContext);
72             } else {
73                 invokePhases(phases, msgContext);
74             }
75
76             TransportOutDescription transportOut = msgContext.getTransportOut();
77
78             TransportSender sender = transportOut.getSender();
79             sender.invoke(msgContext);
80         } catch (Throwable JavaDoc e) {
81             handleFault(msgContext, e);
82         }
83     }
84
85     /**
86      * This methods represents the inflow of the Axis, this could be either at the server side or the client side.
87      * Here the <code>ExecutionChain</code> is created using the Phases. The Handlers at the each Phases is ordered in
88      * deployment time by the deployment module
89      *
90      * @param context
91      * @throws AxisFault
92      * @see MessageContext
93      * @see ExecutionChain
94      * @see Phase
95      * @see Handler
96      */

97     public void receive(MessageContext msgContext) throws AxisFault {
98         boolean paused = msgContext.isPaused();
99         try {
100             ConfigurationContext sysCtx = msgContext.getSystemContext();
101             ArrayList JavaDoc phases =
102                     sysCtx.getAxisConfiguration().getInPhasesUptoAndIncludingPostDispatch();
103
104             if (paused) {
105                 resumeInvocationPhases(phases, msgContext);
106             } else {
107                 invokePhases(phases, msgContext);
108             }
109             verifyContextBuilt(msgContext);
110
111             OperationContext operationContext = msgContext.getOperationContext();
112             OperationDescription operationDescription = operationContext.getAxisOperation();
113             phases = operationDescription.getRemainingPhasesInFlow();
114
115             if (paused) {
116                 resumeInvocationPhases(phases, msgContext);
117             } else {
118                 invokePhases(phases, msgContext);
119             }
120             paused = msgContext.isPaused();
121             if (msgContext.isServerSide() && !paused) {
122                 // add invoke Phase
123
MessageReceiver reciver = operationDescription.getMessageReciever();
124                 reciver.recieve(msgContext);
125             }
126         } catch (Throwable JavaDoc e) {
127             handleFault(msgContext, e);
128         }
129     }
130
131     /**
132      * If error occurs at inflow or the out flow this method will call to handle the error. But if the
133      * execution reach this method twice, means the sending the error handling failed an in that case the
134      * this method just log the error and exit</p>
135      *
136      * @param context
137      * @param e
138      * @throws AxisFault
139      */

140     public void handleFault(MessageContext context, Throwable JavaDoc e) throws AxisFault {
141         boolean serverSide = context.isServerSide();
142         log.error("Error Ocurred", e);
143         if (serverSide && !context.isProcessingFault()) {
144             context.setProcessingFault(true);
145
146             // create a SOAP envelope with the Fault
147
MessageContext faultContext =
148                     new MessageContext(engineContext,
149                             context.getSessionContext(),
150                             context.getTransportIn(),
151                             context.getTransportOut());
152
153             if (context.getFaultTo() != null) {
154                 faultContext.setFaultTo(context.getFaultTo());
155             } else {
156                 Object JavaDoc writer = context.getProperty(MessageContext.TRANSPORT_OUT);
157                 if (writer != null) {
158                     faultContext.setProperty(MessageContext.TRANSPORT_OUT, writer);
159                 } else {
160                     //TODO Opps there are no place to send this, we will log and should we throw the exception?
161
log.error("Error in fault flow", e);
162                     e.printStackTrace();
163                 }
164             }
165
166             faultContext.setOperationContext(context.getOperationContext());
167             faultContext.setProcessingFault(true);
168             faultContext.setServerSide(true);
169             SOAPEnvelope envelope = null;
170
171             try {
172
173                 if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(context.getEnvelope().getNamespace().getName())) {
174                     envelope = OMAbstractFactory.getSOAP12Factory().getDefaultFaultEnvelope();
175                 } else {
176                     envelope = OMAbstractFactory.getSOAP11Factory().getDefaultFaultEnvelope();
177                 }
178             } catch (SOAPProcessingException e1) {
179                 throw new AxisFault(e1);
180             }
181
182             // TODO do we need to set old Headers back?
183
SOAPBody body = envelope.getBody();
184             
185 // body.addFault(new AxisFault(e.getMessage(), e));
186
body.getFault().setException(new AxisFault(e.getMessage(), e));
187             extractFaultInformationFromMessageContext(context, envelope.getBody().getFault());
188
189             faultContext.setEnvelope(envelope);
190
191             OperationContext opContext = context.getOperationContext();
192             if (opContext != null) {
193                 OperationDescription axisOperation = opContext.getAxisOperation();
194                 ArrayList JavaDoc phases = axisOperation.getPhasesOutFaultFlow();
195                 invokePhases(phases, context);
196             }
197             // Write the the error
198
TransportSender sender = context.getTransportOut().getSender();
199             sender.invoke(faultContext);
200         } else if (!serverSide) {
201             // if at the client side throw the exception
202
throw new AxisFault("", e);
203         } else {
204             // TODO log and exit
205
log.error("Error in fault flow", e);
206         }
207     }
208
209     private void extractFaultInformationFromMessageContext(MessageContext context, SOAPFault fault) {
210         Object JavaDoc faultCode = context.getProperty(SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME);
211         if (faultCode != null) {
212             fault.setCode((SOAPFaultCode) faultCode);
213         }
214
215         Object JavaDoc faultReason = context.getProperty(SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME);
216         if (faultReason != null) {
217             fault.setReason((SOAPFaultReason) faultReason);
218         }
219
220         Object JavaDoc faultRole = context.getProperty(SOAP12Constants.SOAP_FAULT_ROLE_LOCAL_NAME);
221         if (faultRole != null) {
222             fault.getRole().setText((String JavaDoc) faultRole);
223         }
224
225         Object JavaDoc faultNode = context.getProperty(SOAP12Constants.SOAP_FAULT_NODE_LOCAL_NAME);
226         if (faultNode != null) {
227             fault.getNode().setText((String JavaDoc) faultNode);
228         }
229
230         Object JavaDoc faultDetail = context.getProperty(SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME);
231         if (faultDetail != null) {
232             fault.setDetail((SOAPFaultDetail) faultDetail);
233         }
234     }
235
236     private void verifyContextBuilt(MessageContext msgctx) throws AxisFault {
237         if (msgctx.getSystemContext() == null) {
238             throw new AxisFault("ConfigurationContext can not be null");
239         }
240         if (msgctx.getOperationContext() == null) {
241             throw new AxisFault("OperationContext can not be null");
242         }
243         if (msgctx.getServiceContext() == null) {
244             throw new AxisFault("ServiceContext can not be null");
245         }
246     }
247
248     private void invokePhases(ArrayList JavaDoc phases, MessageContext msgctx) throws AxisFault {
249         int count = phases.size();
250         for (int i = 0; (i < count && !msgctx.isPaused()); i++) {
251             Phase phase = (Phase) phases.get(i);
252             phase.invoke(msgctx);
253         }
254     }
255
256     public void resumeInvocationPhases(ArrayList JavaDoc phases, MessageContext msgctx) throws AxisFault {
257         msgctx.setPausedFalse();
258         int count = phases.size();
259         boolean foudMatch = false;
260
261         for (int i = 0; i < count && !msgctx.isPaused(); i++) {
262             Phase phase = (Phase) phases.get(i);
263             if (phase.getPhaseName().equals(msgctx.getPausedPhaseName())) {
264                 foudMatch = true;
265                 phase.invokeStartFromHandler(msgctx.getPausedHandlerName(), msgctx);
266             } else {
267                 if (foudMatch) {
268                     phase.invoke(msgctx);
269                 }
270
271             }
272         }
273     }
274
275     /* --------------------------------------------------------------------------------------------*/
276     /* ----------------- Methods related to storage ----------------------------------------------*/
277     /**
278      * Stores an object in the underlying storage
279      *
280      * @param context The relevant engine context
281      * @param obj the object to be stored
282      * @return the storage key
283      */

284     public Object JavaDoc store(ConfigurationContext context, Object JavaDoc obj) {
285         return context.getStorage().put(obj);
286     }
287
288     /**
289      * retrieves an object from the underlying storage
290      *
291      * @param context
292      * @param key
293      * @return
294      * @see #store(org.apache.axis2.context.EngineContext, Object)
295      */

296     public Object JavaDoc retrieve(ConfigurationContext context, Object JavaDoc key) {
297         return context.getStorage().get(key);
298     }
299
300     /**
301      * removes an object from the underlying storage
302      *
303      * @param context
304      * @param key
305      * @return the object removed
306      */

307     public Object JavaDoc remove(ConfigurationContext context, Object JavaDoc key) {
308         return context.getStorage().remove(key);
309     }
310
311     /**
312      * Clears the underlying storage
313      *
314      * @param context
315      * @return
316      */

317     public boolean clearStorage(ConfigurationContext context) {
318         return context.getStorage().clean();
319     }
320 }
321
Popular Tags