fixes issue 6300 log4j messages are now printed to output window
authorMartin Taal <martin.taal@openbravo.com>
Fri, 19 Dec 2008 23:14:26 +0000
changeset 2432 d9081ec855ca
parent 2431 1bcc1234cff6
child 2433 312945e12cac
fixes issue 6300 log4j messages are now printed to output window
build.xml
config/log4j.lcf.template
src-core/src/org/openbravo/utils/OBLogAppender.java
src-db/database/build.xml
src-db/database/lib/dbsourcemanager.jar
src-test/org/openbravo/test/ant/RestartTomcatTest.java
src-test/org/openbravo/test/model/RuntimeModelTest.java
src-test/org/openbravo/test/xml/ClientDataSetCompleteTest.java
src/org/openbravo/erpCommon/utility/AntExecutor.java
src/org/openbravo/erpCommon/utility/OBPrintStream.java
--- a/build.xml	Fri Dec 19 23:08:17 2008 +0000
+++ b/build.xml	Fri Dec 19 23:14:26 2008 +0000
@@ -73,6 +73,7 @@
 	<property name="base.config" location="config" />
 	<property file="${base.config}/Openbravo.properties" />
 
+	<property name="base.config" location="config" />
 	<property name="base.src" location="src" />
 	<property name="base.src.core" location="src-core" />
 	<property name="base.src.db" location="src-db" />
--- a/config/log4j.lcf.template	Fri Dec 19 23:08:17 2008 +0000
+++ b/config/log4j.lcf.template	Fri Dec 19 23:14:26 2008 +0000
@@ -15,7 +15,16 @@
 # * Contributor(s):  ______________________________________.
 # ************************************************************************
 
-log4j.rootCategory=WARN, R
+log4j.rootCategory=INFO, R, O1
+
+# Set our global levels
+log4j.category.org=WARN
+log4j.category.org.openbravo=INFO
+
+# Additional Appender used for apply modules or other cases
+log4j.appender.O1=org.openbravo.utils.OBLogAppender
+log4j.appender.O1.layout=org.apache.log4j.PatternLayout
+log4j.appender.O1.layout.ConversionPattern=%-4r [%t] %-5p %c - %m%n
 
 log4j.appender.R=org.apache.log4j.RollingFileAppender
 log4j.appender.R.File=${catalina.base}/logs/openbravo.log
@@ -29,7 +38,6 @@
 log4j.appender.R.MaxBackupIndex=1
 
 log4j.category.reloadXml=ERROR
-log4j.category.org=WARN
 
 # To debug an specific class
 #log4j.category.org.openbravo.erpCommon.ad_process=DEBUG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-core/src/org/openbravo/utils/OBLogAppender.java	Fri Dec 19 23:14:26 2008 +0000
