/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.modelgenerator.wsdl; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.wst.wsdl.validation.internal.IValidationMessage; import org.eclipse.wst.wsdl.validation.internal.IValidationReport; import org.eclipse.wst.wsdl.validation.internal.WSDLValidator; import org.eclipse.wst.wsdl.validation.internal.eclipse.URIResolverWrapper; import org.teiid.designer.core.util.URLHelper; import org.teiid.designer.modelgenerator.wsdl.model.Model; import org.teiid.designer.modelgenerator.wsdl.model.ModelGenerationException; import org.teiid.designer.modelgenerator.wsdl.model.impl.ModelBuilder; import org.teiid.designer.modelgenerator.wsdl.validation.WSDLValidationException; import org.teiid.designer.modelgenerator.wsdl.validation.WSDLValidationMessage; import org.teiid.designer.ui.common.ICredentialsCommon.SecurityType; /** * This class is responsible for reading WSDL files from a URI or filesystem validating them and producing an OO representation of * the WSDL contents * * @since 8.0 */ public class WSDLReader { private String wsdlURI; private SecurityType securityType = SecurityType.None; private String userName; private String password; private static WSDLValidator VALIDATOR; public static final int VALIDATION_SEVERITY_ERROR = 0; public static final int VALIDATION_SEVERITY_WARNING = 1; public WSDLReader() { this(null); } /** * @param fileUri the URI of the WSDL file */ public WSDLReader( String fileUri ) { wsdlURI = fileUri; } /** * @return the Model based on the given WSDL * @throws ModelGenerationException */ public Model getModel() throws ModelGenerationException { Model theModel = null; try { theModel = buildWSDLStructures(); } catch (NullPointerException ex) { ModelGeneratorWsdlPlugin.Util.log(IStatus.ERROR, ex, getString("WSDLReader.unexpected.parsing.wsdl")); //$NON-NLS-1$ Exception e = new Exception(getString("WSDLReader.unexpected.parsing.wsdl")); //$NON-NLS-1$ throw new ModelGenerationException(e); } catch (Exception ex) { throw new ModelGenerationException(ex); } return theModel; } private Model buildWSDLStructures() throws Exception { if(wsdlURI == null) { throw new Exception(getString("WSDLReader.unexpected.parsing.wsdl")); //$NON-NLS-1$ } ModelBuilder builder = new ModelBuilder(); builder.setAuthentication(securityType, userName, password); builder.setWSDL(wsdlURI.replace("%20", " ")); //$NON-NLS-1$//$NON-NLS-2$ if (!builder.isWSDLParsed()) { Exception myEx = builder.getWSDLException(); throw myEx; } return builder.getModel(); } /** * @return the URI of the given WSDL */ public String getWSDLUri() { return wsdlURI; } /** * Set the optional authentication credentials * * @param securityType * @param userName * @param password */ public void setAuthenticationCredentials(SecurityType securityType, String userName, String password) { this.securityType = securityType; this.userName = userName; this.password = password; } /** * @param fileUri the URI of the WSDL file */ public void setWSDLUri( String fileUri ) { wsdlURI = fileUri; } /** * @return true if the wsdl is valid, false otherwise */ public MultiStatus validateWSDL(IProgressMonitor monitor) { if (SecurityType.Digest.equals(securityType)){ return validateWSDLWithDigest(monitor); } monitor.beginTask( getString("WSDLReader.validating.wsdl"), //$NON-NLS-1$ IProgressMonitor.UNKNOWN); monitor.worked(1); if (VALIDATOR == null) { VALIDATOR = new WSDLValidator(); VALIDATOR.addURIResolver(new URIResolverWrapper()); } String wsdlUri = getWSDLUri(); MultiStatus status; List<WSDLValidationMessage> messages = new ArrayList<WSDLValidationMessage>(); URL remoteURL; URLConnection urlConn = null; InputStream inputStream = null; int code; try { remoteURL = URLHelper.buildURL(wsdlUri); monitor.worked(1); remoteURL = new URL(wsdlUri); urlConn = remoteURL.openConnection(); if (securityType != null && ! SecurityType.None.equals(securityType)) { URLHelper.setCredentials(urlConn, userName, password); } inputStream = urlConn.getInputStream(); IValidationReport report = VALIDATOR.validate(wsdlUri, inputStream, null); monitor.worked(1); boolean success = !report.hasErrors() && report.isWSDLValid(); if (success) { code = 100; monitor.worked(1); monitor.done(); status = buildStatus(code, null, getString("WSDLReader.validation.passed"), null); //$NON-NLS-1$ return status; } // Something went wrong boolean warningsOnly = report.isWSDLValid(); code = 500; // Log all of the report's validation messages IValidationMessage[] vmessages = report.getValidationMessages(); for (int i = 0; i < vmessages.length; i++) { String message = buildValidationMessageString(vmessages[i]); int severity = vmessages[i].getSeverity(); if (severity == IValidationMessage.SEV_ERROR) { warningsOnly = false; } int newSeverity = (severity == IValidationMessage.SEV_ERROR ? IStatus.ERROR : IStatus.WARNING); messages.add(new WSDLValidationMessage(message, newSeverity)); } if (warningsOnly) { monitor.worked(1); monitor.done(); status = buildStatus(code, messages, getString("WSDLReader.validation.warning"), null); //$NON-NLS-1$ return status; } // Errors occurred String contentType = urlConn.getContentType(); if (messages.size() == 0) { // WSDL so invalid that the validator could not even read the file String invalidMsgProperty = "WSDLReader.wsdl.invalid"; //$NON-NLS-1$ if ((null != contentType) && (!contentType.contains("text/xml") || !contentType.contains("application/xml"))) { //$NON-NLS-1$ //$NON-NLS-2$ String messageSuffix = MessageFormat .format(getString("WSDLReader.validation.content.type.error"), //$NON-NLS-1$ wsdlUri, contentType); String fullMessage = getString(invalidMsgProperty) + messageSuffix; messages.add(new WSDLValidationMessage(fullMessage, IStatus.ERROR)); status = buildStatus(code, messages, fullMessage, new WSDLValidationException()); } else { messages.add(new WSDLValidationMessage(getString(invalidMsgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(invalidMsgProperty), new WSDLValidationException()); } } else { // Validation report returned errors String validationErrorProperty = "WSDLReader.validation.error"; //$NON-NLS-1$ if (!remoteURL.getProtocol().equals("file") && !contentType.contains("text/xml") //$NON-NLS-1$//$NON-NLS-2$ || !contentType.equals("application/xml")) { //$NON-NLS-1$ String messageSuffix = MessageFormat .format(getString("WSDLReader.validation.content.type.error"), //$NON-NLS-1$ wsdlUri, contentType); status = buildStatus(code, messages, getString(validationErrorProperty) + messageSuffix, new WSDLValidationException()); } else { status = buildStatus(code, messages, getString(validationErrorProperty), new WSDLValidationException()); } } } catch (Exception e) { code = 500; String msgProperty = "WSDLReader.open.connection.error"; //$NON-NLS-1$ messages.add(new WSDLValidationMessage(getString(msgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(msgProperty), e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException ex) { code = 500; String msgProperty = "WSDLReader.close.connection.error"; //$NON-NLS-1$ messages.add(new WSDLValidationMessage(getString(msgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(msgProperty), ex); } } } monitor.worked(1); monitor.done(); return status; } /** * @return true if the wsdl is valid, false otherwise */ public MultiStatus validateWSDLWithDigest(IProgressMonitor monitor) { monitor.beginTask( getString("WSDLReader.validating.wsdl"), //$NON-NLS-1$ IProgressMonitor.UNKNOWN); monitor.worked(1); if (VALIDATOR == null) { VALIDATOR = new WSDLValidator(); VALIDATOR.addURIResolver(new URIResolverWrapper()); } String wsdlUri = getWSDLUri(); MultiStatus status; List<WSDLValidationMessage> messages = new ArrayList<WSDLValidationMessage>(); URL remoteURL; InputStream inputStream = null; int code; try { remoteURL = URLHelper.buildURL(wsdlUri); monitor.worked(1); remoteURL = new URL(wsdlUri); inputStream = URLHelper.getWSDLWithDigest(remoteURL, userName, password); IValidationReport report = VALIDATOR.validate(wsdlUri, inputStream, null); monitor.worked(1); boolean success = !report.hasErrors() && report.isWSDLValid(); if (success) { code = 100; monitor.worked(1); monitor.done(); status = buildStatus(code, null, getString("WSDLReader.validation.passed"), null); //$NON-NLS-1$ return status; } // Something went wrong boolean warningsOnly = report.isWSDLValid(); code = 500; // Log all of the report's validation messages IValidationMessage[] vmessages = report.getValidationMessages(); for (int i = 0; i < vmessages.length; i++) { String message = buildValidationMessageString(vmessages[i]); int severity = vmessages[i].getSeverity(); if (severity == IValidationMessage.SEV_ERROR) { warningsOnly = false; } int newSeverity = (severity == IValidationMessage.SEV_ERROR ? IStatus.ERROR : IStatus.WARNING); messages.add(new WSDLValidationMessage(message, newSeverity)); } if (warningsOnly) { monitor.worked(1); monitor.done(); status = buildStatus(code, messages, getString("WSDLReader.validation.warning"), null); //$NON-NLS-1$ return status; } // Errors occurred if (messages.size() == 0) { // WSDL so invalid that the validator could not even read the file String invalidMsgProperty = "WSDLReader.wsdl.invalid"; //$NON-NLS-1$ messages.add(new WSDLValidationMessage(getString(invalidMsgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(invalidMsgProperty), new WSDLValidationException()); } else { // Validation report returned errors String validationErrorProperty = "WSDLReader.validation.error"; //$NON-NLS-1$ status = buildStatus(code, messages, getString(validationErrorProperty), new WSDLValidationException()); } } catch (Exception e) { code = 500; String msgProperty = "WSDLReader.open.connection.error"; //$NON-NLS-1$ messages.add(new WSDLValidationMessage(getString(msgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(msgProperty), e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException ex) { code = 500; String msgProperty = "WSDLReader.close.connection.error"; //$NON-NLS-1$ messages.add(new WSDLValidationMessage(getString(msgProperty), IStatus.ERROR)); status = buildStatus(code, messages, getString(msgProperty), ex); } } } monitor.worked(1); monitor.done(); return status; } private MultiStatus buildStatus(int code, List<? extends IStatus> childMessages, String message, Exception exception) { return new MultiStatus( ModelGeneratorWsdlPlugin.PLUGIN_ID, code, childMessages == null ? new IStatus[0] : childMessages.toArray(new IStatus[0]), message, exception); } private String getString(String property) { return ModelGeneratorWsdlPlugin.Util.getString(property); } private String buildValidationMessageString(IValidationMessage vmessage) { StringBuffer buff = new StringBuffer(); buff.append(vmessage.getLine()); buff.append(":"); //$NON-NLS-1$ buff.append(vmessage.getColumn()); buff.append(" - "); //$NON-NLS-1$ buff.append(vmessage.getMessage()); return buff.toString(); } }