blob: 69131a711aec5b5942cdc971a1e9d4dd783b46eb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2020 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* David Carver (STAR) - bug 297005 - Some static constants not made final.
*******************************************************************************/
package org.eclipse.wst.xml.core.internal.validation.core;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xml.core.internal.preferences.XMLCorePreferenceNames;
import org.eclipse.wst.xml.core.internal.validation.XMLValidationMessages;
/**
* This class handles messages from a validator. This class can handle
*
* @author Lawrence Mandel, IBM
*/
public class ValidationInfo implements ValidationReport
{
private boolean WRAPPER_ERROR_SUPPORT_ENABLED = true;
public static final int SEV_ERROR = 0;
public static final int SEV_WARNING = 1;
public static final int SEV_INFO = 2;
private String validating_file_uri = null;
private URL validating_file_url = null;
private boolean valid = true;
private List messages = new ArrayList();
private HashMap nestedMessages = new HashMap();
private IScopeContext[] sameFilePreferenceContext = null;
/**
* Constructor.
*
* @param uri
* The URI of the file for the validation.
*/
public ValidationInfo(String uri)
{
if(uri != null)
{
this.validating_file_uri = uri;
try
{
this.validating_file_url = new URL(uri);
} catch (MalformedURLException e)
{
}
}
}
public String getFileURI()
{
return validating_file_uri;
}
public boolean isValid()
{
return valid;
}
/**
* Add an error message.
*
* @param message The message to add.
* @param line The line location of the message.
* @param column The column location of the message.
* @param uri The URI of the file that contains the message.
*/
public void addError(String message, int line, int column, String uri)
{
addError(message, line, column, uri, null, null);
}
/**
*
* Add an error message.
*
* @param message The message to add.
* @param line The line location of the message.
* @param column The column location of the message.
* @param uri The URI of the file that contains the message.
* @param key The key for the message.
* @param messageArguments more information about the error
*/
public void addError(String message, int line, int column, String uri, String key, Object[] messageArguments)
{
if(addMessage(message, line, column, uri, SEV_ERROR, key, messageArguments))
{
valid = false;
}
}
/**
*
* Add an informational message.
*
* @param message The message to add.
* @param line The line location of the message.
* @param column The column location of the message.
* @param uri The URI of the file that contains the message.
* @param key The key for the message.
* @param messageArguments more information about the error
*/
public void addInfo(String message, int line, int column, String uri, String key, Object[] messageArguments)
{
if(addMessage(message, line, column, uri, SEV_INFO, key, messageArguments))
{
valid = false;
}
}
/**
* Add a warning message.
*
* @param message The string message of the warning.
* @param line The line location of the warning.
* @param column The column location of the warning.
* @param uri The URI of the file that contains the warning.
*/
public void addWarning(String message, int line, int column, String uri)
{
addWarning(message, line, column, uri, null, null);
}
/**
*
* Add an error message.
*
* @param message The message to add.
* @param line The line location of the message.
* @param column The column location of the message.
* @param uri The URI of the file that contains the message.
* @param key The key for the message.
* @param messageArguments more information about the error
*/
public void addWarning(String message, int line, int column, String uri, String key, Object[] messageArguments)
{
addMessage(message, line, column, uri, SEV_WARNING, key, messageArguments);
}
/**
* Add a message to the list. Return true if successful, false otherwise.
*
* @param message The message to add to the list.
* @param line The line location of the message.
* @param column The column location of the message.
* @param uri The URI of the file that contains the message.
* @param severity The severity of the message.
* @param key the Xerces error key for this error
* @param messageArguments more information on the error
* @return True if the message was successfully added, false otherwise.
*/
private boolean addMessage(String message, int line, int column, String uri, int severity, String key, Object[] messageArguments)
{
boolean successfullyAdded = false;
// If the message if null there is nothing to add.
if(message == null)
{
return successfullyAdded;
}
String errorURI = normalize(uri);
URL errorURL = null;
if (errorURI != null)
{
try
{
errorURL = new URL(errorURI);
} catch (MalformedURLException e)
{
}
//errorURI = normalizeURI(errorURI);
}
//boolean doDialog = true;
if (errorURL != null)
{
boolean isSameFile = (validating_file_url != null && validating_file_url.sameFile(errorURL));
int validationErrorSeverity = -1;
if( !isSameFile) {
// Error is in referenced file. Pull from prefs.
int referencedFileSeverity = Platform.getPreferencesService().getInt(XMLCorePlugin.getDefault().getBundle().getSymbolicName(),
XMLCorePreferenceNames.INDICATE_REFERENCED_FILE_CONTAINS_ERRORS, 0, getPreferenceScopes());
// ignore = -1, warning = 1, error = 2
if( referencedFileSeverity == 1 ) {
validationErrorSeverity = ValidationMessage.SEV_LOW;
} else if( referencedFileSeverity == 2) {
validationErrorSeverity = ValidationMessage.SEV_NORMAL;
} // else leave as -1 and ignore
} else {
validationErrorSeverity = (severity == SEV_ERROR ? ValidationMessage.SEV_NORMAL : ValidationMessage.SEV_LOW);
}
successfullyAdded = true;
if( validationErrorSeverity == -1 ) {
// Only possible if error is in different file and user chose to ignore
return successfullyAdded;
}
// Add to the appropriate list if nested error support is off or
// this message is for the current file.
if (!WRAPPER_ERROR_SUPPORT_ENABLED || isSameFile) {
// effectively just isSameFile since WRAPPER_ERROR_SUPPORT_ENABLED is always true?
ValidationMessage valmes = new ValidationMessage(message, line,
column, validating_file_uri, key, messageArguments);
valmes.setSeverity(validationErrorSeverity);
messages.add(valmes);
}
// If nested error support is enabled create a nested error.
else if (WRAPPER_ERROR_SUPPORT_ENABLED)
{
String nesteduri = errorURL.toExternalForm();
ValidationMessage nestedmess = new ValidationMessage(message, line,
column, nesteduri, key, messageArguments);
nestedmess.setSeverity(validationErrorSeverity);
ValidationMessage container = (ValidationMessage) nestedMessages.get(nesteduri);
if(container == null)
{
container = new ValidationMessage(NLS.bind(XMLValidationMessages._UI_REF_FILE_ERROR_MESSAGE, new Object [] { nesteduri }), 1, 0, nesteduri);
// Initially set the nested error to a warning. This will automatically be changed
// to an error if a nested message has a severity of error.
container.setSeverity(ValidationMessage.SEV_LOW);
nestedMessages.put(nesteduri, container);
messages.add(container);
}
container.addNestedMessage(nestedmess);
}
}
return successfullyAdded;
}
private IScopeContext[] getPreferenceScopes() {
if( sameFilePreferenceContext == null ) {
sameFilePreferenceContext = createPreferenceScopes(validating_file_url);
}
return sameFilePreferenceContext;
}
private IScopeContext[] createPreferenceScopes(URL url) {
IProject p = null;
// on null, fall through to non-project-specific defaults
if (url == null) {
try {
URI uri = new URI(url.toString());
IFile[] matching = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri);
if (matching != null && matching.length > 0) {
p = matching[0].getProject();
}
}
catch (URISyntaxException urie) {
// shouldn't happen, but ignore
}
}
return createPreferenceScopesFromProject(p);
}
private IScopeContext[] createPreferenceScopesFromProject(IProject project) {
if (project != null && project.isAccessible()) {
final ProjectScope projectScope = new ProjectScope(project);
if (projectScope.getNode(XMLCorePlugin.getDefault().getBundle().getSymbolicName()).getBoolean(XMLCorePreferenceNames.USE_PROJECT_SETTINGS, false))
return new IScopeContext[]{projectScope, new InstanceScope(), new DefaultScope()};
}
return new IScopeContext[]{ InstanceScope.INSTANCE, DefaultScope.INSTANCE};
}
/**
* Add a nested message to the validation information.
*
* @param message The string message of the validation message.
* @param line The line location of the validation message.
* @param column The column location of the validation message.
* @param uri The URI of the validation message.
* @param severity The severity of the validation message.
*/
// public void addNestedMessage(String message, int line, int column, String uri, int severity)
// {
// ValidationMessage nestedmess = new ValidationMessage(message, line, column, uri);
// if(severity == SEV_WARNING)
// {
// nestedmess.setSeverity(ValidationMessage.SEV_LOW);
// }
// else
// {
// nestedmess.setSeverity(ValidationMessage.SEV_NORMAL);
// }
// ValidationMessage container = (ValidationMessage)nestedMessages.get(uri);
// if(container == null)
// {
// container = new ValidationMessage(XMLCoreValidationPlugin.getResourceString(_UI_REF_FILE_ERROR_MESSAGE, uri), 1, 0, validating_file_uri);
// // Initially set the nested error to a warning. This will automatically be changed
// // to an error if a nested message has a severity of error.
// container.setSeverity(ValidationMessage.SEV_LOW);
// nestedMessages.put(uri, container);
// messages.add(container);
// }
// container.addNestedMessage(nestedmess);
// }
/**
* @see org.eclipse.wsdl.validate.ValidationReport#getValidationMessages()
*/
public ValidationMessage[] getValidationMessages()
{
return (ValidationMessage[])messages.toArray(new ValidationMessage[messages.size()]);
}
public HashMap getNestedMessages()
{
return nestedMessages;
}
/**
* Put the URI in a standard format.
*
* @param uri The URI to put into a standard format.
* @return The standard format of the URI.
*/
private String normalize(String uri)
{
// if(uri.startsWith("platform:"))
// {
// try
// {
// uri = Platform.resolve(new URL(uri)).toString();
// }
// catch(Exception e)
// {
// }
// }
uri = uri.replaceAll("%20"," "); //$NON-NLS-1$ //$NON-NLS-2$
uri = uri.replaceAll("%5E", "^"); //$NON-NLS-1$ //$NON-NLS-2$
uri = uri.replace('\\','/');
return uri;
}
}