/******************************************************************************* * Copyright (c) 2000, 2013 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.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; } }