| /******************************************************************************* |
| * Copyright (c) 2004, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * yyyymmdd bug Email and other contact information |
| * -------- -------- ----------------------------------------------------------- |
| * 20070305 117034 makandre@ca.ibm.com - Andrew Mak, Web Services Explorer should support SOAP Headers |
| * 20070413 176493 makandre@ca.ibm.com - Andrew Mak, WSE: Make message/transport stack pluggable |
| * 20070510 186375 makandre@ca.ibm.com - Andrew Mak, Compile errors in wst.ws.explorer |
| *******************************************************************************/ |
| package org.eclipse.wst.ws.internal.explorer.platform.wsdl.actions; |
| |
| import java.io.IOException; |
| import java.util.Hashtable; |
| |
| import javax.servlet.http.HttpServletResponse; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.eclipse.wst.ws.internal.explorer.platform.perspective.Controller; |
| import org.eclipse.wst.ws.internal.explorer.platform.perspective.MessageQueue; |
| import org.eclipse.wst.ws.internal.explorer.platform.util.MultipartFormDataException; |
| import org.eclipse.wst.ws.internal.explorer.platform.util.MultipartFormDataParser; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.constants.WSDLActionInputs; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.constants.WSDLModelConstants; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.datamodel.Endpoint; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.datamodel.WSDLBindingElement; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.datamodel.WSDLOperationElement; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.perspective.InvokeWSDLOperationTool; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.perspective.WSDLPerspective; |
| import org.eclipse.wst.ws.internal.explorer.platform.wsdl.util.SOAPMessageUtils; |
| import org.eclipse.wst.ws.internal.explorer.transport.HTTPTransportException; |
| import org.eclipse.wst.ws.internal.explorer.transport.ISOAPMessage; |
| import org.eclipse.wst.ws.internal.explorer.transport.ISOAPTransportProvider; |
| import org.eclipse.wst.ws.internal.explorer.transport.TransportException; |
| |
| public abstract class InvokeWSDLSOAPOperationAction extends WSDLPropertiesFormAction |
| { |
| public InvokeWSDLSOAPOperationAction(Controller controller) |
| { |
| super(controller); |
| } |
| |
| protected boolean processParsedResults(MultipartFormDataParser parser) throws MultipartFormDataException |
| { |
| super.processParsedResults(parser); |
| String endPoint = parser.getParameter(WSDLActionInputs.END_POINT); |
| InvokeWSDLOperationTool invokeWSDLOperationTool = (InvokeWSDLOperationTool)(getSelectedNavigatorNode().getCurrentToolManager().getSelectedTool()); |
| invokeWSDLOperationTool.setEndPoint(endPoint); |
| return true; |
| } |
| |
| /** |
| * Returns an ISOAPMessage to use for the current SOAP operation invocation. |
| * |
| * @param operElement The operation element from the WSDL model. |
| * |
| * @return An ISOAPMessage, or null if a message cannot be constructed. |
| */ |
| protected ISOAPMessage getSOAPRequestMessage(WSDLOperationElement operElement) { |
| ISOAPTransportProvider provider = operElement.getSOAPTransportProvider(); |
| if (provider == null) |
| return null; |
| return provider.newTransport().newMessage(operElement.getMessageContext()); |
| } |
| |
| /** |
| * Populate the given ISOAPMessage's header using the inputs from WSE |
| * |
| * @param soapEnvelopeNamespaceTable Hashtable containing a map of the namespace URIs to prefixes. |
| * @param operElement WSDLOperationElement encapsulating the WSDL operation. |
| * @param soapMessage The ISOAPMessage to populate |
| */ |
| protected void setHeaderContent(Hashtable soapEnvelopeNamespaceTable, WSDLOperationElement operElement, ISOAPMessage soapMessage) |
| throws ParserConfigurationException { |
| SOAPMessageUtils.setHeaderContentFromModel(soapEnvelopeNamespaceTable, operElement, soapMessage); |
| } |
| |
| /** |
| * Populate the given ISOAPMessage's body using the inputs from WSE |
| * |
| * @param soapEnvelopeNamespaceTable Hashtable containing a map of the namespace URIs to prefixes. |
| * @param operElement WSDLOperationElement encapsulating the WSDL operation. |
| * @param soapMessage The ISOAPMessage to populate |
| */ |
| protected void setBodyContent(Hashtable soapEnvelopeNamespaceTable, WSDLOperationElement operElement, ISOAPMessage soapMessage) |
| throws ParserConfigurationException { |
| SOAPMessageUtils.setBodyContentFromModel(soapEnvelopeNamespaceTable, operElement, soapMessage); |
| } |
| |
| public boolean run() |
| { |
| String soapAddressLocation = (String)propertyTable_.get(WSDLActionInputs.END_POINT); |
| WSDLPerspective wsdlPerspective = controller_.getWSDLPerspective(); |
| MessageQueue messageQueue = wsdlPerspective.getMessageQueue(); |
| WSDLOperationElement operElement = (WSDLOperationElement)getSelectedNavigatorNode().getTreeElement(); |
| WSDLBindingElement bindingElement = (WSDLBindingElement)operElement.getParentElement(); |
| operElement.setPropertyAsObject(WSDLActionInputs.SOAP_RESPONSE_CACHED, new Boolean(false)); |
| try |
| { |
| // Generate the SOAP envelope and its children. We need to create a DOM element version to display and the object version to execute. |
| // <SOAP-ENV:Envelope |
| // xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" |
| // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| // xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
| // ... |
| |
| ISOAPMessage soapMessage = getSOAPRequestMessage(operElement); |
| if (soapMessage == null) |
| throw new TransportException(wsdlPerspective.getMessage("MSG_ERROR_NO_SUITABLE_TRANSPORT")); |
| |
| Hashtable namespaceTable = new Hashtable(soapMessage.getNamespaceTable()); |
| setHeaderContent(namespaceTable, operElement, soapMessage); |
| setBodyContent(namespaceTable, operElement, soapMessage); |
| soapMessage.setNamespaceTable(namespaceTable); |
| |
| // store the request |
| operElement.setPropertyAsObject(WSDLModelConstants.PROP_SOAP_REQUEST, soapMessage); |
| |
| // Execute the SOAP operation. |
| if (soapAddressLocation != null) |
| { |
| soapMessage.setProperty(ISOAPMessage.PROP_SOAP_ACTION, operElement.getSoapAction()); |
| String[] authParams = retrieveAuthParams(bindingElement, soapAddressLocation); |
| |
| // invoke! |
| ISOAPMessage soapResponse = operElement.getSOAPTransportProvider().newTransport() |
| .send(soapAddressLocation, authParams[0], authParams[1], soapMessage); |
| |
| // store the response |
| operElement.setPropertyAsObject(WSDLModelConstants.PROP_SOAP_RESPONSE, soapResponse); |
| |
| wsdlPerspective.setOperationNode(getSelectedNavigatorNode()); |
| return true; |
| } |
| throw new IOException(wsdlPerspective.getMessage("MSG_ERROR_UNABLE_TO_CONNECT",soapAddressLocation)); |
| } |
| catch (HTTPTransportException e) { |
| throwHTTPTransportException(bindingElement, soapAddressLocation, e); |
| } |
| catch (Exception e) { |
| Throwable t = e; |
| if (e instanceof TransportException && e.getCause() != null) |
| t = e.getCause(); |
| handleUnexpectedException(wsdlPerspective, messageQueue, t.getClass().getName(), t); |
| } |
| return false; |
| } |
| |
| private void throwHTTPTransportException(WSDLBindingElement bindingElement, String endpointString, HTTPTransportException httpTransportException) throws HTTPTransportException |
| { |
| if (httpTransportException.getStatusCode() == HttpServletResponse.SC_UNAUTHORIZED) |
| { |
| Endpoint endpoint = bindingElement.getEndpoint(endpointString); |
| if (endpoint != null) |
| { |
| endpoint.setRequireHTTPBasicAuth(true); |
| endpoint.setHttpBasicAuthUsername(null); |
| endpoint.setHttpBasicAuthPassword(null); |
| } |
| } |
| throw httpTransportException; |
| } |
| |
| private String[] retrieveAuthParams(WSDLBindingElement bindingElement, String endpointString) |
| { |
| String[] authParams = new String[] { null, null }; |
| Endpoint endpoint = bindingElement.getEndpoint(endpointString); |
| if (endpoint != null) |
| { |
| if (endpoint.isRequireHTTPBasicAuth()) |
| { |
| String httpBasicAuthUsername = endpoint.getHttpBasicAuthUsername(); |
| String httpBasicAuthPassword = endpoint.getHttpBasicAuthPassword(); |
| if (httpBasicAuthUsername == null || httpBasicAuthPassword == null) |
| { |
| httpBasicAuthUsername = (String)propertyTable_.get(WSDLActionInputs.HTTP_BASIC_AUTH_USERNAME); |
| httpBasicAuthPassword = (String)propertyTable_.get(WSDLActionInputs.HTTP_BASIC_AUTH_PASSWORD); |
| endpoint.setHttpBasicAuthUsername(httpBasicAuthUsername); |
| endpoint.setHttpBasicAuthPassword(httpBasicAuthPassword); |
| } |
| if (httpBasicAuthUsername != null && httpBasicAuthPassword != null) |
| { |
| authParams[0] = httpBasicAuthUsername; |
| authParams[1] = httpBasicAuthPassword; |
| } |
| } |
| } |
| return authParams; |
| } |
| } |