changeset 947:c0845e58bfba

Client applications now log into new console.
author Jiri Vanek <jvanek@redhat.com>
date Mon, 24 Mar 2014 17:04:51 +0100
parents 2d02a075cb1e
children 80e5a57863e2
files ChangeLog netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/runtime/Boot.java netx/net/sourceforge/jnlp/util/TeeOutputStream.java netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPane.java netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPaneModel.java netx/net/sourceforge/jnlp/util/logging/JavaConsole.java netx/net/sourceforge/jnlp/util/logging/OutputController.java netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java netx/net/sourceforge/jnlp/util/logging/headers/Header.java
diffstat 10 files changed, 261 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Mar 24 16:46:09 2014 +0100
+++ b/ChangeLog	Mon Mar 24 17:04:51 2014 +0100
@@ -1,4 +1,26 @@
-2014-03-20  Jiri Vanek  <jvanek@redhat.com>
+2014-03-24  Jiri Vanek  <jvanek@redhat.com>
+
+	Client applications now log into new console.
+	* netx/net/sourceforge/jnlp/resources/Messages.properties: added keys (COPitw)
+	and (COPclientApp) for new checkboxes in console
+	* netx/net/sourceforge/jnlp/runtime/Boot.java: added brackets to headless if
+	* netx/net/sourceforge/jnlp/util/TeeOutputStream.java: moved to
+	* netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java: and improved to
+	log into new console.
+	* netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPane.java: added new
+	checkboxes to filter out/in custom app/itw logs. copyAll buttons do not include
+	custom app's logs in case of first click.
+	* netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPaneModel.java: Added
+	testing data with custom app. (HTMLCOLOR_PURPLE) and (HTMLCOLOR_GREEN) as
+	new colors for custom app. (filter) now handle client app.
+	* netx/net/sourceforge/jnlp/util/logging/JavaConsole.java: (init) redirect
+	stdout/err over teeOutputStream
+	* /netx/net/sourceforge/jnlp/util/logging/OutputController.java: (consume)
+	do not reprint if header is marked by isClientApp
+	* netx/net/sourceforge/jnlp/util/logging/headers/Header.java: added field
+	(isClientApp)
+	
+2014-03-24  Jiri Vanek  <jvanek@redhat.com>
 
 	* netx/net/sourceforge/jnlp/controlpanel/CachePane.java: (visualCleanCache)
 	consider exception in cache operation as not-scuess.
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Mon Mar 24 17:04:51 2014 +0100
@@ -622,6 +622,8 @@
 COPmatch=match
 COPnot=not
 COPrevert=revert
+COPitw=IcedTea-Web
+COPclientApp=Client app.
 
 # Control Panel - DesktopShortcutPanel
 DSPNeverCreate=Never create
--- a/netx/net/sourceforge/jnlp/runtime/Boot.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/runtime/Boot.java	Mon Mar 24 17:04:51 2014 +0100
@@ -135,8 +135,9 @@
         if (AppContext.getAppContext() == null) {
             SunToolkit.createNewAppContext();
         }
-        if (null != getOption("-headless"))
+        if (null != getOption("-headless")) {
             JNLPRuntime.setHeadless(true);
+        }
 
         DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched();
 
--- a/netx/net/sourceforge/jnlp/util/TeeOutputStream.java	Mon Mar 24 16:46:09 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* TeeOutputStream.java
-   Copyright (C) 2010 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;
-
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-
-/**
- * Behaves like the 'tee' command, sends output to both actual std stream and a
- * file
- */
-public final class TeeOutputStream extends PrintStream {
-
-    // Everthing written to TeeOutputStream is written to this file
-    PrintStream logFile;
-
-    public TeeOutputStream(FileOutputStream fileOutputStream,
-            PrintStream stdStream) {
-        super(stdStream);
-        logFile = new PrintStream(fileOutputStream);
-    }
-
-    @Override
-    public boolean checkError() {
-        boolean thisError = super.checkError();
-        boolean fileError = logFile.checkError();
-
-        return thisError || fileError;
-    }
-
-    @Override
-    public void close() {
-        logFile.close();
-        super.close();
-    }
-
-    @Override
-    public void flush() {
-        logFile.flush();
-        super.flush();
-    }
-
-    /*
-     * The big ones: these do the actual writing
-     */
-
-    @Override
-    public void write(byte[] buf, int off, int len) {
-        logFile.write(buf, off, len);
-
-        super.write(buf, off, len);
-    }
-
-    @Override
-    public void write(int b) {
-        logFile.write(b);
-
-        super.write(b);
-    }
-}
--- a/netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPane.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPane.java	Mon Mar 24 17:04:51 2014 +0100
@@ -31,6 +31,8 @@
 import net.sourceforge.jnlp.util.logging.headers.ObservableMessagesProvider;
 
 public class ConsoleOutputPane extends javax.swing.JPanel implements Observer {
+    
+    private boolean canChange = true;
 
     @Override
     public synchronized void update(Observable o, Object arg) {
@@ -171,7 +173,7 @@
 
             @Override
             public void actionPerformed(java.awt.event.ActionEvent evt) {
-                refreshAction(evt);
+                refreshAction();
             }
         };
     }
