/******************************************************************************* * Copyright (c) 2000, 2015 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 * Martin Oberhuber (Wind River) - [184534] get attributes from native lib *******************************************************************************/ package org.eclipse.core.internal.filesystem.local; import java.net.URL; import java.util.Enumeration; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileSystem; import org.eclipse.core.filesystem.provider.FileInfo; import org.eclipse.core.internal.filesystem.*; import org.eclipse.core.runtime.IStatus; import org.eclipse.osgi.util.NLS; abstract class LocalFileNatives { private static boolean hasNatives = false; private static boolean isUnicode = false; private static int nativeAttributes = -1; /** instance of this library */ // The name convention is to use the plugin version at the time the library is changed. private static final String LIBRARY_NAME = "localfile_1_0_0"; //$NON-NLS-1$ static { try { System.loadLibrary(LIBRARY_NAME); hasNatives = true; isUnicode = internalIsUnicode(); try { nativeAttributes = nativeAttributes(); } catch (UnsatisfiedLinkError e) { // older native implementations did not support this // call, so we need to handle the error silently } } catch (UnsatisfiedLinkError e) { if (isLibraryPresent()) logMissingNativeLibrary(e); } } private static boolean isLibraryPresent() { String libName = System.mapLibraryName(LIBRARY_NAME); Enumeration<URL> entries = Activator.findEntries("/", libName, true); //$NON-NLS-1$ return entries != null && entries.hasMoreElements(); } private static void logMissingNativeLibrary(UnsatisfiedLinkError e) { String libName = System.mapLibraryName(LIBRARY_NAME); String message = NLS.bind(Messages.couldNotLoadLibrary, libName); Policy.log(IStatus.INFO, message, e); } /** * Return the bit-mask of EFS attributes that this native * file system implementation supports. * <p> * This is an optional method: if it has not been compiled * into the native library, the client must catch the * resulting UnsatisfiedLinkError and handle attributes * as known by older version libraries. * </p> * @see IFileSystem#attributes() * @return an integer bit mask of attributes. */ private static final native int nativeAttributes(); /** * Return the value that the native library thinks * {@link IFileSystem#attributes()} should return. * * Returns -1 when the native library has not been * loaded, or is a version that does not support * this investigation method yet. * * @return an positive value that is a bit-mask * suitable for use in {@link IFileSystem#attributes}, * or -1 if native attributes are not available. */ public static int attributes() { return nativeAttributes; } /** * Copies file attributes from source to destination. The copyLastModified attribute * indicates whether the lastModified attribute should be copied. * @param source * @param destination * @param copyLastModified * @return <code>true</code> for success, and <code>false</code> otherwise. */ public static boolean copyAttributes(String source, String destination, boolean copyLastModified) { if (hasNatives) // Note that support for copying last modified info is not implemented on Windows return isUnicode ? internalCopyAttributesW(Convert.toPlatformChars(source), Convert.toPlatformChars(destination), copyLastModified) : internalCopyAttributes(Convert.toPlatformBytes(source), Convert.toPlatformBytes(destination), copyLastModified); return false; // not supported } /** * @param fileName * @return The file info */ public static FileInfo fetchFileInfo(String fileName) { FileInfo info = new FileInfo(); if (isUnicode) internalGetFileInfoW(Convert.toPlatformChars(fileName), info); else internalGetFileInfo(Convert.toPlatformBytes(fileName), info); return info; } /** * Copies file attributes from source to destination. The copyLastModified attribute * indicates whether the lastModified attribute should be copied. */ private static final native boolean internalCopyAttributes(byte[] source, byte[] destination, boolean copyLastModified); /** * Copies file attributes from source to destination. The copyLastModified attribute * indicates whether the lastModified attribute should be copied (Unicode * version - should not be called if <code>isUnicode</code> is * <code>false</code>). */ private static final native boolean internalCopyAttributesW(char[] source, char[] destination, boolean copyLastModified); /** * Stores the file information for the specified filename in the supplied file * information object. This avoids multiple JNI calls. */ private static final native boolean internalGetFileInfo(byte[] fileName, IFileInfo info); /** * Stores the file information for the specified filename in the supplied file * information object. This avoids multiple JNI calls. */ private static final native boolean internalGetFileInfoW(char[] fileName, IFileInfo info); /** * Returns <code>true</code> if the underlying file system API supports Unicode, * <code>false</code> otherwise. */ private static final native boolean internalIsUnicode(); /** Set the extended attributes specified in the IResource attribute. Only attributes * that the platform supports will be set. */ private static final native boolean internalSetFileInfo(byte[] fileName, IFileInfo attribute); /** Set the extended attributes specified in the IResource attribute object. Only * attributes that the platform supports will be set. (Unicode version - should not * be called if <code>isUnicode</code> is <code>false</code>). */ private static final native boolean internalSetFileInfoW(char[] fileName, IFileInfo attribute, int options); /** * @param fileName * @param info * @param options */ public static boolean putFileInfo(String fileName, IFileInfo info, int options) { if (isUnicode) return internalSetFileInfoW(Convert.toPlatformChars(fileName), info, options); return internalSetFileInfo(Convert.toPlatformBytes(fileName), info); } /** * Return <code>true</code> if we have found the core library and are using it for * our file-system calls, and <code>false</code> otherwise. * @return <code>true</code> if native library is available, and <code>false</code> * otherwise. */ public static boolean isUsingNatives() { return hasNatives; } }