| /******************************************************************************* |
| * Copyright (c) 2008-2010 Sonatype, Inc. |
| * All rights reserved. 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: |
| * Sonatype, Inc. - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.core.ui.internal.console; |
| |
| import java.io.IOException; |
| import java.text.DateFormat; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import org.eclipse.jface.preference.JFacePreferences; |
| import org.eclipse.jface.resource.ColorRegistry; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.JFaceColors; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.console.ConsolePlugin; |
| import org.eclipse.ui.console.IConsole; |
| import org.eclipse.ui.console.IConsoleListener; |
| import org.eclipse.ui.console.IConsoleManager; |
| import org.eclipse.ui.console.IOConsole; |
| import org.eclipse.ui.console.IOConsoleOutputStream; |
| |
| import org.eclipse.m2e.core.internal.preferences.MavenPreferenceConstants; |
| import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; |
| import org.eclipse.m2e.core.ui.internal.Messages; |
| |
| |
| /** |
| * Maven Console implementation |
| * |
| * @author Dmitri Maximovich |
| */ |
| public class MavenConsoleImpl extends IOConsole implements MavenConsole, IPropertyChangeListener { |
| |
| private boolean initialized = false; |
| |
| // console is visible in the Console view |
| private boolean visible = false; |
| |
| private ConsoleDocument consoleDocument; |
| |
| // created colors for each line type - must be disposed at shutdown |
| private Color messageColor; |
| |
| // streams for each command type - each stream has its own color |
| private IOConsoleOutputStream commandStream; |
| |
| private IOConsoleOutputStream messageStream; |
| |
| private IOConsoleOutputStream errorStream; |
| |
| private static final String TITLE = Messages.MavenConsoleImpl_title; |
| |
| private List<IMavenConsoleListener> listeners = new CopyOnWriteArrayList<IMavenConsoleListener>(); |
| |
| public MavenConsoleImpl(ImageDescriptor imageDescriptor) { |
| super(TITLE, imageDescriptor); |
| this.setConsoleDocument(new ConsoleDocument()); |
| } |
| |
| protected void init() { |
| super.init(); |
| |
| // Ensure that initialization occurs in the UI thread |
| Display.getDefault().asyncExec(() -> { |
| JFaceResources.getFontRegistry().addListener(MavenConsoleImpl.this); |
| initializeConsoleStreams(Display.getDefault()); |
| dumpConsole(); |
| }); |
| } |
| |
| /* |
| * Initialize three streams of the console. Must be called from the UI thread, so synchronization is unnecessary. |
| */ |
| protected void initializeConsoleStreams(Display display) { |
| if(!initialized) { |
| setCommandStream(newOutputStream()); |
| setErrorStream(newOutputStream()); |
| setMessageStream(newOutputStream()); |
| |
| ColorRegistry colorRegistry = JFaceResources.getColorRegistry(); |
| |
| // TODO convert this to use themes |
| // install colors |
| Color background = colorRegistry.get(JFacePreferences.INFORMATION_BACKGROUND_COLOR); |
| if(background == null) { |
| background = JFaceColors.getInformationViewerBackgroundColor(display); |
| } |
| setBackground(background); |
| |
| Color commandColor = colorRegistry.get(JFacePreferences.INFORMATION_FOREGROUND_COLOR); |
| if(commandColor == null) { |
| commandColor = JFaceColors.getInformationViewerForegroundColor(display); |
| } |
| |
| messageColor = new Color(display, commandColor.getRGB(), 200); |
| |
| Color errorColor = colorRegistry.get(JFacePreferences.ERROR_COLOR); |
| if(errorColor == null) { |
| errorColor = JFaceColors.getErrorText(display); |
| } |
| |
| getCommandStream().setColor(commandColor); |
| getMessageStream().setColor(messageColor); |
| getErrorStream().setColor(errorColor); |
| |
| // install font |
| setFont(JFaceResources.getFontRegistry().get("pref_console_font")); //$NON-NLS-1$ |
| |
| initialized = true; |
| } |
| } |
| |
| /** |
| * Is always called from main thread, so synchronization not necessary |
| */ |
| protected void dumpConsole() { |
| setVisible(true); |
| ConsoleDocument.ConsoleLine[] lines = getConsoleDocument().getLines(); |
| for(int i = 0; i < lines.length; i++ ) { |
| ConsoleDocument.ConsoleLine line = lines[i]; |
| appendLine(line.type, line.line); |
| } |
| getConsoleDocument().clear(); |
| } |
| |
| private void appendLine(final int type, final String line) { |
| show(false); |
| //the synchronization here caused a deadlock. since the writes are simply appending to the output stream |
| //or the document, just doing it on the main thread to avoid deadlocks and or corruption of the |
| //document or output stream |
| Display.getDefault().asyncExec(() -> { |
| if(isVisible()) { |
| try { |
| switch(type) { |
| case ConsoleDocument.COMMAND: |
| getCommandStream().write(line); |
| getCommandStream().write('\n'); |
| break; |
| case ConsoleDocument.MESSAGE: |
| getMessageStream().write(line); |
| getMessageStream().write('\n'); |
| break; |
| case ConsoleDocument.ERROR: |
| getErrorStream().write(line); |
| getErrorStream().write('\n'); |
| break; |
| } |
| } catch(IOException ex) { |
| // Don't log using slf4j - it will cause a cycle |
| ex.printStackTrace(); |
| } |
| } else { |
| getConsoleDocument().appendConsoleLine(type, line); |
| } |
| }); |
| } |
| |
| /** |
| * Show the console. |
| * |
| * @param showNoMatterWhat ignore preferences if <code>true</code> |
| */ |
| public void show(boolean showNoMatterWhat) { |
| if(showNoMatterWhat) { |
| if(!isVisible()) { |
| showConsole(); |
| } else { |
| ConsolePlugin.getDefault().getConsoleManager().showConsoleView(this); |
| } |
| } |
| } |
| |
| public void showConsole() { |
| boolean exists = false; |
| IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager(); |
| for(IConsole element : manager.getConsoles()) { |
| if(this == element) { |
| exists = true; |
| } |
| } |
| if(!exists) { |
| manager.addConsoles(new IConsole[] {this}); |
| } |
| manager.showConsoleView(this); |
| } |
| |
| public void closeConsole() { |
| IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager(); |
| manager.removeConsoles(new IConsole[] {this}); |
| ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(this.newLifecycle()); |
| } |
| |
| public void propertyChange(PropertyChangeEvent event) { |
| // font changed |
| setFont(JFaceResources.getFontRegistry().get("pref_console_font")); //$NON-NLS-1$ |
| } |
| |
| private void bringConsoleToFront() { |
| if(PlatformUI.isWorkbenchRunning()) { |
| IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager(); |
| if(!isVisible()) { |
| manager.addConsoles(new IConsole[] {this}); |
| } |
| manager.showConsoleView(this); |
| } |
| } |
| |
| // Called when console is removed from the console view |
| protected void dispose() { |
| // Here we can't call super.dispose() because we actually want the partitioner to remain |
| // connected, but we won't show lines until the console is added to the console manager |
| // again. |
| Display.getDefault().asyncExec(() -> { |
| setVisible(false); |
| JFaceResources.getFontRegistry().removeListener(MavenConsoleImpl.this); |
| }); |
| } |
| |
| public void shutdown() { |
| // Call super dispose because we want the partitioner to be |
| // disconnected. |
| super.dispose(); |
| if(messageColor != null) { |
| messageColor.dispose(); |
| } |
| } |
| |
| private DateFormat getDateFormat() { |
| return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault()); |
| } |
| |
| // MavenConsole |
| |
| public void debug(String message) { |
| if(!M2EUIPluginActivator.getDefault().getPreferenceStore().getBoolean(MavenPreferenceConstants.P_DEBUG_OUTPUT)) { |
| return; |
| } |
| if(showConsoleOnOutput()) { |
| bringConsoleToFront(); |
| } |
| appendLine(ConsoleDocument.MESSAGE, getDateFormat().format(new Date()) + ": " + message); |
| |
| for(IMavenConsoleListener listener : listeners) { |
| try { |
| listener.loggingMessage(message); |
| } catch(Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public void info(String message) { |
| if(showConsoleOnOutput()) { |
| bringConsoleToFront(); |
| } |
| appendLine(ConsoleDocument.MESSAGE, getDateFormat().format(new Date()) + ": " + message); |
| |
| for(IMavenConsoleListener listener : listeners) { |
| try { |
| listener.loggingMessage(message); |
| } catch(Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public void error(String message) { |
| if(showConsoleOnError()) { |
| bringConsoleToFront(); |
| } |
| appendLine(ConsoleDocument.ERROR, getDateFormat().format(new Date()) + ": " + message); //$NON-NLS-1$ |
| |
| for(IMavenConsoleListener listener : listeners) { |
| try { |
| listener.loggingError(message); |
| } catch(Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| public boolean showConsoleOnError() { |
| return M2EUIPluginActivator.getDefault().getPreferenceStore() |
| .getBoolean(MavenPreferenceConstants.P_SHOW_CONSOLE_ON_ERR); |
| } |
| |
| public boolean showConsoleOnOutput() { |
| return M2EUIPluginActivator.getDefault().getPreferenceStore() |
| .getBoolean(MavenPreferenceConstants.P_SHOW_CONSOLE_ON_OUTPUT); |
| } |
| |
| public IConsoleListener newLifecycle() { |
| return new MavenConsoleLifecycle(); |
| } |
| |
| /** |
| * @param commandStream The commandStream to set. |
| */ |
| protected void setCommandStream(IOConsoleOutputStream commandStream) { |
| this.commandStream = commandStream; |
| } |
| |
| /** |
| * @return Returns the commandStream. |
| */ |
| protected IOConsoleOutputStream getCommandStream() { |
| return commandStream; |
| } |
| |
| /** |
| * @param messageStream The messageStream to set. |
| */ |
| protected void setMessageStream(IOConsoleOutputStream messageStream) { |
| this.messageStream = messageStream; |
| } |
| |
| /** |
| * @return Returns the messageStream. |
| */ |
| protected IOConsoleOutputStream getMessageStream() { |
| return messageStream; |
| } |
| |
| /** |
| * @param errorStream The errorStream to set. |
| */ |
| protected void setErrorStream(IOConsoleOutputStream errorStream) { |
| this.errorStream = errorStream; |
| } |
| |
| /** |
| * @return Returns the errorStream. |
| */ |
| protected IOConsoleOutputStream getErrorStream() { |
| return errorStream; |
| } |
| |
| /** |
| * @param visible The visible to set. |
| */ |
| protected void setVisible(boolean visible) { |
| this.visible = visible; |
| } |
| |
| /** |
| * @return Returns the visible. |
| */ |
| protected boolean isVisible() { |
| return visible; |
| } |
| |
| /** |
| * @param consoleDocument The consoleDocument to set. |
| */ |
| private void setConsoleDocument(ConsoleDocument consoleDocument) { |
| this.consoleDocument = consoleDocument; |
| } |
| |
| /** |
| * @return Returns the consoleDocument. |
| */ |
| protected ConsoleDocument getConsoleDocument() { |
| return consoleDocument; |
| } |
| |
| /** |
| * Used to notify this console of lifecycle methods <code>init()</code> and <code>dispose()</code>. |
| */ |
| public class MavenConsoleLifecycle implements org.eclipse.ui.console.IConsoleListener { |
| |
| public void consolesAdded(IConsole[] consoles) { |
| for(int i = 0; i < consoles.length; i++ ) { |
| IConsole console = consoles[i]; |
| if(console == MavenConsoleImpl.this) { |
| init(); |
| } |
| } |
| |
| } |
| |
| public void consolesRemoved(IConsole[] consoles) { |
| for(int i = 0; i < consoles.length; i++ ) { |
| IConsole console = consoles[i]; |
| if(console == MavenConsoleImpl.this) { |
| ConsolePlugin.getDefault().getConsoleManager().removeConsoleListener(this); |
| dispose(); |
| } |
| } |
| } |
| |
| } |
| |
| public void addMavenConsoleListener(IMavenConsoleListener listener) { |
| listeners.remove(listener); |
| listeners.add(listener); |
| } |
| |
| public void removeMavenConsoleListener(IMavenConsoleListener listener) { |
| listeners.remove(listener); |
| } |
| |
| } |