blob: e57433739ab123ab8deee00dd4f8f93d436d4388 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2013 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.core.IAntCoreConstants;
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;
default:
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)
*/
@Override
public void buildStarted(BuildEvent event) {
fStartTime = System.currentTimeMillis();
}
/*
* (non-Javadoc)
*
* @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
*/
@Override
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(IAntCoreConstants.EMPTY_STRING, event, Project.MSG_ERR);
}
catch (IOException e) {
// do nothing
}
}
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)
*/
@Override
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)
*/
@Override
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;
}
}