| /******************************************************************************* |
| * 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 |
| *******************************************************************************/ |
| package org.eclipse.wst.ws.internal.wsil; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.OutputStream; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import javax.wsdl.Definition; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import org.apache.wsil.Abstract; |
| import org.apache.wsil.Description; |
| import org.apache.wsil.Inspection; |
| import org.apache.wsil.QName; |
| import org.apache.wsil.Service; |
| import org.apache.wsil.WSILDocument; |
| import org.apache.wsil.WSILException; |
| import org.apache.wsil.extension.ExtensionBuilder; |
| import org.apache.wsil.extension.wsdl.ImplementedBinding; |
| import org.apache.wsil.extension.wsdl.Reference; |
| import org.apache.wsil.extension.wsdl.ReferencedService; |
| import org.apache.wsil.extension.wsdl.WSDLConstants; |
| import org.apache.wsil.xml.XMLWriter; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.wst.command.internal.env.core.common.StatusUtils; |
| import org.eclipse.wst.common.environment.IEnvironment; |
| import org.eclipse.wst.common.environment.uri.IURIFactory; |
| import org.eclipse.wst.common.environment.uri.URIException; |
| import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation; |
| import org.eclipse.wst.ws.internal.parser.wsil.IllegalArgumentsException; |
| import org.eclipse.wst.ws.internal.parser.wsil.WSILMessages; |
| import org.eclipse.wst.ws.internal.parser.wsil.WWWAuthenticationException; |
| import org.eclipse.wst.ws.internal.parser.wsil.WWWAuthenticationHandler; |
| import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser; |
| import org.w3c.dom.Element; |
| import org.xml.sax.SAXException; |
| |
| public class AddWSDLToWSILCommand extends AbstractDataModelOperation |
| { |
| public static final String ARG_WSIL = "-wsil"; |
| public static final String ARG_WSDL = "-wsdl"; |
| public static final String ARG_RESOLVE_WSDL = "-resolvewsdl"; |
| public static final String ARG_HTTP_BASIC_AUTH_USERNAME = "-httpusername"; |
| public static final String ARG_HTTP_BASIC_AUTH_PASSWORD = "-httppassword"; |
| private WWWAuthenticationHandler wwwAuthHandler_; |
| private String[] args_; |
| private String wsil_; |
| private ArrayList wsdls_; |
| private boolean resolveWSDL_; |
| private String httpUsername_; |
| private String httpPassword_; |
| |
| public AddWSDLToWSILCommand() |
| { |
| wwwAuthHandler_ = null; |
| args_ = new String[0]; |
| clearParsedArgs(); |
| } |
| |
| private void clearParsedArgs() |
| { |
| wsil_ = null; |
| if (wsdls_ == null) |
| wsdls_ = new ArrayList(); |
| else |
| wsdls_.clear(); |
| resolveWSDL_ = false; |
| httpUsername_ = null; |
| httpPassword_ = null; |
| } |
| |
| /** |
| * Executes the Command. |
| * |
| * @param environment |
| * The environment. Must not be null. |
| * @return A <code>Status</code> object indicating the degree to which the |
| * <code>execute</code> method was successful. A valud of <code>null</code>, |
| * or a Status with a severity of less than <code>Status.ERROR</code> |
| * signifies success. |
| */ |
| public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable ) |
| { |
| IEnvironment environment = getEnvironment(); |
| |
| IURIFactory uriFactory = environment.getURIFactory(); |
| // Parse arguments |
| try |
| { |
| parseArguments(); |
| } |
| catch (IllegalArgumentsException iae) |
| { |
| return StatusUtils.errorStatus( WSILMessages.MSG_ERROR_ILLEGAL_ARGUMENTS, iae); |
| } |
| catch (ArrayIndexOutOfBoundsException e) |
| { |
| return StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_ARGUMENTS, e); |
| } |
| // Create new WSIL document |
| WSILDocument wsilDocument = null; |
| URL wsilURL = null; |
| try |
| { |
| wsilDocument = WSILDocument.newInstance(); |
| wsilURL = new URL(wsil_); |
| } |
| catch (MalformedURLException murle) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_WSIL_URI, murle); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (WSILException wsile) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| // Read WSIL |
| try |
| { |
| InputStream is = uriFactory.newURI(wsilURL).getInputStream(); |
| if (is != null) |
| { |
| wsilDocument.read(new InputStreamReader(is)); |
| is.close(); |
| } |
| } |
| catch (URIException urie) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, urie); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (IOException ioe) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, ioe); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (WSILException wsile) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| // internalExecute |
| String httpUsername = null; |
| String httpPassword = null; |
| if (wsdls_.size() == 1 && httpUsername_ != null && httpPassword_ != null) |
| { |
| httpUsername = httpUsername_; |
| httpPassword = httpPassword_; |
| } |
| for (Iterator it = wsdls_.iterator(); it.hasNext();) |
| { |
| String wsdl = (String) it.next(); |
| IStatus status = null; |
| try |
| { |
| status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, httpUsername, httpPassword); |
| } |
| catch (WWWAuthenticationException wwwae) |
| { |
| if (wwwAuthHandler_ != null && httpUsername == null && httpPassword == null) |
| { |
| wwwAuthHandler_.handleWWWAuthentication(wwwae); |
| String handlerUsername = wwwAuthHandler_.getUsername(); |
| String handlerPassword = wwwAuthHandler_.getPassword(); |
| if (handlerUsername != null && handlerPassword != null) |
| { |
| try |
| { |
| status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, handlerUsername, handlerPassword); |
| } |
| catch (WWWAuthenticationException wwwae2) |
| { |
| IStatus wwwaeStatus = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, wwwae2.getIOException()); |
| environment.getStatusHandler().reportError(wwwaeStatus); |
| return wwwaeStatus; |
| } |
| } |
| } |
| if (status == null) |
| { |
| IStatus s = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, wwwae.getIOException()); |
| environment.getStatusHandler().reportError(s); |
| return s; |
| } |
| } |
| if (status.getSeverity() != Status.OK) |
| return status; |
| } |
| // Write WSIL |
| try |
| { |
| XMLWriter xmlWriter = new XMLWriter(); |
| OutputStream os = uriFactory.newURI(wsilURL).getOutputStream(); |
| if (os != null) |
| xmlWriter.writeDocument(wsilDocument, os); |
| else |
| throw new IOException(); |
| os.close(); |
| } |
| catch (URIException urie) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, urie); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (IOException ioe) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, ioe); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (WSILException wsile) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, wsile); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| return Status.OK_STATUS; |
| } |
| |
| private IStatus internalExecute(IEnvironment environment, WSILDocument wsilDocument, String wsil, String wsdl, String httpUsername, String httpPassword) throws WWWAuthenticationException |
| { |
| Definition definition = null; |
| ArrayList wsdlService = new ArrayList(); |
| ArrayList wsdlBinding = new ArrayList(); |
| if (resolveWSDL_) |
| { |
| // Parse WSDL |
| try |
| { |
| definition = parseWSDL(wsdl, wsdlService, wsdlBinding, httpUsername, httpPassword); |
| } |
| catch (MalformedURLException murle) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_WSDL_URI, murle); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (IOException ioe) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, ioe); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (ParserConfigurationException pce) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, pce); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (SAXException saxe) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_MALFORMED_WSDL, saxe); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| } |
| // Add WSDL to WSIL |
| try |
| { |
| Inspection inspection = wsilDocument.getInspection(); |
| Service service = wsilDocument.createService(); |
| if (definition != null) |
| { |
| Element documentation = definition.getDocumentationElement(); |
| Abstract serviceAbstract = wsilDocument.createAbstract(); |
| serviceAbstract.setText(Element2String(documentation)); |
| service.addAbstract(serviceAbstract); |
| } |
| Description desc = wsilDocument.createDescription(); |
| desc.setReferencedNamespace(WSDLConstants.NS_URI_WSDL); |
| desc.setLocation(getRelativeURI(wsil, wsdl)); |
| ExtensionBuilder extBuilder = wsilDocument.getExtensionRegistry().getBuilder(WSDLConstants.NS_URI_WSIL_WSDL); |
| if (definition == null || endpointPresent(definition)) |
| { |
| for (Iterator it = wsdlService.iterator(); it.hasNext();) |
| { |
| Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE)); |
| reference.setEndpointPresent(new Boolean(true)); |
| ReferencedService refService = (ReferencedService) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REF_SERVICE)); |
| refService.setReferencedServiceName((QName) it.next()); |
| reference.setReferencedService(refService); |
| desc.setExtensionElement(reference); |
| } |
| } |
| else |
| { |
| Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE)); |
| reference.setEndpointPresent(new Boolean(false)); |
| for (Iterator it = wsdlBinding.iterator(); it.hasNext();) |
| { |
| ImplementedBinding binding = (ImplementedBinding) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_IMPL_BINDING)); |
| binding.setBindingName((QName) it.next()); |
| reference.addImplementedBinding(binding); |
| } |
| } |
| service.addDescription(desc); |
| inspection.addService(service); |
| } |
| catch (WSILException wsile) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| catch (Exception t) |
| { |
| IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, t); |
| environment.getStatusHandler().reportError(status); |
| return status; |
| } |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Returns <code>true</code> if, and only if, the Command's <code>undo</code> |
| * method is supported. |
| * |
| * @return True if the Command supports being undone. |
| */ |
| public boolean isUndoable() |
| { |
| return false; |
| } |
| |
| /** |
| * Undoes the Command. |
| * |
| * @param environment |
| * The environment. Must not be null. |
| * @return A <code>Status</code> object indicating the degree to which the |
| * <code>undo</code> method was successful. A valud of <code>null</code>, |
| * or a Status with a severity of less than <code>Status.ERROR</code> |
| * signifies success. |
| */ |
| public IStatus undo(IEnvironment environment) |
| { |
| return Status.OK_STATUS; |
| } |
| |
| private Definition parseWSDL(String wsdl, ArrayList wsdlService, ArrayList wsdlBinding, String httpUsername, String httpPassword) throws MalformedURLException, IOException, ParserConfigurationException, SAXException, WWWAuthenticationException |
| { |
| WebServicesParser wsParser = new WebServicesParser(wsdl); |
| if (httpUsername != null && httpPassword != null) |
| { |
| wsParser.setHTTPBasicAuthUsername(httpUsername); |
| wsParser.setHTTPBasicAuthPassword(httpPassword); |
| } |
| wsParser.parse(WebServicesParser.PARSE_NONE); |
| Definition definition = wsParser.getWSDLDefinition(wsdl); |
| if (definition != null) |
| { |
| Map services = definition.getServices(); |
| for (Iterator it = services.keySet().iterator(); it.hasNext();) |
| wsdlService.add(parseQName((javax.xml.namespace.QName) it.next())); |
| Map bindings = definition.getBindings(); |
| for (Iterator it = bindings.keySet().iterator(); it.hasNext();) |
| wsdlBinding.add(parseQName((javax.xml.namespace.QName) it.next())); |
| } |
| return definition; |
| } |
| |
| private boolean endpointPresent(Definition definition) |
| { |
| return (definition.getServices().size() > 0); |
| } |
| |
| public String[] getArguments() |
| { |
| return args_; |
| } |
| |
| public void setArguments(String[] args) |
| { |
| args_ = args; |
| } |
| |
| public WWWAuthenticationHandler getWWWAuthenticationHandler() |
| { |
| return wwwAuthHandler_; |
| } |
| |
| public void setWWWAuthenticationHandler(WWWAuthenticationHandler wwwAuthHandler) |
| { |
| wwwAuthHandler_ = wwwAuthHandler; |
| } |
| |
| private void parseArguments() throws IllegalArgumentsException |
| { |
| clearParsedArgs(); |
| for (int i = 0; i < args_.length; i++) |
| { |
| if (ARG_WSIL.equals(args_[i])) |
| wsil_ = args_[++i]; |
| else if (ARG_WSDL.equals(args_[i])) |
| wsdls_.add(args_[++i]); |
| else if (ARG_RESOLVE_WSDL.equals(args_[i])) |
| resolveWSDL_ = true; |
| else if (ARG_HTTP_BASIC_AUTH_USERNAME.equals(args_[i])) |
| httpUsername_ = args_[++i]; |
| else if (ARG_HTTP_BASIC_AUTH_PASSWORD.equals(args_[i])) |
| httpPassword_ = args_[++i]; |
| else |
| throw new IllegalArgumentsException(args_[i]); |
| } |
| } |
| |
| private QName parseQName(javax.xml.namespace.QName qname) |
| { |
| return new QName(qname.getNamespaceURI(), qname.getLocalPart()); |
| } |
| |
| private String Element2String(Element e) throws TransformerConfigurationException, TransformerException, IOException |
| { |
| byte[] b = new byte[0]; |
| if (e != null) |
| { |
| DOMSource domSource = new DOMSource(e); |
| Transformer serializer = TransformerFactory.newInstance().newTransformer(); |
| serializer.setOutputProperty(OutputKeys.INDENT, "yes"); |
| serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| serializer.transform(domSource, new StreamResult(baos)); |
| baos.close(); |
| b = baos.toByteArray(); |
| } |
| return new String(b); |
| } |
| |
| private String platform2File(IURIFactory uriFactory, String uri) |
| { |
| try |
| { |
| return uriFactory.newURI(uri).asFile().toURL().toString(); |
| } |
| catch (Exception t) |
| { |
| t.printStackTrace(); |
| } |
| return uri; |
| } |
| |
| private final char FWD_SLASH = '/'; |
| private final char BWD_SLASH = '\\'; |
| private final String parentDir = "../"; |
| |
| private String getRelativeURI(String baseURI, String targetURI) |
| { |
| try |
| { |
| String baseURICopy = baseURI.replace(BWD_SLASH, FWD_SLASH); |
| String targetURICopy = targetURI.replace(BWD_SLASH, FWD_SLASH); |
| int matchingIndex = -1; |
| int index = targetURICopy.indexOf(FWD_SLASH); |
| while (index != -1) |
| { |
| if (baseURICopy.startsWith(targetURICopy.substring(0, index + 1))) |
| { |
| matchingIndex = index; |
| index = targetURICopy.indexOf(FWD_SLASH, index + 1); |
| } |
| else |
| break; |
| } |
| if (matchingIndex != -1) |
| { |
| int slashCount = -1; |
| int fromIndex = matchingIndex; |
| while (fromIndex != -1) |
| { |
| slashCount++; |
| fromIndex = baseURICopy.indexOf(FWD_SLASH, fromIndex + 1); |
| } |
| StringBuffer relativeURI = new StringBuffer(); |
| for (int i = 0; i < slashCount; i++) |
| relativeURI.append(parentDir); |
| relativeURI.append(targetURI.substring(matchingIndex + 1, targetURI.length())); |
| return relativeURI.toString(); |
| } |
| } |
| catch (Exception t) |
| { |
| } |
| return targetURI; |
| } |
| } |