@@ -0,0 +1,91 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SL 
+ * All portions are Copyright (C) 2008 Openbravo SL 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.utils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * This appender can be used to send log4j to a programmatically set
+ * OutputStream. The OutputStream is stored in a ThreadLocal so only log events
+ * of the thread itself are send to the OutputStream set by that thread.
+ * 
+ * @author mtaal
+ */
+public class OBLogAppender extends AppenderSkeleton {
+
+    private static final ThreadLocal<OutputStream> outputStreamHolder = new ThreadLocal<OutputStream>();
+
+    /**
+     * Sets the passed OutputStream in a ThreadLocal, this OutputStream is then
+     * used by the appender to pass in log4j statements.
+     * 
+     * @param os
+     *            the OutputStream to which log4j events will be send.
+     */
+    public static void setOutputStream(OutputStream os) {
+        outputStreamHolder.set(os);
+    }
+
+    /**
+     * @return the OutputStream stored in the ThreadLocal, note can be null if
+     *         no OutputStream has been set.
+     */
+    public static OutputStream getOutputStream() {
+        return outputStreamHolder.get();
+    }
+
+    @Override
+    protected void append(LoggingEvent event) {
+        try {
+            if (outputStreamHolder.get() != null) {
+                if (getLayout() != null) {
+                    outputStreamHolder.get().write(
+                            getLayout().format(event).getBytes());
+                } else {
+                    outputStreamHolder.get().write(
+                            (event.getMessage().toString() + "\n").getBytes());
+                }
+                outputStreamHolder.get().flush();
+            }
+        } catch (final IOException e) {
+            // TODO: replace with OBException to log this exception
+            // can be done when OBException has been moved to the core
+            // lib
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Does not do anything in this implementation.
+     */
+    public void close() {
+    }
+
+    /**
+     * @return always returns false
+     */
+    public boolean requiresLayout() {
+        return false;
+    }
+}
--- a/src-db/database/build.xml	Fri Dec 19 23:08:17 2008 +0000
+++ b/src-db/database/build.xml	Fri Dec 19 23:14:26 2008 +0000
@@ -206,8 +206,9 @@
            	       input="sourcedata"
                        object="${bbdd.object}"
                        failonerror="false"
-                       verbosity="${bbdd.verbosity}" 
+                       verbosity="DEBUG"
 		       basedir="${base.modules}/"
+        	   baseConfig="${base.config}"
 		       dirFilter="*/src-db/database/model"
 		       datadir="${base.modules}/"
            	       dataFilter="*/src-db/database/sourcedata"
Binary file src-db/database/lib/dbsourcemanager.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/org/openbravo/test/ant/RestartTomcatTest.java	Fri Dec 19 23:14:26 2008 +0000
@@ -0,0 +1,36 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SL 
+ * All portions are Copyright (C) 2008 Openbravo SL 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.ant;
+
+import org.openbravo.service.system.ReloadContext;
+
+/**
+ * Tests an ant task.
+ * 
+ * @author mtaal
+ */
+
+public class RestartTomcatTest extends BaseAntTest {
+
+    public void testRestart() {
+        ReloadContext.reload();
+        // RestartTomcat.restart();
+    }
+}
\ No newline at end of file
--- a/src-test/org/openbravo/test/model/RuntimeModelTest.java	Fri Dec 19 23:08:17 2008 +0000
+++ b/src-test/org/openbravo/test/model/RuntimeModelTest.java	Fri Dec 19 23:14:26 2008 +0000
@@ -39,8 +39,9 @@
 
     // don't initialize dal layer for model tests
     @Override
-    protected void setUp() {
+    protected void setUp() throws Exception {
         setConfigPropertyFiles();
+        super.setUp();
     }
 
     public void testModelProvider() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/org/openbravo/test/xml/ClientDataSetCompleteTest.java	Fri Dec 19 23:14:26 2008 +0000
@@ -0,0 +1,67 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SL 
+ * All portions are Copyright (C) 2008 Openbravo SL 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.xml;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hibernate.criterion.Expression;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.dal.service.OBCriteria;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.ad.utility.DataSet;
+import org.openbravo.model.ad.utility.DataSetTable;
+import org.openbravo.service.db.DataExportService;
+
+/**
+ * Tests if the client definition data set is complete.
+ * 
+ * @author mtaal
+ */
+
+public class ClientDataSetCompleteTest extends XMLBaseTest {
+
+    public void testDataSetComplete() {
+        setUserContext("0");
+        final OBCriteria<DataSet> obc = OBDal.getInstance().createCriteria(
+                DataSet.class);
+        obc.add(Expression.eq("name", DataExportService.CLIENT_DATA_SET_NAME));
+        if (obc.list().size() == 0) {
+            throw new OBException("No dataset found with name "
+                    + DataExportService.CLIENT_DATA_SET_NAME);
+        }
+        final DataSet dataSet = obc.list().get(0);
+        final File dir = new File(
+                "/home/mtaal/mydata/dev/workspaces/obtrunk/openbravo/src-db/database/sampledata");
+        final Set<String> names = new HashSet<String>();
+        for (final File child : dir.listFiles()) {
+            if (!child.isDirectory()) {
+                names.add(child.getName());
+            }
+        }
+        for (final DataSetTable dst : dataSet.getDataSetTableList()) {
+            names.remove(dst.getTable().getTableName().toUpperCase() + ".xml");
+        }
+        for (final String name : names) {
+            System.err.println(name);
+        }
+    }
+}
\ No newline at end of file
--- a/src/org/openbravo/erpCommon/utility/AntExecutor.java	Fri Dec 19 23:08:17 2008 +0000
+++ b/src/org/openbravo/erpCommon/utility/AntExecutor.java	Fri Dec 19 23:14:26 2008 +0000
@@ -20,14 +20,20 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.util.Vector;
 
+import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
 import org.apache.tools.ant.DefaultLogger;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.ProjectHelper;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.utils.OBLogAppender;
 
 /**
  * The AntExecutor class allows to execute ant tasks in a given build.xml file.
@@ -159,6 +165,10 @@
         project.addBuildListener(logger1);
         err = ps2;
         log = ps1;
+
+        // force log4j to also print to this response
+        OBLogAppender.setOutputStream(ps1);
+
     }
 
     /**
@@ -246,9 +256,69 @@
         String rt = err.getLog(OBPrintStream.TEXT_PLAIN);
         if (rt == null || rt.equals("")) {
             final String mode = project.getProperty("deploy.mode");
-            rt = "SuccessRebuild."+mode;
+            rt = "SuccessRebuild." + mode;
         }
         return rt;
     }
 
+    private class LocalListener implements BuildListener {
+
+        private final OutputStream os;
+
+        private LocalListener(OutputStream os) {
+            this.os = os;
+        }
+
+        @Override
+        public void buildFinished(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void buildStarted(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void messageLogged(BuildEvent arg0) {
+            try {
+                if (arg0.getMessage() != null) {
+                    os.write(arg0.getMessage().getBytes());
+                }
+                if (arg0.getException() != null) {
+                    os.write(arg0.getException().getMessage().getBytes());
+                }
+            } catch (final IOException e) {
+                throw new OBException(e);
+            }
+        }
+
+        @Override
+        public void targetFinished(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void targetStarted(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void taskFinished(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void taskStarted(BuildEvent arg0) {
+            // TODO Auto-generated method stub
+
+        }
+
+    }
+
 }
--- a/src/org/openbravo/erpCommon/utility/OBPrintStream.java	Fri Dec 19 23:08:17 2008 +0000
+++ b/src/org/openbravo/erpCommon/utility/OBPrintStream.java	Fri Dec 19 23:14:26 2008 +0000
@@ -15,118 +15,134 @@
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
-*/
+ */
 
 package org.openbravo.erpCommon.utility;
-import java.io.*;
 
+import java.io.File;
+import java.io.PrintStream;
+import java.io.PrintWriter;
 
 /**
- * OBPrintStream class is a PrintStream, it allows to obtain a log (using the getLog() method) as a String. Each time this method
- * is called the log is emptied. Its purpose is to be used from an HTML using AJAX to fill a log textarea in real time.
+ * OBPrintStream class is a PrintStream, it allows to obtain a log (using the
+ * getLog() method) as a String. Each time this method is called the log is
+ * emptied. Its purpose is to be used from an HTML using AJAX to fill a log
+ * textarea in real time.
  * 
- *  @see org.openbravo.erpCommon.ad_process.ApplyModules
- *  @see AntExecutor
- *
+ * @see org.openbravo.erpCommon.ad_process.ApplyModules
+ * @see AntExecutor
+ * 
  */
-public class OBPrintStream extends PrintStream{
-  private StringBuffer log;
-  private boolean finished;
-  private PrintWriter out;
-  private PrintStream psout;
-  public static final int TEXT_HTML=1;
-  public static final int TEXT_PLAIN=2;
-  private File logFile;
-  private PrintWriter logWriter;
-  
-  /**
-   * Crates a new OBPrintStream object
-   */
-  public OBPrintStream(PrintWriter p) {
-    
-    super(System.out); //It is needed to call a super constructor, though it is not going to be used
-    setPrintWritter(p);
-    log = new StringBuffer();
-    finished = false;
-  }
-  public OBPrintStream(PrintStream p) {
-    
-    super(System.out); //It is needed to call a super constructor, though it is not going to be used
-    psout=p;
-    log = new StringBuffer();
-    finished = false;
-  }
-  
-  public void setPrintWritter(PrintWriter p){
-    out = p;
-  }
-  
-  public void setLogFile(File f)
-  {
-    logFile=f;
-    try{
-      logWriter=new PrintWriter(f);
-      
+public class OBPrintStream extends PrintStream {
+    private StringBuffer log;
+    private boolean finished;
+    private PrintWriter out;
+    private PrintStream psout;
+    public static final int TEXT_HTML = 1;
+    public static final int TEXT_PLAIN = 2;
+    private File logFile;
+    private PrintWriter logWriter;
+
+    /**
+     * Crates a new OBPrintStream object
+     */
+    public OBPrintStream(PrintWriter p) {
+
+        super(System.out); // It is needed to call a super constructor, though
+                           // it is not going to be used
+        setPrintWritter(p);
+        log = new StringBuffer();
+        finished = false;
     }
-    catch(Exception e)
-    {
-      e.printStackTrace();
+
+    public OBPrintStream(PrintStream p) {
+
+        super(System.out); // It is needed to call a super constructor, though
+                           // it is not going to be used
+        psout = p;
+        log = new StringBuffer();
+        finished = false;
     }
-  }
-  
-  /**
-   * Writes the log in a StringBuffer, if the PrintWritter is set if also writes there
-   * and flushes it.
-   */
-  public void write(byte[] buf, int off, int len) {
-    String s = new String(buf, off,len);
-    if(psout!=null){
-      psout.println(s.replace("\n", "<br/>"));
-      psout.flush();
+
+    public void setPrintWritter(PrintWriter p) {
+        out = p;
     }
-    else if (out!=null) {
-      out.println(s.replace("\n", "<br/>"));
-      out.flush();
+
+    public void setLogFile(File f) {
+        logFile = f;
+        try {
+            logWriter = new PrintWriter(f);
+
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
     }
-    if(logWriter!=null)
-    {
-      logWriter.print(s);
-      logWriter.flush();
+
+    /**
+     * Writes a byte array to the internal PrintStream, replaces line breaks
+     * with the <br/>
+     * html tag.
+     */
+    @Override
+    public void write(byte[] buf) {
+        write(buf, 0, buf.length);
     }
-    log.append(s);   
-  }
-  
-  /**
-   * Returns a String with the piece of log generated after the last call to this method.
-   * In case no log has been generated and the finished property is set to true, it returns and END String
-   * to be used in case the AJAX call has timed out.
-   * 
-   * @param showType - Defines the format to display the text
-   * @return - The newly generated log
-   */
-  public String getLog(int showType){
-    String rt = "";
-    if (log!=null) {
-      rt = log.toString();
-      log = new StringBuffer();
+
+    /**
+     * Writes the log in a StringBuffer, if the PrintWritter is set if also
+     * writes there and flushes it.
+     */
+    @Override
+    public void write(byte[] buf, int off, int len) {
+        final String s = new String(buf, off, len);
+        if (psout != null) {
+            psout.println(s.replace("\n", "<br/>"));
+            psout.flush();
+        } else if (out != null) {
+            out.println(s.replace("\n", "<br/>"));
+            out.flush();
+        }
+        if (logWriter != null) {
+            logWriter.print(s);
+            logWriter.flush();
+        }
+        log.append(s);
     }
-    if (rt.equals("") && finished) {
-      rt="@END@"; //to force end
-    } else {
-      switch (showType) {
-      case TEXT_HTML:
-        rt = rt.replace("\n", "<br/>");
-      }
+
+    /**
+     * Returns a String with the piece of log generated after the last call to
+     * this method. In case no log has been generated and the finished property
+     * is set to true, it returns and END String to be used in case the AJAX
+     * call has timed out.
+     * 
+     * @param showType
+     *            - Defines the format to display the text
+     * @return - The newly generated log
+     */
+    public String getLog(int showType) {
+        String rt = "";
+        if (log != null) {
+            rt = log.toString();
+            log = new StringBuffer();
+        }
+        if (rt.equals("") && finished) {
+            rt = "@END@"; // to force end
+        } else {
+            switch (showType) {
+            case TEXT_HTML:
+                rt = rt.replace("\n", "<br/>");
+            }
+        }
+        return rt;
     }
-    return rt;
-  }
-  
-  /**
-   * Sets the finished property to the passed value.
-   * 
-   * @param v - boolean value to set the finished property.
-   */
-  public void setFinished(boolean v) {
-    finished = v;
-  }
+
+    /**
+     * Sets the finished property to the passed value.
+     * 
+     * @param v
+     *            - boolean value to set the finished property.
+     */
+    public void setFinished(boolean v) {
+        finished = v;
+    }
 }