| /******************************************************************************* |
| * Copyright (c) 2007, 2018 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 v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.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; |
| |
| /** |
| * 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 (!Character.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; |
| } |
| } |