Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2004-2005, 2009 Charles O Nutter <headius@headius.com> Copyright (C) 2004 Thomas E Enebo <enebo@acm.org> Copyright (C) 2004 Jan Arne Petersen <jpetersen@uni-bonn.de> Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 package org.jruby;
 
 import static org.jruby.RubyFile.get_path;
 import static org.jruby.RubyFile.file;
 
 
 
 @JRubyModule(name = "FileTest")
 public class RubyFileTest {
 
     public static RubyModule createFileTestModule(Ruby runtime) {
         RubyModule fileTestModule = runtime.defineModule("FileTest");
         runtime.setFileTest(fileTestModule);
 
         fileTestModule.defineAnnotatedMethods(RubyFileTest.class);
 
         return fileTestModule;
     }
 
     @JRubyMethod(name = "blockdev?", required = 1, module = true)
     public static IRubyObject blockdev_p(IRubyObject recvIRubyObject filename) {
         Ruby runtime = recv.getRuntime();
         JRubyFile file = file(filename);
 
         return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isBlockDev());
     }
 
     @JRubyMethod(name = "chardev?", required = 1, module = true)
     public static IRubyObject chardev_p(IRubyObject recvIRubyObject filename) {
         Ruby runtime = recv.getRuntime();
         JRubyFile file = file(filename);
 
         return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isCharDev());
     }
 
     public static IRubyObject directory_p(IRubyObject recvIRubyObject filename) {
         return directory_p(recv.getRuntime().getCurrentContext(), recvfilename);
     }
 
     public static IRubyObject directory_p(Ruby rubyIRubyObject filename) {
         return directory_p(ruby.getCurrentContext(), filename);
     }
 
     @JRubyMethod(name = "directory?", required = 1, module = true)
     public static IRubyObject directory_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
         return directory_p(contextfilename);
     }
 
     public static IRubyObject directory_p(ThreadContext contextIRubyObject filename) {
         Ruby runtime = context.runtime;
         if (!(filename instanceof RubyFile)) {
             filename = get_path(contextfilename);
         }
 
         ZipEntry entry = file_in_archive(filename);
         if (entry != null) {
             return entry.isDirectory() ? runtime.getTrue() : runtime.getFalse();
         }
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isDirectory());
    }
    @JRubyMethod(name = "executable?", required = 1, module = true)
    public static IRubyObject executable_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isExecutable());
    }
    @JRubyMethod(name = "executable_real?", required = 1, module = true)
    public static IRubyObject executable_real_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isExecutableReal());
    }
    public static IRubyObject exist_p(IRubyObject recvIRubyObject filename) {
        return exist_p(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    @JRubyMethod(name = {"exist?""exists?"}, required = 1, module = true)
    public static IRubyObject exist_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = context.runtime;
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        
        if (existsOnClasspath(filename)) {
            return runtime.getTrue();
        }
        if (Ruby.isSecurityRestricted()) {
            return runtime.getFalse();
        }
        if (file_in_archive(filename) != null) {
            return runtime.getTrue();
        }
        return runtime.newBoolean(file(filename).exists());
    }
    public static RubyBoolean file_p(IRubyObject recvIRubyObject filename) {
        return file_p(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    @JRubyMethod(name = "file?", required = 1, module = true)
    public static RubyBoolean file_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = context.runtime;
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        
        ZipEntry entry = file_in_archive(filename);
        if (entry != null) {
            return entry.isDirectory() ?
                recv.getRuntime().getFalse() :
                recv.getRuntime().getTrue();
        }
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && file.isFile());
    }
    @JRubyMethod(name = "grpowned?", required = 1, module = true)
    public static IRubyObject grpowned_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        // JRUBY-4446, grpowned? always returns false on Windows
        if (.) {
            return runtime.getFalse();
        }
        
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isGroupOwned());
    }
    @JRubyMethod(name = "identical?", required = 2, module = true)
    public static IRubyObject identical_p(IRubyObject recvIRubyObject filename1IRubyObject filename2) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file1 = file(filename1);
        JRubyFile file2 = file(filename2);
        if (. || !runtime.getPosix().isNative()) {
            // posix stat uses inodes to determine indentity, and windows has no inodes
            // (they are always zero), so we use canonical paths instead. (JRUBY-5726)
            // If we can't load a native POSIX, use this same logic. (JRUBY-6982)
            try {
                return runtime.newBoolean(file1.exists() && file2.exists() &&
                                          file1.getCanonicalPath().equals(file2.getCanonicalPath()));
            } catch (IOException e) {
                // this is indicative of something really wrong, but for now...
                return runtime.getFalse();
            }
        }
        return runtime.newBoolean(file1.exists() && file2.exists() &&
                runtime.getPosix().stat(file1.getAbsolutePath()).isIdentical(runtime.getPosix().stat(file2.getAbsolutePath())));   
    }
    @JRubyMethod(name = "owned?", required = 1, module = true)
    public static IRubyObject owned_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isOwned());
    }
    @JRubyMethod(name = "pipe?", required = 1, module = true)
    public static IRubyObject pipe_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isNamedPipe());
    }
    public static IRubyObject readable_p(IRubyObject recvIRubyObject filename) {
        return readable_p(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    // We use file test since it is faster than a stat; also euid == uid in Java always
    @JRubyMethod(name = {"readable?""readable_real?"}, required = 1, module = true)
    public static IRubyObject readable_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = context.runtime;
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        ZipEntry entry = file_in_archive(filename);
        if (entry != null) {
            return entry.isDirectory() ?
                recv.getRuntime().getFalse() :
                recv.getRuntime().getTrue();
        }
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && file.canRead());
    }
    // Not exposed by filetest, but so similiar in nature that it is stored here
    public static IRubyObject rowned_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isROwned());
    }
    @JRubyMethod(name = "setgid?", required = 1, module = true)
    public static IRubyObject setgid_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isSetgid());
    }
    @JRubyMethod(name = "setuid?", required = 1, module = true)
    public static IRubyObject setuid_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isSetuid());
    }
    public static IRubyObject size(IRubyObject recvIRubyObject filename) {
        return size(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    @JRubyMethod(name = "size", required = 1, module = true)
    public static IRubyObject size(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        
        ZipEntry entry = file_in_archive(filename);
        if (entry != null) {
            return runtime.newFixnum(entry.getSize());
        }
        JRubyFile file = file(filename);
        if (!file.exists()) {
            noFileError(filename);
        }
        return runtime.newFixnum(file.length());
    }
    public static IRubyObject size_p(IRubyObject recvIRubyObject filename) {
        return size_p(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    
    @JRubyMethod(name = "size?", required = 1, module = true)
    public static IRubyObject size_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = context.runtime;
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        
        ZipEntry entry = file_in_archive(filename);
        if (entry != null) {
            long size = entry.getSize();
            if (size > 0) {
                return runtime.newFixnum(size);
            } else {
                return runtime.getNil();
            }
        }
        JRubyFile file = file(filename);
        if (!file.exists()) {
            return runtime.getNil();
        }
        long length = file.length();
        if (length > 0) {
            return runtime.newFixnum(length);
        } else {
            return runtime.getNil();
        }
    }
    @JRubyMethod(name = "socket?", required = 1, module = true)
    public static IRubyObject socket_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isSocket());
    }
    @JRubyMethod(name = "sticky?", required = 1, module = true)
    public static IRubyObject sticky_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        return runtime.newBoolean(file.exists() && runtime.getPosix().stat(file.getAbsolutePath()).isSticky());
    }
    @JRubyMethod(name = "symlink?", required = 1, module = true)
    public static RubyBoolean symlink_p(IRubyObject recvIRubyObject filename) {
        Ruby runtime = recv.getRuntime();
        JRubyFile file = file(filename);
        try {
            // Note: We can't use file.exists() to check whether the symlink
            // exists or not, because that method returns false for existing
            // but broken symlink. So, we try without the existence check,
            // but in the try-catch block.
            // MRI behavior: symlink? on broken symlink should return true.
            return runtime.newBoolean(runtime.getPosix().lstat(file.getAbsolutePath()).isSymlink());
        } catch (SecurityException re) {
            return runtime.getFalse();
        } catch (RaiseException re) {
            return runtime.getFalse();
        }
    }
    // We do both writable and writable_real through the same method because
    // in our java process effective and real userid will always be the same.
    @JRubyMethod(name = {"writable?""writable_real?"}, required = 1, module = true)
    public static RubyBoolean writable_p(IRubyObject recvIRubyObject filename) {
        return filename.getRuntime().newBoolean(file(filename).canWrite());
    }
    public static RubyBoolean zero_p(IRubyObject recvIRubyObject filename) {
        return zero_p(recv.getRuntime().getCurrentContext(), recvfilename);
    }
    @JRubyMethod(name = "zero?", required = 1, module = true)
    public static RubyBoolean zero_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
        Ruby runtime = context.runtime;
        if (!(filename instanceof RubyFile)) {
            filename = get_path(contextfilename);
        }
        
        ZipEntry entry = file_in_archive(filename);
        if (entry != null) {
            return runtime.newBoolean(entry.getSize() == 0L);
        }
        JRubyFile file = file(filename);
        if (file.exists()) {
            if (file.isDirectory()) {
                // MRI behavior, enforced by RubySpecs.
                return runtime.newBoolean(.);
            } else {
                return runtime.newBoolean(file.length() == 0L);
            }
        } else {
            return runtime.getFalse();
        }
    }
    @JRubyMethod(name = "world_readable?", required = 1, module = true, compat = .)
    public static IRubyObject worldReadable(ThreadContext contextIRubyObject recvIRubyObject filename) {
        RubyFileStat stat = getFileStat(contextfilename);
        if (stat == null) {
            return context.runtime.getNil();
        }
        return stat.worldReadable(context);
    }
    @JRubyMethod(name = "world_writable?", required = 1, module = true, compat = .)
    public static IRubyObject worldWritable(ThreadContext contextIRubyObject recvIRubyObject filename) {
        RubyFileStat stat = getFileStat(contextfilename);
        if (stat == null) {
            return context.runtime.getNil();
        }
        return stat.worldWritable(context);
    }

    
