/* * 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.core.validation.rules; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.ResourceNameUtil; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.validation.ResourceValidationRule; import org.teiid.designer.core.validation.ValidationContext; import org.teiid.designer.core.validation.ValidationProblem; import org.teiid.designer.core.validation.ValidationProblemImpl; import org.teiid.designer.core.validation.ValidationResult; import org.teiid.designer.core.validation.ValidationResultImpl; import org.teiid.designer.core.workspace.ModelStatusImpl; import org.teiid.designer.runtime.spi.ITeiidVdb; /** * ModelFileExtensionRule * * @since 8.0 */ public class ModelFileExtensionRule implements ResourceValidationRule, StringConstants { /* (non-Javadoc) * @See org.teiid.designer.core.validation.ResourceValidationRule#validate(org.eclipse.emf.ecore.resource.Resource, org.teiid.designer.core.validation.ValidationContext) */ @Override public void validate( final Resource resource, final ValidationContext context ) { CoreArgCheck.isNotNull(resource); CoreArgCheck.isNotNull(context); // Run this rule only on file based resources final URI uri = resource.getURI(); if (uri != null && uri.isFile()) { // Case 6581 - First Check the modelname for validity String name = ModelerCore.getModelEditor().getModelName(resource); // Decode any uri encoding String decodedName = URI.decode(name); final ValidationResultImpl vresult = new ValidationResultImpl(decodedName); if (!isReservedInvalidModelName(decodedName)) { CoreValidationRulesUtil.validateStringNameChars(vresult, decodedName, null); } if (!vresult.hasProblems()) { if (!name.equals(decodedName) && !isReservedInvalidModelName(name)) { CoreValidationRulesUtil.validateStringNameChars(vresult, name, null); if (vresult.hasProblems()) { context.addResult(vresult); } } } else { context.addResult(vresult); } final IStatus status = validate(uri.lastSegment()); if (!status.isOK()) { final ValidationResult result = new ValidationResultImpl(resource); final ValidationProblem problem = new ValidationProblemImpl(0, IStatus.WARNING, status.getMessage()); result.addProblem(problem); context.addResult(result); } } } /** * Return an IStatus indicating if the specified file name is considered to have a valid file extension. The extension is * considered invalid if it matches one of the well-known file extensions for the modeler (e.g. ".xmi", ".xsd", ".vdb") but * the extension is not lower-case. There are a number of places in the modeler and console code that assumes lower-case * extensions. Because of this, a mixed or upper-case extension could produce problems which is the reason for the validation * rule. This method will return an OK status if the specified file name has no extension, is not one of the well-known * extensions, is a well-known extension with the correct case. * * @param fileNameWithExtension * @return * @since 4.3 */ public static IStatus validate( final String fileNameWithExtension ) { CoreArgCheck.isNotNull(fileNameWithExtension); CoreArgCheck.isNotZeroLength(fileNameWithExtension); String actualExtension = null; int beginIndex = fileNameWithExtension.lastIndexOf('.') + 1; if (beginIndex > 0 && beginIndex < fileNameWithExtension.length()) { actualExtension = fileNameWithExtension.substring(beginIndex); } String expectedExtension = getMatchingKnownExtension(actualExtension); // If this resource extension does not match any of the well-known extensions then return if (expectedExtension == null) { return ModelStatusImpl.VERIFIED_OK; } // If the extension is a case-sensitive match for one of the well-known extensions then return if (expectedExtension.equals(actualExtension)) { return ModelStatusImpl.VERIFIED_OK; } // If the extension is a case-insensitive match for one of the well-known extensions then validation error if (expectedExtension.equalsIgnoreCase(actualExtension)) { final int endIndex = fileNameWithExtension.length() - actualExtension.length(); final String expectedFileName = fileNameWithExtension.substring(0, endIndex) + expectedExtension; final Object[] params = new Object[] {fileNameWithExtension, expectedFileName}; final String msg = ModelerCore.Util.getString("ModelerCore.file_extension_not_correct_case_please_rename_file", params); //$NON-NLS-1$ return new Status(IStatus.WARNING, ModelerCore.PLUGIN_ID, -1, msg, null); } return ModelStatusImpl.VERIFIED_OK; } // Case 6581 - added since we have some internal modelNames that are invalid (contain dashes). // This method is used to detect whether a modelname is one of the invalid internal names, // and bypass the name validation for it. private static boolean isReservedInvalidModelName( String name ) { boolean isReservedInvalid = false; if (ResourceNameUtil.XMLSCHEMA_INSTANCE_NAME.equals(name) || ResourceNameUtil.SIMPLEDATATYPES_INSTANCE_NAME.equals(name)) { isReservedInvalid = true; } return isReservedInvalid; } private static String getMatchingKnownExtension( final String extension ) { // Return the "expected" extension by performing a case-insensitive match against all well-known model file extensions if (XML.equalsIgnoreCase(extension)) { return XML; } else if (XMI.equalsIgnoreCase(extension)) { return XMI; } else if (XSD.equalsIgnoreCase(extension)) { return XSD; } else if (ITeiidVdb.VDB_EXTENSION.equalsIgnoreCase(extension)) { return ITeiidVdb.VDB_EXTENSION; } return null; } }