@@ -284,6 +286,8 @@
         wordWrap = new javax.swing.JCheckBox();
         showDebug = new javax.swing.JCheckBox();
         showInfo = new javax.swing.JCheckBox();
+        showItw = new javax.swing.JCheckBox();
+        showApp = new javax.swing.JCheckBox();
         showCode = new javax.swing.JCheckBox();
         statistics = new javax.swing.JLabel();
         showPostInit = new javax.swing.JCheckBox();
@@ -384,7 +388,7 @@
             @Override
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                 model.usedPattern = model.lastValidPattern;
-                refreshAction(evt);
+                refreshAction();
             }
         });
 
@@ -447,6 +451,14 @@
         showInfo.setSelected(true);
         showInfo.setText(Translator.R("COPinfo"));
         showInfo.addActionListener(getDefaultActionSingleton());
+        
+        showItw.setSelected(true);
+        showItw.setText(Translator.R("COPitw"));
+        showItw.addActionListener(getDefaultActionSingleton());
+        
+        showApp.setSelected(true);
+        showApp.setText(Translator.R("COPclientApp"));
+        showApp.addActionListener(getDefaultActionSingleton());
 
         showCode.setSelected(true);
         showCode.setText(Translator.R("COPcode"));
@@ -523,7 +535,10 @@
                 addComponent(showJava).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).
                 addComponent(showPlugin).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addComponent(showDebug).addGap(6, 6, 6).
-                addComponent(showInfo))).addGap(2, 2, 2).
+                addComponent(showInfo).addGap(6, 6, 6).
+                addComponent(showItw).addGap(6, 6, 6).
+                addComponent(showApp)
+                )).addGap(2, 2, 2).
                 addComponent(statistics)).addGroup(
                 javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup().
                 addComponent(showPreInit).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).
@@ -564,6 +579,8 @@
                 addComponent(showPlugin).
                 addComponent(showDebug).
                 addComponent(showInfo).
+                addComponent(showItw).
+                addComponent(showApp).
                 addComponent(statistics)).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(
                 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).
                 addComponent(showPreInit).
@@ -708,7 +725,7 @@
         validate();
     }
 
-    private void refreshAction(java.awt.event.ActionEvent evt) {
+    private void refreshAction() {
         updateModel();
         refreshPane();
     }
@@ -807,10 +824,20 @@
     }
 
     private void copyPlainActionPerformed(java.awt.event.ActionEvent evt) {
+        if (canChange) {
+            showApp.setSelected(false);
+            refreshAction();
+            canChange = false;
+        }
         fillClipBoard(false, sortCopyAll.isSelected());
     }
 
     private void copyRichActionPerformed(java.awt.event.ActionEvent evt) {
+        if (canChange) {
+            showApp.setSelected(false);
+            refreshAction();
+            canChange = false;
+        }
         fillClipBoard(true, sortCopyAll.isSelected());
     }
     
@@ -856,6 +883,8 @@
         model.showHeaders = showHeaders.isSelected();
         model.showIncomplete = showIncomplete.isSelected();
         model.showInfo = showInfo.isSelected();
+        model.showItw = showItw.isSelected();
+        model.showApp = showApp.isSelected();
         model.showJava = showJava.isSelected();
         model.showLevel = showLevel.isSelected();
         model.showMessage = showMessage.isSelected();
@@ -900,6 +929,8 @@
     private javax.swing.JButton showHide;
     private javax.swing.JCheckBox showIncomplete;
     private javax.swing.JCheckBox showInfo;
+    private javax.swing.JCheckBox showItw;
+    private javax.swing.JCheckBox showApp;
     private javax.swing.JCheckBox showJava;
     private javax.swing.JCheckBox showLevel;
     private javax.swing.JCheckBox showMessage;
