/*******************************************************************************
* Copyright (c) 2015, 2016 Pivotal, Inc.
* 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:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.cloudfoundry.console;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.cloudfoundry.doppler.LogMessage;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsoleOutputStream;
import org.eclipse.ui.console.MessageConsole;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.util.Log;
import reactor.core.Cancellation;
@SuppressWarnings("restriction")
public class ApplicationLogConsole extends MessageConsole implements IPropertyChangeListener, IApplicationLogConsole {
private Map<LogType, IOConsoleOutputStream> activeStreams = new HashMap<>();
private Cancellation logStreamingToken;
public ApplicationLogConsole(String name, String type) {
super(name, type, BootDashActivator.getImageDescriptor("icons/cloud_obj.png"), true);
}
public synchronized void setLogStreamingToken(Cancellation logStreamingToken) {
if (this.logStreamingToken != null) {
this.logStreamingToken.dispose();
}
this.logStreamingToken = logStreamingToken;
}
public synchronized Cancellation getLogStreamingToken() {
return this.logStreamingToken;
}
public synchronized void writeLog(LogMessage log) {
if (log == null) {
return;
}
final LogType logType = LogType.getLogType(log);
writeApplicationLog(log.getMessage(), logType);
}
/**
*
* @param message
* @param type
* @return true if successfully wrote to stream. False otherwise
*/
public synchronized boolean writeApplicationLog(String message, LogType type) {
if (message != null) {
IOConsoleOutputStream stream = getStream(type);
try {
if (stream != null && !stream.isClosed()) {
message = format(message);
stream.write(message);
return true;
}
} catch (IOException e) {
BootDashActivator.log(e);
}
}
return false;
}
protected static String format(String message) {
if (message.contains("\n") || message.contains("\r")) {
return message;
}
return message + '\n';
}
public synchronized void close() {
setLogStreamingToken(null);
for (IOConsoleOutputStream outputStream : activeStreams.values()) {
if (!outputStream.isClosed()) {
try {
outputStream.close();
} catch (IOException e) {
Log.log(e);
}
}
}
activeStreams.clear();
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
manager.removeConsoles(new IConsole[] { this });
}
protected synchronized IOConsoleOutputStream getStream(final LogType logType) {
IOConsoleOutputStream stream = activeStreams.get(logType);
// If the console is no longer managed by the Eclipse console manager,
// do NOT
// write to the stream to avoid exceptions
if (!isStillManaged() || (stream != null && stream.isClosed())) {
return null;
}
if (stream == null) {
stream = newOutputStream();
final IOConsoleOutputStream toConfig = stream;
// Setting colour must be done in UI thread
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
toConfig.setColor(Display.getDefault().getSystemColor(logType.getDisplayColour()));
}
});
activeStreams.put(logType, stream);
}
return stream;
}
protected synchronized boolean isStillManaged() {
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
IConsole[] activeConsoles = manager.getConsoles();
if (activeConsoles != null) {
for (IConsole console : activeConsoles) {
if (console.getName().equals(this.getName())) {
return true;
}
}
}
return false;
}
@Override
public void onMessage(LogMessage log) {
writeLog(log);
}
@Override
public void onComplete() {
// Leave open for tail
}
@Override
public void onError(Throwable exception) {
writeApplicationLog(exception.getMessage(), LogType.CFSTDERROR);
}
@Override
protected void init() {
super.init();
JFaceResources.getFontRegistry().addListener(this);
}
@Override
protected void dispose() {
JFaceResources.getFontRegistry().removeListener(this);
super.dispose();
}
/**
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
String property = evt.getProperty();
if (property.equals(IDebugUIConstants.PREF_CONSOLE_FONT)) {
setFont(JFaceResources.getFont(IDebugUIConstants.PREF_CONSOLE_FONT));
}
}
}