001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.jaxws.server;
021:
022: import org.apache.axis2.AxisFault;
023: import org.apache.axis2.context.OperationContext;
024: import org.apache.axis2.description.AxisOperation;
025: import org.apache.axis2.description.AxisService;
026: import org.apache.axis2.description.WSDL2Constants;
027: import org.apache.axis2.engine.AxisEngine;
028: import org.apache.axis2.engine.MessageReceiver;
029: import org.apache.axis2.jaxws.ExceptionFactory;
030: import org.apache.axis2.jaxws.core.InvocationContext;
031: import org.apache.axis2.jaxws.core.InvocationContextFactory;
032: import org.apache.axis2.jaxws.core.InvocationContextImpl;
033: import org.apache.axis2.jaxws.core.MessageContext;
034: import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
035: import org.apache.axis2.jaxws.handler.MEPContext;
036: import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
037: import org.apache.axis2.jaxws.i18n.Messages;
038: import org.apache.axis2.jaxws.message.util.MessageUtils;
039: import org.apache.axis2.jaxws.util.Constants;
040: import org.apache.axis2.util.ThreadContextMigratorUtil;
041: import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants;
042: import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants;
043: import org.apache.commons.logging.Log;
044: import org.apache.commons.logging.LogFactory;
045:
046: import javax.xml.ws.Binding;
047: import javax.xml.ws.WebServiceException;
048:
049: /**
050: * The JAXWSMessageReceiver is the entry point, from the server's perspective, to the JAX-WS code.
051: * This will be called by the Axis Engine and is the end of the chain from an Axis2 perspective.
052: */
053: public class JAXWSMessageReceiver implements MessageReceiver {
054:
055: private static final Log log = LogFactory
056: .getLog(JAXWSMessageReceiver.class);
057:
058: private static String PARAM_SERVICE_CLASS = "ServiceClass";
059: public static String PARAM_BINDING = "Binding";
060:
061: /**
062: * We should have already determined which AxisService we're targetting at this point. So now,
063: * just get the service implementation and invoke the appropriate method.
064: */
065: public void receive(
066: org.apache.axis2.context.MessageContext axisRequestMsgCtx)
067: throws AxisFault {
068: AxisFault faultToReturn = null;
069:
070: if (log.isDebugEnabled()) {
071: log.debug("new request received");
072: }
073:
074: //Get the name of the service impl that was stored as a parameter
075: // inside of the services.xml.
076: AxisService service = axisRequestMsgCtx.getAxisService();
077: AxisOperation operation = axisRequestMsgCtx.getAxisOperation();
078: String mep = operation.getMessageExchangePattern();
079: if (log.isDebugEnabled()) {
080: log.debug("MEP: " + mep);
081: }
082:
083: org.apache.axis2.description.Parameter svcClassParam = service
084: .getParameter(PARAM_SERVICE_CLASS);
085:
086: try {
087: if (svcClassParam == null) {
088: throw new RuntimeException(
089: Messages
090: .getMessage("JAXWSMessageReceiverNoServiceClass"));
091: }
092:
093: //This assumes that we are on the ultimate execution thread
094: ThreadContextMigratorUtil.performMigrationToThread(
095: Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
096: axisRequestMsgCtx);
097:
098: //We'll need an instance of the EndpointController to actually
099: //drive the invocation.
100: //TODO: More work needed to determine the lifecycle of this thing
101: EndpointController endpointCtlr = new EndpointController();
102:
103: MessageContext requestMsgCtx = new MessageContext(
104: axisRequestMsgCtx);
105: requestMsgCtx.setMEPContext(new MEPContext(requestMsgCtx));
106: // The adapters need to be installed on the new request Message Context
107: AttachmentsAdapter.install(requestMsgCtx);
108: TransportHeadersAdapter.install(requestMsgCtx);
109:
110: Binding binding = (Binding) axisRequestMsgCtx
111: .getProperty(PARAM_BINDING);
112: InvocationContext ic = InvocationContextFactory
113: .createInvocationContext(binding);
114: ic.setRequestMessageContext(requestMsgCtx);
115:
116: //TODO:Once we the JAX-WS MessageContext one of the next things that
117: //needs to be done here is setting up all of the javax.xml.ws.*
118: //properties for the MessageContext.
119:
120: ic = endpointCtlr.invoke(ic);
121: MessageContext responseMsgCtx = ic
122: .getResponseMessageContext();
123:
124: //If there is a fault it could be Robust In-Only
125: if (!isMepInOnly(mep) || hasFault(responseMsgCtx)) {
126: // If this is a two-way exchange, there should already be a
127: // JAX-WS MessageContext for the response. We need to pull
128: // the Message data out of there and set it on the Axis2
129: // MessageContext.
130: org.apache.axis2.context.MessageContext axisResponseMsgCtx = responseMsgCtx
131: .getAxisMessageContext();
132:
133: MessageUtils.putMessageOnMessageContext(responseMsgCtx
134: .getMessage(), axisResponseMsgCtx);
135:
136: OperationContext opCtx = axisResponseMsgCtx
137: .getOperationContext();
138: opCtx.addMessageContext(axisResponseMsgCtx);
139:
140: // If this is a fault message, we want to throw it as an
141: // exception so that the transport can do the appropriate things
142: if (responseMsgCtx.getMessage().isFault()) {
143:
144: //Rather than create a new AxisFault, we should use the AxisFault that was
145: //created at the causedBy
146: if (responseMsgCtx.getCausedByException() != null)
147: faultToReturn = responseMsgCtx
148: .getCausedByException();
149: else {
150: faultToReturn = new AxisFault(
151: "An error was detected during JAXWS processing",
152: axisResponseMsgCtx);
153: }
154: } else {
155: //This assumes that we are on the ultimate execution thread
156: ThreadContextMigratorUtil
157: .performMigrationToContext(
158: Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
159: axisResponseMsgCtx);
160:
161: //Create the AxisEngine for the reponse and send it.
162: AxisEngine engine = new AxisEngine(
163: axisResponseMsgCtx
164: .getConfigurationContext());
165: engine.send(axisResponseMsgCtx);
166: //This assumes that we are on the ultimate execution thread
167: ThreadContextMigratorUtil.performContextCleanup(
168: Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
169: axisResponseMsgCtx);
170: }
171: }
172:
173: } catch (Exception e) {
174: ThreadContextMigratorUtil.performThreadCleanup(
175: Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
176: axisRequestMsgCtx);
177:
178: // Make a webservice exception (which will strip out a unnecessary stuff)
179: WebServiceException wse = ExceptionFactory
180: .makeWebServiceException(e);
181:
182: // The AxisEngine expects an AxisFault
183: throw AxisFault.makeFault(wse);
184:
185: }
186:
187: //This assumes that we are on the ultimate execution thread
188: ThreadContextMigratorUtil.performThreadCleanup(
189: Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
190: axisRequestMsgCtx);
191:
192: if (faultToReturn != null) {
193: throw faultToReturn;
194: }
195: }
196:
197: private boolean hasFault(MessageContext responseMsgCtx) {
198: if (responseMsgCtx == null
199: || responseMsgCtx.getMessage() == null) {
200: return false;
201: }
202: return responseMsgCtx.getMessage().isFault();
203: }
204:
205: private boolean isMepInOnly(String mep) {
206: boolean inOnly = mep
207: .equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY)
208: || mep.equals(WSDL20_2004_Constants.MEP_URI_IN_ONLY)
209: || mep.equals(WSDL2Constants.MEP_URI_IN_ONLY)
210: || mep.equals(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY)
211: || mep
212: .equals(WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY)
213: || mep.equals(WSDL20_2006Constants.MEP_URI_IN_ONLY);
214: return inOnly;
215: }
216:
217: }
|