diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index c7fc582f5f2c..fd8ee019e44b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -117,7 +117,7 @@ public class BuildManager implements ApplicationComponent{ ApplicationManager.getApplication().executeOnPooledThread(command); } }; - private final SequentialTaskExecutor myEventsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor); + private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor); private final Map myProjectDataMap = Collections.synchronizedMap(new HashMap()); private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); @@ -187,7 +187,7 @@ public class BuildManager implements ApplicationComponent{ private void doNotify(final Collection paths, final boolean notifyDeletion) { // ensure events processed in the order they arrived - myEventsProcessor.submit(new Runnable() { + myRequestsProcessor.submit(new Runnable() { @Override public void run() { synchronized (myProjectDataMap) { @@ -364,7 +364,7 @@ public class BuildManager implements ApplicationComponent{ final Collection modules, final Collection artifacts, final Collection paths, - final Map userData, DefaultMessageHandler handler) { + final Map userData, final DefaultMessageHandler handler) { final String projectPath = getProjectPath(project); final UUID sessionId = UUID.randomUUID(); @@ -375,127 +375,153 @@ public class BuildManager implements ApplicationComponent{ myListenPort = startListening(); } catch (Exception e) { - myMessageDispatcher.unregisterBuildMessageHandler(sessionId); handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null)); handler.sessionTerminated(); return null; } } - final CmdlineRemoteProto.Message.ControllerMessage params; - CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals; - if (globals == null) { - globals = buildGlobalSettings(); - myGlobals = globals; - } - - CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges = null; - final SequentialTaskExecutor projectTaskQueue; - synchronized (myProjectDataMap) { - ProjectData data = myProjectDataMap.get(projectPath); - if (data == null) { - data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor)); - myProjectDataMap.put(projectPath, data); - } - if (isRebuild) { - data.dropChanges(); - } - if (IS_UNIT_TEST_MODE) { - LOG.info("Scheduling build for " + projectPath + "; CHANGED: " + data.myChanged + "; DELETED: " + data.myDeleted); - } - currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent(); - projectTaskQueue = data.taskQueue; - } - - if (isRebuild) { - params = CmdlineProtoUtil.createRebuildRequest(projectPath, userData, globals); - } - else { - params = isMake ? - CmdlineProtoUtil.createMakeRequest(projectPath, modules, artifacts, userData, globals, currentFSChanges) : - CmdlineProtoUtil.createForceCompileRequest(projectPath, modules, artifacts, paths, userData, globals, currentFSChanges); - } - - myMessageDispatcher.registerBuildMessageHandler(sessionId, handler, params); - - final RequestFuture future = new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { - @Override - public void cancel(RequestFuture future) throws Exception { - myMessageDispatcher.cancelSession(future.getRequestID()); - } - }); - - projectTaskQueue.submit(new Runnable() { - @Override - public void run() { - try { - if (project.isDisposed()) { - future.cancel(false); + try { + final RequestFuture future = new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { + @Override + public void cancel(RequestFuture future) throws Exception { + myMessageDispatcher.cancelSession(future.getRequestID()); + } + }); + // by using the same queue that processes events we ensure that + // the build will be aware of all events that have happened before this request + myRequestsProcessor.submit(new Runnable() { + @Override + public void run() { + if (future.isCancelled() || project.isDisposed()) { + handler.sessionTerminated(); + future.setDone(); return; } - myBuildsInProgress.put(projectPath, future); - final Process process = launchBuildProcess(project, myListenPort, sessionId); - final OSProcessHandler processHandler = new OSProcessHandler(process, null) { - @Override - protected boolean shouldDestroyProcessRecursively() { - return true; - } - }; - final StringBuilder stdErrOutput = new StringBuilder(); - processHandler.addProcessListener(new ProcessAdapter() { - @Override - public void processTerminated(ProcessEvent event) { - final BuilderMessageHandler handler = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); - if (handler != null) { - handler.sessionTerminated(); - } - } - @Override - public void onTextAvailable(ProcessEvent event, Key outputType) { - // re-translate builder's output to idea.log - final String text = event.getText(); - if (!StringUtil.isEmptyOrSpaces(text)) { - LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim()); - if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) { - stdErrOutput.append(text); - } - } + CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals; + if (globals == null) { + globals = buildGlobalSettings(); + myGlobals = globals; + } + CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges = null; + final SequentialTaskExecutor projectTaskQueue; + synchronized (myProjectDataMap) { + ProjectData data = myProjectDataMap.get(projectPath); + if (data == null) { + data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor)); + myProjectDataMap.put(projectPath, data); } - }); - processHandler.startNotify(); - final boolean terminated = processHandler.waitFor(); - if (terminated) { - final int exitValue = processHandler.getProcess().exitValue(); - if (exitValue != 0) { - final StringBuilder msg = new StringBuilder(); - msg.append("Abnormal build process termination: "); - if (stdErrOutput.length() > 0) { - msg.append("\n").append(stdErrOutput); - } - else { - msg.append("unknown error"); - } - future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null)); + if (isRebuild) { + data.dropChanges(); } + if (IS_UNIT_TEST_MODE) { + LOG.info("Scheduling build for " + projectPath + "; CHANGED: " + new HashSet(data.myChanged) + "; DELETED: " + new HashSet(data.myDeleted)); + } + currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent(); + projectTaskQueue = data.taskQueue; + } + + final CmdlineRemoteProto.Message.ControllerMessage params; + if (isRebuild) { + params = CmdlineProtoUtil.createRebuildRequest(projectPath, userData, globals); } else { - future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); + params = isMake ? + CmdlineProtoUtil.createMakeRequest(projectPath, modules, artifacts, userData, globals, currentFSChanges) : + CmdlineProtoUtil.createForceCompileRequest(projectPath, modules, artifacts, paths, userData, globals, currentFSChanges); + } + + myMessageDispatcher.registerBuildMessageHandler(sessionId, handler, params); + + try { + projectTaskQueue.submit(new Runnable() { + @Override + public void run() { + try { + if (project.isDisposed()) { + myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + handler.sessionTerminated(); + return; + } + myBuildsInProgress.put(projectPath, future); + final Process process = launchBuildProcess(project, myListenPort, sessionId); + final OSProcessHandler processHandler = new OSProcessHandler(process, null) { + @Override + protected boolean shouldDestroyProcessRecursively() { + return true; + } + }; + final StringBuilder stdErrOutput = new StringBuilder(); + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void processTerminated(ProcessEvent event) { + final BuilderMessageHandler handler = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + if (handler != null) { + handler.sessionTerminated(); + } + } + + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + // re-translate builder's output to idea.log + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim()); + if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) { + stdErrOutput.append(text); + } + } + } + }); + processHandler.startNotify(); + final boolean terminated = processHandler.waitFor(); + if (terminated) { + final int exitValue = processHandler.getProcess().exitValue(); + if (exitValue != 0) { + final StringBuilder msg = new StringBuilder(); + msg.append("Abnormal build process termination: "); + if (stdErrOutput.length() > 0) { + msg.append("\n").append(stdErrOutput); + } + else { + msg.append("unknown error"); + } + future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null)); + } + } + else { + future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); + } + } + catch (ExecutionException e) { + myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e)); + handler.sessionTerminated(); + } + finally { + myBuildsInProgress.remove(projectPath); + future.setDone(); + } + } + }); + } + catch (Throwable e) { + myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + handler.sessionTerminated(); + future.setDone(); } } - catch (ExecutionException e) { - myMessageDispatcher.unregisterBuildMessageHandler(sessionId); - future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e)); - future.getMessageHandler().sessionTerminated(); - } - finally { - myBuildsInProgress.remove(projectPath); - future.setDone(); - } - } - }); + }); - return future; + return future; + } + catch (Throwable e) { + handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null)); + handler.sessionTerminated(); + } + + return null; } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java index 19785a247184..8f9a2f0059dc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java @@ -21,6 +21,9 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.impl.watch.*; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.icons.AllIcons; +import com.intellij.openapi.editor.SyntaxHighlighterColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.RowIcon; @@ -194,16 +197,30 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { valueLabel = DebuggerUtilsEx.truncateString(valueLabel); + final SimpleTextAttributes valueLabelAttribs; + if (valueDescriptor.isDirty()) { + valueLabelAttribs = XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES; + } + else { + TextAttributes highlightingAttribs = null; + if (valueDescriptor.isNull()){ + highlightingAttribs = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.KEYWORD); + } + else if (valueDescriptor.isString()) { + highlightingAttribs = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.STRING); + } + valueLabelAttribs = highlightingAttribs != null? SimpleTextAttributes.fromTextAttributes(highlightingAttribs) : DEFAULT_ATTRIBUTES; + } + final EvaluateException exception = descriptor.getEvaluateException(); if(exception != null) { final String errorMessage = exception.getMessage(); - if(valueLabel.endsWith(errorMessage)) { - appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES); + appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), valueLabelAttribs); descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES); } else { - appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES); + appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueLabelAttribs); descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES); } } @@ -212,7 +229,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { descriptorText.append(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES); } else { - appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES); + appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueLabelAttribs); } } } @@ -226,7 +243,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { } private static void appendValueTextWithEscapesRendering(SimpleColoredText descriptorText, String valueText, final SimpleTextAttributes attribs) { - final SimpleTextAttributes boldAttribs = attribs.derive(SimpleTextAttributes.STYLE_BOLD, null, Color.lightGray, null); + SimpleTextAttributes escapeAttribs = null; final StringBuilder buf = new StringBuilder(); boolean slashFound = false; for (int idx= 0; idx < valueText.length(); idx++) { @@ -238,10 +255,21 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { descriptorText.append(buf.toString(), attribs); buf.setLength(0); } - if (ch != '\\' && ch != '\"') { - descriptorText.append("\\", boldAttribs); + + if (escapeAttribs == null) { // lazy init + final TextAttributes fromHighlighter = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.VALID_STRING_ESCAPE); + if (fromHighlighter != null) { + escapeAttribs = SimpleTextAttributes.fromTextAttributes(fromHighlighter); + } + else { + escapeAttribs = DEFAULT_ATTRIBUTES.derive(SimpleTextAttributes.STYLE_BOLD, Color.gray, null, null); + } } - descriptorText.append(String.valueOf(ch), boldAttribs); + + if (ch != '\\' && ch != '\"') { + descriptorText.append("\\", escapeAttribs); + } + descriptorText.append(String.valueOf(ch), escapeAttribs); } else { buf.append('\\').append(ch); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 3694dbb7cde7..3e1114500faa 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -93,8 +93,13 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements public boolean isNull() { return myValue == null; } - - public boolean isPrimitive() { + + @Override + public boolean isString() { + return myValue instanceof StringReference; + } + + public boolean isPrimitive() { return myValue instanceof PrimitiveValue; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java index 77b807ff3f48..d4a444e898b6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/ValueDescriptor.java @@ -40,6 +40,7 @@ public interface ValueDescriptor extends NodeDescriptor{ boolean isLvalue(); boolean isNull(); boolean isPrimitive(); + boolean isString(); @Nullable ValueMarkup getMarkup(final DebugProcess debugProcess); diff --git a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java index 5507aee2972d..f46ded741d0b 100644 --- a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java +++ b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegTableUI.java @@ -53,6 +53,8 @@ public class BegTableUI extends BasicTableUI { public void installUI(JComponent c) { super.installUI(c); c.getActionMap().put(START_EDITING_ACTION_KEY, new StartEditingAction()); + // fix missing escape shortcut + c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("pressed ESCAPE"), "cancel"); } protected KeyListener createKeyListener() { diff --git a/plugins/devkit/resources/fileTemplates/j2ee/plugin.xml.ft b/plugins/devkit/resources/fileTemplates/j2ee/plugin.xml.ft index b3b4420020e7..908c960f915e 100644 --- a/plugins/devkit/resources/fileTemplates/j2ee/plugin.xml.ft +++ b/plugins/devkit/resources/fileTemplates/j2ee/plugin.xml.ft @@ -1,9 +1,13 @@ Plugin name here - short description of the plugin 1.0 YourCompany + + most HTML tags may be used + ]]> +