blob: 5d681fc1d9d10ae8296952faa6499b9eda39bf9c [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.config.execution;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.OpenFileHyperlinkInfo;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.OutputStream;
public final class PlainTextView implements AntOutputView {
private final ConsoleView myConsole;
private final Project myProject;
private String myCommandLine;
private final LightProcessHandler myProcessHandler = new LightProcessHandler();
public PlainTextView(Project project) {
myProject = project;
TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
builder.addFilter(new AntMessageFilter());
builder.addFilter(new JUnitFilter());
myConsole = builder.getConsole();
myConsole.attachToProcess(myProcessHandler);
}
public void dispose() {
Disposer.dispose(myConsole);
}
@Override
public String getId() {
return "_text_view_";
}
public JComponent getComponent() {
return myConsole.getComponent();
}
@Nullable
public Object addMessage(AntMessage message) {
print(message.getText() + "\n", ProcessOutputTypes.STDOUT);
return null;
}
private void print(String text, Key type) {
myProcessHandler.notifyTextAvailable(text, type);
}
public void addMessages(AntMessage[] messages) {
for (AntMessage message : messages) {
addMessage(message);
}
}
public void addJavacMessage(AntMessage message, String url) {
final VirtualFile file = message.getFile();
if (message.getLine() > 0) {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
if (file != null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
String presentableUrl = file.getPresentableUrl();
builder.append(presentableUrl);
builder.append(' ');
}
});
}
else if (url != null) {
builder.append(url);
builder.append(' ');
}
builder.append('(');
builder.append(message.getLine());
builder.append(':');
builder.append(message.getColumn());
builder.append(")");
print(builder.toString(), ProcessOutputTypes.STDOUT);
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
print(message.getText(), ProcessOutputTypes.STDOUT);
}
public void addException(AntMessage exception, boolean showFullTrace) {
String text = exception.getText();
if (!showFullTrace) {
int index = text.indexOf("\r\n");
if (index != -1) {
text = text.substring(0, index) + "\n";
}
}
print(text, ProcessOutputTypes.STDOUT);
}
public void clearAllMessages() {
myConsole.clear();
}
public void startBuild(AntMessage message) {
print(myCommandLine + "\n", ProcessOutputTypes.SYSTEM);
addMessage(message);
}
public void buildFailed(AntMessage message) {
print(myCommandLine + "\n", ProcessOutputTypes.SYSTEM);
addMessage(message);
}
public void startTarget(AntMessage message) {
addMessage(message);
}
public void startTask(AntMessage message) {
addMessage(message);
}
public void finishBuild(String messageText) {
print("\n" + messageText + "\n", ProcessOutputTypes.SYSTEM);
}
public void finishTarget() {
}
public void finishTask() {
}
@Nullable
public Object getData(String dataId) {
return null;
}
public void setBuildCommandLine(String commandLine) {
myCommandLine = commandLine;
}
private final class JUnitFilter implements Filter {
@Nullable
public Result applyFilter(String line, int entireLength) {
HyperlinkUtil.PlaceInfo placeInfo = HyperlinkUtil.parseJUnitMessage(myProject, line);
if (placeInfo == null) {
return null;
}
int textStartOffset = entireLength - line.length();
int highlightStartOffset = textStartOffset + placeInfo.getLinkStartIndex();
int highlightEndOffset = textStartOffset + placeInfo.getLinkEndIndex() + 1;
OpenFileHyperlinkInfo info = new OpenFileHyperlinkInfo(myProject, placeInfo.getFile(), placeInfo.getLine(), placeInfo.getColumn());
return new Result(highlightStartOffset, highlightEndOffset, info);
}
}
private final class AntMessageFilter implements Filter {
public Result applyFilter(String line, int entireLength) {
int afterLineNumberIndex = line.indexOf(": "); // end of file_name_and_line_number sequence
if (afterLineNumberIndex == -1) {
return null;
}
String fileAndLineNumber = line.substring(0, afterLineNumberIndex);
int index = fileAndLineNumber.lastIndexOf(':');
if (index == -1) {
return null;
}
final String fileName = fileAndLineNumber.substring(0, index);
String lineNumberStr = fileAndLineNumber.substring(index + 1, fileAndLineNumber.length()).trim();
int lineNumber;
try {
lineNumber = Integer.parseInt(lineNumberStr);
}
catch (NumberFormatException e) {
return null;
}
final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
if (file == null) {
return null;
}
int textStartOffset = entireLength - line.length();
int highlightEndOffset = textStartOffset + afterLineNumberIndex;
OpenFileHyperlinkInfo info = new OpenFileHyperlinkInfo(myProject, file, lineNumber - 1);
return new Result(textStartOffset, highlightEndOffset, info);
}
}
private static class LightProcessHandler extends ProcessHandler {
protected void destroyProcessImpl() {
throw new UnsupportedOperationException();
}
protected void detachProcessImpl() {
throw new UnsupportedOperationException();
}
public boolean detachIsDefault() {
return false;
}
@Nullable
public OutputStream getProcessInput() {
return null;
}
}
}