/* * 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.workspace; import java.io.File; import java.io.InputStream; import org.teiid.core.designer.CoreModelerPlugin; import org.teiid.core.designer.TeiidDesignerException; import org.teiid.core.designer.util.FileUtils; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.common.xmi.XMIHeader; import org.teiid.designer.common.xmi.XMIHeaderReader; import org.teiid.designer.runtime.spi.ITeiidVdb; /** * @since 8.0 */ public class ModelFileUtil implements StringConstants { /** * @since 8.0 */ public interface XmiHeaderCache { XMIHeader getCachedXmiHeader( File resource ); void setXmiHeaderToCache( File resource, XMIHeader header ); } public static final String UML_MODEL_URI = "http://www.eclipse.org/uml2/3.0.0/UML"; //$NON-NLS-1$ public static final String XML_SERVICE_MODEL_URI = "http://www.metamatrix.com/metamodels/XmlService"; //$NON-NLS-1$ public static final String RELATIONSHIP_MODEL_URI = "http://www.metamatrix.com/metamodels/Relationship"; //$NON-NLS-1$ private static XmiHeaderCache CACHE; public static void setCache( XmiHeaderCache cache ) { ModelFileUtil.CACHE = cache; } /** * Return true if the File represents a MetaMatrix model file or an xsd file this method does not check if the file exists in * a project with model nature. Returns a false for vdb files. * * @param resource The file that may be a model file * @return true if it is a ModelFile. */ public static boolean isModelFile( final File resource ) { if (resource == null) { return false; } // If the file does not yet exist then the only thing // we can do is to check the name and extension. if (!resource.exists()) { final String extension = FileUtils.getExtension(resource.getAbsolutePath()); return isModelFileExtension(extension, true); } // If this is an xsd resource return true if (isXsdFile(resource)) { return true; } // If this is an vdb resource return false if (isVdbArchiveFile(resource)) { return false; } // If the resource does not have the correct lower-case extension then return false if (!XMI.equals(getFileExtension(resource))) { return false; } XMIHeader header = getXmiHeader(resource); // If the header is not null then we know the file is, at least, // a well formed xml document. if (header != null) { // If the XMI version for the header is not null, then return // false if the file represents an older 1.X model file if (header.getXmiVersion() != null && header.getXmiVersion().startsWith("1.")) { //$NON-NLS-1$ return false; } String uri = header.getPrimaryMetamodelURI(); if( uri == null ) { return false; } if( uri.equalsIgnoreCase(XML_SERVICE_MODEL_URI) || uri.equalsIgnoreCase(RELATIONSHIP_MODEL_URI) || uri.equalsIgnoreCase(UML_MODEL_URI) ) { return false; } // If the UUID for the header is not null, then the file is a // MetaMatrix model file containing a ModelAnnotation element. if (header.getUUID() != null) { return true; } } return false; } /** * Return true if the IResource represents a xsd file. * * @param resource The file that may be a xsd file * @return true if it is a xsd */ public static boolean isXsdFile( final File resource ) { // Check that the resource has the correct lower-case extension if (XSD.equals(getFileExtension(resource))) { return true; } return false; } /** * <p> * </p> * * @since 4.0 */ public static boolean isVdbArchiveFile( final File resource ) { // Check that the resource has the correct lower-case extension if (ITeiidVdb.VDB_EXTENSION.equals(getFileExtension(resource))) { return true; } return false; } /** * Returns the file extension portion of this file, or an empty string if there is none. * <p> * The file extension portion is defined as the string following the last period (".") character in the file name. If there is * no period in the file name, the file has no file extension portion. If the name ends in a period, the file extension * portion is the empty string. * </p> * * @param resource * @return the file extension or <code>null</code> * @since 4.3 */ public static String getFileExtension( final File resource ) { if (resource != null) { return FileUtils.getExtension(resource); } return ""; //$NON-NLS-1$ } /** * Return true if a file with the specified name and extension represents a MetaMatrix model file. * * @param name * @param extension * @return */ public static boolean isModelFileExtension( final String extension, boolean caseSensitive ) { // Check if the extension is one of the well-known extensions // The method assumes the extension is lower-case. Relaxing // this assumption may cause the Modeler to work incorrectly. if (extension == null) { return false; } final String exten = (caseSensitive ? extension : extension.toLowerCase()); if (XMI.equals(exten)) { return true; } if (XSD.equals(exten)) { return true; } if (ITeiidVdb.VDB_EXTENSION.equals(exten)) { return false; } return false; } /** * Return the XMIHeader for the specified File or null if the file does not represent a MetaMatrix model file. * * @param resource The file of a metamatrix model file. * @return The XMIHeader for the model file */ public static XMIHeader getXmiHeader( final File resource ) { if (resource != null && resource.isFile() && resource.exists() && resource.canRead()) { // check cache if (CACHE != null) { XMIHeader header = CACHE.getCachedXmiHeader(resource); if (header != null) { return header; } } try { XMIHeader header = XMIHeaderReader.readHeader(resource); // add to cache if (CACHE != null) { CACHE.setXmiHeaderToCache(resource, header); } return header; } catch (TeiidDesignerException e) { CoreModelerPlugin.Util.log(e); } catch (IllegalArgumentException iae) { // Swallowing this exception because we're doing all three checks that would produce it. // If this exception is caught, it's because the files really were closed/deleted in another thread and this // thread didn't know about it. // Fixes Defect 22117 } } return null; } /** * Return the XMIHeader for the specified inputstream of a model file. * * @param resourceStream The inputStream of a metamatrix model file. * @return The XMIHeader for the model file */ public static XMIHeader getXmiHeader( final InputStream resourceStream ) { if (resourceStream != null) { try { return XMIHeaderReader.readHeader(resourceStream); } catch (TeiidDesignerException e) { CoreModelerPlugin.Util.log(e); } } return null; } }