Skip to content

Commit

Permalink
Add Log window preferences
Browse files Browse the repository at this point in the history
including settings of:
- the line wrap
- the character limit
- the log level
- the log pattern
- the foreground colors of messages
  • Loading branch information
ykazakov committed Nov 24, 2017
1 parent 8bab8b9 commit 6bdc8fa
Show file tree
Hide file tree
Showing 12 changed files with 1,098 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@ public static void handleRestart() {

}

public static void applyLogPreferences() {
logManager.applyPreferences();
}

public static void showLogView() {
logManager.showLogView();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.protege.editor.core.log;

import javax.swing.SizeRequirements;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.Element;
import javax.swing.text.IconView;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;

/**
* A {@link StyledEditorKit} using which one can set line wrapping of the text
*
* @author Yevgeny Kazakov
*/
public class LogEditorKit extends StyledEditorKit implements ViewFactory {

private static final long serialVersionUID = -6193302665953492671L;
private boolean lineWrap_ = false;

public boolean isLineWrap() {
return lineWrap_;

}

public void setLineWrap(boolean wrap) {
this.lineWrap_ = wrap;
}

private class LogParagraphView extends ParagraphView {
public LogParagraphView(Element elem) {
super(elem);
}

@Override
protected SizeRequirements calculateMinorAxisRequirements(int axis,
SizeRequirements r) {

if (lineWrap_)
return super.calculateMinorAxisRequirements(axis, r);

SizeRequirements req = super.calculateMinorAxisRequirements(axis,
r);
req.minimum = req.preferred;
return req;
}

@Override
public int getFlowSpan(int index) {

if (lineWrap_)
return super.getFlowSpan(index);

return Integer.MAX_VALUE;
}
}

@Override
public ViewFactory getViewFactory() {
return this;
}

@Override
public View create(Element elem) {
String kind = elem.getName();
if (kind != null)
if (kind.equals(AbstractDocument.ContentElementName)) {
return new LabelView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new LogParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new BoxView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
return new LabelView(elem);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package org.protege.editor.core.log;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Context;

import org.slf4j.Logger;
import org.protege.editor.core.FileUtils;
import org.protege.editor.core.ui.action.TimestampOutputAction;
import org.slf4j.LoggerFactory;

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -19,13 +26,17 @@
*/
public class LogManager {

private final LogView logView;

private final Appender<ILoggingEvent> appender;

private final List<LogStatusListener> listenerList = new ArrayList<>();

private final JDialog logViewDialog;

public LogManager(LogView logView) {

this.logView = logView;

appender = new AppenderBase<ILoggingEvent>() {

Expand Down Expand Up @@ -54,7 +65,31 @@ protected void append(ILoggingEvent event) {
}
};

JOptionPane op = new JOptionPane(logView.asJComponent(), JOptionPane.PLAIN_MESSAGE);
JComponent holder = new JPanel(new BorderLayout(7, 7));
holder.setPreferredSize(new Dimension(800, 600));
JScrollPane sp = new JScrollPane(logView.asJComponent());
sp.getVerticalScrollBar().setUnitIncrement(15);
holder.add(sp);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton clearLogButton = new JButton("Clear log");
clearLogButton.setToolTipText("Remove all log messages");
clearLogButton.addActionListener(e -> logView.clearView());
JButton showLogFile = new JButton("Show log file");
showLogFile.setToolTipText("Show the log file in the system file browser");
showLogFile.addActionListener(e -> FileUtils.showLogFile());
JButton preferencesButton = new JButton("Preferences");
preferencesButton.addActionListener(e -> showPreferences());
preferencesButton.setToolTipText("Display log preferences");
JButton timeStampButton = new JButton("Time stamp");
timeStampButton.addActionListener(e -> TimestampOutputAction.createTimeStamp(holder));
timeStampButton.setToolTipText("Print a timestamp and optional message into the logs or console");
buttonPanel.add(showLogFile);
buttonPanel.add(preferencesButton);
buttonPanel.add(timeStampButton);
buttonPanel.add(clearLogButton);
holder.add(buttonPanel, BorderLayout.SOUTH);

JOptionPane op = new JOptionPane(holder, JOptionPane.PLAIN_MESSAGE);
logViewDialog = op.createDialog(null, "Log");
logViewDialog.setModal(false);
logViewDialog.setResizable(true);
Expand All @@ -78,15 +113,16 @@ private synchronized void fireErrorsCleared() {
listenerList.stream().forEach(LogStatusListener::statusCleared);
}

private ch.qos.logback.classic.Logger getRootLogger() {
return (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
private Logger getRootLogger() {
return (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
}

public void bind() {
ch.qos.logback.classic.Logger rootLogger = getRootLogger();
applyPreferences();
Logger rootLogger = getRootLogger();
appender.setContext(rootLogger.getLoggerContext());
appender.start();
rootLogger.addAppender(appender);
appender.start();
rootLogger.addAppender(appender);
}

public void unbind() {
Expand All @@ -98,4 +134,24 @@ public void showLogView() {
logViewDialog.setVisible(true);
fireErrorsCleared();
}

private void showPreferences() {
LogPreferencesPanel panel = new LogPreferencesPanel();
panel.initialise();
JOptionPane op = new JOptionPane(panel, JOptionPane.PLAIN_MESSAGE,
JOptionPane.OK_CANCEL_OPTION);
JDialog dlg = op.createDialog(logViewDialog, "Log Preferences");
dlg.setResizable(true);
dlg.setVisible(true);
Object value = op.getValue();
if (value != null && (int) value == JOptionPane.OK_OPTION) {
panel.applyChanges();
}
}

public void applyPreferences() {
getRootLogger().setLevel(
Level.toLevel(LogPreferences.create().load().logLevel));
logView.applyPreferences();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package org.protege.editor.core.log;

import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.protege.editor.core.ProtegeApplication;
import org.protege.editor.core.prefs.Preferences;
import org.protege.editor.core.prefs.PreferencesManager;

/**
* Preference settings for Protege log window
*
* @author Yevgeny Kazakov
*/
public class LogPreferences {

private static final String PREFERENCES_SET_KEY_ = "org.protege.editor.core.log",
LOG_LEVEL_KEY_ = "LOG_LEVEL",
LOG_WRAP_LINES_KEY_ = "LOG_WRAP_LINES",
LOG_LIMIT_OUTPUT_KEY_ = "LOG_LIMIT_OUTPUT",
LOG_CHARACTER_LIMIT_KEY_ = "LOG_CHARACTER_LIMIT",
LOG_PATTERN_KEY_ = "LOG_PATTERN",
LOG_STYLES_NAMES_KEY_ = "LOG_STYLES_NAME",
LOG_STYLES_FOREGTROUD_KEY_ = "LOG_STYLES_FORGROUND";

private final static String DEFAULT_LOG_LEVEL_ = "INFO";
private final static Boolean DEFAULT_WRAP_LINES_ = false,
DEFAULT_LOG_LIMIT_OUTPUT_ = true;
private final static int DEFAULT_LOG_CHARACTER_LIMIT_ = 80000;
private final static String DEFAULT_LOG_PATTERN_ = "%7level %date{HH:mm:ss} %message%n";
private final static List<String> DEFAULT_LOG_SYTLE_LEVELS_ = Collections
.emptyList();
private final static List<byte[]> DEFAULT_LOG_SYTLE_FOREGROUNDS_ = Collections
.emptyList();

public String logLevel;
public Boolean wrapLines, limitLogOutput;
public int logCharacterLimit;
public String logPattern;
public Map<String, Color> logStyleForegrounds;

private LogPreferences() {
// use create()
}

/**
* @return the preferences initialized with default values
*/
public static LogPreferences create() {
return new LogPreferences().reset();
}

private static Preferences getPrefs() {
PreferencesManager prefMan = PreferencesManager.getInstance();
return prefMan.getPreferencesForSet(PREFERENCES_SET_KEY_,
LogPreferences.class);
}

public LogPreferences load() {
Preferences prefs = getPrefs();
logLevel = prefs.getString(LOG_LEVEL_KEY_, DEFAULT_LOG_LEVEL_);
wrapLines = prefs.getBoolean(LOG_WRAP_LINES_KEY_, DEFAULT_WRAP_LINES_);
limitLogOutput = prefs.getBoolean(LOG_LIMIT_OUTPUT_KEY_,
DEFAULT_LOG_LIMIT_OUTPUT_);
logCharacterLimit = prefs.getInt(LOG_CHARACTER_LIMIT_KEY_,
DEFAULT_LOG_CHARACTER_LIMIT_);
logPattern = prefs.getString(LOG_PATTERN_KEY_, DEFAULT_LOG_PATTERN_);
List<String> names = prefs.getStringList(LOG_STYLES_NAMES_KEY_,
DEFAULT_LOG_SYTLE_LEVELS_);
List<byte[]> foregrounds = prefs.getByteArrayList(
LOG_STYLES_FOREGTROUD_KEY_, DEFAULT_LOG_SYTLE_FOREGROUNDS_);
logStyleForegrounds = new HashMap<String, Color>(foregrounds.size());
try {
for (int i = 0; i < foregrounds.size(); i++) {
logStyleForegrounds.put(names.get(i),
(Color) deserialize(foregrounds.get(i)));
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return this;
}

public LogPreferences save() {
Preferences prefs = getPrefs();
prefs.putString(LOG_LEVEL_KEY_, logLevel);
prefs.putBoolean(LOG_WRAP_LINES_KEY_, wrapLines);
prefs.putBoolean(LOG_LIMIT_OUTPUT_KEY_, limitLogOutput);
prefs.putInt(LOG_CHARACTER_LIMIT_KEY_, logCharacterLimit);
prefs.putString(LOG_PATTERN_KEY_, logPattern);
try {
List<String> names = new ArrayList<String>(
logStyleForegrounds.keySet());
List<byte[]> foregroundColors = new ArrayList<byte[]>(names.size());
for (int i = 0; i < names.size(); i++) {
foregroundColors
.add(serialize(logStyleForegrounds.get(names.get(i))));
}
prefs.putStringList(LOG_STYLES_NAMES_KEY_, names);
prefs.putByteArrayList(LOG_STYLES_FOREGTROUD_KEY_,
foregroundColors);
} catch (IOException e) {
e.printStackTrace();
}
ProtegeApplication.applyLogPreferences();
return this;
}

public LogPreferences reset() {
logLevel = DEFAULT_LOG_LEVEL_;
wrapLines = DEFAULT_WRAP_LINES_;
limitLogOutput = DEFAULT_LOG_LIMIT_OUTPUT_;
logCharacterLimit = DEFAULT_LOG_CHARACTER_LIMIT_;
logPattern = DEFAULT_LOG_PATTERN_;
logStyleForegrounds = Collections.emptyMap();
return this;
}

public static byte[] serialize(Object obj) throws IOException {
try (ByteArrayOutputStream b = new ByteArrayOutputStream()) {
try (ObjectOutputStream o = new ObjectOutputStream(b)) {
o.writeObject(obj);
}
return b.toByteArray();
}
}

public static Object deserialize(byte[] bytes)
throws IOException, ClassNotFoundException {
try (ByteArrayInputStream b = new ByteArrayInputStream(bytes)) {
try (ObjectInputStream o = new ObjectInputStream(b)) {
return o.readObject();
}
}
}

}
Loading

0 comments on commit 6bdc8fa

Please sign in to comment.