[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[egit-dev] [JGit-io-RFC-PATCH v2 3/4] Incorporate current FileSystem Util implementations to the SPI
|
From: Imran M Yousuf <imyousuf@xxxxxxxxxxxxxxxxxxxxxx>
Operations such as setting executable bits if supported and resolving
relative path is incorporated with this change, as a result now it should
be possible to completely replace the currently being used util FS and
java.io.File.
Signed-off-by: Imran M Yousuf <imyousuf@xxxxxxxxxxxxxxxxxxxxxx>
---
.../src/org/eclipse/jgit/io/Entry.java | 35 ++++-
.../src/org/eclipse/jgit/io/StorageSystem.java | 16 ++
.../eclipse/jgit/io/localfs/LocalFileEntry.java | 52 ++++++-
.../eclipse/jgit/io/localfs/LocalFileSystem.java | 159 ++++++++++++++++++++
4 files changed, 257 insertions(+), 5 deletions(-)
diff --git a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/Entry.java b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/Entry.java
index cd69172..5256815 100644
--- a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/Entry.java
+++ b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/Entry.java
@@ -78,6 +78,24 @@
public boolean isExists();
/**
+ * Does this operating system and JRE support the execute flag on entries?
+ *
+ * @return true if this implementation can provide reasonably accurate
+ * executable bit information; false otherwise.
+ */
+ public boolean isExecutableSupported();
+
+ /**
+ * Determine if the entry is executable (or not).
+ * <p>
+ * Not all platforms and JREs support executable flags on entries. If the
+ * feature is unsupported this method will always return false.
+ *
+ * @return true if the entry is believed to be executable by the user.
+ */
+ public boolean isExecutable();
+
+ /**
* Make directories upto the entry represented by this instance, provided
* that this instance itself is a directory.
* @return True if directories were created.
@@ -85,6 +103,19 @@
public boolean mkdirs();
/**
+ * Set an entry to be executable by the user.
+ * <p>
+ * Not all platforms and JREs support executable flags on entries. If the
+ * feature is unsupported this method will always return false and no
+ * changes will be made to the entry specified.
+ *
+ * @param executable
+ * true to enable execution; false to disable it.
+ * @return true if the change succeeded; false otherwise.
+ */
+ public boolean setExecutable(boolean executable);
+
+ /**
* Retrieves the URI of this entry. URI in this case acts as a primary key
* to identify an entry.
* @return URI to identify this entry instance
@@ -101,7 +132,7 @@
/**
* Retrieves the InputStream for reading the content of the entry
* @return Input stream to read entry content
- * @throws IOException If no such file exists or there is any other error
+ * @throws IOException If no such entry exists or there is any other error
*/
public InputStream getInputStream()
throws IOException;
@@ -111,7 +142,7 @@ public InputStream getInputStream()
* opened to either overwrite it or append to it.
* @param overwrite False if to write in append mode else true
* @return Output stream to write content to
- * @throws IOException If no such file exists in append mode or there is any
+ * @throws IOException If no such entry exists in append mode or there is any
* error in retrieving it.
*/
public OutputStream getOutputStream(boolean overwrite)
diff --git a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/StorageSystem.java b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/StorageSystem.java
index 9f45cb3..15af614 100644
--- a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/StorageSystem.java
+++ b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/StorageSystem.java
@@ -65,4 +65,20 @@
* @return Entry for current working directory.
*/
public Entry getWorkingDirectory();
+
+ /**
+ * Retrieve the home directory of the current user
+ * @return Home directory
+ */
+ public Entry getHomeDirectory();
+
+ /**
+ * Resolve relative path with respect to a path and return the absolute
+ * entry representing the relative path.
+ * @param entry The point of reference for the relative path
+ * @param path The relative path
+ * @return The absolute entry representing the relative path entry
+ */
+ public Entry resolve(Entry entry,
+ String path);
}
diff --git a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileEntry.java b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileEntry.java
index 99df831..4ef3076 100644
--- a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileEntry.java
+++ b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileEntry.java
@@ -43,6 +43,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import org.eclipse.jgit.io.Entry;
import org.eclipse.jgit.io.StorageSystem;
@@ -60,7 +61,7 @@
implements Entry {
private File localFile;
- private StorageSystem storageSystem;
+ private LocalFileSystem storageSystem;
/**
* Contructs an entry based of on the local file system storage and a file
@@ -70,7 +71,7 @@
* @throws IllegalArgumentException If either argument is NULL
*/
protected LocalFileEntry(File localFile,
- StorageSystem storageSystem)
+ LocalFileSystem storageSystem)
throws IllegalArgumentException {
setLocalFile(localFile);
setStorageSystem(storageSystem);
@@ -81,7 +82,7 @@ protected LocalFileEntry(File localFile,
* @param storageSystem Storage system
* @throws IllegalArgumentException IF storageSystem is null
*/
- protected void setStorageSystem(StorageSystem storageSystem)
+ protected void setStorageSystem(LocalFileSystem storageSystem)
throws IllegalArgumentException {
if (storageSystem == null) {
throw new IllegalArgumentException("Storage system can't be NULL!");
@@ -216,4 +217,49 @@ public StorageSystem getStorageSystem() {
public long length() {
return getLocalFile().length();
}
+
+ public boolean isExecutableSupported() {
+ return LocalFileSystem.platform.isExecutableSupproted();
+ }
+
+ public boolean isExecutable() {
+ if (LocalFileSystem.platform.isExecutableSupproted()) {
+ try {
+ final Object r = LocalFileSystem.canExecute.invoke(
+ getLocalFile(),
+ (Object[]) null);
+ return ((Boolean) r).booleanValue();
+ }
+ catch (IllegalArgumentException e) {
+ throw new Error(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new Error(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new Error(e);
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ public boolean setExecutable(boolean executable) {
+ try {
+ final Object r;
+ r = LocalFileSystem.setExecute.invoke(getLocalFile(), new Object[] {
+ Boolean.valueOf(executable)});
+ return ((Boolean) r).booleanValue();
+ }
+ catch (IllegalArgumentException e) {
+ throw new Error(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new Error(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new Error(e);
+ }
+ }
}
diff --git a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileSystem.java b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileSystem.java
index d0cb536..7cef2d8 100644
--- a/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileSystem.java
+++ b/org.eclipse.jgit.io/src/org/eclipse/jgit/io/localfs/LocalFileSystem.java
@@ -36,8 +36,14 @@
*/
package org.eclipse.jgit.io.localfs;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
import java.net.URI;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import org.eclipse.jgit.io.Entry;
import org.eclipse.jgit.io.StorageSystem;
@@ -50,6 +56,14 @@
implements StorageSystem {
public static final String PROTOCOL_FILE = "file";
+ public static final Platform platform;
+ public static Method canExecute;
+ public static Method setExecute;
+ public static String cygpath;
+
+ static {
+ platform = Platform.detect();
+ }
public String getURIScheme() {
return PROTOCOL_FILE;
@@ -68,4 +82,149 @@ public Entry getWorkingDirectory() {
String curDir = System.getProperty("user.dir");
return new LocalFileEntry(new File(curDir), this);
}
+
+ public Entry resolve(Entry entry,
+ String path) {
+ if (!(entry instanceof LocalFileEntry)) {
+ return null;
+ }
+ LocalFileEntry fileEntry = (LocalFileEntry) entry;
+ File localFile = fileEntry.getLocalFile();
+ if (platform.equals(Platform.WIN32_CYGWIN)) {
+ try {
+ final Process p;
+
+ p = Runtime.getRuntime().exec(
+ new String[] {cygpath, "--windows", "--absolute", path},
+ null, localFile);
+ p.getOutputStream().close();
+
+ final BufferedReader lineRead = new BufferedReader(
+ new InputStreamReader(p.getInputStream(), "UTF-8"));
+ String r = null;
+ try {
+ r = lineRead.readLine();
+ }
+ finally {
+ lineRead.close();
+ }
+
+ for (;;) {
+ try {
+ if (p.waitFor() == 0 && r != null && r.length() > 0) {
+ return new LocalFileEntry(new File(r), this);
+ }
+ break;
+ }
+ catch (InterruptedException ie) {
+ // Stop bothering me, I have a zombie to reap.
+ }
+ }
+ }
+ catch (IOException ioe) {
+ // Fall through and use the default return.
+ }
+
+ }
+ final File abspn = new File(path);
+ if (abspn.isAbsolute()) {
+ return new LocalFileEntry(abspn, this);
+ }
+ return new LocalFileEntry(new File(localFile, path), this);
+ }
+
+ public Entry getHomeDirectory() {
+ if (platform.equals(Platform.WIN32_CYGWIN)) {
+ final String home = AccessController.doPrivileged(new PrivilegedAction<String>() {
+
+ public String run() {
+ return System.getenv("HOME");
+ }
+ });
+ if (!(home == null || home.length() == 0)) {
+ return resolve(new LocalFileEntry(new File("."), this), home);
+ }
+ }
+ final String home = AccessController.doPrivileged(new PrivilegedAction<String>() {
+
+ public String run() {
+ return System.getProperty("user.home");
+ }
+ });
+ if (home == null || home.length() == 0) {
+ return null;
+ }
+ return new LocalFileEntry(new File(home).getAbsoluteFile(), this);
+ }
+
+ public enum Platform {
+
+ WIN32_CYGWIN(false),
+ WIN32(false),
+ POSIX_JAVA5(false),
+ POSIX_JAVA6(true);
+ private boolean executableSupproted;
+
+ private Platform(boolean executableSupproted) {
+ this.executableSupproted = executableSupproted;
+ }
+
+ public boolean isExecutableSupproted() {
+ return executableSupproted;
+ }
+
+ public static Platform detect() {
+ final String osDotName = AccessController.doPrivileged(new PrivilegedAction<String>() {
+
+ public String run() {
+ return System.getProperty("os.name");
+ }
+ });
+ if (osDotName != null &&
+ osDotName.toLowerCase().indexOf("windows") != -1) {
+ final String path = AccessController.doPrivileged(new PrivilegedAction<String>() {
+
+ public String run() {
+ return System.getProperty("java.library.path");
+ }
+ });
+ if (path == null) {
+ return WIN32;
+ }
+ for (final String p : path.split(";")) {
+ final File e = new File(p, "cygpath.exe");
+ if (e.isFile()) {
+ cygpath = e.getAbsolutePath();
+ return WIN32_CYGWIN;
+ }
+ }
+ return WIN32;
+ }
+ else {
+ canExecute = needMethod(File.class, "canExecute");
+ setExecute = needMethod(File.class, "setExecutable",
+ Boolean.TYPE);
+ if (canExecute != null && setExecute != null) {
+ return POSIX_JAVA6;
+ }
+ else {
+ return POSIX_JAVA5;
+ }
+ }
+ }
+
+ private static Method needMethod(final Class<?> on,
+ final String name,
+ final Class<?>... args) {
+ try {
+ return on.getMethod(name, args);
+ }
+ catch (SecurityException e) {
+ return null;
+ }
+ catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+ }
}
--
1.6.2.1