diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java index c0e03bf8af7a..801fc75aace4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java @@ -16,11 +16,15 @@ package com.intellij.compiler.impl.javaCompiler.api; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; /** * User: cdr @@ -31,12 +35,33 @@ class JavaIoFile extends SimpleJavaFileObject { @Nullable private final String myEncoding; - JavaIoFile(File file, Kind kind, @Nullable String encoding) { - super(file.toURI(), kind); + JavaIoFile(@NotNull File file, @NotNull Kind kind, @Nullable String encoding) { + super(convertToURI(file.getPath()), kind); myFile = file; myEncoding = encoding; } + // File.toURI() asks for File.isDirectory which is too expensive + @NotNull + private static URI convertToURI(@NotNull String path) { + if (File.separatorChar != '/') { + path = path.replace(File.separatorChar, '/'); + } + if (!StringUtil.startsWithChar(path, '/')) { + path = "/" + path; + } + + if (path.startsWith("//")) { + path = "//" + path; + } + try { + return new URI("file", null, path, null); + } + catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return FileUtil.loadFile(myFile, myEncoding); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java index 8da3c0d46fe3..d46d5042e6bf 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java @@ -123,7 +123,8 @@ class MyFileManager implements StandardJavaFileManager { if (kind == JavaFileObject.Kind.SOURCE && child.getFileSystem() instanceof JarFileSystem) continue; //for some reasdon javac looks for java files inside jar // use VFS to read content inside .jar - JavaFileObject fileObject = !child.getPath().contains("!/") ? new JavaIoFile(new File(child.getPath()), kind, myEncoding) : new JavaVirtualFile(child, kind); + String childPath = child.getPath(); + JavaFileObject fileObject = !childPath.contains("!/") ? new JavaIoFile(new File(childPath), kind, myEncoding) : new JavaVirtualFile(child, kind); results.add(fileObject); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java index 3c2f626eb0df..25aaea4ad2c8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeBase.java @@ -66,8 +66,8 @@ public class DebuggerTreeBase extends DnDAwareTree implements Disposable { return DebuggerTreeBase.this.createToolTip(e); } - public MouseEvent createTooltipEvent(MouseEvent candiateEvent) { - return DebuggerTreeBase.this.createTooltipEvent(candiateEvent); + public MouseEvent createTooltipEvent(MouseEvent candidateEvent) { + return DebuggerTreeBase.this.createTooltipEvent(candidateEvent); } public boolean isFocusOwner() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java index 9dd8aa77174b..5a8f0c1066a0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java @@ -16,6 +16,8 @@ package com.intellij.debugger.ui.impl; import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.ide.FrameStateListener; +import com.intellij.ide.FrameStateManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -23,7 +25,6 @@ import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.util.registry.RegistryValue; import com.intellij.openapi.wm.IdeGlassPane; import com.intellij.openapi.wm.IdeGlassPaneUtil; import com.intellij.util.Alarm; @@ -45,13 +46,12 @@ public class TipManager implements Disposable, PopupMenuListener { private volatile boolean myIsDisposed = false; private boolean myPopupShown; private MyAwtPreprocessor myHideCanceller; - private RegistryValue myTooltipProperty; private MouseEvent myLastMouseEvent; public interface TipFactory { JComponent createToolTip (MouseEvent e); - MouseEvent createTooltipEvent(MouseEvent candiateEvent); + MouseEvent createTooltipEvent(MouseEvent candidateEvent); boolean isFocusOwner(); } @@ -99,6 +99,18 @@ public class TipManager implements Disposable, PopupMenuListener { } } + private class MyFrameStateListener implements FrameStateListener { + @Override + public void onFrameDeactivated() { + hideTooltip(true); + } + + @Override + public void onFrameActivated() { + //Do nothing + } + } + public JPopupMenu registerPopup(JPopupMenu menu) { menu.addPopupMenuListener(this); return menu; @@ -243,6 +255,7 @@ public class TipManager implements Disposable, PopupMenuListener { private final JComponent myComponent; private MouseListener myMouseListener = new MyMouseListener(); private MouseMotionListener myMouseMotionListener = new MyMouseMotionListener(); + private FrameStateListener myFrameStateListener = new MyFrameStateListener(); private final Alarm myShowAlarm = new Alarm(); private final Alarm myHideAlarm = new Alarm(); @@ -294,7 +307,8 @@ public class TipManager implements Disposable, PopupMenuListener { myGP.addMouseMotionPreprocessor(myMouseMotionListener, this); myHideCanceller = new MyAwtPreprocessor(); - Toolkit.getDefaultToolkit().addAWTEventListener(myHideCanceller, MouseEvent.MOUSE_MOTION_EVENT_MASK | KeyEvent.KEY_EVENT_MASK | MouseEvent.MOUSE_EVENT_MASK); + Toolkit.getDefaultToolkit().addAWTEventListener(myHideCanceller, AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK); + FrameStateManager.getInstance().addListener(myFrameStateListener); } public void dispose() { @@ -308,6 +322,8 @@ public class TipManager implements Disposable, PopupMenuListener { myShowAlarm.cancelAllRequests(); myMouseListener = null; myMouseMotionListener = null; + FrameStateManager.getInstance().removeListener(myFrameStateListener); + myFrameStateListener = null; } private class MyAwtPreprocessor implements AWTEventListener { diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitProcessHandler.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitProcessHandler.java index 96963958f61a..d7dc91215c1d 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/JUnitProcessHandler.java +++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitProcessHandler.java @@ -16,13 +16,12 @@ package com.intellij.execution.junit; import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.CommandLineBuilder; import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.junit2.segments.Extractor; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessTerminatedListener; -import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.NotNull; import java.io.Reader; import java.nio.charset.Charset; @@ -35,17 +34,19 @@ public class JUnitProcessHandler extends OSProcessHandler { private final Extractor myErr; private final Charset myCharset; - public JUnitProcessHandler(final Process process, final String commandLine, final Charset charset) { + public JUnitProcessHandler(@NotNull Process process, final String commandLine, @NotNull Charset charset) { super(process, commandLine); myOut = new Extractor(getProcess().getInputStream(), charset); myErr = new Extractor(getProcess().getErrorStream(), charset); myCharset = charset; } + @Override protected Reader createProcessOutReader() { return myOut.createReader(); } + @Override protected Reader createProcessErrReader() { return myErr.createReader(); } @@ -58,22 +59,29 @@ public class JUnitProcessHandler extends OSProcessHandler { return myOut; } + @Override public Charset getCharset() { return myCharset; } - public static JUnitProcessHandler runJava(final JavaParameters javaParameters) throws ExecutionException { - return runJava(javaParameters, null); - } - - public static JUnitProcessHandler runJava(final JavaParameters javaParameters, final Project project) throws ExecutionException { - return runCommandLine(CommandLineBuilder.createFromJavaParameters(javaParameters, project, true)); - } - public static JUnitProcessHandler runCommandLine(final GeneralCommandLine commandLine) throws ExecutionException { final JUnitProcessHandler processHandler = new JUnitProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString(), commandLine.getCharset()); ProcessTerminatedListener.attach(processHandler); return processHandler; } + + @Override + protected void notifyProcessTerminated(int exitCode) { + super.notifyProcessTerminated(exitCode); + Disposer.dispose(myOut); + Disposer.dispose(myErr); + } + + @Override + protected void notifyProcessDetached() { + super.notifyProcessDetached(); + Disposer.dispose(myOut); + Disposer.dispose(myErr); + } } diff --git a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java index 3fc4d64b968c..7ebb739a0366 100644 --- a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java +++ b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java @@ -19,6 +19,7 @@ import com.intellij.rt.execution.junit.segments.Packet; import com.intellij.rt.execution.junit.segments.PacketProcessor; import com.intellij.rt.execution.junit.segments.SegmentedStream; import com.intellij.util.StringBuilderSpinAllocator; +import org.jetbrains.annotations.NotNull; import java.io.BufferedReader; import java.io.IOException; @@ -31,10 +32,11 @@ public class SegmentedInputStream extends InputStream { private PacketProcessor myEventsDispatcher; private int myStartupPassed = 0; - public SegmentedInputStream(final InputStream sourceStream, final Charset charset) { + public SegmentedInputStream(@NotNull InputStream sourceStream, @NotNull Charset charset) { mySourceStream = new PushReader(new BufferedReader(new InputStreamReader(sourceStream, charset))); } + @Override public int read() throws IOException { if (myStartupPassed < SegmentedStream.STARTUP_MESSAGE.length()) { return rawRead(); @@ -86,9 +88,9 @@ public class SegmentedInputStream extends InputStream { } private char[] readMarker() throws IOException { - int nextRead = '0'; final StringBuilder buffer = StringBuilderSpinAllocator.alloc(); try { + int nextRead = '0'; while (nextRead != ' ' && nextRead != SegmentedStream.SPECIAL_SYMBOL) { buffer.append((char)nextRead); nextRead = readNext(); @@ -108,10 +110,12 @@ public class SegmentedInputStream extends InputStream { return mySourceStream.next(); } + @Override public int available() throws IOException { return mySourceStream.ready() ? 1 : 0; } + @Override public void close() throws IOException { mySourceStream.close(); } @@ -126,10 +130,11 @@ public class SegmentedInputStream extends InputStream { i++; chr = chars[i]; if (chr != Packet.ourSpecialSymbol) { - final StringBuffer codeBuffer = new StringBuffer(Packet.CODE_LENGTH); + final StringBuilder codeBuffer = new StringBuilder(Packet.CODE_LENGTH); codeBuffer.append(chr); - for (int j = 1; j < Packet.CODE_LENGTH; j++) - codeBuffer.append(chars[i+j]); + for (int j = 1; j < Packet.CODE_LENGTH; j++) { + codeBuffer.append(chars[i + j]); + } i += Packet.CODE_LENGTH - 1; decodedChar = (char)Integer.parseInt(codeBuffer.toString()); } diff --git a/java/execution/impl/src/com/intellij/execution/junit2/segments/Extractor.java b/java/execution/impl/src/com/intellij/execution/junit2/segments/Extractor.java index 8a8ac619b0d0..b4f99c9de72a 100644 --- a/java/execution/impl/src/com/intellij/execution/junit2/segments/Extractor.java +++ b/java/execution/impl/src/com/intellij/execution/junit2/segments/Extractor.java @@ -18,10 +18,12 @@ package com.intellij.execution.junit2.segments; import com.intellij.execution.junit.SegmentedInputStreamReader; import com.intellij.execution.junit2.SegmentedInputStream; import com.intellij.execution.testframework.Printable; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.rt.execution.junit.segments.PacketProcessor; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; +import org.jetbrains.annotations.NotNull; import java.io.InputStream; import java.io.Reader; @@ -30,24 +32,29 @@ import java.nio.charset.Charset; /** * @author dyoma */ -public class Extractor { +public class Extractor implements Disposable { private DeferredActionsQueue myFulfilledWorkGate = null; private final SegmentedInputStream myStream; private OutputPacketProcessor myEventsDispatcher; private static final Logger LOG = Logger.getInstance("#" + Extractor.class.getName()); - private MergingUpdateQueue myQueue = new MergingUpdateQueue("Test Extractor", 20, true, MergingUpdateQueue.ANY_COMPONENT); + private final MergingUpdateQueue myQueue = new MergingUpdateQueue("Test Extractor", 20, true, MergingUpdateQueue.ANY_COMPONENT, this); - public Extractor(final InputStream stream, final Charset charset) { + public Extractor(@NotNull InputStream stream, @NotNull Charset charset) { myStream = new SegmentedInputStream(stream, charset); myQueue.setPassThrough(false);//should be updated in awt thread } + @Override + public void dispose() { + } + public void setDispatchListener(final DispatchListener listener) { myFulfilledWorkGate.setDispactchListener(listener); } public void setPacketDispatcher(final PacketProcessor packetProcessor, final DeferredActionsQueue queue) { myFulfilledWorkGate = new DeferredActionsQueue() { //todo make it all later + @Override public void addLast(final Runnable runnable) { myQueue.queue(new Update(runnable) { @Override @@ -57,13 +64,16 @@ public class Extractor { }); } + @Override public void setDispactchListener(final DispatchListener listener) { queue.setDispactchListener(listener); } }; myEventsDispatcher = new OutputPacketProcessor() { + @Override public void processPacket(final String packet) { myFulfilledWorkGate.addLast(new Runnable() { + @Override public void run() { packetProcessor.processPacket(packet); } @@ -74,6 +84,7 @@ public class Extractor { public void processOutput(final Printable printable) { LOG.assertTrue(packetProcessor instanceof OutputPacketProcessor); myFulfilledWorkGate.addLast(new Runnable() { + @Override public void run() { ((OutputPacketProcessor)packetProcessor).processOutput(printable); } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java index 67b8ff194e43..1947299670c1 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java @@ -516,16 +516,18 @@ public abstract class IntervalTreeImpl extends RedBla @NotNull DisposableIterator overlappingIterator(final int startOffset, final int endOffset) { ProperTextRange.assertProperRange(startOffset, endOffset, ""); + + l.readLock().lock(); + final IntervalNode firstOverlap = findMinOverlappingWith(getRoot(), new TextRangeInterval(startOffset, endOffset), modCount, 0); if (firstOverlap == null) { + l.readLock().unlock(); return DisposableIterator.EMPTY; } final int firstOverlapDelta = firstOverlap.computeDeltaUpToRoot(); final int firstOverlapStart = firstOverlap.intervalStart() + firstOverlapDelta; final int modCountBefore = modCount; - l.readLock().lock(); - return new DisposableIterator() { private IntervalNode currentNode = firstOverlap; private int deltaUpToRootExclusive = firstOverlapDelta-firstOverlap.delta; diff --git a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java index 7753c3a83499..d5fdce4b7fdc 100644 --- a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java @@ -68,7 +68,6 @@ public class OSProcessHandler extends BaseOSProcessHandler { /** * Kill whole process tree. * @param process Process - * @param forceKill If failed to kill process tree - try to kill it using Java API * @return True if process tree has been successfully killed. */ protected boolean killProcessTree(final Process process) { diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFileSystem.java b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFileSystem.java index f2ba97153912..b7f274080b78 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFileSystem.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/NewVirtualFileSystem.java @@ -19,11 +19,11 @@ */ package com.intellij.openapi.vfs.newvfs; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileListener; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileSystem; -import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,10 +45,12 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements return path; } + @Override public void refreshWithoutFileWatcher(final boolean asynchronous) { refresh(asynchronous); } + @Override public boolean isReadOnly() { return true; } @@ -70,6 +72,7 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements protected abstract String extractRootPath(@NotNull String path); + @Override public void addVirtualFileListener(@NotNull final VirtualFileListener listener) { synchronized (myListenerWrappers) { VirtualFileListener wrapper = new VirtualFileFilteringListener(listener, this); @@ -78,6 +81,7 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements } } + @Override public void removeVirtualFileListener(@NotNull final VirtualFileListener listener) { synchronized (myListenerWrappers) { final VirtualFileListener wrapper = myListenerWrappers.remove(listener); @@ -89,12 +93,18 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements public abstract int getRank(); + @Override public abstract VirtualFile copyFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent, @NotNull final String copyName) throws IOException; + @Override @NotNull public abstract VirtualFile createChildDirectory(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String dir) throws IOException; + @Override public abstract VirtualFile createChildFile(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String file) throws IOException; + @Override public abstract void deleteFile(final Object requestor, @NotNull final VirtualFile file) throws IOException; + @Override public abstract void moveFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent) throws IOException; + @Override public abstract void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException; public boolean markNewFilesAsDirty() { @@ -105,14 +115,6 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements return file.getName(); } - public static final int BA_EXISTS = 0x01; - public static final int BA_REGULAR = 0x02; - public static final int BA_DIRECTORY = 0x04; - public static final int BA_HIDDEN = 0x08; - - @MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN}) - public @interface FileBooleanAttributes {} - /** * Queries the file about several attributes at once, and returns them ORed together. * This method is typically faster than several methods calls querying corresponding file attributes one by one. @@ -122,10 +124,10 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements * Each attribute is an int constant from this class. * Following attributes are defined: *
    - *
  • {@link #BA_EXISTS} is set if {@link java.io.File#exists()} returns true
  • - *
  • {@link #BA_DIRECTORY} is set if {@link java.io.File#isDirectory()} returns true
  • - *
  • {@link #BA_HIDDEN} is set if {@link java.io.File#isHidden()} returns true
  • - *
  • {@link #BA_REGULAR} is set if {@link java.io.File#isFile()} returns true
  • + *
  • {@link com.intellij.openapi.util.io.FileUtil#BA_EXISTS} is set if {@link java.io.File#exists()} returns true
  • + *
  • {@link com.intellij.openapi.util.io.FileUtil#BA_DIRECTORY} is set if {@link java.io.File#isDirectory()} returns true
  • + *
  • {@link com.intellij.openapi.util.io.FileUtil#BA_HIDDEN} is set if {@link java.io.File#isHidden()} returns true
  • + *
  • {@link com.intellij.openapi.util.io.FileUtil#BA_REGULAR} is set if {@link java.io.File#isFile()} returns true
  • *
* Attributes can be bitwise ORed together to query several file attributes at once. * -1 as an argument value will query all attributes. @@ -146,6 +148,6 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements * boolean isDirectory = (attributes & BA_DIRECTORY) != 0; * }} */ - @FileBooleanAttributes - public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileBooleanAttributes int flags); + @FileUtil.FileBooleanAttributes + public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileUtil.FileBooleanAttributes int flags); } diff --git a/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java b/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java index 0dd329414613..5f566400c3d6 100644 --- a/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java +++ b/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java @@ -46,10 +46,10 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { private volatile boolean myFlushing; - private String myName; + private final String myName; private int myMergingTimeSpan; private JComponent myModalityStateComponent; - private boolean myExecuteInDispatchThread; + private final boolean myExecuteInDispatchThread; private boolean myPassThrough; private boolean myDisposed; @@ -163,6 +163,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { restartTimer(); } + @Override public void hideNotify() { if (!myActive) { return; @@ -175,6 +176,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { clearWaiter(); } + @Override public void showNotify() { if (myActive) { return; @@ -202,6 +204,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { } } + @Override public void run() { if (mySuspended) return; flush(); @@ -227,6 +230,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { myFlushing = true; final Runnable toRun = new Runnable() { + @Override public void run() { try { final Update[] all; @@ -289,6 +293,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { if (each.executeInWriteAction()) { ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override public void run() { execute(each); } @@ -381,6 +386,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { return myActive; } + @Override public void dispose() { myDisposed = true; myActive = false; diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 6c6bfbce43a7..d0d773a199ec 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -130,7 +130,9 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener hideCurrent(me, null, null); } } else if (me.getID() == MouseEvent.MOUSE_MOVED) { - if (me.getComponent() == myCurrentComponent || me.getComponent() == myQueuedComponent) { + if (c instanceof JComponent && ((JComponent)c).getToolTipText(me) == null) { + hideCurrent(me, null, null);//There is no tooltip here, let's proceed it as MOUSE_EXITED + } else if (me.getComponent() == myCurrentComponent || me.getComponent() == myQueuedComponent) { if (myCurrentTipUi != null && myCurrentTipUi.wasFadedIn()) { if (hideCurrent(me, null, null)) { maybeShowFor(c, me); @@ -174,6 +176,17 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener boolean centerStrict = Boolean.TRUE.equals(comp.getClientProperty(UIUtil.CENTER_TOOLTIP_STRICT)); int shift = centerStrict ? 0 : (centerDefault ? 4 : 0); + // Balloon may appear exactly above useful content, such behavior is rather annoying. + if (c instanceof JTree) { + javax.swing.tree.TreePath path = ((JTree)c).getClosestPathForLocation(me.getX(), me.getY()); + if (path != null) { + Rectangle pathBounds = ((JTree)c).getPathBounds(path); + if (pathBounds != null && pathBounds.y + 4 < me.getY()) { + shift += me.getY() - pathBounds.y - 4; + } + } + } + queueShow(comp, me, centerStrict || centerDefault, shift, -shift, -shift); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java index 7f35b77eba8c..c1da943f68a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java @@ -21,6 +21,7 @@ package com.intellij.openapi.vfs.ex.temp; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.ManagingFS; @@ -369,9 +370,9 @@ public class TempFileSystem extends NewVirtualFileSystem { @Override public int getBooleanAttributes(@NotNull VirtualFile file, int flags) { FSItem item = convert(file); - int isDir = item instanceof FSDir ? BA_DIRECTORY : 0; - int exists = item == null ? 0 : BA_EXISTS; - int regular = isDir == 0 ? BA_REGULAR : 0; + int isDir = item instanceof FSDir ? FileUtil.BA_DIRECTORY : 0; + int exists = item == null ? 0 : FileUtil.BA_EXISTS; + int regular = isDir == 0 ? FileUtil.BA_REGULAR : 0; return isDir | exists | regular; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java index 6d1e3a3687a2..c7c451895759 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -368,16 +368,16 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo public int getBooleanAttributes(@NotNull VirtualFile file, int flags) { int exists = 0; JarHandler handler = getHandler(file); - if ((flags & BA_EXISTS) != 0) { - exists = handler.exists(file) ? BA_EXISTS : 0; + if ((flags & FileUtil.BA_EXISTS) != 0) { + exists = handler.exists(file) ? FileUtil.BA_EXISTS : 0; } int isDir = 0; - if ((flags & BA_DIRECTORY) != 0) { - isDir = handler.isDirectory(file) ? BA_DIRECTORY : 0; + if ((flags & FileUtil.BA_DIRECTORY) != 0) { + isDir = handler.isDirectory(file) ? FileUtil.BA_DIRECTORY : 0; } int regular = 0; - if ((flags & BA_REGULAR) != 0) { - regular = isDir == 0 ? BA_REGULAR : 0; + if ((flags & FileUtil.BA_REGULAR) != 0) { + regular = isDir == 0 ? FileUtil.BA_REGULAR : 0; } return exists | isDir | regular; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index 4a43a8c8a897..0b839baafafb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -35,12 +35,10 @@ import com.intellij.util.Processor; import com.intellij.util.ThrowableConsumer; import com.intellij.util.io.SafeFileOutputStream; import com.intellij.util.io.fs.IFile; -import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -137,44 +135,13 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { return new File(path); } - private static final Method JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD; - private static final Object/* java.io.FileSystem */ JAVA_IO_FILESYSTEM; - // copied from FileSystem - - static { - Object fs; - Method getBooleanAttributes; - try { - Class fsClass = Class.forName("java.io.FileSystem"); - Method getFileSystem = fsClass.getMethod("getFileSystem"); - getFileSystem.setAccessible(true); - fs = getFileSystem.invoke(null); - getBooleanAttributes = fsClass.getDeclaredMethod("getBooleanAttributes", File.class); - if (fs == null || getBooleanAttributes == null) { - fs = null; - getBooleanAttributes = null; - } - else { - getBooleanAttributes.setAccessible(true); - } - } - catch (Exception e) { - fs = null; - getBooleanAttributes = null; - } - JAVA_IO_FILESYSTEM = fs; - JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD = getBooleanAttributes; - } - - - @NotNull private static File convertToIOFileAndCheck(@NotNull final VirtualFile file) throws FileNotFoundException { final File ioFile = convertToIOFile(file); - int intFlags = getBooleanAttributes(ioFile); + int intFlags = FileUtil.getBooleanAttributes(ioFile); if (intFlags != -1) { - if ((intFlags & BA_EXISTS) != 0 && (intFlags & BA_REGULAR) == 0) { + if ((intFlags & FileUtil.BA_EXISTS) != 0 && (intFlags & FileUtil.BA_REGULAR) == 0) { throw new FileNotFoundException("Not a file: " + ioFile); } return ioFile; @@ -186,20 +153,6 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { return ioFile; } - // todo[r.sh] use NIO2 API after migration to JDK 7 - // returns -1 if could not get attributes - @MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN}) - private static int getBooleanAttributes(@NotNull File f) { - if (JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD != null) { - try { - Object flags = JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD.invoke(JAVA_IO_FILESYSTEM, f); - return ((Integer)flags).intValue(); - } - catch (Exception ignored) { } - } - return -1; - } - @Override public boolean exists(@NotNull final VirtualFile fileOrDirectory) { String path = fileOrDirectory.getPath(); @@ -246,9 +199,9 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { } private static boolean isSpecialFile(@NotNull File ioFile) { - int flags = getBooleanAttributes(ioFile); + int flags = FileUtil.getBooleanAttributes(ioFile); if (flags != -1) { - return (flags & (BA_REGULAR | BA_DIRECTORY | BA_EXISTS)) == (~BA_REGULAR & ~BA_DIRECTORY & BA_EXISTS); + return (flags & (FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS)) == (~FileUtil.BA_REGULAR & ~FileUtil.BA_DIRECTORY & FileUtil.BA_EXISTS); } return !ioFile.isFile() && !ioFile.isDirectory() && ioFile.exists(); } @@ -774,12 +727,12 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @Override public int getBooleanAttributes(@NotNull VirtualFile file, int flags) { - int attributes = getBooleanAttributes(convertToIOFile(file)); + int attributes = FileUtil.getBooleanAttributes(convertToIOFile(file)); if (attributes != -1) return attributes & flags; - return ((flags & BA_EXISTS) != 0 && exists(file) ? BA_EXISTS : 0) | - ((flags & BA_DIRECTORY) != 0 && isDirectory(file) ? BA_DIRECTORY : 0) | - ((flags & BA_REGULAR) != 0 && !isSpecialFile(file) ? BA_REGULAR : 0) | - ((flags & BA_HIDDEN) != 0 && convertToIOFile(file).isHidden() ? BA_HIDDEN : 0) + return ((flags & FileUtil.BA_EXISTS) != 0 && exists(file) ? FileUtil.BA_EXISTS : 0) | + ((flags & FileUtil.BA_DIRECTORY) != 0 && isDirectory(file) ? FileUtil.BA_DIRECTORY : 0) | + ((flags & FileUtil.BA_REGULAR) != 0 && !isSpecialFile(file) ? FileUtil.BA_REGULAR : 0) | + ((flags & FileUtil.BA_HIDDEN) != 0 && convertToIOFile(file).isHidden() ? FileUtil.BA_HIDDEN : 0) ; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java index 18450eb9ea6c..501b706420db 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java @@ -15,7 +15,7 @@ */ package com.intellij.openapi.vfs.impl.win32; -import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -109,21 +109,21 @@ public class Win32Kernel { return info; } - @NewVirtualFileSystem.FileBooleanAttributes - public int getBooleanAttributes(@NotNull String path, @NewVirtualFileSystem.FileBooleanAttributes int flags) { + @FileUtil.FileBooleanAttributes + public int getBooleanAttributes(@NotNull String path, @FileUtil.FileBooleanAttributes int flags) { FileInfo info = doGetInfo(path); int result = 0; - if ((flags & NewVirtualFileSystem.BA_EXISTS) != 0) { - result |= info == null ? 0 : NewVirtualFileSystem.BA_EXISTS; + if ((flags & FileUtil.BA_EXISTS) != 0) { + result |= info == null ? 0 : FileUtil.BA_EXISTS; } - if ((flags & NewVirtualFileSystem.BA_DIRECTORY) != 0) { - result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : NewVirtualFileSystem.BA_DIRECTORY; + if ((flags & FileUtil.BA_DIRECTORY) != 0) { + result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : FileUtil.BA_DIRECTORY; } - if ((flags & NewVirtualFileSystem.BA_REGULAR) != 0) { - result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : NewVirtualFileSystem.BA_REGULAR; + if ((flags & FileUtil.BA_REGULAR) != 0) { + result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : FileUtil.BA_REGULAR; } - if ((flags & NewVirtualFileSystem.BA_HIDDEN) != 0) { - result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : NewVirtualFileSystem.BA_HIDDEN; + if ((flags & FileUtil.BA_HIDDEN) != 0) { + result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : FileUtil.BA_HIDDEN; } return result; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 5363593d452a..79f208e07e03 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -321,10 +321,10 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { private VirtualFileSystemEntry createAndFindChildWithEventFire(@NotNull String name) { final NewVirtualFileSystem delegate = getFileSystem(); VirtualFile fake = new FakeVirtualFile(this, name); - int attributes = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY); - if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) { + int attributes = delegate.getBooleanAttributes(fake, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY); + if ((attributes & FileUtil.BA_EXISTS) != 0) { final String realName = delegate.getCanonicallyCasedName(fake); - boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0; + boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0; VFileCreateEvent event = new VFileCreateEvent(null, this, realName, isDir, true); RefreshQueue.getInstance().processSingleEvent(event); return findChild(realName); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index 08cf80c6f47e..0d26031e5b77 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -145,7 +145,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { return pattern.regionMatches(ignoreCase, length, suffix, 0, suffix.length()); } - private Object rawName() { + protected Object rawName() { return myName; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java index 125445349646..79d7c701a32a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java @@ -292,7 +292,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final int parentId, @NotNull VirtualFile file, @NotNull NewVirtualFileSystem delegate, - @NewVirtualFileSystem.FileBooleanAttributes int attributes) { + @FileUtil.FileBooleanAttributes int attributes) { String name = file.getName(); if (!name.isEmpty() && namesEqual(delegate, name, FSRecords.getName(id))) return false; // TODO: Handle root attributes change. @@ -308,11 +308,11 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { FSRecords.setTimestamp(id, delegate.getTimeStamp(file)); - boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0; + boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0; FSRecords.setLength(id, isDir ? -1L : delegate.getLength(file)); - boolean isSpecial = (attributes & (NewVirtualFileSystem.BA_REGULAR | NewVirtualFileSystem.BA_DIRECTORY | NewVirtualFileSystem.BA_EXISTS)) == - NewVirtualFileSystem.BA_EXISTS; + boolean isSpecial = (attributes & (FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS)) == + FileUtil.BA_EXISTS; FSRecords.setFlags(id, (isDir ? IS_DIRECTORY_FLAG : 0) | (delegate.isWritable(file) ? 0 : IS_READ_ONLY) | (delegate.isSymLink(file) ? IS_SYMLINK : 0) | @@ -408,7 +408,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { VirtualFile fake = new FakeVirtualFile(parent, childName); int attributes = delegate.getBooleanAttributes(fake, -1); - if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) { + if ((attributes & FileUtil.BA_EXISTS) != 0) { int child = createAndCopyRecord(delegate, fake, parentId, attributes); FSRecords.updateList(parentId, ArrayUtil.append(children, child)); return child; @@ -673,6 +673,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } }; + @NotNull private static List validateEvents(@NotNull List events) { final List deletionEvents = Lists.newArrayList(); for (int i = 0, size = events.size(); i < size; i++) { @@ -756,25 +757,22 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { }; } else { - root = new VirtualDirectoryImpl(basePath, null, fs, rootId) { - @NotNull - @Override - public String getName() { - final String name = super.getName(); - - // TODO: HACK!!! Get to simpler solution. - if (getFileSystem() instanceof JarFileSystem) { - String jarName = name.substring(0, name.length() - JarFileSystem.JAR_SEPARATOR.length()); - return jarName.substring(jarName.lastIndexOf('/') + 1); - } - - return name; - } - }; + if (fs instanceof JarFileSystem) { + // optimization: for jar roots do not store base path in the myName field, use local FS file's getPath() + String parentPath = basePath.substring(0, basePath.indexOf(JarFileSystem.JAR_SEPARATOR)); + final VirtualFile parentLocalFile = LocalFileSystem.getInstance().findFileByPath(parentPath); + if (parentLocalFile == null) return null; + root = new JarRoot(fs, rootId, parentLocalFile); + } + else { + root = new VirtualDirectoryImpl(basePath, null, fs, rootId); + } + } + if (!fs.exists(root)) { + return null; } - if (!fs.exists(root)) return null; - int attributes = NewVirtualFileSystem.BA_DIRECTORY | NewVirtualFileSystem.BA_EXISTS; + int attributes = FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS; boolean newRoot = copyRecordFromDelegateFS(rootId, 0, root, fs, attributes); if (!newRoot) { if (fs.getTimeStamp(root) != FSRecords.getTimestamp(rootId)) { @@ -964,7 +962,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final NewVirtualFileSystem delegate = getDelegate(parent); VirtualFile fake = new FakeVirtualFile(parent, name); int attributes = delegate.getBooleanAttributes(fake, -1); - if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) { + if ((attributes & FileUtil.BA_EXISTS) != 0) { final int parentId = getFileId(parent); int childId = createAndCopyRecord(delegate, fake, parentId, attributes); appendIdToParentList(parentId, childId); @@ -973,7 +971,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } } - private static int createAndCopyRecord(@NotNull NewVirtualFileSystem delegateSystem, @NotNull VirtualFile delegateFile, int parentId, @NewVirtualFileSystem.FileBooleanAttributes int attributes) { + private static int createAndCopyRecord(@NotNull NewVirtualFileSystem delegateSystem, @NotNull VirtualFile delegateFile, int parentId, @FileUtil.FileBooleanAttributes int attributes) { int childId = FSRecords.createRecord(); copyRecordFromDelegateFS(childId, parentId, delegateFile, delegateSystem, attributes); return childId; @@ -1140,4 +1138,24 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } return delegate; } + + private static class JarRoot extends VirtualDirectoryImpl { + private final VirtualFile myParentLocalFile; + + public JarRoot(@NotNull NewVirtualFileSystem fs, int rootId, @NotNull VirtualFile parentLocalFile) { + super("", null, fs, rootId); + myParentLocalFile = parentLocalFile; + } + + @NotNull + @Override + public String getName() { + return myParentLocalFile.getName(); + } + + @Override + protected Object rawName() { + return myParentLocalFile.getPath() + JarFileSystem.JAR_SEPARATOR; + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 4b7cdb8a2e78..77abe7f40088 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.newvfs.persistent; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.ManagingFS; @@ -32,8 +33,6 @@ import org.jetbrains.annotations.NotNull; import java.util.*; -import static com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem.*; - /** * @author max */ @@ -53,14 +52,14 @@ public class RefreshWorker { public void scan() { final NewVirtualFile root = (NewVirtualFile)myRefreshRoot; NewVirtualFileSystem delegate = root.getFileSystem(); - final int rootAttributes = delegate.getBooleanAttributes(root, BA_EXISTS | BA_DIRECTORY); + final int rootAttributes = delegate.getBooleanAttributes(root, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY); - if (root.isDirty() && (rootAttributes & BA_EXISTS) == 0) { + if (root.isDirty() && (rootAttributes & FileUtil.BA_EXISTS) == 0) { scheduleDeletion(root); root.markClean(); } else { - if ((rootAttributes & BA_DIRECTORY) != 0) { + if ((rootAttributes & FileUtil.BA_DIRECTORY) != 0) { delegate = PersistentFS.replaceWithNativeFS(delegate); } @@ -106,7 +105,7 @@ public class RefreshWorker { else { for (VirtualFile child : file.getCachedChildren()) { final int childAttributes = delegate.getBooleanAttributes(child, -1); - if ((childAttributes & BA_EXISTS) != 0) { + if ((childAttributes & FileUtil.BA_EXISTS) != 0) { scheduleChildRefresh(file, child, delegate, childAttributes); } else { @@ -119,9 +118,9 @@ public class RefreshWorker { if (name.isEmpty()) continue; final VirtualFile fake = new FakeVirtualFile(file, name); - final int attributes = delegate.getBooleanAttributes(fake, BA_EXISTS | BA_DIRECTORY); - if ((attributes & BA_EXISTS) != 0) { - final boolean isDir = (attributes & BA_DIRECTORY) != 0; + final int attributes = delegate.getBooleanAttributes(fake, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY); + if ((attributes & FileUtil.BA_EXISTS) != 0) { + final boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0; scheduleCreation(file, name, isDir); } } @@ -150,20 +149,20 @@ public class RefreshWorker { } } - private static final int SPECIAL_MASK = BA_REGULAR | BA_DIRECTORY | BA_EXISTS; + private static final int SPECIAL_MASK = FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS; // todo[r.sh] compare link targets for files too private void scheduleChildRefresh(@NotNull VirtualFileSystemEntry parent, @NotNull VirtualFile child, @NotNull NewVirtualFileSystem delegate, - @FileBooleanAttributes int childAttributes) { + @FileUtil.FileBooleanAttributes int childAttributes) { final boolean currentIsDirectory = child.isDirectory(); final boolean currentIsSymlink = child.isSymLink(); final boolean currentIsSpecial = child.isSpecialFile(); final String currentLinkTarget = child instanceof SymlinkDirectory ? ((SymlinkDirectory)child).getTargetPath() : null; - final boolean upToDateIsDirectory = (childAttributes & BA_DIRECTORY) != 0; + final boolean upToDateIsDirectory = (childAttributes & FileUtil.BA_DIRECTORY) != 0; final boolean upToDateIsSymlink = delegate.isSymLink(child); - final boolean upToDateIsSpecial = (childAttributes & SPECIAL_MASK) == BA_EXISTS; + final boolean upToDateIsSpecial = (childAttributes & SPECIAL_MASK) == FileUtil.BA_EXISTS; final String upToDateLinkTarget = currentLinkTarget != null ? delegate.resolveSymLink(child) : null; if (currentIsDirectory != upToDateIsDirectory || diff --git a/platform/util/src/com/intellij/execution/process/BaseOSProcessHandler.java b/platform/util/src/com/intellij/execution/process/BaseOSProcessHandler.java index 4612ff03698a..9788ea6e3873 100644 --- a/platform/util/src/com/intellij/execution/process/BaseOSProcessHandler.java +++ b/platform/util/src/com/intellij/execution/process/BaseOSProcessHandler.java @@ -51,19 +51,23 @@ public class BaseOSProcessHandler extends ProcessHandler { return ExecutorServiceHolder.ourThreadExecutorsService.submit(task); } + @NotNull public Process getProcess() { return myProcess; } + @Override public void startNotify() { if (myCommandLine != null) { notifyTextAvailable(myCommandLine + '\n', ProcessOutputTypes.SYSTEM); } addProcessListener(new ProcessAdapter() { + @Override public void startNotified(final ProcessEvent event) { try { final OutputReader stdoutReader = new OutputReader(createProcessOutReader()) { + @Override protected void onTextAvailable(@NotNull String text) { notifyTextAvailable(text, ProcessOutputTypes.STDOUT); } @@ -75,6 +79,7 @@ public class BaseOSProcessHandler extends ProcessHandler { }; final OutputReader stderrReader = new OutputReader(createProcessErrReader()) { + @Override protected void onTextAvailable(@NotNull String text) { notifyTextAvailable(text, ProcessOutputTypes.STDERR); } @@ -135,6 +140,7 @@ public class BaseOSProcessHandler extends ProcessHandler { return new InputStreamReader(streamToRead, charset); } + @Override protected void destroyProcessImpl() { try { closeStreams(); @@ -148,8 +154,10 @@ public class BaseOSProcessHandler extends ProcessHandler { getProcess().destroy(); } + @Override protected void detachProcessImpl() { final Runnable runnable = new Runnable() { + @Override public void run() { closeStreams(); @@ -170,10 +178,12 @@ public class BaseOSProcessHandler extends ProcessHandler { } } + @Override public boolean detachIsDefault() { return false; } + @Override public OutputStream getProcessInput() { return myProcess.getOutputStream(); } @@ -194,6 +204,7 @@ public class BaseOSProcessHandler extends ProcessHandler { private static ThreadPoolExecutor createServiceImpl() { return new ThreadPoolExecutor(10, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue(), new ThreadFactory() { + @Override @SuppressWarnings({"HardCodedStringLiteral"}) public Thread newThread(Runnable r) { return new Thread(r, "OSProcessHandler pooled thread"); @@ -213,6 +224,7 @@ public class BaseOSProcessHandler extends ProcessHandler { public ProcessWaitFor(final Process process) { myWaitForThreadFuture = executeOnPooledThread(new Runnable() { + @Override public void run() { int exitCode = 0; try { diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 923655c66b55..a3837cda2ba5 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -28,6 +28,7 @@ import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Stack; import com.intellij.util.io.URLUtil; +import org.intellij.lang.annotations.MagicConstant; import org.intellij.lang.annotations.RegExp; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -57,6 +58,8 @@ public class FileUtil { private static final long CHANNELS_COPYING_LIMIT = 5L * MEGABYTE; private static String ourCanonicalTempPathCache = null; private static final int MAX_FILE_DELETE_ATTEMPTS = 10; + public static final Method JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD; + public static final Object/* java.io.FileSystem */ JAVA_IO_FILESYSTEM; @Nullable public static String getRelativePath(File base, File file) { @@ -613,7 +616,10 @@ public class FileUtil { String parentDirPath = file.getParent(); if (parentDirPath != null) { final File parentFile = new File(parentDirPath); - return parentFile.exists() && parentFile.isDirectory() || parentFile.mkdirs(); + int attributes = getBooleanAttributes(file); + boolean ok = attributes != -1 && (attributes & (BA_EXISTS | BA_DIRECTORY)) == (BA_EXISTS | BA_DIRECTORY) + || parentFile.exists() && parentFile.isDirectory(); + return ok || parentFile.mkdirs(); } } return true; @@ -1327,4 +1333,53 @@ public class FileUtil { } return firstLine.contains(marker); } + + // copied from FileSystem: they are package local there + public static final int BA_EXISTS = 0x01; + public static final int BA_REGULAR = 0x02; + public static final int BA_DIRECTORY = 0x04; + public static final int BA_HIDDEN = 0x08; + + // todo[r.sh] use NIO2 API after migration to JDK 7 + // returns -1 if could not get attributes + @MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN}) + public static int getBooleanAttributes(@NotNull File f) { + if (JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD != null) { + try { + Object flags = JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD.invoke(JAVA_IO_FILESYSTEM, f); + return ((Integer)flags).intValue(); + } + catch (Exception ignored) { } + } + return -1; + } + + @MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN}) + public @interface FileBooleanAttributes {} + + + static { + Object fs; + Method getBooleanAttributes; + try { + Class fsClass = Class.forName("java.io.FileSystem"); + Method getFileSystem = fsClass.getMethod("getFileSystem"); + getFileSystem.setAccessible(true); + fs = getFileSystem.invoke(null); + getBooleanAttributes = fsClass.getDeclaredMethod("getBooleanAttributes", File.class); + if (fs == null || getBooleanAttributes == null) { + fs = null; + getBooleanAttributes = null; + } + else { + getBooleanAttributes.setAccessible(true); + } + } + catch (Exception e) { + fs = null; + getBooleanAttributes = null; + } + JAVA_IO_FILESYSTEM = fs; + JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD = getBooleanAttributes; + } } diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 28c14d21d91b..7ef35d90713f 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -122,10 +122,12 @@ public abstract class TestObject implements JavaCommandLine { public abstract String suggestActionName(); + @Override public RunnerSettings getRunnerSettings() { return myRunnerSettings; } + @Override public ConfigurationPerRunnerSettings getConfigurationSettings() { return myConfigurationSettings; } @@ -145,6 +147,7 @@ public abstract class TestObject implements JavaCommandLine { } private static final TestObject NOT_CONFIGURED = new TestObject(null, null, null, null) { + @Override public RefactoringElementListener getListener(final PsiElement element, final JUnitConfiguration configuration) { return null; } @@ -233,6 +236,7 @@ public abstract class TestObject implements JavaCommandLine { } } + @Override public JavaParameters getJavaParameters() throws ExecutionException { if (myJavaParameters == null) { myJavaParameters = new JavaParameters(); @@ -246,6 +250,7 @@ public abstract class TestObject implements JavaCommandLine { return myJavaParameters; } + @Override public ExecutionResult execute(final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException { final JUnitProcessHandler handler = createHandler(); final RunnerSettings runnerSettings = getRunnerSettings(); @@ -269,6 +274,7 @@ public abstract class TestObject implements JavaCommandLine { if (model != null) { handler.getOut().setDispatchListener(model.getNotifier()); Disposer.register(model, new Disposable() { + @Override public void dispose() { handler.getOut().setDispatchListener(DispatchListener.DEAF); } @@ -293,16 +299,19 @@ public abstract class TestObject implements JavaCommandLine { FileUtil.delete(myListenersFile); } IJSwingUtilities.invoke(new Runnable() { + @Override public void run() { - unboundOutputRoot.flush(); - packetsReceiver.checkTerminated(); - final JUnitRunningModel model = packetsReceiver.getModel(); - notifyByBalloon(model, consoleProperties); - - if (ApplicationManager.getApplication().isUnitTestMode()) { - Disposer.dispose(consoleView); + try { + unboundOutputRoot.flush(); + packetsReceiver.checkTerminated(); + final JUnitRunningModel model = packetsReceiver.getModel(); + notifyByBalloon(model, consoleProperties); + } + finally { + if (ApplicationManager.getApplication().isUnitTestMode()) { + Disposer.dispose(consoleView); + } } - } }); } @@ -312,6 +321,7 @@ public abstract class TestObject implements JavaCommandLine { final String text = event.getText(); final ConsoleViewContentType consoleViewType = ConsoleViewContentType.getConsoleViewType(outputType); final Printable printable = new Printable() { + @Override public void printOn(final Printer printer) { printer.print(text, consoleViewType); } @@ -335,6 +345,7 @@ public abstract class TestObject implements JavaCommandLine { final RerunFailedTestsAction rerunFailedTestsAction = new RerunFailedTestsAction(consoleView.getComponent()); rerunFailedTestsAction.init(consoleProperties, myRunnerSettings, myConfigurationSettings); rerunFailedTestsAction.setModelProvider(new Getter() { + @Override public TestFrameworkRunningModel get() { return packetsReceiver.getModel(); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java index 8aedf47d3258..b42fd6bf0520 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/make/Form2ByteCodeCompiler.java @@ -59,11 +59,13 @@ import java.util.StringTokenizer; public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.make.Form2ByteCodeCompiler"); + @Override @NotNull public String getDescription() { return UIDesignerBundle.message("component.gui.designer.form.to.bytecode.compiler"); } + @Override public boolean validateConfiguration(CompileScope scope) { return true; } @@ -83,6 +85,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { return new URLClassLoader(urls.toArray(new URL[urls.size()]), null); } + @Override @NotNull public ProcessingItem[] getProcessingItems(final CompileContext context) { final Project project = context.getProject(); @@ -93,6 +96,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { final ArrayList items = new ArrayList(); ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override public void run() { final CompileScope scope = context.getCompileScope(); final CompileScope projectScope = context.getProjectCompileScope(); @@ -257,6 +261,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { return outerQualifiedName.replace('.','/') + _className.substring(outerQualifiedName.length()).replace('.','$'); } + @Override public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) { final ArrayList compiledItems = new ArrayList(); @@ -298,21 +303,23 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { final VirtualFile formFile = item.getFormFile(); context.getProgressIndicator().setText2(formFile.getPresentableUrl()); - final Document doc = ApplicationManager.getApplication().runReadAction(new Computable() { - public Document compute() { + final String text = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { if (!belongsToCompileScope(context, formFile, item.getClassToBindFQname())) { return null; } - return FileDocumentManager.getInstance().getDocument(formFile); + Document document = FileDocumentManager.getInstance().getDocument(formFile); + return document == null ? null : document.getText(); } }); - if (doc == null) { + if (text == null) { continue; // does not belong to current scope } final LwRootContainer rootContainer; try { - rootContainer = Utils.getRootContainer(doc.getText(), new CompiledClassPropertiesProvider(loader)); + rootContainer = Utils.getRootContainer(text, new CompiledClassPropertiesProvider(loader)); } catch (Exception e) { addMessage(context, UIDesignerBundle.message("error.cannot.process.form.file", e), formFile, CompilerMessageCategory.ERROR); @@ -326,6 +333,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { new PsiNestedFormLoader(module), false, new PsiClassWriter(module)); ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override public void run() { codeGenerator.patchFile(classFile); } @@ -371,6 +379,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { } } + @Override public ValidityState createValidityState(final DataInput in) throws IOException { return TimestampValidityState.load(in); } @@ -406,6 +415,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { myState = new TimestampValidityState(formFile.getTimeStamp()); } + @Override @NotNull public VirtualFile getFile() { return myClassFile; @@ -419,6 +429,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler { return myClassToBindFQname; } + @Override public ValidityState getValidityState() { return myState; }