/******************************************************************************* * Copyright (c) 2005, 2009 IBM 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.core.internal.propertytester; import org.eclipse.core.internal.utils.Policy; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentTypeMatcher; /** * A property tester for various properties of files. * * @since 3.2 */ public class FilePropertyTester extends ResourcePropertyTester { /** * A property indicating a content type on the selected file (value <code>"contentTypeId"</code>). * <code>"kindOf"</code> indicates that the file content type should be the kind of the one given as the expected value. * If <code>"kindOf"</code> is not specified, the file content type identifier should equals the expected value. * @see IContentType#isKindOf(IContentType) */ private static final String CONTENT_TYPE_ID = "contentTypeId"; //$NON-NLS-1$ /** * An argument for <code>"contentTypeId"</code>. * <code>"kindOf"</code> indicates that the file content type should be the kind of the one given as the expected value. * If <code>"kindOf"</code> is not specified, the file content type identifier should equals the expected value. * @see IContentType#isKindOf(IContentType) */ private static final String IS_KIND_OF = "kindOf"; //$NON-NLS-1$ /** * An argument for <code>"contentTypeId"</code>. * Setting <code>"useFilenameOnly"</code> indicates that the file content type should be determined by the file name only. * If <code>"useFilenameOnly"</code> is not specified, the file content type is determined by both, the file name and content. * @see IContentTypeMatcher#findContentTypeFor(String) */ private static final String USE_FILENAME_ONLY = "useFilenameOnly"; //$NON-NLS-1$ /* * (non-Javadoc) * * @see org.eclipse.core.internal.resources.ResourcePropertyTester#test(java.lang.Object, * java.lang.String, java.lang.Object[], java.lang.Object) */ public boolean test(Object receiver, String method, Object[] args, Object expectedValue) { if ((receiver instanceof IFile) && method.equals(CONTENT_TYPE_ID)) return testContentType((IFile) receiver, toString(expectedValue), isArgumentUsed(args, IS_KIND_OF), isArgumentUsed(args, USE_FILENAME_ONLY)); return false; } private boolean isArgumentUsed(Object[] args, String value) { for (int i = 0; i < args.length; i++) if (value.equals(args[i])) return true; return false; } /** * <p> * Tests whether the content type for <code>file</code> matches * or is a kind of <code>contentTypeId</code>. * </p> * <p> * It is possible that this method call could * cause the file to be read. It is also possible (through poor plug-in * design) for this method to load plug-ins. * </p> * * @param file * The file to test. Must not be <code>null</code>. * @param contentTypeId * The content type to test. Must not be <code>null</code>. * @param isKindOfUsed * Indicates whether the file content type should match <code>contentTypeId</code> * or should be a kind of <code>contentTypeId</code>. * @param useFilenameOnly * Indicates to determine the file content type based on the file name only. * @return <code>true</code>, if the best matching content type for <code>file</code> * <ul> * <li>has an identifier that matches <code>contentTypeId</code> * and <code>isKindOfUsed</code> is <code>false</code>, or</li> * <li>is a kind of <code>contentTypeId</code> * and <code>isKindOfUsed</code> is <code>true</code>.</li> * </ul> * Otherwise it returns <code>false</code>. */ private boolean testContentType(final IFile file, String contentTypeId, boolean isKindOfUsed, boolean useFilenameOnly) { final String expectedValue = contentTypeId.trim(); IContentType actualContentType = null; if (!useFilenameOnly) { if (!file.exists()) return false; IContentDescription contentDescription = null; try { contentDescription = file.getContentDescription(); } catch (CoreException e) { Policy.log(IStatus.ERROR, "Core exception while retrieving the content description", e);//$NON-NLS-1$ } if (contentDescription != null) actualContentType = contentDescription.getContentType(); } else { actualContentType = Platform.getContentTypeManager().findContentTypeFor(file.getName()); } if (actualContentType != null) { if (isKindOfUsed) return actualContentType.isKindOf(Platform.getContentTypeManager().getContentType(expectedValue)); return expectedValue.equals(actualContentType.getId()); } return false; } }