blob: f09b384f48c2f4277242046a9bceb620b29b1f90 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2009 Borland Software 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:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.m2m.internal.qvt.oml.common.CommonPlugin;
import org.eclipse.m2m.internal.qvt.oml.common.MDAConstants;
import org.eclipse.m2m.internal.qvt.oml.cst.parser.QvtKeywords;
import com.ibm.icu.lang.UCharacter;
/**
* Provides validation functionality for QVT elements identifiers.
*/
public class QvtNamesChecker {
public static final String QNAME_DELIMITER = "."; //$NON-NLS-1$
private static final String ADJACENT_DELIMITERS_ERROR = QNAME_DELIMITER + QNAME_DELIMITER;
private static final IStatus invalidCUFileNameStatus = CommonPlugin.createStatus(IStatus.ERROR,
NLS.bind(Messages.QvtNamesChecker_InvalidCUnitName,
new String[] { MDAConstants.QVTO_FILE_EXTENSION }), null);
private QvtNamesChecker() {
super();
}
public static boolean isValidCompilationUnitFileName(String fileName) {
return validateCompilationUnitFileName(fileName).isOK();
}
public static IStatus validateCompilationUnitFileName(String fileName) {
IStatus result = Status.OK_STATUS;
boolean isBlank = fileName == null || fileName.trim().length() == 0;
if(isBlank || !fileName.endsWith(MDAConstants.QVTO_FILE_EXTENSION_WITH_DOT) || fileName.startsWith(".")) { //$NON-NLS-1$
return invalidCUFileNameStatus;
}
return result;
}
/**
* Get the name of the main module for the given compilation unit file name.
* <p>
* @param compilationUnitFileName a valid compilation unit file name
*
* @return the module name, representing the give file name without the file name extension.
*/
public static String getCompilationUnitMainModuleName(String compilationUnitFileName) {
int lastPos = compilationUnitFileName.lastIndexOf(MDAConstants.QVTO_FILE_EXTENSION_WITH_DOT);
if(lastPos > 0) {
return compilationUnitFileName.substring(0, lastPos);
}
return ""; //$NON-NLS-1$
}
/**
* Extracts the qualifying part of the given qualified identifier.
* <p>
*
* @param qualifiedIdentifier
* a valid qualified identifier
*
* @return the qualifying part is the string up-to the last '.' separated
* segment of the given qualified identifier.
* <p>
* Note: If the qualified identifier is a simple identifier, which
* also represents a valid qualified identifier, empty string representing
* the default name-space is returned.
*
* @throws IllegalArgumentException
* in case that the passed <code>qualifiedIdentifier</code> is
* not valid
*
* @see #validateQualifiedIdentifier(String, String)
*/
public static String extractQualifyingIdentifierPart(String qualifiedIdentifier) {
if(!validateQualifiedIdentifier(qualifiedIdentifier, "").isOK()) {//$NON-NLS-1$
throw new IllegalArgumentException("Invalid qualifiedIdentifier"); //$NON-NLS-1$
}
int pos = qualifiedIdentifier.lastIndexOf(QNAME_DELIMITER);
if(pos >= 0) {
return qualifiedIdentifier.substring(0, pos);
}
return ""; //$NON-NLS-1$
}
/**
* Extracts the local identifier from the given qualified identifier.
* <p>
*
* @param qualifiedIdentifier
* a valid qualified identifier
*
* @return the local identifier as the last '.' separated segment of the
* given qualified identifier.
* <p>
* Note: If the qualified identifier is a simple identifier, which
* also represents a valid qualified identifier, the passed value is
* returned.
*
* @throws IllegalArgumentException
* in case that the passed <code>qualifiedIdentifier</code> is
* not valid
*
* @see #validateQualifiedIdentifier(String, String)
*/
public static String extractLocalIdentifierPart(String qualifiedIdentifier) {
if(!validateQualifiedIdentifier(qualifiedIdentifier, "").isOK()) {//$NON-NLS-1$
throw new IllegalArgumentException("Invalid qualifiedIdentifier"); //$NON-NLS-1$
}
String[] segments = getQualifiedNameSegments(qualifiedIdentifier);
assert segments.length > 0;
return segments[segments.length - 1];
}
public static IStatus validateQualifiedIdentifier(String qualifiedIdentifier, String identifierKindName) {
IStatus result = Status.OK_STATUS;
if(qualifiedIdentifier == null || qualifiedIdentifier.trim().length() == 0) {
String message = Messages.QvtNamesChecker_blankIdentifierError;
return CommonPlugin.createStatus(IStatus.ERROR, NLS.bind(message, identifierKindName), null);
}
String[] segments = getQualifiedNameSegments(qualifiedIdentifier);
if(segments.length == 0 ||
qualifiedIdentifier.startsWith(QNAME_DELIMITER) || // wrong '.' position
qualifiedIdentifier.endsWith(QNAME_DELIMITER) || // wrong '.' position
qualifiedIdentifier.indexOf(ADJACENT_DELIMITERS_ERROR) >= 0 // empty segment name detection
) {
String message = Messages.QvtNamesChecker_invalidQualifiedIdentifierError;
return CommonPlugin.createStatus(IStatus.ERROR, NLS.bind(message, qualifiedIdentifier, identifierKindName), null);
}
for (String segmentName : segments) {
// check for segment invalid characters
IStatus segmentStatus = validateIdentifier(segmentName, Messages.QvtNamesChecker_namespaceIndentifierKindName);
if (!segmentStatus.isOK()) {
return segmentStatus;
}
}
return result;
}
public static IStatus validateNamespaceSimpleIdenfier(String name) {
return validateIdentifier(name, Messages.QvtNamesChecker_namespaceIndentifierKindName);
}
public static IStatus validateNamespaceQualifiedIdentifier(String name) {
return validateQualifiedIdentifier(name, Messages.QvtNamesChecker_namespaceIndentifierKindName);
}
public static IStatus validateQvtModuleIdentifier(String name) {
return validateIdentifier(name, Messages.QvtNamesChecker_moduleIndentifierKindName);
}
public static IStatus validateIdentifier(String name, String identifierKindName) {
if (name == null || name.trim().length() == 0) {
return CommonPlugin.createStatus(IStatus.ERROR, NLS.bind(Messages.QvtNamesChecker_blankIdentifierError, identifierKindName), null);
}
for (int i = 0; i < name.length(); ++i) {
char c = name.charAt(i);
// For now, check just as a Java identifier as the QVT specification is not clear about this
if (!UCharacter.isJavaIdentifierPart(name.charAt(i))) {
String[] args = new String[] { identifierKindName, name, String.valueOf(c) };
String message = NLS.bind(Messages.QvtNamesChecker_illegalCharInIdentifierError, args);
return CommonPlugin.createStatus(IStatus.ERROR, message, null);
}
}
// check for reserved words
if(QvtKeywords.isKeyword(name)) {
String message = NLS.bind(Messages.QvtNamesChecker_reservedQVTWord, name);
return CommonPlugin.createStatus(IStatus.ERROR, message, null);
}
return Status.OK_STATUS;
}
/**
* Get the name segments of the given qualified-name.
* <p>
* Note: No kind of validation is performed by this method, simply tokens
* delimited by '<code>.</code>' are returned.
*
* @param qualifiedName
* a valid qualified identifier in the form of sequence of simple
* identifiers separated by '<code>.</code>'
*
* @return array of name segments composing the given qualified name
*/
public static String[] getQualifiedNameSegments(String qualifiedName) {
StringTokenizer tokenizer = new StringTokenizer(qualifiedName, QNAME_DELIMITER);
int segmentCount = tokenizer.countTokens();
String[] segments = new String[segmentCount];
for (int i = 0; i < segmentCount; i++) {
segments[i] = tokenizer.nextToken();
}
return segments;
}
}