Skip to content

Commit

Permalink
Merge with jruby-1_7
Browse files Browse the repository at this point in the history
  • Loading branch information
enebo committed Mar 3, 2014
2 parents 79f2a0d + cde69f8 commit 7a58e62
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 80 deletions.
93 changes: 20 additions & 73 deletions core/src/main/java/org/jruby/RubyDir.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
Expand All @@ -61,6 +59,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.Dir;
import org.jruby.util.FileResource;
import org.jruby.util.JRubyFile;
import org.jruby.util.ByteList;

Expand All @@ -72,7 +71,7 @@
@JRubyClass(name = "Dir", include = "Enumerable")
public class RubyDir extends RubyObject {
private RubyString path; // What we passed to the constructor for method 'path'
protected JRubyFile dir;
protected FileResource dir;
private long lastModified = Long.MIN_VALUE;
private String[] snapshot; // snapshot of contents of directory
private int pos; // current position in directory
Expand Down Expand Up @@ -115,8 +114,6 @@ private void update() {
if (snapshot == null || dir.exists() && dir.lastModified() > lastModified) {
lastModified = dir.lastModified();
List<String> snapshotList = new ArrayList<String>();
snapshotList.add(".");
snapshotList.add("..");
snapshotList.addAll(getContents(dir));
snapshot = (String[]) snapshotList.toArray(new String[snapshotList.size()]);
}
Expand All @@ -129,24 +126,24 @@ private void update() {
* <code>Dir</code> object returned, so a new <code>Dir</code> instance
* must be created to reflect changes to the underlying file system.
*/
public IRubyObject initialize(IRubyObject arg) {
return initialize19(arg);
public IRubyObject initialize(ThreadContext context, IRubyObject arg) {
return initialize19(context, arg);
}

@JRubyMethod(name = "initialize")
public IRubyObject initialize19(IRubyObject arg) {
public IRubyObject initialize19(ThreadContext context, IRubyObject arg) {
RubyString newPath = RubyFile.get_path(getRuntime().getCurrentContext(), arg).convertToString();
path = newPath;
pos = 0;

String adjustedPath = RubyFile.adjustRootPathOnWindows(getRuntime(), newPath.toString(), null);
String adjustedPath = RubyFile.adjustRootPathOnWindows(context.runtime, newPath.toString(), null);
checkDirIsTwoSlashesOnWindows(getRuntime(), adjustedPath);

dir = JRubyFile.create(getRuntime().getCurrentDirectory(), adjustedPath);
List<String> snapshotList = RubyDir.getEntries(getRuntime(), adjustedPath);
dir = JRubyFile.createResource(context, adjustedPath);
List<String> snapshotList = RubyDir.getEntries(context, adjustedPath);
snapshot = (String[]) snapshotList.toArray(new String[snapshotList.size()]);

return this;
return this;
}

// ----- Ruby Class Methods ----------------------------------------------------
Expand Down Expand Up @@ -254,80 +251,32 @@ public static RubyArray entries(IRubyObject recv, IRubyObject path) {

@JRubyMethod(name = "entries", meta = true)
public static RubyArray entries19(ThreadContext context, IRubyObject recv, IRubyObject arg) {
return entriesCommon(context.runtime, RubyFile.get_path(context, arg).asJavaString());
return entriesCommon(context, RubyFile.get_path(context, arg).asJavaString());
}

@JRubyMethod(name = "entries", meta = true)
public static RubyArray entries19(ThreadContext context, IRubyObject recv, IRubyObject arg, IRubyObject opts) {
// FIXME: do something with opts
return entriesCommon(context.runtime, RubyFile.get_path(context, arg).asJavaString());
return entriesCommon(context, RubyFile.get_path(context, arg).asJavaString());
}

private static RubyArray entriesCommon(Ruby runtime, String path) {
private static RubyArray entriesCommon(ThreadContext context, String path) {
Ruby runtime = context.runtime;
String adjustedPath = RubyFile.adjustRootPathOnWindows(runtime, path, null);
checkDirIsTwoSlashesOnWindows(runtime, adjustedPath);

Object[] files = getEntries(runtime, adjustedPath).toArray();
Object[] files = getEntries(context, adjustedPath).toArray();
return runtime.newArrayNoCopy(JavaUtil.convertJavaArrayToRuby(runtime, files));
}

private static List<String> getEntries(Ruby runtime, String path) {
if (!RubyFileTest.directory_p(runtime, RubyString.newString(runtime, path)).isTrue()) {
throw runtime.newErrnoENOENTError("No such directory: " + path);
private static List<String> getEntries(ThreadContext context, String path) {
if (!RubyFileTest.directory_p(context.runtime, RubyString.newString(context.runtime, path)).isTrue()) {
throw context.runtime.newErrnoENOENTError("No such directory: " + path);
}

if (path.startsWith("jar:")) path = path.substring(4);
if (path.startsWith("file:")) return entriesIntoAJarFile(runtime, path);

return entriesIntoADirectory(runtime, path);
}

private static List<String> entriesIntoADirectory(Ruby runtime, String path) {
final JRubyFile directory = JRubyFile.create(runtime.getCurrentDirectory(), path);
FileResource directory = JRubyFile.createResource(context, path);

List<String> fileList = getContents(directory);
fileList.add(0, ".");
fileList.add(1, "..");
return fileList;
}

private static List<String> entriesIntoAJarFile(Ruby runtime, String path) {
String file = path.substring(5);
int bang = file.indexOf('!');
if (bang == -1) {
return entriesIntoADirectory(runtime, path.substring(5));
}
if (bang == file.length() - 1) {
file = file + "/";
}
String jar = file.substring(0, bang);
String after = file.substring(bang + 2);
if (after.length() > 0 && after.charAt(after.length() - 1) != '/') {
after = after + "/";
}
JarFile jf;
try {
jf = new JarFile(jar);
} catch (IOException e) {
throw new RuntimeException("Valid JAR file expected", e);
}

List<String> fileList = new ArrayList<String>();
Enumeration<? extends ZipEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
String zipEntry = entries.nextElement().getName();
if (zipEntry.matches(after + "[^/]+(/.*)?")) {
int end_index = zipEntry.indexOf('/', after.length());
if (end_index == -1) {
end_index = zipEntry.length();
}
String entry_str = zipEntry.substring(after.length(), end_index);
if (!fileList.contains(entry_str)) {
fileList.add(entry_str);
}
}
}

return fileList;
}

Expand Down Expand Up @@ -657,7 +606,6 @@ public static IRubyObject exists_p(ThreadContext context, IRubyObject recv, IRub
*
* @param path path for which to return the <code>File</code> object.
* @param mustExist is true the directory must exist. If false it must not.
* @throws IOError if <code>path</code> is not a directory.
*/
protected static JRubyFile getDir(final Ruby runtime, final String path, final boolean mustExist) {
String dir = dirFromPath(path, runtime);
Expand Down Expand Up @@ -685,7 +633,6 @@ protected static JRubyFile getDir(final Ruby runtime, final String path, final b
* Similar to getDir, but performs different checks to match rmdir behavior.
* @param runtime
* @param path
* @param mustExist
* @return
*/
protected static JRubyFile getDirForRmdir(final Ruby runtime, final String path) {
Expand Down Expand Up @@ -729,7 +676,7 @@ private static String dirFromPath(final String path, final Ruby runtime) throws
* Returns the contents of the specified <code>directory</code> as an
* <code>ArrayList</code> containing the names of the files as Java Strings.
*/
protected static List<String> getContents(File directory) {
protected static List<String> getContents(FileResource directory) {
String[] contents = directory.list();
List<String> result = new ArrayList<String>();

Expand All @@ -744,7 +691,7 @@ protected static List<String> getContents(File directory) {
* Returns the contents of the specified <code>directory</code> as an
* <code>ArrayList</code> containing the names of the files as Ruby Strings.
*/
protected static List<RubyString> getContents(File directory, Ruby runtime) {
protected static List<RubyString> getContents(FileResource directory, Ruby runtime) {
List<RubyString> result = new ArrayList<RubyString>();
String[] contents = directory.list();

Expand Down
7 changes: 1 addition & 6 deletions core/src/main/java/org/jruby/util/Dir.java
Original file line number Diff line number Diff line change
Expand Up @@ -553,12 +553,7 @@ private static String[] files(FileResource directory) {
String[] files = directory.list();

if (files != null) {
String[] filesPlusDotFiles = new String[files.length + 2];
System.arraycopy(files, 0, filesPlusDotFiles, 2, files.length);
filesPlusDotFiles[0] = ".";
filesPlusDotFiles[1] = "..";

return filesPlusDotFiles;
return files;
} else {
return new String[0];
}
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/util/JRubyFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

import org.jruby.Ruby;
import org.jruby.RubyFile;
import org.jruby.runtime.ThreadContext;

import jnr.posix.JavaSecuredFile;
import org.jruby.platform.Platform;
Expand All @@ -57,6 +58,10 @@ public static JRubyFile create(String cwd, String pathname) {
return createNoUnicodeConversion(cwd, pathname);
}

public static FileResource createResource(ThreadContext context, String pathname) {
return createResource(context.runtime, pathname);
}

public static FileResource createResource(Ruby runtime, String pathname) {
return createResource(runtime.getCurrentDirectory(), pathname);
}
Expand All @@ -73,6 +78,9 @@ public static FileResource createResource(String cwd, String pathname) {
return jarResource;
}

if (pathname.startsWith("file:")) {
pathname = pathname.substring(5);
}
return new RegularFileResource(create(cwd, pathname));
}

Expand Down
16 changes: 15 additions & 1 deletion core/src/main/java/org/jruby/util/RegularFileResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,21 @@ public boolean canWrite() {

@Override
public String[] list() {
return file.list();
String[] fileList = file.list();

if (fileList != null) {
// If we got some entries, then it's probably a directory and in Ruby all file
// directories should have '.' and '..' entries
String[] list = new String[fileList.length + 2];
list[0] = ".";
list[1] = "..";
for (int i = 0; i < fileList.length; i++) {
list[i+2] = fileList[i];
}
fileList = list;
}

return fileList;
}

@Override
Expand Down

0 comments on commit 7a58e62

Please sign in to comment.