Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2012-07-09 17:21:50 +02:00
16 changed files with 191 additions and 105 deletions
@@ -46,6 +46,9 @@ public abstract class VFileEvent {
/**
* Returns the VirtualFile which this event belongs to.
* In some cases it may be null - it is not guaranteed that there is such file.
*
* NB: Use this method with caution, because {@link com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent#getFile()} needs
* {@link VirtualFile#findChild(String)} which may be a performance leak.
*/
@Nullable
public abstract VirtualFile getFile();
@@ -567,4 +567,17 @@ public class AndroidCommonUtils {
}
}
}
@NotNull
public static String getStackTrace(@NotNull Throwable t) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
try {
t.printStackTrace(writer);
return stringWriter.toString();
}
finally {
writer.close();
}
}
}
@@ -21,10 +21,7 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ExecutionStatus;
import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -53,9 +50,10 @@ public class RunAndroidAvdManagerAction extends AndroidRunSdkToolAction {
commandLine.setExePath(toolPath);
commandLine.addParameter("avd");
final StringBuilder messageBuilder = new StringBuilder();
final StringBuildingOutputProcessor processor = new StringBuildingOutputProcessor();
try {
if (AndroidUtils.executeCommand(commandLine, messageBuilder, 500) == ExecutionStatus.TIMEOUT) {
if (AndroidUtils.executeCommand(commandLine, processor, WaitingStrategies.WaitForTime.getInstance(500)) ==
ExecutionStatus.TIMEOUT) {
return;
}
}
@@ -64,12 +62,12 @@ public class RunAndroidAvdManagerAction extends AndroidRunSdkToolAction {
return;
}
final String message = messageBuilder.toString();
final String message = processor.getMessage();
if (message.contains("Error")) {
commandLine = new GeneralCommandLine();
commandLine.setExePath(toolPath);
try {
AndroidUtils.executeCommand(commandLine, messageBuilder, 0);
AndroidUtils.executeCommand(commandLine, null, WaitingStrategies.DoNotWait.getInstance());
}
catch (ExecutionException e) {
LOG.error(e);
@@ -21,10 +21,7 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ExecutionStatus;
import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -49,9 +46,10 @@ public class RunAndroidSdkManagerAction extends AndroidRunSdkToolAction {
commandLine.setExePath(toolPath);
commandLine.addParameter("sdk");
final StringBuilder messageBuilder = new StringBuilder();
final StringBuildingOutputProcessor processor = new StringBuildingOutputProcessor();
try {
if (AndroidUtils.executeCommand(commandLine, messageBuilder, 500) == ExecutionStatus.TIMEOUT) {
if (AndroidUtils.executeCommand(commandLine, processor, WaitingStrategies.WaitForTime.getInstance(500)) ==
ExecutionStatus.TIMEOUT) {
return;
}
}
@@ -60,12 +58,12 @@ public class RunAndroidSdkManagerAction extends AndroidRunSdkToolAction {
return;
}
final String message = messageBuilder.toString();
final String message = processor.getMessage();
if (message.contains("Error")) {
commandLine = new GeneralCommandLine();
commandLine.setExePath(toolPath);
try {
AndroidUtils.executeCommand(commandLine, messageBuilder, 0);
AndroidUtils.executeCommand(commandLine, null, WaitingStrategies.DoNotWait.getInstance());
}
catch (ExecutionException e) {
LOG.error(e);
@@ -27,6 +27,8 @@ import com.intellij.openapi.util.Computable;
import com.intellij.util.containers.HashMap;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ExecutionStatus;
import org.jetbrains.android.util.StringBuildingOutputProcessor;
import org.jetbrains.android.util.WaitingStrategies;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.execution.MavenExternalParameters;
import org.jetbrains.idea.maven.execution.MavenRunnerParameters;
@@ -79,10 +81,11 @@ public class AndroidMavenExecutor {
}
GeneralCommandLine commandLine = CommandLineBuilder.createFromJavaParameters(javaParams);
StringBuilder messageBuilder = new StringBuilder();
boolean success = AndroidUtils.executeCommand(commandLine, messageBuilder, null) == ExecutionStatus.SUCCESS;
String message = messageBuilder.toString();
if (message != null && !success) {
final StringBuildingOutputProcessor processor = new StringBuildingOutputProcessor();
boolean success =
AndroidUtils.executeCommand(commandLine, processor, WaitingStrategies.WaitForever.getInstance()) == ExecutionStatus.SUCCESS;
String message = processor.getMessage();
if (!success) {
LOG.info(message);
String lcmessage = message.toLowerCase();
int buildErrorIndex = lcmessage.indexOf(BUILD_ERROR_INDICATOR);
@@ -26,6 +26,7 @@ import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.intellij.CommonBundle;
import com.intellij.ProjectTopics;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.process.ProcessHandler;
@@ -84,9 +85,7 @@ import org.jetbrains.android.resourceManagers.LocalResourceManager;
import org.jetbrains.android.resourceManagers.ResourceManager;
import org.jetbrains.android.resourceManagers.SystemResourceManager;
import org.jetbrains.android.sdk.*;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -401,7 +400,7 @@ public class AndroidFacet extends Facet<AndroidFacetConfiguration> {
return myAvdManager;
}
public void launchEmulator(@Nullable final String avdName, @NotNull final String commands, @Nullable ProcessHandler handler) {
public void launchEmulator(@Nullable final String avdName, @NotNull final String commands, @NotNull final ProcessHandler handler) {
AndroidPlatform platform = getConfiguration().getAndroidPlatform();
if (platform != null) {
final String emulatorPath = platform.getSdkData().getLocation() + File.separator + AndroidCommonUtils
@@ -418,10 +417,25 @@ public class AndroidFacet extends Facet<AndroidFacetConfiguration> {
commandLine.addParameter(s);
}
}
if (handler != null) {
handler.notifyTextAvailable(commandLine.getCommandLineString() + '\n', ProcessOutputTypes.STDOUT);
}
AndroidUtils.runExternalToolInSeparateThread(commandLine, handler);
handler.notifyTextAvailable(commandLine.getCommandLineString() + '\n', ProcessOutputTypes.STDOUT);
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
try {
AndroidUtils.executeCommand(commandLine, new OutputProcessor() {
@Override
public void onTextAvailable(@NotNull String text) {
handler.notifyTextAvailable(text, ProcessOutputTypes.STDOUT);
}
}, WaitingStrategies.WaitForTime.getInstance(5000));
}
catch (ExecutionException e) {
final String stackTrace = AndroidCommonUtils.getStackTrace(e);
handler.notifyTextAvailable(stackTrace, ProcessOutputTypes.STDERR);
}
}
});
}
}
@@ -281,7 +281,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
@Override
public void run() {
final Project project = module.getProject();
AndroidUtils.runExternalTool(commandLine, null, true, project);
AndroidUtils.runExternalTool(commandLine, project);
if (finalTempContentRoot != null) {
final File[] children = finalTempContentRoot.listFiles();
@@ -22,6 +22,8 @@ import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.intellij.CommonBundle;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -30,10 +32,7 @@ import com.intellij.ui.DoubleClickListener;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidSdkData;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.BooleanCellRenderer;
import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -122,7 +121,13 @@ public class AvdChooser extends DialogWrapper {
public void actionPerformed(ActionEvent e) {
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath(androidToolPath);
AndroidUtils.runExternalToolInSeparateThread(commandLine, null);
try {
AndroidUtils.executeCommand(commandLine, new StringBuildingOutputProcessor(), WaitingStrategies.DoNotWait.getInstance());
}
catch (ExecutionException e1) {
final String message = e1.getMessage() != null ? e1.getMessage() : "Cannot launch AVD manager";
Messages.showErrorDialog(myPanel, message, CommonBundle.getErrorTitle());
}
}
});
updateTable();
@@ -68,6 +68,7 @@ import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
import org.jetbrains.android.sdk.AndroidSdkType;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.android.util.AndroidSdkNotConfiguredException;
import org.jetbrains.annotations.NonNls;
@@ -80,8 +81,6 @@ import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -454,7 +453,7 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
if (messageBuilder.length() > 0) {
messageBuilder.append("\n\n");
}
messageBuilder.append(getStackTrace(t));
messageBuilder.append(AndroidCommonUtils.getStackTrace(t));
}
final DialogWrapper wrapper = new DialogWrapper(myProject, false) {
@@ -478,19 +477,6 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
wrapper.show();
}
@NotNull
private static String getStackTrace(@NotNull Throwable t) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
try {
t.printStackTrace(writer);
return stringWriter.toString();
}
finally {
writer.close();
}
}
@Nullable
private TextEditor getActiveLayoutXmlEditor() {
FileEditor[] fileEditors = myFileEditorManager.getSelectedEditors();
@@ -30,7 +30,9 @@ import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.process.*;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.facet.FacetManager;
@@ -339,27 +341,29 @@ public class AndroidUtils {
@NotNull
public static ExecutionStatus executeCommand(@NotNull GeneralCommandLine commandLine,
@NotNull final StringBuilder messageBuilder,
@Nullable Integer timeout) throws ExecutionException {
@Nullable final OutputProcessor processor,
@Nullable WaitingStrategies.Strategy strategy) throws ExecutionException {
LOG.info(commandLine.getCommandLineString());
OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), "");
final StringBuffer buffer = new StringBuffer();
final ProcessAdapter listener = new ProcessAdapter() {
public void onTextAvailable(final ProcessEvent event, final Key outputType) {
buffer.append(event.getText());
if (processor != null) {
final String message = event.getText();
processor.onTextAvailable(message);
}
}
};
if (timeout == null || timeout > 0) {
if (!(strategy instanceof WaitingStrategies.DoNotWait)) {
handler.addProcessListener(listener);
}
handler.startNotify();
try {
if (timeout != null) {
if (timeout > 0) {
handler.waitFor(timeout);
if (!(strategy instanceof WaitingStrategies.WaitForever)) {
if (strategy instanceof WaitingStrategies.WaitForTime) {
handler.waitFor(((WaitingStrategies.WaitForTime)strategy).getTimeMs());
}
}
else {
@@ -374,58 +378,37 @@ public class AndroidUtils {
return ExecutionStatus.TIMEOUT;
}
if (timeout == null || timeout > 0) {
if (!(strategy instanceof WaitingStrategies.DoNotWait)) {
handler.removeProcessListener(listener);
final String message = buffer.toString();
messageBuilder.append(message);
LOG.info(message);
}
int exitCode = handler.getProcess().exitValue();
return exitCode == 0 ? ExecutionStatus.SUCCESS : ExecutionStatus.ERROR;
}
public static void runExternalToolInSeparateThread(@NotNull final GeneralCommandLine commandLine,
@Nullable final ProcessHandler processHandler) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
runExternalTool(commandLine, processHandler, false, null);
}
});
}
public static void runExternalTool(@NotNull GeneralCommandLine commandLine,
@Nullable ProcessHandler processHandler,
boolean printOutputToAndroidConsole,
@Nullable final Project project) {
StringBuilder messageBuilder = new StringBuilder();
public static void runExternalTool(@NotNull GeneralCommandLine commandLine, @Nullable final Project project) {
final StringBuildingOutputProcessor processor = new StringBuildingOutputProcessor();
String result;
boolean success = false;
try {
success = executeCommand(commandLine, messageBuilder, null) == ExecutionStatus.SUCCESS;
result = messageBuilder.toString();
success = executeCommand(commandLine, processor, WaitingStrategies.WaitForever.getInstance()) == ExecutionStatus.SUCCESS;
result = processor.getMessage();
}
catch (ExecutionException e) {
result = e.getMessage();
}
if (result != null) {
if (printOutputToAndroidConsole) {
final ConsoleViewContentType contentType = success ?
ConsoleViewContentType.NORMAL_OUTPUT :
ConsoleViewContentType.ERROR_OUTPUT;
final String finalResult = result;
assert project != null;
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
printMessageToConsole(project, finalResult, contentType);
}
});
}
else if (processHandler != null) {
processHandler.notifyTextAvailable(result + '\n', ProcessOutputTypes.STDOUT);
}
final ConsoleViewContentType contentType = success ?
ConsoleViewContentType.NORMAL_OUTPUT :
ConsoleViewContentType.ERROR_OUTPUT;
final String finalResult = result;
assert project != null;
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
printMessageToConsole(project, finalResult, contentType);
}
});
}
}
@@ -0,0 +1,10 @@
package org.jetbrains.android.util;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
public interface OutputProcessor {
void onTextAvailable(@NotNull String text);
}
@@ -0,0 +1,20 @@
package org.jetbrains.android.util;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
public class StringBuildingOutputProcessor implements OutputProcessor {
private final StringBuffer myBuffer = new StringBuffer();
@Override
public void onTextAvailable(@NotNull String text) {
myBuffer.append(text);
}
@NotNull
public String getMessage() {
return myBuffer.toString();
}
}
@@ -0,0 +1,55 @@
package org.jetbrains.android.util;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
public class WaitingStrategies {
public static abstract class Strategy {
private Strategy() {
}
}
public static class DoNotWait extends Strategy {
private static final DoNotWait INSTANCE = new DoNotWait();
private DoNotWait() {
}
@NotNull
public static DoNotWait getInstance() {
return INSTANCE;
}
}
public static class WaitForTime extends Strategy {
private final int myTimeMs;
private WaitForTime(int timeMs) {
assert timeMs > 0;
myTimeMs = timeMs;
}
@NotNull
public static WaitForTime getInstance(int timeMs) {
return new WaitForTime(timeMs);
}
public int getTimeMs() {
return myTimeMs;
}
}
public static class WaitForever extends Strategy {
private static final WaitForever INSTANCE = new WaitForever();
private WaitForever() {
}
@NotNull
public static WaitForever getInstance() {
return INSTANCE;
}
}
}
@@ -112,11 +112,11 @@ final class GitRepositoryUpdater implements Disposable, BulkFileListener {
boolean rebaseFileChanged = false;
boolean mergeFileChanged = false;
for (VFileEvent event : events) {
final VirtualFile file = event.getFile();
if (file == null) {
String filePath = event.getPath();
if (filePath == null) {
continue;
}
String filePath = GitFileUtils.stripFileProtocolPrefix(file.getPath());
filePath = GitFileUtils.stripFileProtocolPrefix(filePath);
if (myRepositoryFiles.isConfigFile(filePath)) {
configChanged = true;
} else if (myRepositoryFiles.isHeadFile(filePath)) {
@@ -227,11 +227,10 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
if (allChanged) {
break;
}
VirtualFile file = event.getFile();
if (file == null) {
String path = event.getPath();
if (path == null) {
continue;
}
String path = file.getPath();
if (totalRefreshNeeded(path)) {
allChanged = true;
}
@@ -25,7 +25,6 @@ import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsListener;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
@@ -79,8 +78,8 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
VirtualFile file = event.getFile();
if (file != null && file.getName().equalsIgnoreCase(GitUtil.DOT_GIT) && file.isDirectory()) {
String filePath = event.getPath();
if (filePath != null && filePath.toLowerCase().endsWith(GitUtil.DOT_GIT)) {
scanIfReady();
}
}