diff options
author | Jiri Vanek <[email protected]> | 2013-12-15 11:07:05 +0100 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2013-12-15 11:07:05 +0100 |
commit | d91bf9ee53eebc7028f4143e03881ee350e4ebef (patch) | |
tree | d1886733f58835ff3a9ae5d51a5411139ae55ce5 | |
parent | 3c5836190bd9954c56c7d4180bfc2e7ed9a0d82d (diff) |
Console made aware of plugin messages
17 files changed, 916 insertions, 91 deletions
@@ -1,3 +1,43 @@ +2013-12-15 Jiri Vanek <[email protected]> + + Console made aware of plugin messages + * NEWS : mentioned + * netx/net/sourceforge/jnlp/util/logging/FileLog.java: call to log adapted + to new Header. + * netx/net/sourceforge/jnlp/util/logging/JavaConsole.java: (logOutput) and + (logError) replaced by (addMessage). Added (createPluginReader) to process + plugin debug pipe + * netx/net/sourceforge/jnlp/util/logging/LogConfig.java: (getConfig) do + config available untill JNLPRuntime config is proper singleton + * netx/net/sourceforge/jnlp/util/logging/OutputController.java: (Level) + static methods converted to members and enhanced. (getHeader) and + (getCallerClass) moved to Headers. + * netx/net/sourceforge/jnlp/util/logging/headers/Header.java: Structure + to keep header as object instead of string. + * netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java: Structure + to hold message and its header. + * netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java: + Interface for JavaMessage and PluginMessage + * netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java: extended + header to handle plugin's preinit and threads. + * netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java: + implementation of MessageWithHeader which parse from String from plugin + debug pipe. + * plugin/icedteanp/IcedTeaNPPlugin.cc: added debug pipe (debug_pipe_name), + synced via (debug_pipe_lock), controlled by (debug_to_appletviewer) and used + by method (plugin_send_message_to_appletviewer_console). + * plugin/icedteanp/IcedTeaNPPlugin.h: (debug_pipe_name) and (jvvm_up) declared + extern. Utility methods (plugin_send_message_to_appletviewer_console) and + (flush_plugin_send_message_to_appletviewer_console) declared and impelmented + * plugin/icedteanp/IcedTeaPluginUtils.cc: print debug info enhanced for + debug pipe + * plugin/icedteanp/IcedTeaPluginUtils.h: (PLUGIN_MESSAGE) and (PLIGIN_ERROR) + now log to debug pipe if enabled. + * plugin/icedteanp/java/sun/applet/PluginMain.java: args reprinted, checked + third parameter debug pipe if should. Started debug_pipe reader if should + * tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java: + added tests for parsing the plugin message. + 2013-12-13 Jiri Vanek <[email protected]> Made again compatible with JDK6.All JLists, JComboBoxs, and DefaultComboBoxModels @@ -26,6 +26,7 @@ New in release 1.5 (2013-XX-XX): - PR1026 - Apps fail to run because of the nanoxml parser's strict XML validation - PR1473 - javaws should not depend on name of local file - Redesigned About dialogue layout and contents + - Console made aware of plugin messages * Plugin - PR854: Resizing an applet several times causes 100% CPU load - PR1271: icedtea-web does not handle 'javascript:'-protocol URLs diff --git a/netx/net/sourceforge/jnlp/util/logging/FileLog.java b/netx/net/sourceforge/jnlp/util/logging/FileLog.java index 3ac048b..962e4ab 100644 --- a/netx/net/sourceforge/jnlp/util/logging/FileLog.java +++ b/netx/net/sourceforge/jnlp/util/logging/FileLog.java @@ -46,6 +46,7 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import net.sourceforge.jnlp.util.FileUtils; +import net.sourceforge.jnlp.util.logging.headers.Header; /** * This class writes log information to file. @@ -90,7 +91,7 @@ public final class FileLog implements SingleStreamLogger { impl = Logger.getLogger(loggerName); impl.setLevel(Level.ALL); impl.addHandler(fh); - log(OutputController.getHeader(null, null)); + log(new Header(OutputController.Level.WARNING_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false).toString()); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java b/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java index 52bc1aa..2ee601e 100644 --- a/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java +++ b/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java @@ -46,6 +46,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -63,6 +68,10 @@ import javax.swing.border.TitledBorder; import net.sourceforge.jnlp.config.DeploymentConfiguration; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.util.ImageResources; +import net.sourceforge.jnlp.util.logging.headers.Header; +import net.sourceforge.jnlp.util.logging.headers.JavaMessage; +import net.sourceforge.jnlp.util.logging.headers.MessageWithHeader; +import net.sourceforge.jnlp.util.logging.headers.PluginMessage; /** * A simple Java console for IcedTeaPlugin and JavaWS @@ -392,7 +401,7 @@ public class JavaConsole { final JavaConsole console = new JavaConsole(); - boolean toShowConsole = false; + boolean toShowConsole = true; for (String arg : args) { if ("--show-console".equals(arg)) { @@ -406,11 +415,73 @@ public class JavaConsole { } - void logOutput(String s) { - stdOutText.setText(stdOutText.getText() + s + "\n"); + + void addMessage(Header header, String message) { + if (!LogConfig.getLogConfig().isEnableHeaders()){ + if (header.level.isError()){ + stdErrText.setText(stdErrText.getText() + message + "\n"); + } + if (header.level.isOutput()){ + stdOutText.setText(stdOutText.getText() + message + "\n"); + } + } else { + if (header.level.isError()){ + stdErrText.setText(stdErrText.getText( )+ header.toString() + message +"\n"); + } + if (header.level.isOutput()){ + stdOutText.setText(stdOutText.getText() + header.toString() + message + "\n"); + } + } + } + + /** + * parse plugin message and add it as header+message to data + * @param s string to be parsed + */ + private void processPluginMessage(String s) { + PluginMessage pm = new PluginMessage(s); + addMessage(pm.getHeader(), pm.getMessage()); } - void logError(String s) { - stdErrText.setText(stdErrText.getText() + s + "\n"); + + public void createPluginReader(final File file) { + OutputController.getLogger().log("Starting processing of plugin-debug-to-console " + file.getAbsolutePath()); + Thread t = new Thread(new Runnable() { + + @Override + public void run() { + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader(new FileInputStream(file), + Charset.forName("UTF-8"))); + //never ending loop + while (true) { + try{ + String s = br.readLine(); + if (s == null) { + break; + } + processPluginMessage(s); + }catch(Exception ex){ + OutputController.getLogger().log(ex); + } + } + } catch (Exception ex) { + OutputController.getLogger().log(ex); + if (br != null) { + try { + br.close(); + } catch (Exception exx) { + OutputController.getLogger().log(exx); + } + } + } + OutputController.getLogger().log("Ended processing of plugin-debug-to-console " + file.getAbsolutePath()); + } + }, "plugin-debug-to-console reader thread"); + t.setDaemon(true); + t.start(); + + OutputController.getLogger().log("Started processing of plugin-debug-to-console " + file.getAbsolutePath()); } } diff --git a/netx/net/sourceforge/jnlp/util/logging/LogConfig.java b/netx/net/sourceforge/jnlp/util/logging/LogConfig.java index 2c98cd2..72941f3 100644 --- a/netx/net/sourceforge/jnlp/util/logging/LogConfig.java +++ b/netx/net/sourceforge/jnlp/util/logging/LogConfig.java @@ -55,12 +55,13 @@ public class LogConfig { private boolean logToFile; private boolean logToStreams; private boolean logToSysLog; + private DeploymentConfiguration config; private static LogConfig logConfig; public LogConfig() { try { - DeploymentConfiguration config = JNLPRuntime.getConfiguration(); + config = JNLPRuntime.getConfiguration(); if (config.getRaw().isEmpty()){ config = new DeploymentConfiguration();//JNLPRuntime.getConfiguration() cannotbe loaded time config.load(); //read one prior @@ -161,7 +162,11 @@ public class LogConfig { return JavaConsole.isEnabled(); } - - + /* + * logging stuff may be interested in used config + */ + public DeploymentConfiguration getConfig() { + return config; + } } diff --git a/netx/net/sourceforge/jnlp/util/logging/OutputController.java b/netx/net/sourceforge/jnlp/util/logging/OutputController.java index 6a6dcd6..d84950a 100644 --- a/netx/net/sourceforge/jnlp/util/logging/OutputController.java +++ b/netx/net/sourceforge/jnlp/util/logging/OutputController.java @@ -54,20 +54,37 @@ public class OutputController { ERROR_ALL, // - stderr/log in all cases (default for ERROR_DEBUG; // - stderr/log in verbose/debug mode //ERROR_DEBUG is default for Throwable - //MESSAGE_VERBOSE is defautrl for String + //MESSAGE_DEBUG is default for String - private static boolean isOutput(MessageWithLevel s) { - return s.level == Level.MESSAGE_ALL - || s.level == Level.MESSAGE_DEBUG - || s.level == Level.WARNING_ALL - || s.level == Level.WARNING_DEBUG; + public boolean isOutput() { + return this == Level.MESSAGE_ALL + || this == Level.MESSAGE_DEBUG + || this == Level.WARNING_ALL + || this == Level.WARNING_DEBUG; } - private static boolean isError(MessageWithLevel s) { - return s.level == Level.ERROR_ALL - || s.level == Level.ERROR_DEBUG - || s.level == Level.WARNING_ALL - || s.level == Level.WARNING_DEBUG; + public boolean isError() { + return this == Level.ERROR_ALL + || this == Level.ERROR_DEBUG + || this == Level.WARNING_ALL + || this == Level.WARNING_DEBUG; + } + + public boolean isWarning() { + return this == Level.WARNING_ALL + || this == Level.WARNING_DEBUG; + } + + public boolean isDebug() { + return this == Level.ERROR_DEBUG + || this == Level.MESSAGE_DEBUG + || this == Level.WARNING_DEBUG; + } + + public boolean isInfo() { + return this == Level.ERROR_ALL + || this == Level.WARNING_ALL + || this == Level.MESSAGE_ALL; } } @@ -76,6 +93,8 @@ public class OutputController { public final String message; public final Level level; public final StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + public final Thread thread = Thread.currentThread(); + public final Date loggedAt = new Date(); public MessageWithLevel(String message, Level level) { this.message = message; @@ -132,6 +151,11 @@ public class OutputController { private void consume() { MessageWithLevel s = messageQue.get(0); messageQue.remove(0); + net.sourceforge.jnlp.util.logging.headers.Header header = new net.sourceforge.jnlp.util.logging.headers.Header(s.level, s.stack, s.thread, s.loggedAt, false); + //filtering is done in console during runtime + if (LogConfig.getLogConfig().isLogToConsole()) { + JavaConsole.getConsole().addMessage(header, s.message); + } if (!JNLPRuntime.isDebug() && (s.level == Level.MESSAGE_DEBUG || s.level == Level.WARNING_DEBUG || s.level == Level.ERROR_DEBUG)) { @@ -142,16 +166,16 @@ public class OutputController { String message = s.message; if (LogConfig.getLogConfig().isEnableHeaders()) { if (message.contains("\n")) { - message = getHeader(s.level, s.stack) + "\n" + message; + message = header.toString() + "\n" + message; } else { - message = getHeader(s.level, s.stack) + " " + message; + message = header.toString() + " " + message; } } if (LogConfig.getLogConfig().isLogToStreams()) { - if (Level.isOutput(s)) { + if (s.level.isOutput()) { outLog.log(message); } - if (Level.isError(s)) { + if (s.level.isError()) { errLog.log(message); } } @@ -161,14 +185,6 @@ public class OutputController { if (LogConfig.getLogConfig().isLogToSysLog()) { getSystemLog().log(message); } - if (LogConfig.getLogConfig().isLogToConsole()) { - if (Level.isOutput(s)){ - JavaConsole.getConsole().logOutput(message); - } - if (Level.isError(s)){ - JavaConsole.getConsole().logError(message); - } - } } @@ -344,59 +360,6 @@ public class OutputController { printOut(e); printError(e); } - - public static String getHeader(Level level, StackTraceElement[] stack) { - StringBuilder sb = new StringBuilder(); - try { - String user = System.getProperty("user.name"); - sb.append("[").append(user).append("]"); - if (JNLPRuntime.isWebstartApplication()) { - sb.append("[ITW-JAVAWS]"); - } else { - sb.append("[ITW]"); - } - if (level != null) { - sb.append('[').append(level.toString()).append(']'); - } - sb.append('[').append(new Date().toString()).append(']'); - if (stack != null) { - sb.append('[').append(getCallerClass(stack)).append(']'); - } - sb.append(" NETX Thread# ") - .append(Integer.toHexString(((Object)Thread.currentThread()).hashCode())) - .append(", name ") - .append(Thread.currentThread().getName()); - } catch (Exception ex) { - getLogger().log(ex); - } - return sb.toString(); - - } - - static String getCallerClass(StackTraceElement[] stack) { - try { - //0 is always thread - //1..? is OutputController itself - //pick up first after. - StackTraceElement result = stack[0]; - int i = 1; - for (; i < stack.length; i++) { - result = stack[i];//at least moving up - if (stack[i].getClassName().contains(OutputController.class.getName()) || - //PluginDebug.class.getName() not avaiable during netx make - stack[i].getClassName().contains("sun.applet.PluginDebug") ) { - continue; - } else { - break; - } - } - return result.toString(); - } catch (Exception ex) { - getLogger().log(ex); - return "Unknown caller"; - } - } - //package private setters for testing diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/Header.java b/netx/net/sourceforge/jnlp/util/logging/headers/Header.java new file mode 100644 index 0000000..a87a14f --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/logging/headers/Header.java @@ -0,0 +1,161 @@ +/* +Copyright (C) 2009, 2013 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ +package net.sourceforge.jnlp.util.logging.headers; + +import java.util.Date; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.logging.OutputController; +import net.sourceforge.jnlp.util.logging.OutputController.Level; + +public class Header { + + public String user; + public boolean application; + public Level level; + public Date date = new Date(); + public boolean isC;//false=> java + public String caller; + public String thread1; + public String thread2; + + //to alow simple inheritance + public Header() { + } + + public Header(Level level, StackTraceElement[] stack, Thread thread, boolean isC) { + this(level, stack, thread, new Date(), isC); + } + + public Header(Level level, StackTraceElement[] stack, Thread thread, Date d, boolean isC) { + this.user = System.getProperty("user.name"); + this.application = JNLPRuntime.isWebstartApplication(); + this.level = level; + this.date = d; + this.isC = isC; + if (stack != null) { + this.caller = getCallerClass(stack); + } + this.thread1 = Integer.toHexString(((Object) thread).hashCode()); + this.thread2 = thread.getName(); + } + + @Override + public String toString() { + return toString(true, true, true, true, true, true, true); + } + + public String toString(boolean userb, boolean originb, boolean levelb, boolean dateb, boolean callerb, boolean thread1b, boolean thread2b) { + StringBuilder sb = new StringBuilder(); + try { + if (userb){ + sb.append("[").append(user).append("]"); + } + if(originb){ + sb.append("[").append(getOrigin()).append("]"); + } + + if (levelb && level != null) { + sb.append('[').append(level.toString()).append(']'); + } + if (dateb){ + sb.append('[').append(date.toString()).append(']'); + } + if (callerb && caller != null) { + sb.append('[').append(caller).append(']'); + } + if (thread1b && thread2b){ + sb.append(threadsToString()); + }else if (thread1b) { + sb.append(thread1ToString()); + }else if (thread2b) { + sb.append(thread2ToString()); + } + } catch (Exception ex) { + OutputController.getLogger().log(ex); + } + return sb.toString(); + } + + public String thread1ToString() { + return " NETX Thread# " + thread1; + } + + public String thread2ToString() { + return "name " + thread2; + } + + public String threadsToString() { + return thread1ToString() + + ", " + thread2ToString(); + } + + public String getOrigin() { + if (application) { + return "ITW-JAVAWS"; + } else { + if (isC) { + return "ITW-C-PLUGIN"; + } else { + return "ITW-APPLET"; + } + } + } + + static String getCallerClass(StackTraceElement[] stack) { + try { + //0 is always thread + //1..? is OutputController itself + //pick up first after. + StackTraceElement result = stack[0]; + int i = 1; + for (; i < stack.length; i++) { + result = stack[i];//at least moving up + if (stack[i].getClassName().contains(OutputController.class.getName()) + || //PluginDebug.class.getName() not avaiable during netx make + stack[i].getClassName().contains("sun.applet.PluginDebug")) { + continue; + } else { + break; + } + } + return result.toString(); + } catch (Exception ex) { + OutputController.getLogger().log(ex); + return "Unknown caller"; + } + } +} diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java b/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java new file mode 100644 index 0000000..6994f9e --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/logging/headers/JavaMessage.java @@ -0,0 +1,63 @@ +/* +Copyright (C) 2009, 2013 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package net.sourceforge.jnlp.util.logging.headers; + + + +public class JavaMessage implements MessageWithHeader{ + + public Header header; + public String message; + + public JavaMessage(Header header, String message) { + this.header = header; + this.message = message; + } + + + + @Override + public String getMessage() { + return message; + } + + @Override + public Header getHeader() { + return header; + } +} diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java b/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java new file mode 100644 index 0000000..5af997b --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/logging/headers/MessageWithHeader.java @@ -0,0 +1,46 @@ +/* +Copyright (C) 2009, 2013 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package net.sourceforge.jnlp.util.logging.headers; + + +public interface MessageWithHeader { + + String getMessage(); + Header getHeader(); + +} diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java b/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java new file mode 100644 index 0000000..31ed19d --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/logging/headers/PluginHeader.java @@ -0,0 +1,82 @@ +/* +Copyright (C) 2009, 2013 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. * + */ +package net.sourceforge.jnlp.util.logging.headers; + +import java.util.Date; +import java.util.regex.Pattern; + +public class PluginHeader extends Header { + + public boolean preinit; + public Date originalTimeStamp; + static final String PLUGIN_DEBUG = "plugindebug "; + static final String PLUGIN_DEBUG_PREINIT = "preinit_plugindebug "; + static final String PLUGIN_ERROR = "pluginerror "; + static final String PLUGIN_ERROR_PREINIT = "preinit_pluginerror "; + static final Pattern bracketsPattern = Pattern.compile("(\\]\\s*\\[)|(\\s*\\[)|(\\]\\s*)"); + static final Pattern whiteSpaces = Pattern.compile("\\s+"); + static final Pattern threadsPattern = Pattern.compile("\\s+|,\\s*|:"); + + @Override + public String toString() { + if (preinit) { + return "!" + super.toString(); + } else { + return super.toString(); + } + } + + @Override + public String toString(boolean userb, boolean originb, boolean levelb, boolean dateb, boolean callerb, boolean thread1b, boolean thread2b) { + if (preinit) { + return "!" + super.toString(userb, originb, levelb, dateb, callerb, thread1b, thread2b); + } else { + return super.toString(userb, originb, levelb, dateb, callerb, thread1b, thread2b); + } + } + + @Override + public String thread1ToString() { + return " ITNPP Thread# " + thread1; + } + + @Override + public String thread2ToString() { + return "gthread " + thread2; + } +} diff --git a/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java b/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java new file mode 100644 index 0000000..098d258 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/logging/headers/PluginMessage.java @@ -0,0 +1,94 @@ +/* +Copyright (C) 2009, 2013 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package net.sourceforge.jnlp.util.logging.headers; + +import java.util.Date; +import net.sourceforge.jnlp.util.logging.FileLog; +import net.sourceforge.jnlp.util.logging.OutputController; + +public class PluginMessage implements MessageWithHeader{ + + public PluginHeader header; + public String restOfMessage; + public boolean wasError = false; + + public PluginMessage(String orig) { + restOfMessage = orig; + header = new PluginHeader(); + String s = orig.trim(); + PluginHeader p = this.header; + try { + p.isC = true; + p.application = false; + if (s.startsWith("preinit_plugin")) { + p.preinit = true; + } + if (s.startsWith(PluginHeader.PLUGIN_DEBUG) || s.startsWith(PluginHeader.PLUGIN_DEBUG_PREINIT)) { + p.level = OutputController.Level.MESSAGE_DEBUG; + } else if (s.startsWith(PluginHeader.PLUGIN_ERROR) || s.startsWith(PluginHeader.PLUGIN_ERROR_PREINIT)) { + p.level = OutputController.Level.ERROR_ALL; + } else { + p.level = OutputController.Level.WARNING_ALL; + } + String[] init = PluginHeader.whiteSpaces.split(s); + p.originalTimeStamp = new Date(Long.parseLong(init[1]) / 1000); + String[] main = PluginHeader.bracketsPattern.split(s); + p.user = main[1]; + p.caller = main[5]; + p.date = FileLog.getPluginSharedFormatter().parse(main[4]); + String[] threads = PluginHeader.threadsPattern.split(main[6]); + p.thread1 = threads[2]; + p.thread2 = threads[4]; + int i = orig.indexOf(p.thread2); + restOfMessage = orig.substring(i + p.thread2.length() + 2); //+": " + } catch (Exception ex) { + OutputController.getLogger().log(ex); + this.wasError = true; + } + } + + @Override + public String getMessage() { + return restOfMessage; + } + + @Override + public Header getHeader() { + return header; + } +} diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc index 9a0d0c4..1317831 100644 --- a/plugin/icedteanp/IcedTeaNPPlugin.cc +++ b/plugin/icedteanp/IcedTeaNPPlugin.cc @@ -138,6 +138,9 @@ gint in_watch_source; // Applet viewer output pipe name. gchar* out_pipe_name; +// Applet viewer debug pipe name. +gchar* debug_pipe_name = NULL; + // Applet viewer output watch source. gint out_watch_source; @@ -147,9 +150,15 @@ pthread_t itnp_plugin_thread_id; // Mutex to lock async call queue pthread_mutex_t pluginAsyncCallMutex; +/*to sync pipe to apletviewer console*/ +pthread_mutex_t debug_pipe_lock = PTHREAD_MUTEX_INITIALIZER; + // Applet viewer output channel. GIOChannel* out_to_appletviewer; +// Applet viewer debug channel. +GIOChannel* debug_to_appletviewer = NULL; + // Tracks jvm status gboolean jvm_up = FALSE; @@ -488,6 +497,34 @@ void start_jvm_if_needed() } PLUGIN_DEBUG ("ITNP_New: created output fifo: %s\n", out_pipe_name); + // Create plugin-debug-to-appletviewer pipe which we refer to as the + // debug pipe. + initialize_debug();//should be already initialized, but... + if (plugin_debug_to_console){ + // debug_pipe_name + debug_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-debug-to-appletviewer", + data_directory.c_str(), getpid()); + + if (!debug_pipe_name) + { + PLUGIN_ERROR ("Failed to create debug pipe name.\n"); + np_error = NPERR_OUT_OF_MEMORY_ERROR; + goto cleanup_debug_pipe_name; + } + + // clean up any older pip + unlink (debug_pipe_name); + + PLUGIN_DEBUG ("ITNP_New: creating debug fifo: %s\n", debug_pipe_name); + if (mkfifo (debug_pipe_name, 0600) == -1 && errno != EEXIST) + { + PLUGIN_ERROR ("Failed to create debug pipe\n", strerror (errno)); + np_error = NPERR_GENERIC_ERROR; + goto cleanup_debug_pipe_name; + } + PLUGIN_DEBUG ("ITNP_New: created debug fifo: %s\n", debug_pipe_name); + } + // Start a separate appletviewer process for each applet, even if // there are multiple applets in the same page. We may need to // change this behaviour if we find pages with multiple applets that @@ -548,12 +585,46 @@ void start_jvm_if_needed() g_io_add_watch (in_from_appletviewer, (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP), plugin_in_pipe_callback, (gpointer) in_from_appletviewer); + + // Create plugin-to-appletviewer console debug channel. The default encoding for + // the file is UTF-8. + // debug_to_appletviewer + if (plugin_debug_to_console){ + debug_to_appletviewer = g_io_channel_new_file (debug_pipe_name, + "w", &channel_error); + if (!debug_to_appletviewer) + { + if (channel_error) + { + PLUGIN_ERROR ("Failed to debug output channel, '%s'\n", + channel_error->message); + g_error_free (channel_error); + channel_error = NULL; + } + else + PLUGIN_ERROR ("Failed to create debug channel\n"); + + np_error = NPERR_GENERIC_ERROR; + goto cleanup_debug_to_appletviewer; + } + } jvm_up = TRUE; - + + if (plugin_debug_to_console){ + //jvm is up, we can start console producer thread + pthread_t debug_to_console_consumer; + pthread_create(&debug_to_console_consumer,NULL,&flush_pre_init_messages,NULL); + } goto done; // Free allocated data in case of error + cleanup_debug_to_appletviewer: + if (plugin_debug_to_console){ + if (debug_to_appletviewer) + g_io_channel_unref (debug_to_appletviewer); + debug_to_appletviewer = NULL; + } cleanup_in_watch_source: // Removing a source is harmless if it fails since it just means the @@ -575,6 +646,21 @@ void start_jvm_if_needed() g_io_channel_unref (out_to_appletviewer); out_to_appletviewer = NULL; + if (plugin_debug_to_console){ + // cleanup_debug_pipe: + // Delete output pipe. + PLUGIN_DEBUG ("ITNP_New: deleting debug fifo: %s\n", debug_pipe_name); + unlink (debug_pipe_name); + PLUGIN_DEBUG ("ITNP_New: deleted debug fifo: %s\n", debug_pipe_name); + } + cleanup_debug_pipe_name: + if (plugin_debug_to_console){ + g_free (debug_pipe_name); + debug_pipe_name = NULL; + } + + + // cleanup_out_pipe: // Delete output pipe. PLUGIN_DEBUG ("ITNP_New: deleting input fifo: %s\n", in_pipe_name); @@ -1401,6 +1487,9 @@ plugin_start_appletviewer (ITNPPluginData* data) command_line.push_back("sun.applet.PluginMain"); command_line.push_back(out_pipe_name); command_line.push_back(in_pipe_name); + if (plugin_debug_to_console){ + command_line.push_back(debug_pipe_name); + } // Finished command line parameters @@ -1576,6 +1665,38 @@ plugin_send_message_to_appletviewer (gchar const* message) PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n"); } +// unlike like plugin_send_message_to_appletviewer +// do not debug +// do not error +// do not have its own line end +// is accesed by only one thread +// have own pipe +// jvm must be up +void +plugin_send_message_to_appletviewer_console (gchar const* newline_message) +{ + gsize bytes_written = 0; + if (g_io_channel_write_chars (debug_to_appletviewer, + newline_message, -1, &bytes_written, + &channel_error) != G_IO_STATUS_NORMAL) { + if (channel_error) { + //error must be freed + g_error_free (channel_error); + channel_error = NULL; + } + } +} +//flush only when its full +void flush_plugin_send_message_to_appletviewer_console (){ + if (g_io_channel_flush (debug_to_appletviewer, &channel_error) + != G_IO_STATUS_NORMAL) { + if (channel_error) { + g_error_free (channel_error); + channel_error = NULL; + } + } +} + /* * Sends the initialization message (handle/size/url) to the plugin */ @@ -2046,6 +2167,36 @@ NP_Shutdown (void) g_free (in_pipe_name); in_pipe_name = NULL; + if (plugin_debug_to_console){ + //jvm_up is now false + if (g_io_channel_shutdown (debug_to_appletviewer, + TRUE, &channel_error) + != G_IO_STATUS_NORMAL) + { + if (channel_error) + { + PLUGIN_ERROR ("Failed to shut down appletviewer" + " debug channel\n", channel_error->message); + g_error_free (channel_error); + channel_error = NULL; + } + else + PLUGIN_ERROR ("Failed to shut down debug to appletviewer\n"); + } + // cleanup_out_to_appletviewer: + if (debug_to_appletviewer) + g_io_channel_unref (debug_to_appletviewer); + out_to_appletviewer = NULL; + // cleanup_debug_pipe: + // Delete debug pipe. + PLUGIN_DEBUG ("NP_Shutdown: deleting debug fifo: %s\n", debug_pipe_name); + unlink (debug_pipe_name); + PLUGIN_DEBUG ("NP_Shutdown: deleted debug fifo: %s\n", debug_pipe_name); + // cleanup_out_pipe_name: + g_free (debug_pipe_name); + debug_pipe_name = NULL; + } + // Destroy the call queue mutex pthread_mutex_destroy(&pluginAsyncCallMutex); diff --git a/plugin/icedteanp/IcedTeaNPPlugin.h b/plugin/icedteanp/IcedTeaNPPlugin.h index 6e1465b..3e66599 100644 --- a/plugin/icedteanp/IcedTeaNPPlugin.h +++ b/plugin/icedteanp/IcedTeaNPPlugin.h @@ -115,6 +115,9 @@ extern pthread_t itnp_plugin_thread_id; /* Mutex around plugin async call queue ops */ extern pthread_mutex_t pluginAsyncCallMutex; +/*to sync pipe to apletviewer console*/ +extern pthread_mutex_t debug_pipe_lock; + // debug switches extern bool debug_initiated; extern int plugin_debug; @@ -125,6 +128,9 @@ extern bool plugin_debug_to_system; extern bool plugin_debug_to_console; extern FILE * plugin_file_log; extern std::string plugin_file_log_name; +extern gchar* debug_pipe_name; + +extern gboolean jvm_up; // Browser function table. extern NPNetscapeFuncs browser_functions; @@ -152,6 +158,9 @@ int get_id_from_instance(NPP instance); /* Sends a message to the appletviewer */ void plugin_send_message_to_appletviewer(gchar const* message); +/*this method is not logging, do not add \n and is using different pipe*/ +void plugin_send_message_to_appletviewer_console(gchar const* message); +void flush_plugin_send_message_to_appletviewer_console(); /* Returns an appropriate (package/object) scriptable npobject */ NPObject* get_scriptable_object(NPP instance); diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc index 0986aa8..5cd4231 100644 --- a/plugin/icedteanp/IcedTeaPluginUtils.cc +++ b/plugin/icedteanp/IcedTeaPluginUtils.cc @@ -54,10 +54,37 @@ int IcedTeaPluginUtilities::reference = -1; pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALIZER; std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>(); std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>(); +std::queue<std::string> pre_jvm_message; /* Plugin async call queue */ static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >(); +void *flush_pre_init_messages(void* data) { +while (true){ + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + nanosleep(&ts ,0); + if (jvm_up) { + while (!pre_jvm_message.empty()) { + pthread_mutex_lock(&debug_pipe_lock); + std::string message = pre_jvm_message.front(); + pre_jvm_message.pop(); + pthread_mutex_unlock(&debug_pipe_lock); + plugin_send_message_to_appletviewer_console(message.c_str()); + + } + flush_plugin_send_message_to_appletviewer_console(); + } + +} +} +void push_pre_init_messages(char * ldm){ + pthread_mutex_lock(&debug_pipe_lock); + pre_jvm_message.push(std::string(ldm)); + pthread_mutex_unlock(&debug_pipe_lock); +} + /** * Given a context number, constructs a message prefix to send to Java * @@ -1161,7 +1188,11 @@ void IcedTeaPluginUtilities::printDebugStatus(){ PLUGIN_DEBUG("plugin_debug_to_system: false\n"); } if (plugin_debug_to_console){ - PLUGIN_DEBUG("plugin_debug_to_console: true\n"); + if (debug_pipe_name){ + PLUGIN_DEBUG("plugin_debug_to_console: true, pipe %s\n", debug_pipe_name); + } else { + PLUGIN_DEBUG("plugin_debug_to_console: true, pipe not yet known or broken\n"); + } } else { PLUGIN_DEBUG("plugin_debug_to_console: false\n"); } diff --git a/plugin/icedteanp/IcedTeaPluginUtils.h b/plugin/icedteanp/IcedTeaPluginUtils.h index f0f52d7..6967793 100644 --- a/plugin/icedteanp/IcedTeaPluginUtils.h +++ b/plugin/icedteanp/IcedTeaPluginUtils.h @@ -58,6 +58,7 @@ exception statement from your version. */ #include <sstream> #include <string> #include <vector> +#include <queue> #include <npapi.h> #include <glib.h> @@ -65,6 +66,9 @@ exception statement from your version. */ #include "IcedTeaParseProperties.h" +void *flush_pre_init_messages(void* data); +void push_pre_init_messages(char * ldm); + // debugging macro. #define initialize_debug() \ do \ @@ -81,7 +85,7 @@ exception statement from your version. */ IcedTeaPluginUtilities::initFileLog(); \ } \ if (plugin_debug_to_console) { \ - /*no op now*/ \ + /*initialisation done during jvm startup*/ \ } \ IcedTeaPluginUtilities::printDebugStatus(); \ } \ @@ -91,6 +95,7 @@ exception statement from your version. */ #define HEADER_SIZE 500 #define BODY_SIZE 500 #define MESSAGE_SIZE HEADER_SIZE + BODY_SIZE +#define LDEBUG_MESSAGE_SIZE MESSAGE_SIZE+50 //header is destination char array #define CREATE_HEADER(ldebug_header) \ @@ -132,7 +137,21 @@ exception statement from your version. */ fflush(plugin_file_log); \ } \ if (plugin_debug_to_console) { \ - /*no op now*/ \ + /*headers are always going to console*/ \ + if (!plugin_debug_headers){ \ + CREATE_HEADER(ldebug_header); \ + } \ + snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ + char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \ + struct timeval current_time; \ + gettimeofday (¤t_time, NULL);\ + if (jvm_up) { \ + snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ + push_pre_init_messages(ldebug_channel_message); \ + } else { \ + snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ + push_pre_init_messages(ldebug_channel_message); \ + } \ } \ } \ } while (0) @@ -161,7 +180,21 @@ exception statement from your version. */ fflush(plugin_file_log); \ } \ if (plugin_debug_to_console) { \ - /*no op now*/ \ + /*headers are always going to console*/ \ + if (!plugin_debug_headers){ \ + CREATE_HEADER(ldebug_header); \ + } \ + snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ + char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \ + struct timeval current_time; \ + gettimeofday (¤t_time, NULL);\ + if (jvm_up) { \ + snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ + push_pre_init_messages(ldebug_channel_message); \ + } else { \ + snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ + push_pre_init_messages(ldebug_channel_message); \ + } \ } \ } while (0) diff --git a/plugin/icedteanp/java/sun/applet/PluginMain.java b/plugin/icedteanp/java/sun/applet/PluginMain.java index e6ba080..421edb5 100644 --- a/plugin/icedteanp/java/sun/applet/PluginMain.java +++ b/plugin/icedteanp/java/sun/applet/PluginMain.java @@ -84,6 +84,7 @@ import net.sourceforge.jnlp.config.DeploymentConfiguration; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.security.JNLPAuthenticator; import net.sourceforge.jnlp.util.logging.JavaConsole; +import net.sourceforge.jnlp.util.logging.LogConfig; import net.sourceforge.jnlp.util.logging.OutputController; /** @@ -119,16 +120,30 @@ public class PluginMain { */ public static void main(String args[]) throws IOException { + //we are polite, we reprint start arguments + OutputController.getLogger().log("startup arguments: "); + for (int i = 0; i < args.length; i++) { + String string = args[i]; + OutputController.getLogger().log(i + ": "+string); + + } if (AppContext.getAppContext() == null) { SunToolkit.createNewAppContext(); } installDummyJavascriptProtocolHandler(); - if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) { + if (args.length < 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) { OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Invalid pipe names provided. Refusing to proceed."); JNLPRuntime.exit(1); } DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched(); + if (JavaConsole.isEnabled()) { + if ((args.length < 3) || !new File(args[2]).exists()) { + OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Warning, although console is on, plugin debug connection do not exists. No plugin information will be displayed in console (only java ones)."); + } else { + JavaConsole.getConsole().createPluginReader(new File(args[2])); + } + } try { PluginStreamHandler streamHandler = connect(args[0], args[1]); diff --git a/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java b/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java new file mode 100644 index 0000000..8b36bac --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/util/logging/JavaConsoleTest.java @@ -0,0 +1,59 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package net.sourceforge.jnlp.util.logging; + +import net.sourceforge.jnlp.util.logging.headers.PluginMessage; +import java.util.Date; +import org.junit.Assert; +import org.junit.Test; + + +public class JavaConsoleTest { + + + String s1 = "plugindebug 1384850630162925 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1204] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: PIPE: plugin read: plugin PluginProxyInfo reference 1 http://www.walter-fendt.de:80"; + String s2 = "plugindebugX 1384850630162954 [jvanek][ITW-Cplugindebug 1384850630163008 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1124] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: parts[0]=plugin, parts[1]=PluginProxyInfo, reference, parts[3]=1, parts[4]=http://www.walter-fendt.de:80 -- decoded_url=http://www.walter-fendt.de:80"; + String s3 = "preinit_pluginerror 1384850630163298 [jvanek][ITW-C-PLUGIN][MESSAGE_DEBUG][Tue Nov 19 09:43:50 CET 2013][/home/jvanek/Desktop/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc:1134] ITNPP Thread# 140513434003264, gthread 0x7fcbd531f8c0: Proxy info: plugin PluginProxyInfo reference 1 DIRECT"; + + @Test + public void CreatePluginHeaderTestOK() throws Exception{ + PluginMessage p1 = new PluginMessage(s1); + System.out.println(p1.header + p1.restOfMessage); + PluginMessage p3 = new PluginMessage(s3); + Assert.assertFalse(p1.wasError); + Assert.assertFalse(p3.wasError); + Assert.assertTrue(p1.header.isC); + Assert.assertTrue(p3.header.isC); + Assert.assertEquals(OutputController.Level.MESSAGE_DEBUG,p1.header.level); + Assert.assertEquals(OutputController.Level.ERROR_ALL,p3.header.level); + Assert.assertTrue(p1.header.date.toString().contains("Tue Nov 19 09:43:50") && p1.header.date.toString().contains("2013")); + Assert.assertTrue(p3.header.date.toString().contains("Tue Nov 19 09:43:50") && p3.header.date.toString().contains("2013")); + Assert.assertTrue(p1.header.caller.contains("/home/jvanek")); + Assert.assertTrue(p3.header.caller.contains("/home/jvanek")); + Assert.assertTrue(p1.header.user.equals("jvanek")); + Assert.assertTrue(p3.header.user.equals("jvanek")); + Assert.assertTrue(p1.header.thread1.equals("140513434003264")); + Assert.assertTrue(p1.header.thread2.equals("0x7fcbd531f8c0")); + Assert.assertTrue(p3.header.thread1.equals("140513434003264")); + Assert.assertTrue(p3.header.thread2.equals("0x7fcbd531f8c0")); + Assert.assertTrue(p1.restOfMessage.equals(" PIPE: plugin read: plugin PluginProxyInfo reference 1 http://www.walter-fendt.de:80")); + Assert.assertTrue(p3.restOfMessage.equals("Proxy info: plugin PluginProxyInfo reference 1 DIRECT")); + + } + @Test + public void CreatePluginHeaderTestNotOK()throws Exception{ + PluginMessage p2 = new PluginMessage(s2); + Assert.assertTrue(p2.wasError); + Assert.assertTrue(p2.header.isC); + Assert.assertEquals(OutputController.Level.WARNING_ALL,p2.header.level); + Assert.assertTrue(p2.header.date.toString().contains(new Date().toString().substring(0,16))); //means no Tue Nov 19 09:43:50 :) + Assert.assertTrue(p2.header.user.equals("jvanek")); + Assert.assertTrue(p2.header.thread1 == null); + Assert.assertTrue(p2.header.thread2 == null); + + + } +} |