MRI defines the FileTest methods both as module functions on FileTest and as singleton methods on the File class. Since our annotations can't be both module and singleton method definitions, we define proxies here for File. Note that these are to be defined on the singleton class of the File class.
    public static class FileTestFileMethods {
        @JRubyMethod(name = "blockdev?", required = 1)
        public static IRubyObject blockdev_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.blockdev_p(recvfilename);
        }
        @JRubyMethod(name = "chardev?", required = 1)
        public static IRubyObject chardev_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.chardev_p(recvfilename);
        }
        @JRubyMethod(name = "directory?", required = 1)
        public static IRubyObject directory_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.directory_p(contextrecvfilename);
        }
        @JRubyMethod(name = "executable?", required = 1)
        public static IRubyObject executable_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.executable_p(recvfilename);
        }
        @JRubyMethod(name = "executable_real?", required = 1)
        public static IRubyObject executable_real_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.executable_real_p(recvfilename);
        }
        @JRubyMethod(name = {"exist?""exists?"}, required = 1)
        public static IRubyObject exist_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.exist_p(contextrecvfilename);
        }
        @JRubyMethod(name = "file?", required = 1)
        public static RubyBoolean file_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.file_p(contextrecvfilename);
        }
        @JRubyMethod(name = "grpowned?", required = 1)
        public static IRubyObject grpowned_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.grpowned_p(recvfilename);
        }
        @JRubyMethod(name = "identical?", required = 2)
        public static IRubyObject identical_p(IRubyObject recvIRubyObject filename1IRubyObject filename2) {
            return RubyFileTest.identical_p(recvfilename1filename2);
        }
        @JRubyMethod(name = "owned?", required = 1)
        public static IRubyObject owned_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.owned_p(recvfilename);
        }
        @JRubyMethod(name = "pipe?", required = 1)
        public static IRubyObject pipe_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.pipe_p(recvfilename);
        }
        @JRubyMethod(name = {"readable?""readable_real?"}, required = 1)
        public static IRubyObject readable_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.readable_p(contextrecvfilename);
        }
        @JRubyMethod(name = "setgid?", required = 1)
        public static IRubyObject setgid_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.setgid_p(recvfilename);
        }
        @JRubyMethod(name = "setuid?", required = 1)
        public static IRubyObject setuid_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.setuid_p(recvfilename);
        }
        @JRubyMethod(name = "size", required = 1)
        public static IRubyObject size(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.size(contextrecvfilename);
        }
        @JRubyMethod(name = "size?", required = 1)
        public static IRubyObject size_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.size_p(contextrecvfilename);
        }
        @JRubyMethod(name = "socket?", required = 1)
        public static IRubyObject socket_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.socket_p(recvfilename);
        }
        @JRubyMethod(name = "sticky?", required = 1)
        public static IRubyObject sticky_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.sticky_p(recvfilename);
        }
        @JRubyMethod(name = "symlink?", required = 1)
        public static RubyBoolean symlink_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.symlink_p(recvfilename);
        }
        @JRubyMethod(name = {"writable?""writable_real?"}, required = 1)
        public static RubyBoolean writable_p(IRubyObject recvIRubyObject filename) {
            return RubyFileTest.writable_p(recvfilename);
        }
        @JRubyMethod(name = "zero?", required = 1)
        public static RubyBoolean zero_p(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.zero_p(contextrecvfilename);
        }
        @JRubyMethod(name = "world_readable?", required = 1, compat = .)
        public static IRubyObject worldReadable(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.worldReadable(contextrecvfilename);
        }
        @JRubyMethod(name = "world_writable?", required = 1, compat = .)
        public static IRubyObject worldWritable(ThreadContext contextIRubyObject recvIRubyObject filename) {
            return RubyFileTest.worldWritable(contextrecvfilename);
        }
    }
    private static RubyFileStat getFileStat(ThreadContext contextIRubyObject filename) {
        Ruby runtime = context.runtime;
        RubyFileStat stat = null;
        if (!(filename instanceof RubyFile)) {
            RubyString path = get_path(contextfilename);
            JRubyFile file = JRubyFile.create(runtime.getCurrentDirectory(), path.getUnicodeValue());
            if (file.exists()) {
                stat = runtime.newFileStat(file.getPath(), false);
            }
        } else {
            stat = (RubyFileStat) ((RubyFilefilename).stat(context);
        }
        return stat;
    }
    private static ZipEntry file_in_archive(IRubyObject path) {
        Ruby runtime = path.getRuntime();
        if (path instanceof RubyFile) {
            return null;
        }
        RubyString pathStr = get_path(runtime.getCurrentContext(), path);
        String pathJStr = pathStr.asJavaString();
        
        if (pathJStr.startsWith("jar:")) {
            pathJStr = pathJStr.substring(4);
        }
        if (pathJStr.startsWith("file:")) {
            String file = pathJStr.substring(5);
            int bang = file.indexOf('!');
            if (bang == -1 || bang == file.length() - 1) {
                return null;
            }
            String jar = file.substring(0, bang);
            String after = file.substring(bang + 2);
            try {
                return RubyFile.getDirOrFileEntry(jarafter);
            } catch (Exception e) {
            }
        }
        return null;
    }
    private static boolean existsOnClasspath(IRubyObject path) {
        if (path instanceof RubyFile) {
            return false;
        }
        Ruby runtime = path.getRuntime();
        RubyString pathStr = get_path(runtime.getCurrentContext(), path);
        String pathJStr = pathStr.getUnicodeValue();
        if (pathJStr.startsWith("classpath:/")) {
            pathJStr = pathJStr.substring("classpath:/".length());
            ClassLoader classLoader = runtime.getJRubyClassLoader();
            // handle security-sensitive case
            if (Ruby.isSecurityRestricted() && classLoader == null) {
                classLoader = runtime.getInstanceConfig().getLoader();
            }
            InputStream is = classLoader.getResourceAsStream(pathJStr);
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignore) {
                } catch (NullPointerException wtf) {
                    // that's what sometimes happens, weird
                }
                return true;
            }
        }
        return false;
    }
    private static void noFileError(IRubyObject filename) {
        throw filename.getRuntime().newErrnoENOENTError("No such file or directory - " +
                filename.convertToString());
    }
New to GrepCode? Check out our FAQ X