KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > localstore > CoreFileSystemLibrary


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Red Hat Incorporated - get/setResourceAttribute code
11  *******************************************************************************/

12 package org.eclipse.core.internal.localstore;
13
14 import java.io.File JavaDoc;
15 import org.eclipse.core.internal.resources.ResourceException;
16 import org.eclipse.core.internal.resources.ResourceStatus;
17 import org.eclipse.core.internal.utils.Convert;
18 import org.eclipse.core.internal.utils.Messages;
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.runtime.*;
21 import org.eclipse.osgi.util.NLS;
22
23 public abstract class CoreFileSystemLibrary {
24
25     /** Indicates whether or not this FS is case sensitive */
26     private static final boolean caseSensitive = Platform.OS_MACOSX.equals(Platform.getOS()) ? false : new File JavaDoc("a").compareTo(new File JavaDoc("A")) != 0; //$NON-NLS-1$ //$NON-NLS-2$
27
private static boolean hasNatives = false;
28     private static boolean isUnicode = false;
29
30     /** instance of this library */
31     // The name convention is to get the plugin version at the time
32
// the library is changed.
33
private static final String JavaDoc LIBRARY_NAME = "core_3_1_0"; //$NON-NLS-1$
34

35     private static boolean loggedFailedGetAttributes = false;
36
37     /**
38      * The following masks are used to represent the bits
39      * returned by the getStat() and internalGetStat() methods.
40      * The idea is to save JNI calls. So internalGetStat() is a native
41      * that grabs as much important information as it can and puts it in
42      * a long variable.
43      * The lower bits represent the last modified timestamp of the
44      * given file and the higher bits represent some relevant flags.
45      */

46
47     /** indicates if the resource is a folder or a file */
48     private static final long STAT_FOLDER = 0x2000000000000000l;
49     /** indicates if the resource is marked as read-only */
50     private static final long STAT_READ_ONLY = 0x1000000000000000l;
51     /** reserved, should not be used */
52     private static final long STAT_RESERVED = 0x8000000000000000l;
53     /** indicates if this is a valid stat or some problem happened when
54      retrieving the information */

55     private static final long STAT_VALID = 0x4000000000000000l;
56     /** used to extract the last modified timestamp */
57     private static final long STAT_LASTMODIFIED = ~(STAT_RESERVED | STAT_VALID | STAT_FOLDER | STAT_READ_ONLY);
58
59     static {
60         try {
61             System.loadLibrary(LIBRARY_NAME);
62             hasNatives = true;
63             isUnicode = internalIsUnicode();
64         } catch (UnsatisfiedLinkError JavaDoc e) {
65             logMissingNativeLibrary(e);
66         }
67     }
68
69     /**
70      * Copies file attributes from source to destination. The copyLastModified attribute
71      * indicates whether the lastModified attribute should be copied.
72      */

73     public static boolean copyAttributes(String JavaDoc source, String JavaDoc destination, boolean copyLastModified) {
74         if (hasNatives)
75             // Note that support for copying last modified info is not implemented on Windows
76
return isUnicode ? internalCopyAttributesW(source.toCharArray(), destination.toCharArray(), copyLastModified) : internalCopyAttributes(Convert.toPlatformBytes(source), Convert.toPlatformBytes(destination), copyLastModified);
77         return false; // not supported
78
}
79
80     public static long getLastModified(long stat) {
81         return (stat & STAT_LASTMODIFIED);
82     }
83
84     public static long getLastModified(String JavaDoc fileName) {
85         if (hasNatives)
86             return getLastModified(getStat(fileName));
87
88         // inlined (no native) implementation
89
return new File JavaDoc(fileName).lastModified();
90     }
91
92     public static ResourceAttributes getResourceAttributes(String JavaDoc fileName) {
93         try {
94             ResourceAttributes attributes = new ResourceAttributes();
95             if (!hasNatives) {
96                 //non-native implementation
97
attributes.setReadOnly(isReadOnly(fileName));
98                 return attributes;
99             }
100             //ensure we return null on failure
101
if (isUnicode ? internalGetResourceAttributesW(fileName.toCharArray(), attributes) : internalGetResourceAttributes(Convert.toPlatformBytes(fileName), attributes))
102                 return attributes;
103         } catch (UnsatisfiedLinkError JavaDoc e) {
104             if (!loggedFailedGetAttributes) {
105                 loggedFailedGetAttributes = true;
106                 String JavaDoc message = NLS.bind(Messages.resources_getResourceAttributesFailed, fileName);
107                 ResourceStatus status = new ResourceStatus(IStatus.INFO, new Path(fileName), message);
108                 ResourcesPlugin.getPlugin().getLog().log(status);
109             }
110         }
111         return null;
112     }
113
114     public static long getStat(String JavaDoc fileName) {
115         if (hasNatives)
116             return isUnicode ? internalGetStatW(fileName.toCharArray()) : internalGetStat(Convert.toPlatformBytes(fileName));
117
118         // inlined (no native) implementation
119
File JavaDoc target = new File JavaDoc(fileName);
120         long result = target.lastModified();
121         if (result == 0) // non-existing
122
return result;
123         result |= STAT_VALID;
124         if (target.isDirectory())
125             result |= STAT_FOLDER;
126         if (!(new File JavaDoc(fileName).canWrite()))
127             result |= STAT_READ_ONLY;
128         return result;
129     }
130
131     /**
132      * Copies file attributes from source to destination. The copyLastModified attribute
133      * indicates whether the lastModified attribute should be copied.
134      */

135     private static final native boolean internalCopyAttributes(byte[] source, byte[] destination, boolean copyLastModified);
136
137     /**
138      * Copies file attributes from source to destination. The copyLastModified attribute
139      * indicates whether the lastModified attribute should be copied (Unicode
140      * version - should not be called if <code>isUnicode</code> is
141      * <code>false</code>).
142      */

143     private static final native boolean internalCopyAttributesW(char[] source, char[] destination, boolean copyLastModified);
144
145     /** Put the extended attributes that the platform supports in the IResource attributes object. Attributes
146      * that are not supported by the platform will not be set and will remain the default value (<code>false</code>). */

147     private static final native boolean internalGetResourceAttributes(byte[] fileName, ResourceAttributes attribute);
148
149     /** Put the extended attributes that the platform supports in the IResource attributes object. Attributes
150      * that are not supported by the platform will not be set and will remain null (the default).
151      * (Unicode version - should not be called if <code>isUnicode</code> is <code>false</code>). */

152     private static final native boolean internalGetResourceAttributesW(char[] fileName, ResourceAttributes attribute);
153
154     /**
155      * Returns the stat information for the specified filename in a long (64 bits). We just
156      * retrieve the stat information we consider necessary and store everything in one long
157      * to save some JNI calls (standard version)
158      */

159     private static final native long internalGetStat(byte[] fileName);
160
161     /**
162      * Returns the stat information for the specified filename in a long (64 bits). We just
163      * retrieve the stat information we consider necessary and store everything in one long
164      * to save some JNI calls (Unicode version - should not be called if <code>isUnicode</code>
165      * is <code>false</code>).
166      */

167     private static final native long internalGetStatW(char[] fileName);
168
169     /**
170      * Returns <code>true</code> if the underlying file system API supports Unicode,
171      * <code>false</code> otherwise.
172      */

173     private static final native boolean internalIsUnicode();
174
175     /** Set the extended attributes specified in the IResource attribute. Only attributes
176      * that the platform supports will be set. */

177     private static final native boolean internalSetResourceAttributes(byte[] fileName, ResourceAttributes attribute);
178
179     /** Set the extended attributes specified in the IResource attribute object. Only
180      * attributes that the platform supports will be set. (Unicode version - should not
181      * be called if <code>isUnicode</code> is <code>false</code>). */

182     private static final native boolean internalSetResourceAttributesW(char[] fileName, ResourceAttributes attribute);
183
184     public static boolean isCaseSensitive() {
185         return caseSensitive;
186     }
187
188     public static boolean isFile(long stat) {
189         return isSet(stat, STAT_VALID) && !isSet(stat, STAT_FOLDER);
190     }
191
192     public static boolean isFolder(long stat) {
193         return isSet(stat, STAT_VALID) && isSet(stat, STAT_FOLDER);
194     }
195
196     public static boolean isReadOnly(String JavaDoc fileName) {
197         // Use the same implementation whether or not we are using
198
// the natives. If the file doesn't exist then getStat() will return 0
199
// and this method will return false.
200
return isSet(getStat(fileName), STAT_READ_ONLY);
201     }
202
203     public static boolean isReadOnly(long stat) {
204         return isSet(stat, STAT_READ_ONLY);
205     }
206
207     private static boolean isSet(long stat, long mask) {
208         return (stat & mask) != 0;
209     }
210
211     private static void logMissingNativeLibrary(UnsatisfiedLinkError JavaDoc e) {
212         String JavaDoc libName = System.mapLibraryName(LIBRARY_NAME);
213         String JavaDoc message = NLS.bind(Messages.localstore_couldNotLoadLibrary, libName);
214         ResourceStatus status = new ResourceStatus(IStatus.INFO, null, message, null);
215         ResourcesPlugin.getPlugin().getLog().log(status);
216     }
217
218     public static boolean setReadOnly(String JavaDoc fileName, boolean readonly) {
219         ResourceAttributes attributes = getResourceAttributes(fileName);
220         if (attributes == null)
221             return false;
222         attributes.setReadOnly(readonly);
223         try {
224             setResourceAttributes(fileName, attributes);
225         } catch (CoreException e) {
226             //spec of setReadOnly doesn't throw exceptions on failure
227
return false;
228         }
229         return true;
230     }
231
232     public static void setResourceAttributes(String JavaDoc fileName, ResourceAttributes attributes) throws CoreException {
233         if (!hasNatives) {
234             //do nothing if there are no natives
235
return;
236         }
237         if (isUnicode ? internalSetResourceAttributesW(fileName.toCharArray(), attributes) : internalSetResourceAttributes(Convert.toPlatformBytes(fileName), attributes))
238             return;
239         String JavaDoc message = NLS.bind(Messages.resources_setResourceAttributesFailed, fileName);
240         throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, new Path(fileName), message, null);
241     }
242
243     /**
244      * Return <code>true</code> if we have found the core library and are using it for
245      * our file-system calls, and <code>false</code> otherwise.
246      */

247     public static boolean usingNatives() {
248         return hasNatives;
249     }
250 }
251
Popular Tags