2 * Copyright (C) 2008 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org
.spearce
.jgit
.util
;
20 import java
.security
.AccessController
;
21 import java
.security
.PrivilegedAction
;
23 /** Abstraction to support various file system operations not in Java. */
24 public abstract class FS
{
25 /** The implementation selected for this operating system and JRE. */
26 public static final FS INSTANCE
;
29 if (FS_Win32
.detect()) {
30 if (FS_Win32_Cygwin
.detect())
31 INSTANCE
= new FS_Win32_Cygwin();
33 INSTANCE
= new FS_Win32();
34 } else if (FS_POSIX_Java6
.detect())
35 INSTANCE
= new FS_POSIX_Java6();
37 INSTANCE
= new FS_POSIX_Java5();
41 * Does this operating system and JRE support the execute flag on files?
43 * @return true if this implementation can provide reasonably accurate
44 * executable bit information; false otherwise.
46 public abstract boolean supportsExecute();
49 * Determine if the file is executable (or not).
51 * Not all platforms and JREs support executable flags on files. If the
52 * feature is unsupported this method will always return false.
55 * abstract path to test.
56 * @return true if the file is believed to be executable by the user.
58 public abstract boolean canExecute(File f
);
61 * Set a file to be executable by the user.
63 * Not all platforms and JREs support executable flags on files. If the
64 * feature is unsupported this method will always return false and no
65 * changes will be made to the file specified.
68 * path to modify the executable status of.
70 * true to enable execution; false to disable it.
71 * @return true if the change succeeded; false otherwise.
73 public abstract boolean setExecute(File f
, boolean canExec
);
76 * Resolve this file to its actual path name that the JRE can use.
78 * This method can be relatively expensive. Computing a translation may
79 * require forking an external process per path name translated. Callers
80 * should try to minimize the number of translations necessary by caching
83 * Not all platforms and JREs require path name translation. Currently only
84 * Cygwin on Win32 require translation for Cygwin based paths.
87 * directory relative to which the path name is.
89 * path name to translate.
90 * @return the translated path. <code>new File(dir,name)</code> if this
91 * platform does not require path name translation.
93 public static File
resolve(final File dir
, final String name
) {
94 return INSTANCE
.resolveImpl(dir
, name
);
98 * Resolve this file to its actual path name that the JRE can use.
100 * This method can be relatively expensive. Computing a translation may
101 * require forking an external process per path name translated. Callers
102 * should try to minimize the number of translations necessary by caching
105 * Not all platforms and JREs require path name translation. Currently only
106 * Cygwin on Win32 require translation for Cygwin based paths.
109 * directory relative to which the path name is.
111 * path name to translate.
112 * @return the translated path. <code>new File(dir,name)</code> if this
113 * platform does not require path name translation.
115 protected File
resolveImpl(final File dir
, final String name
) {
116 final File abspn
= new File(name
);
117 if (abspn
.isAbsolute())
119 return new File(dir
, name
);
123 * Determine the user's home directory (location where preferences are).
125 * This method can be expensive on the first invocation if path name
126 * translation is required. Subsequent invocations return a cached result.
128 * Not all platforms and JREs require path name translation. Currently only
129 * Cygwin on Win32 requires translation of the Cygwin HOME directory.
131 * @return the user's home directory; null if the user does not have one.
133 public static File
userHome() {
134 return USER_HOME
.home
;
137 private static class USER_HOME
{
138 static final File home
= INSTANCE
.userHomeImpl();
142 * Determine the user's home directory (location where preferences are).
144 * @return the user's home directory; null if the user does not have one.
146 protected File
userHomeImpl() {
147 final String home
= AccessController
148 .doPrivileged(new PrivilegedAction
<String
>() {
149 public String
run() {
150 return System
.getProperty("user.home");
153 if (home
== null || home
.length() == 0)
155 return new File(home
).getAbsoluteFile();