--- a/netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPaneModel.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/util/logging/ConsoleOutputPaneModel.java	Mon Mar 24 17:04:51 2014 +0100
@@ -96,6 +96,12 @@
             origData.add(new JavaMessage(new Header(Level.WARNING_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "message 2"));
             origData.add(new JavaMessage(new Header(Level.WARNING_DEBUG, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "message 4"));
             origData.add(new JavaMessage(new Header(Level.MESSAGE_DEBUG, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "message 9"));
+            JavaMessage m1 = new JavaMessage(new Header(Level.MESSAGE_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "app1");
+            JavaMessage m2 = new JavaMessage(new Header(Level.ERROR_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "app2");
+            m1.getHeader().isClientApp = true;
+            m2.getHeader().isClientApp = true;
+            origData.add(m1);
+            origData.add(m2);
             origData.add(new JavaMessage(new Header(Level.MESSAGE_ALL, Thread.currentThread().getStackTrace(), Thread.currentThread(), false), "message 0 - multilined \n"
                     + "since beggining\n"
                     + "         later\n"
@@ -117,7 +123,8 @@
     private static final String HTMLCOLOR_GREENYELLOW = "AAAA00";
     private static final String HTMLCOLOR_PINKYREAD = "FF0055";
     private static final String HTMLCOLOR_BLACK = "000000";
-
+    private static final String HTMLCOLOR_GREEN = "669966";
+    private static final String HTMLCOLOR_PURPLE = "990066";
     String importList() {
         return importList(lastUpdateIndex);
     }
@@ -174,12 +181,20 @@
                         }
                     }
                 } else {
-                    if (messageWithHeader.getHeader().level.isWarning()) {
-                        sb.append(HTMLCOLOR_GREENYELLOW);
-                    } else if (messageWithHeader.getHeader().level.isError()) {
-                        sb.append(HTMLCOLOR_PINKYREAD);
+                    if (messageWithHeader.getHeader().isClientApp) {
+                        if (messageWithHeader.getHeader().level.isError()) {
+                            sb.append(HTMLCOLOR_PURPLE);
+                        } else {
+                            sb.append(HTMLCOLOR_GREEN);
+                        }
                     } else {
-                        sb.append(HTMLCOLOR_BLACK);
+                        if (messageWithHeader.getHeader().level.isWarning()) {
+                            sb.append(HTMLCOLOR_GREENYELLOW);
+                        } else if (messageWithHeader.getHeader().level.isError()) {
+                            sb.append(HTMLCOLOR_PINKYREAD);
+                        } else {
+                            sb.append(HTMLCOLOR_BLACK);
+                        }
                     }
                 }
                 sb.append("'>");
@@ -328,6 +343,12 @@
         if (!showInfo && m.getHeader().level.isInfo()) {
             return true;
         }
+        if (!showItw && !m.getHeader().isClientApp) {
+            return true;
+        }
+        if (!showApp && m.getHeader().isClientApp) {
+            return true;
+        }
         if (!showJava && !m.getHeader().isC) {
             return true;
         }
@@ -376,6 +397,8 @@
     boolean showHeaders;
     boolean showIncomplete;
     boolean showInfo;
+    boolean showItw;
+    boolean showApp;
     boolean showJava;
     boolean showLevel;
     boolean showMessage;
--- a/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/util/logging/JavaConsole.java	Mon Mar 24 17:04:51 2014 +0100
@@ -89,6 +89,16 @@
     final private List<MessageWithHeader> rawData = Collections.synchronizedList(new ArrayList<MessageWithHeader>());
     final private List<ConsoleOutputPane> outputs = new ArrayList<ConsoleOutputPane>();
 
+    public JavaConsole() {
+        //add middleware, which catches client's application stdout/err
+        //and will submit it into console
+        System.setErr(new TeeOutputStream(System.err, true));
+        System.setOut(new TeeOutputStream(System.out, false));
+        //internal stdOut/Err are going throughs outLog/errLog
+        //when console is off, those tees are not installed
+    }
+
+    
     private void refreshOutputs() {
         refreshOutputs(outputsPanel, (Integer)numberOfOutputs.getValue());
     }
--- a/netx/net/sourceforge/jnlp/util/logging/OutputController.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/util/logging/OutputController.java	Mon Mar 24 17:04:51 2014 +0100
@@ -148,6 +148,10 @@
         if (LogConfig.getLogConfig().isLogToConsole()) {
             JavaConsole.getConsole().addMessage(s);
         }
+        //clients app's messages are reprinted only to console
+        if (s.getHeader().isClientApp){
+            return;
+        }
         if (!JNLPRuntime.isDebug() && (s.getHeader().level == Level.MESSAGE_DEBUG
                 || s.getHeader().level == Level.WARNING_DEBUG
                 || s.getHeader().level == Level.ERROR_DEBUG)) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/util/logging/TeeOutputStream.java	Mon Mar 24 17:04:51 2014 +0100
@@ -0,0 +1,141 @@
+/* TeeOutputStream.java
+   Copyright (C) 2010 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;
+
+
+import java.io.PrintStream;
+import net.sourceforge.jnlp.util.logging.JavaConsole;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import net.sourceforge.jnlp.util.logging.OutputController.Level;
+import net.sourceforge.jnlp.util.logging.SingleStreamLogger;
+import net.sourceforge.jnlp.util.logging.headers.Header;
+import net.sourceforge.jnlp.util.logging.headers.JavaMessage;
+import net.sourceforge.jnlp.util.logging.headers.MessageWithHeader;
+
+/**
+ * Behaves like the 'tee' command, sends output to both actual std stream and a
+ * log
+ */
+public final class TeeOutputStream extends PrintStream implements SingleStreamLogger{
+
+    // Everthing written to TeeOutputStream is written to our log too
+    
+    private final StringBuffer string = new StringBuffer();
+    private final boolean isError;
+
+    public TeeOutputStream(PrintStream stdStream, boolean isError) {
+        super(stdStream);
+        this.isError = isError;
+    }
+
+
+    @Override
+    public void close() {
+        flushLog();
+        super.close();
+    }
+
+    @Override
+    public void flush() {
+        flushLog();
+        super.flush();
+    }
+
+    /*
+     * The big ones: these do the actual writing
+     */
+
+    @Override
+    public synchronized void write(byte[] b, int off, int len) {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if ((off < 0) || (off > b.length) || (len < 0)
+                || ((off + len) > b.length) || ((off + len) < 0)) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return;
+        }
+        for (int i = 0; i < len; i++) {
+            appendChar(b[off + i]);
+        }
+        super.write(b, off, len);
+    }
+
+    @Override
+    public synchronized void write(int b) {
+        appendChar(b);
+        super.write(b);
+    }
+
+    private void flushLog() {
+        if (string.length() <= 0 ){
+            return;
+        }
+        log(string.toString());
+        string.setLength(0);
+    }
+
+    @Override
+    public void log(String s) {
+        JavaMessage  jm = new JavaMessage(new Header(getlevel(), false), s);
+        jm.getHeader().isClientApp = true;
+        OutputController.getLogger().log(jm);
+    }
+
+    public boolean isError() {
+        return isError;
+    }
+
+    private void appendChar(int b) {
+         if ( b <= 0 || b == '\n'){
+            flushLog();
+        } else {
+            string.append((char)b);
+        }
+    }
+
+    private Level getlevel() {
+        if (isError()){
+            return OutputController.Level.ERROR_ALL;
+        } else {
+            return OutputController.Level.MESSAGE_ALL;
+        }
+    }
+    
+    
+}
--- a/netx/net/sourceforge/jnlp/util/logging/headers/Header.java	Mon Mar 24 16:46:09 2014 +0100
+++ b/netx/net/sourceforge/jnlp/util/logging/headers/Header.java	Mon Mar 24 17:04:51 2014 +0100
@@ -40,6 +40,7 @@
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.util.logging.OutputController;
 import net.sourceforge.jnlp.util.logging.OutputController.Level;
+import net.sourceforge.jnlp.util.logging.TeeOutputStream;
 
 public class Header {
     public static String  default_user = System.getProperty("user.name");
@@ -49,6 +50,7 @@
     public Level level = Level.WARNING_ALL;
     public Date date = new Date();
     public boolean isC = false;//false=> java
+    public boolean isClientApp = false;//false=> ITW
     public String caller = "unknown";
     public String thread1 = "unknown";
     public String thread2 = "unknown";
@@ -127,16 +129,24 @@
                 + ", " + thread2ToString();
     }
 
+    private static final String CLIENT = "CLIENT";
+
     public String getOrigin() {
+        String s;
         if (application) {
-            return "ITW-JAVAWS";
+            s = "ITW-JAVAWS";
         } else {
             if (isC) {
-                return "ITW-C-PLUGIN";
+                s = "ITW-C-PLUGIN";
             } else {
-                return "ITW-APPLET";
+                s = "ITW-APPLET";
             }
         }
+        if (isClientApp) {
+            s = s + "-" + CLIENT;
+        }
+        return s;
+
     }
 
     static String getCallerClass(StackTraceElement[] stack) {
@@ -151,7 +161,8 @@
                 if (stack[i].getClassName().contains(OutputController.class.getName())
                         || //PluginDebug.class.getName() not avaiable during netx make
                         stack[i].getClassName().contains("sun.applet.PluginDebug")
-                        || stack[i].getClassName().contains(Header.class.getName())) {
+                        || stack[i].getClassName().contains(Header.class.getName())
+                        || stack[i].getClassName().contains(TeeOutputStream.class.getName())) {
                     continue;
                 } else {
                     break;