diff --git a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java index 62ab6d2abda4..64b591b75eea 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java @@ -266,7 +266,7 @@ public class FileSystemUtil { long lastModified = (Long)myToMillis.invoke(attributes.get("lastModifiedTime")); if (SystemInfo.isWindows) { boolean isHidden = new File(path).getParent() == null ? false : (Boolean)attributes.get("hidden"); - boolean isWritable = !(Boolean)attributes.get("readonly"); + boolean isWritable = isDirectory || !(Boolean)attributes.get("readonly"); return new FileAttributes(isDirectory, isOther, isSymbolicLink, isHidden, size, lastModified, isWritable); } else { @@ -546,19 +546,19 @@ public class FileSystemUtil { if (myFileSystem != null) { final int flags = (Integer)myGetBooleanAttributes.invoke(myFileSystem, file); if (flags != 0) { - final boolean isDirectory = isSet(flags, BA_DIRECTORY); - final boolean isSpecial = notSet(flags, BA_REGULAR | BA_DIRECTORY); - final boolean isHidden = isSet(flags, BA_HIDDEN); - return new FileAttributes(isDirectory, isSpecial, false, isHidden, file.length(), file.lastModified(), file.canWrite()); + boolean isDirectory = isSet(flags, BA_DIRECTORY); + boolean isSpecial = notSet(flags, BA_REGULAR | BA_DIRECTORY); + boolean isHidden = isSet(flags, BA_HIDDEN); + boolean isWritable = SystemInfo.isWindows && isDirectory || file.canWrite(); + return new FileAttributes(isDirectory, isSpecial, false, isHidden, file.length(), file.lastModified(), isWritable); } } - else { - if (file.exists()) { - final boolean isDirectory = file.isDirectory(); - final boolean isSpecial = !isDirectory && !file.isFile(); - final boolean isHidden = file.isHidden(); - return new FileAttributes(isDirectory, isSpecial, false, isHidden, file.length(), file.lastModified(), file.canWrite()); - } + else if (file.exists()) { + boolean isDirectory = file.isDirectory(); + boolean isSpecial = !isDirectory && !file.isFile(); + boolean isHidden = file.isHidden(); + boolean isWritable = SystemInfo.isWindows && isDirectory || file.canWrite(); + return new FileAttributes(isDirectory, isSpecial, false, isHidden, file.length(), file.lastModified(), isWritable); } return null; diff --git a/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java b/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java index c01be76d6536..5c15243f5ff6 100644 --- a/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java +++ b/platform/util/src/com/intellij/openapi/util/io/win32/FileInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,8 +52,8 @@ public class FileInfo { final boolean isSymlink = isSet(attributes, FILE_ATTRIBUTE_REPARSE_POINT); final boolean isHidden = isSet(attributes, FILE_ATTRIBUTE_HIDDEN); final boolean isWritable = !isSet(attributes, FILE_ATTRIBUTE_READONLY); - final long javaTimestamp = timestamp / 10000 - 11644473600000l; - return new FileAttributes(isDirectory, isSpecial, isSymlink, isHidden, length, javaTimestamp, isWritable); + final long javaTimestamp = timestamp / 10000 - 11644473600000L; + return new FileAttributes(isDirectory, isSpecial, isSymlink, isHidden, length, javaTimestamp, isDirectory || isWritable); } @Override diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java index 8acb3891b389..3c97eae7e4b3 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java @@ -80,6 +80,18 @@ public class FileAttributesReadingTest { assertEquals(file.getPath(), target); } + @Test + public void readOnlyFile() throws Exception { + final File file = FileUtil.createTempFile(myTempDirectory, "test.", ".txt"); + + String[] cmd = SystemInfo.isWindows ? new String[]{"attrib", "+R", file.getPath()} : new String[]{"chmod", "500", file.getPath()}; + assertEquals(0, Runtime.getRuntime().exec(cmd).waitFor()); + + FileAttributes attributes = getAttributes(file); + assertEquals(FileAttributes.Type.FILE, attributes.type); + assertFalse(attributes.isWritable()); + } + @Test public void directory() throws Exception { final File file = FileUtil.createTempDirectory(myTempDirectory, "test.", ".tmp"); @@ -98,6 +110,18 @@ public class FileAttributesReadingTest { assertEquals(file.getPath(), target); } + @Test + public void readOnlyDirectory() throws Exception { + File file = FileUtil.createTempDirectory(myTempDirectory, "test.", ".tmp"); + + String[] cmd = SystemInfo.isWindows ? new String[]{"attrib", "+R", file.getPath()} : new String[]{"chmod", "500", file.getPath()}; + assertEquals(0, Runtime.getRuntime().exec(cmd).waitFor()); + + FileAttributes attributes = getAttributes(file); + assertEquals(FileAttributes.Type.DIRECTORY, attributes.type); + assertEquals(SystemInfo.isWindows, attributes.isWritable()); + } + @Test public void root() throws Exception { final File file = new File(SystemInfo.isWindows ? "C:\\" : "/");