/*
* 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.metamodels.core.util;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.CoreStringUtil;
import org.teiid.core.designer.util.I18nUtil;
import org.teiid.designer.metamodels.core.CoreMetamodelPlugin;
/**
* The <code>UriValidator</code> class validates textual representations of {@link org.eclipse.emf.common.util.URI} and its
* components.
*
* @author <a href="mailto:dflorian@metamatrix.com">Dan Florian</a>
* @since 8.0
*/
public class UriValidator {
/**
* Properties key prefix used when obtaining localized messages.
*
* @since 4.3
*/
static final String PREFIX = I18nUtil.getPropertyPrefix(UriValidator.class);
/**
* Properties key prefix used when obtaining URI component labels.
*
* @since 4.3
*/
private static final String URI_COMPONENTS_PREFIX = "uricomponents."; //$NON-NLS-1$
/**
* Label for the URI.
*
* @since 4.3
*/
private static final String URI_LABEL = CoreMetamodelPlugin.Util.getString(PREFIX + "uri"); //$NON-NLS-1$
/**
* Multiplication factor on status codes for invalid values.
*/
private static final int INVALID_FACTOR = -1;
/**
* Values for code field of the {@link IStatus} objects returned by the validate methods.
*
* @since 4.3
*/
public interface StatusCodes {
/**
* Status code indicating the value is valid.
*
* @since 4.3
*/
int VALID_URI = 1;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI}.
*
* @since 4.3
*/
int INVALID_URI = VALID_URI * INVALID_FACTOR;
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} authority component.
*
* @since 4.3
*/
int VALID_AUTHORITY = 10;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} authority component.
*
* @since 4.3
*/
int INVALID_AUTHORITY = VALID_AUTHORITY * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} device component.
*
* @since 4.3
*/
int VALID_DEVICE = 20;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} device component.
*
* @since 4.3
*/
int INVALID_DEVICE = VALID_DEVICE * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} fragment component.
*
* @since 4.3
*/
int VALID_FRAGMENT = 30;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} fragment component.
*
* @since 4.3
*/
int INVALID_FRAGMENT = VALID_FRAGMENT * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} jar authority component.
*
* @since 4.3
*/
int VALID_ARCHIVE_AUTHORITY = 40;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} jar authority component.
*
* @since 4.3
*/
int INVALID_ARCHIVE_AUTHORITY = VALID_ARCHIVE_AUTHORITY * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} opaque part component.
*
* @since 4.3
*/
int VALID_OPAQUE_PART = 50;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} opaque part component.
*
* @since 4.3
*/
int INVALID_OPAQUE_PART = VALID_OPAQUE_PART * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} query component.
*
* @since 4.3
*/
int VALID_QUERY = 60;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} query component.
*
* @since 4.3
*/
int INVALID_QUERY = VALID_QUERY * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} scheme component.
*
* @since 4.3
*/
int VALID_SCHEME = 70;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} scheme component.
*
* @since 4.3
*/
int INVALID_SCHEME = VALID_SCHEME * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} segment component.
*
* @since 4.3
*/
int VALID_SEGMENT = 80;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} segment component.
*
* @since 4.3
*/
int INVALID_SEGMENT = VALID_SEGMENT * INVALID_FACTOR; // NO_UCD
/**
* Status code indicating the value is a valid {@link org.eclipse.emf.common.util.URI} segment array component.
*
* @since 4.3
*/
int VALID_SEGMENTS = 90;
/**
* Status code indicating the value is not a valid {@link org.eclipse.emf.common.util.URI} segment array component.
*
* @since 4.3
*/
int INVALID_SEGMENTS = VALID_SEGMENTS * INVALID_FACTOR; // NO_UCD
}
/**
* Labels for the {@link org.eclipse.emf.common.util.URI} components.
*
* @since 4.3
*/
public interface UriComponents {
/**
* Label for the authority component.
*
* @since 4.3
*/
String AUTHORITY = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "authority"); //$NON-NLS-1$
/**
* Label for the device component.
*
* @since 4.3
*/
String DEVICE = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "device"); //$NON-NLS-1$
/**
* Label for the fragment component.
*
* @since 4.3
*/
String FRAGMENT = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "fragment"); //$NON-NLS-1$
/**
* Label for the jar authority component.
*
* @since 4.3
*/
String JAR_AUTHORITY = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "jarauthority"); //$NON-NLS-1$
/**
* Label for the opaque part component.
*
* @since 4.3
*/
String OPAQUE_PART = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "opaquepart"); //$NON-NLS-1$
/**
* Label for the query component.
*
* @since 4.3
*/
String QUERY = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "query"); //$NON-NLS-1$
/**
* Label for the scheme component.
*
* @since 4.3
*/
String SCHEME = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "scheme"); //$NON-NLS-1$
/**
* Label for the segment component.
*
* @since 4.3
*/
String SEGMENT = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "segment"); //$NON-NLS-1$
/**
* Label for multiple segment components.
*
* @since 4.3
*/
String SEGMENTS = CoreMetamodelPlugin.Util.getString(PREFIX + URI_COMPONENTS_PREFIX + "multiplesegment"); //$NON-NLS-1$
}
/**
* Obtains a message reporting that the value being set for the specified {@link org.eclipse.emf.common.util.URI} component is
* <code>null</code> or empty.
*
* @param theComponent the component whose value is being validated
* @return the message
* @since 4.3
*/
private static String createNullValueMessage( String theComponent ) {
return CoreMetamodelPlugin.Util.getString(PREFIX + "nullValue", theComponent); //$NON-NLS-1$;
}
/**
* Obtains an <code>IStatus</code> suitable for the specified parameters.
*
* @param theComponent the URI component label
* @param theValue the value being validated
* @param theIsValidFlag the flag indicating if the value is valid
* @since 4.3
*/
private static IStatus createStatus( String theComponent,
String theValue,
boolean theIsValidFlag ) {
return new Status(getSeverity(theIsValidFlag), CoreMetamodelPlugin.PLUGIN_ID, getCode(theComponent, theIsValidFlag),
createValidationMessage(theComponent, theValue, theIsValidFlag), null); // no exception
}
/**
* Obtains a validation message suitable for the specified parameters.
*
* @param theComponent the component whose value is being validated
* @param theValue the proposed value
* @param theIsValidFlag the flag indicating if the value is valid
* @return the validation message
* @since 4.3
*/
private static String createValidationMessage( String theComponent,
String theValue,
boolean theIsValidFlag ) {
if (theIsValidFlag) {
return CoreMetamodelPlugin.Util.getString(PREFIX + "componentValid", new Object[] {theComponent, theValue}); //$NON-NLS-1$;
}
return CoreMetamodelPlugin.Util.getString(PREFIX + "componentNotValid", new Object[] {theComponent, theValue}); //$NON-NLS-1$;
}
/**
* Obtains an <code>IStatus</code> code suitable for the specified parameters.
*
* @param theComponent the URI component label
* @param theIsValidFlag the flag indicating if the value is valid
* @since 4.3
*/
private static int getCode( String theComponent,
boolean theIsValidFlag ) {
int result = StatusCodes.VALID_URI;
if (URI_LABEL.equals(theComponent)) {
result = StatusCodes.VALID_URI;
} else if (UriComponents.AUTHORITY.equals(theComponent)) {
result = StatusCodes.VALID_AUTHORITY;
} else if (UriComponents.DEVICE.equals(theComponent)) {
result = StatusCodes.VALID_DEVICE;
} else if (UriComponents.FRAGMENT.equals(theComponent)) {
result = StatusCodes.VALID_FRAGMENT;
} else if (UriComponents.JAR_AUTHORITY.equals(theComponent)) {
result = StatusCodes.VALID_ARCHIVE_AUTHORITY;
} else if (UriComponents.OPAQUE_PART.equals(theComponent)) {
result = StatusCodes.VALID_OPAQUE_PART;
} else if (UriComponents.QUERY.equals(theComponent)) {
result = StatusCodes.VALID_QUERY;
} else if (UriComponents.SCHEME.equals(theComponent)) {
result = StatusCodes.VALID_SCHEME;
} else if (UriComponents.SEGMENT.equals(theComponent)) {
result = StatusCodes.VALID_SEGMENT;
} else if (UriComponents.SEGMENTS.equals(theComponent)) {
result = StatusCodes.VALID_SEGMENTS;
}
if (!theIsValidFlag) {
result *= INVALID_FACTOR;
}
return result;
}
/**
* Obtains an {@link IStatus} severity for the specified validation result.
*
* @param theIsValidFlag the flag indicating if the validation was successful
* @return the severity
* @since 4.3
*/
private static int getSeverity( boolean theIsValidFlag ) {
return (theIsValidFlag ? IStatus.OK : IStatus.ERROR);
}
/**
* Indicates if the specified value can be converted into a valid {@link org.eclipse.emf.common.util.URI}.
*
* @param theUri the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
*/
public static boolean isValid( String theUri ) { // NO_UCD
boolean result = false;
if (CoreStringUtil.isEmpty(theUri)) {
// clearing the URI is OK
result = true;
} else {
try {
URI.createURI(theUri);
result = true;
} catch (IllegalArgumentException theException) {
// no handling required since result is already false
}
}
return result;
}
/**
* Indicates if the specified value can be converted into a valid {@link org.eclipse.emf.common.util.URI}.
*
* @param theUri the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
*/
public static IStatus validate( String theUri ) {
IStatus result = null;
if (!CoreStringUtil.isEmpty(theUri)) {
try {
URI.createURI(theUri);
} catch (IllegalArgumentException theException) {
int code = StatusCodes.INVALID_URI;
String uriMsg = theException.getMessage(); // exception caught will have details on why invalid
String msg = null;
// look at msg searching for key words in order to set the code properly.
// not crazy about doing this but the URI class is not localized and wanted to get
// the status code and message to represent a detailed error
if ((uriMsg != null) && (uriMsg.length() > 0)) {
String component = null;
if (uriMsg.indexOf("scheme") != -1) { //$NON-NLS-1$
component = UriComponents.SCHEME;
} else if (uriMsg.indexOf("opaquePart") != -1) { //$NON-NLS-1$
component = UriComponents.OPAQUE_PART;
} else if (uriMsg.indexOf("authority") != -1) { //$NON-NLS-1$
if (CoreStringUtil.startsWithIgnoreCase(theUri, "jar")) { //$NON-NLS-1$
component = UriComponents.JAR_AUTHORITY;
} else {
component = UriComponents.AUTHORITY;
}
} else if (uriMsg.indexOf("device") != -1) { //$NON-NLS-1$
component = UriComponents.DEVICE;
} else if (uriMsg.indexOf("segments") != -1) { //$NON-NLS-1$
component = UriComponents.SEGMENTS;
} else if (uriMsg.indexOf("query") != -1) { //$NON-NLS-1$
component = UriComponents.QUERY;
} else if (uriMsg.indexOf("fragment") != -1) { //$NON-NLS-1$
component = UriComponents.FRAGMENT;
} else {
msg = uriMsg;
}
// found the component that is in error
if (component != null) {
code = getCode(component, false);
msg = CoreMetamodelPlugin.Util.getString(PREFIX + "uriComponentInvalid", new Object[] {component, theUri}); //$NON-NLS-1$;
}
} else {
// exception message is null or empty
code = getCode(URI_LABEL, false);
msg = CoreMetamodelPlugin.Util.getString(PREFIX + "genericUriError", new Object[] {theUri}); //$NON-NLS-1$;
}
result = new Status(getSeverity(false), CoreMetamodelPlugin.PLUGIN_ID, code, msg, null);
}
}
// create OK status message if no error found
if (result == null) {
result = createStatus(URI_LABEL, theUri, true);
}
return result;
}
/**
* Indicates if the specified value is a valid authority component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theAuthority the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validAuthority(java.lang.String)
*/
public static boolean isValidAuthority( String theAuthority ) {
return URI.validAuthority(theAuthority);
}
/**
* Indicates if the specified value is a valid authority component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theAuthority the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validAuthority(java.lang.String)
*/
public static IStatus validateAuthority( String theAuthority ) { // NO_UCD
return createStatus(UriComponents.AUTHORITY, theAuthority, isValidAuthority(theAuthority));
}
/**
* Indicates if the specified value is a valid device component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theDevice the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validDevice(java.lang.String)
*/
public static boolean isValidDevice( String theDevice ) {
return URI.validDevice(theDevice);
}
/**
* Indicates if the specified value is a valid device component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theDevice the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validDevice(java.lang.String)
*/
public static IStatus validateDevice( String theDevice ) { // NO_UCD
return createStatus(UriComponents.DEVICE, theDevice, isValidDevice(theDevice));
}
/**
* Indicates if the specified value is a valid fragment component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theFragment the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validFragment(java.lang.String)
*/
public static boolean isValidFragment( String theFragment ) {
return URI.validFragment(theFragment);
}
/**
* Indicates if the specified value is a valid fragment component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theFragment the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validFragment(java.lang.String)
*/
public static IStatus validateFragment( String theFragment ) { // NO_UCD
return createStatus(UriComponents.FRAGMENT, theFragment, isValidFragment(theFragment));
}
/**
* Indicates if the specified value is a valid archive authority component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theArchiveAuthority the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validArchiveAuthority(java.lang.String)
*/
public static boolean isValidArchiveAuthority( String theArchiveAuthority ) {
return URI.validArchiveAuthority(theArchiveAuthority);
}
/**
* Indicates if the specified value is a valid archive authority component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theArchiveAuthority the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validArchiveAuthority(java.lang.String)
*/
public static IStatus validateArchiveAuthority( String theArchiveAuthority ) { // NO_UCD
return createStatus(UriComponents.JAR_AUTHORITY, theArchiveAuthority, isValidArchiveAuthority(theArchiveAuthority));
}
/**
* Indicates if the specified value is a valid opaque part component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theOpaquePart the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validOpaquePart(java.lang.String)
*/
public static boolean isValidOpaquePart( String theOpaquePart ) {
return URI.validOpaquePart(theOpaquePart);
}
/**
* Indicates if the specified value is a valid opaque part component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theOpaquePart the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validOpaquePart(java.lang.String)
*/
public static IStatus validateOpaquePart( String theOpaquePart ) { // NO_UCD
return createStatus(UriComponents.OPAQUE_PART, theOpaquePart, isValidOpaquePart(theOpaquePart));
}
/**
* Indicates if the specified value is a valid query component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theQuery the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validQuery(java.lang.String)
*/
public static boolean isValidQuery( String theQuery ) {
return URI.validQuery(theQuery);
}
/**
* Indicates if the specified value is a valid query component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theQuery the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validQuery(java.lang.String)
*/
public static IStatus validateQuery( String theQuery ) { // NO_UCD
return createStatus(UriComponents.QUERY, theQuery, isValidQuery(theQuery));
}
/**
* Indicates if the specified value is a valid query component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theScheme the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validScheme(java.lang.String)
*/
public static boolean isValidScheme( String theScheme ) {
return URI.validScheme(theScheme);
}
/**
* Indicates if the specified value is a valid query component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theScheme the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validScheme(java.lang.String)
*/
public static IStatus validateScheme( String theScheme ) { // NO_UCD
return createStatus(UriComponents.SCHEME, theScheme, isValidScheme(theScheme));
}
/**
* Indicates if the specified value is a valid seqment component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theSegment the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @since 4.3
* @see URI#validSegment(java.lang.String)
*/
public static boolean isValidSegment( String theSegment ) {
return URI.validSegment(theSegment);
}
/**
* Indicates if the specified value is a valid seqment component of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theSegment the value being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @since 4.3
* @see URI#validSegment(java.lang.String)
*/
public static IStatus validateSegment( String theSegment ) { // NO_UCD
return createStatus(UriComponents.SEGMENT, theSegment, isValidSegment(theSegment));
}
/**
* Indicates if all the specified values are valid seqment components of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theSegments the value being checked
* @return <code>true</code>if valid; <code>false</code> otherwise.
* @throws AssertionError if value is <code>null</code>
* @since 4.3
* @see URI#validSegments(java.lang.String[])
*/
public static boolean isValidSegments( String[] theSegments ) throws AssertionError { // NO_UCD
CoreArgCheck.isNotNull(theSegments, createNullValueMessage(UriComponents.SEGMENTS));
return URI.validSegments(theSegments);
}
/**
* Indicates if all the specified values are valid seqment components of a {@link org.eclipse.emf.common.util.URI}.
*
* @param theSegments the values being checked
* @return a status indicating the result of the validity check; never <code>null</code>
* @throws AssertionError if value is <code>null</code>
* @since 4.3
* @see URI#validSegments(java.lang.String[])
*/
public static IStatus validateSegments( String[] theSegments ) throws AssertionError { // NO_UCD
CoreArgCheck.isNotNull(theSegments, createNullValueMessage(UriComponents.SEGMENTS));
IStatus result = null;
for (int i = 0; i < theSegments.length; ++i) {
boolean valid = isValidSegment(theSegments[i]);
if (!valid) {
result = createStatus(UriComponents.SEGMENTS, theSegments[i], false);
break;
}
}
// all segments valid
if (result == null) {
result = new Status(IStatus.OK, CoreMetamodelPlugin.PLUGIN_ID, StatusCodes.VALID_SEGMENTS,
CoreMetamodelPlugin.Util.getString(PREFIX + "allsegmentsvalid"), //$NON-NLS-1$
null);
}
return result;
}
/**
* Don't allow object construction.
*/
private UriValidator() {
// no impl required
}
}