blob: f8acbe49f25aaed994f821daaa006510a41e1134 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Matt Conway - Patch for Bug 28052
*******************************************************************************/
package org.eclipse.ant.internal.launching.runtime.logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.eclipse.ant.internal.core.AbstractEclipseBuildLogger;
import org.eclipse.ant.internal.launching.AntLaunch;
import org.eclipse.ant.internal.launching.AntLaunching;
import org.eclipse.ant.internal.launching.AntLaunchingUtil;
import org.eclipse.ant.internal.launching.debug.AntDebugState;
import org.eclipse.ant.internal.launching.launchConfigurations.AntProcess;
import org.eclipse.ant.internal.launching.launchConfigurations.AntStreamMonitor;
import org.eclipse.ant.internal.launching.launchConfigurations.AntStreamsProxy;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
public class AntProcessBuildLogger extends NullBuildLogger {
private long fStartTime;
/**
* Associated process - discovered as needed to log messages
*/
private AntProcess fProcess = null;
protected void logMessage(String message, BuildEvent event, int overridePriority) {
int priority= overridePriority;
if (priority == -1) {
priority= event.getPriority();
}
if (priority > getMessageOutputLevel()) {
return;
}
AntProcess antProcess = getAntProcess(fProcessId);
if (antProcess == null) {
return;
}
StringBuffer fullMessage= new StringBuffer();
if (!loggingToLogFile()) {
fullMessage.append(System.getProperty("line.separator")); //$NON-NLS-1$
}
if (event.getException() == null && event.getTask() != null && !fEmacsMode) {
adornMessage(event, fullMessage);
} else {
fullMessage.append(message);
}
message= fullMessage.toString();
if (loggingToLogFile()) {
logMessageToLogFile(message, priority);
} else {
AntStreamMonitor monitor = getMonitor(priority);
monitor.append(message);
}
}
/**
* Builds a right justified task prefix for the given build event, placing it
* in the given string buffer. Creates the hyperlinks for the task prefix.
*
* @param event build event
* @param fullMessage buffer to place task prefix in
*/
private void adornMessage(BuildEvent event, StringBuffer fullMessage) {
String name = event.getTask().getTaskName();
if (name == null) {
name = "null"; //$NON-NLS-1$
}
Location location = event.getTask().getLocation();
StringBuffer column= new StringBuffer();
int size = AntLaunching.LEFT_COLUMN_SIZE - (name.length() + 3);
for (int i = 0; i < size; i++) {
column.append(' ');
}
StringBuffer labelBuff= new StringBuffer();
labelBuff.append('[');
labelBuff.append(name);
labelBuff.append("] "); //$NON-NLS-1$
int offset = Math.max(size, 0) + 1;
String label= labelBuff.toString();
if (event.getMessage() == null) {
return;
}
try {
BufferedReader r = new BufferedReader(new StringReader(event.getMessage()));
String line = r.readLine();
fullMessage.append(column);
appendAndLink(fullMessage, location, label, offset, line);
line = r.readLine();
while (line != null) {
fullMessage.append(System.getProperty("line.separator")); //$NON-NLS-1$
fullMessage.append(column);
appendAndLink(fullMessage, location, label, offset, line);
line = r.readLine();
}
} catch (IOException e) {
if (event.getMessage() != null) {
fullMessage.append(label).append(event.getMessage());
}
}
}
private void appendAndLink(StringBuffer fullMessage, Location location, String label, int offset, String line) {
fullMessage.append(label);
fullMessage.append(line);
if (location != null) {
String newLine= (label + line).trim();
IRegion region= new Region(offset, label.length() - 3); // only
// want
// the
// name
// length
// "[name] "
AntProcess antProcess = getAntProcess(fProcessId);
AntLaunch antLaunch = (AntLaunch)antProcess.getLaunch();
antLaunch.addLinkDescriptor(newLine, location.getFileName(), location.getLineNumber(), region.getOffset(), region.getLength());
}
}
private AntStreamMonitor getMonitor(int priority) {
AntStreamsProxy proxy = (AntStreamsProxy)fProcess.getStreamsProxy();
AntStreamMonitor monitor = null;
switch (priority) {
case Project.MSG_INFO:
monitor = (AntStreamMonitor)proxy.getOutputStreamMonitor();
break;
case Project.MSG_ERR:
monitor = (AntStreamMonitor)proxy.getErrorStreamMonitor();
break;
case Project.MSG_DEBUG:
monitor = (AntStreamMonitor)proxy.getDebugStreamMonitor();
break;
case Project.MSG_WARN:
monitor = (AntStreamMonitor)proxy.getWarningStreamMonitor();
break;
case Project.MSG_VERBOSE:
monitor = (AntStreamMonitor)proxy.getVerboseStreamMonitor();
break;
}
return monitor;
}
private void logMessageToLogFile(String message, int priority) {
if (priority == Project.MSG_ERR) {
getErrorPrintStream().println(message);
} else {
getOutputPrintStream().println(message);
}
}
/**
* Returns the associated Ant process, finding it if necessary, if not
* already found.
*/
protected AntProcess getAntProcess(String processId) {
if (fProcess == null && processId != null) {
IProcess[] all = DebugPlugin.getDefault().getLaunchManager().getProcesses();
for (int i = 0; i < all.length; i++) {
IProcess process = all[i];
if (process instanceof AntProcess && processId.equals(process.getAttribute(AbstractEclipseBuildLogger.ANT_PROCESS_ID))) {
fProcess = (AntProcess)process;
break;
}
}
}
return fProcess;
}
/* (non-Javadoc)
* Set the start time.
*
* @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
*/
public void buildStarted(BuildEvent event) {
fStartTime= System.currentTimeMillis();
}
/* (non-Javadoc)
* @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
*/
public void buildFinished(BuildEvent event) {
String message= handleException(event);
if (message != null) {
try {
BufferedReader r = new BufferedReader(new StringReader(message));
String line = r.readLine();
logMessage(line, event, Project.MSG_ERR);
line = r.readLine();
AntProcess antProcess = getAntProcess(fProcessId);
while (line != null) {
logMessage(line, event, Project.MSG_ERR);
if (!message.startsWith("Total time:")) { //$NON-NLS-1$
AntLaunchingUtil.linkBuildFailedMessage(line, antProcess);
}
line = r.readLine();
}
logMessage("", event, Project.MSG_ERR); //$NON-NLS-1$
} catch (IOException e) {
}
}
fHandledException= null;
if (!(event.getException() instanceof OperationCanceledException)) {
logMessage(getTimeString(System.currentTimeMillis() - fStartTime), event, fMessageOutputLevel);
}
fProcess= null;
event.getProject().removeBuildListener(this);
}
private String getTimeString(long milliseconds) {
long seconds = milliseconds / 1000;
long minutes = seconds / 60;
seconds= seconds % 60;
StringBuffer result= new StringBuffer(RuntimeMessages.AntProcessBuildLogger_Total_time);
if (minutes > 0) {
result.append(minutes);
if (minutes > 1) {
result.append(RuntimeMessages.AntProcessBuildLogger__minutes_2);
} else {
result.append(RuntimeMessages.AntProcessBuildLogger__minute_3);
}
}
if (seconds > 0) {
if (minutes > 0) {
result.append(' ');
}
result.append(seconds);
if (seconds > 1) {
result.append(RuntimeMessages.AntProcessBuildLogger__seconds_4);
} else {
result.append(RuntimeMessages.AntProcessBuildLogger__second_5);
}
}
if (seconds == 0 && minutes == 0) {
result.append(milliseconds);
result.append(RuntimeMessages.AntProcessBuildLogger__milliseconds_6);
}
result.append(System.getProperty("line.separator")); //$NON-NLS-1$
return result.toString();
}
/* (non-Javadoc)
* @see org.apache.tools.ant.BuildListener#messageLogged(org.apache.tools.ant.BuildEvent)
*/
public void messageLogged(BuildEvent event) {
if (event.getPriority() > getMessageOutputLevel()) {
return;
}
if (event.getMessage() != null && event.getMessage().length() > 0) {
logMessage(event.getMessage(), event, -1);
}
}
/* (non-Javadoc)
* @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
*/
public void targetStarted(BuildEvent event) {
if (Project.MSG_INFO > getMessageOutputLevel()) {
return;
}
Target target= event.getTarget();
StringBuffer msg= new StringBuffer(System.getProperty("line.separator")); //$NON-NLS-1$
String targetName= target.getName();
msg.append(targetName);
msg.append(':');
String message= msg.toString();
Location location= AntDebugState.getLocation(target);
if (location != null && location != Location.UNKNOWN_LOCATION) {
IRegion region = new Region(0, targetName.length());
AntProcess antProcess = getAntProcess(fProcessId);
AntLaunch antLaunch = (AntLaunch)antProcess.getLaunch();
antLaunch.addLinkDescriptor(message, location.getFileName(), location.getLineNumber(), region.getOffset(), region.getLength());
}
logMessage(message, event, Project.MSG_INFO);
}
private boolean loggingToLogFile() {
//check if user has designated to log to a log file
return getErrorPrintStream() != null && getErrorPrintStream() != System.err;
}
}