Log.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:11k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit.util;
  26. import com.sun.lwuit.Command;
  27. import com.sun.lwuit.Display;
  28. import com.sun.lwuit.Form;
  29. import com.sun.lwuit.TextArea;
  30. import com.sun.lwuit.events.ActionEvent;
  31. import com.sun.lwuit.layouts.BorderLayout;
  32. import java.io.ByteArrayOutputStream;
  33. import java.io.IOException;
  34. import java.io.InputStreamReader;
  35. import java.io.OutputStreamWriter;
  36. import java.io.Reader;
  37. import java.io.Writer;
  38. import javax.microedition.io.Connector;
  39. import javax.microedition.io.file.FileConnection;
  40. import javax.microedition.io.file.FileSystemRegistry;
  41. import javax.microedition.rms.RecordStore;
  42. import javax.microedition.rms.RecordStoreException;
  43. /**
  44.  * Pluggable logging framework that allows a developer to log into storage
  45.  * using the file connector API. It is highly recommended to use this 
  46.  * class coupled with Netbeans preprocessing tags to reduce its overhead
  47.  * completely in runtime.
  48.  *
  49.  * @author Shai Almog
  50.  */
  51. public class Log {
  52.     /**
  53.      * Constant indicating the logging level Debug is the default and the lowest level
  54.      * followed by info, warning and error
  55.      */
  56.     public static final int DEBUG = 1;
  57.     /**
  58.      * Constant indicating the logging level Debug is the default and the lowest level
  59.      * followed by info, warning and error
  60.      */
  61.     public static final int INFO = 2;
  62.     /**
  63.      * Constant indicating the logging level Debug is the default and the lowest level
  64.      * followed by info, warning and error
  65.      */
  66.     public static final int WARNING = 3;
  67.     /**
  68.      * Constant indicating the logging level Debug is the default and the lowest level
  69.      * followed by info, warning and error
  70.      */
  71.     public static final int ERROR = 4;
  72.     
  73.     
  74.     private int level = DEBUG;
  75.     private static Log instance = new Log();
  76.     private long zeroTime = System.currentTimeMillis();
  77.     private Writer output;
  78.     private boolean fileWriteEnabled = false;//System.getProperty("microedition.io.file.FileConnection.version") != null;
  79.     private String fileURL = null;
  80.     
  81.     /**
  82.      * Installs a log subclass that can replace the logging destination/behavior
  83.      * 
  84.      * @param newInstance the new instance for the Log object
  85.      */
  86.     public static void install(Log newInstance) {
  87.         instance = newInstance;
  88.     }
  89.     
  90.     /**
  91.      * Default println method invokes the print instance method, uses DEBUG level
  92.      * 
  93.      * @param text the text to print
  94.      */
  95.     public static void p(String text) {
  96.         p(text, DEBUG);
  97.     }
  98.     
  99.     /**
  100.      * Default println method invokes the print instance method, uses given level
  101.      * 
  102.      * @param text the text to print
  103.      * @param level one of DEBUG, INFO, WARNING, ERROR
  104.      */
  105.     public static void p(String text, int level) {
  106.         instance.print(text, level);
  107.     }
  108.     
  109.     /**
  110.      * Default log implementation prints to the console and the file connector
  111.      * if applicable. Also prepends the thread information and time before 
  112.      * 
  113.      * @param text the text to print
  114.      * @param level one of DEBUG, INFO, WARNING, ERROR
  115.      */
  116.     protected void print(String text, int level) {
  117.         if(this.level > level) {
  118.             return;
  119.         }
  120.         text = getThreadAndTimeStamp() + " - " + text;
  121.         System.out.println(text);
  122.         if(isFileWriteEnabled()) {
  123.             try {
  124.                 synchronized(this) {
  125.                     Writer w = getWriter();
  126.                     w.write(text + "n");
  127.                     w.close();
  128.                     output = null;
  129.                 }
  130.             } catch(Throwable err) {
  131.                 err.printStackTrace();
  132.                 setFileWriteEnabled(false);
  133.             }
  134.         } else {
  135.             try {
  136.                 RecordStore outputStore = RecordStore.openRecordStore("log", true);
  137.                 byte[] bytes = text.getBytes();
  138.                 outputStore.addRecord(bytes, 0, bytes.length);
  139.                 outputStore.closeRecordStore();
  140.             } catch (RecordStoreException ex) {
  141.                 ex.printStackTrace();
  142.             }
  143.         }
  144.     }
  145.     
  146.     /**
  147.      * Default method for creating the output writer into which we write, this method
  148.      * creates a simple log file using the file connector
  149.      * 
  150.      * @return writer object
  151.      * @throws IOException when thrown by the connector
  152.      */
  153.     protected Writer createWriter() throws IOException {
  154.         try {
  155.             if(instance.getFileURL() == null) {
  156.                 instance.setFileURL("file:///" + FileSystemRegistry.listRoots().nextElement() + "/lwuit.log");
  157.             }
  158.             FileConnection con = (FileConnection)Connector.open(instance.getFileURL(), Connector.READ_WRITE);
  159.             if(con.exists()) {
  160.                 return new OutputStreamWriter(con.openOutputStream(con.fileSize()));
  161.             }
  162.             con.create();
  163.             return new OutputStreamWriter(con.openOutputStream());
  164.         } catch(Exception err) {
  165.             setFileWriteEnabled(false);
  166.             // currently return a "dummy" writer so we won't fail on device
  167.             return new OutputStreamWriter(new ByteArrayOutputStream());
  168.         }
  169.     }
  170.     
  171.     private Writer getWriter() throws IOException {
  172.         if(output == null) {
  173.             output = createWriter();
  174.         }
  175.         return output;
  176.     }
  177.     /**
  178.      * Returns a simple string containing a timestamp and thread name.
  179.      * 
  180.      * @return timestamp string for use in the log
  181.      */
  182.     protected String getThreadAndTimeStamp() {
  183.         long time = System.currentTimeMillis() - zeroTime;
  184.         long milli = time % 1000;
  185.         time /= 1000;
  186.         long sec = time % 60;
  187.         time /= 60;
  188.         long min = time % 60; 
  189.         time /= 60;
  190.         long hour = time % 60; 
  191.         
  192.         return "[" + Thread.currentThread().getName() + "] " + hour  + ":" + min + ":" + sec + "," + milli;
  193.     }
  194.     
  195.     /**
  196.      * Sets the logging level for printing log details, the lower the value 
  197.      * the more verbose would the printouts be
  198.      * 
  199.      * @param level one of DEBUG, INFO, WARNING, ERROR
  200.      */
  201.     public static void setLevel(int level) {
  202.         instance.level = level;
  203.     }
  204.     /**
  205.      * Returns the logging level for printing log details, the lower the value 
  206.      * the more verbose would the printouts be
  207.      * 
  208.      * @return one of DEBUG, INFO, WARNING, ERROR
  209.      */
  210.     public static int getLevel() {
  211.         return instance.level;
  212.     }
  213.     
  214.     /**
  215.      * Returns the contents of the log as a single long string to be displayed by
  216.      * the application any way it sees fit
  217.      * 
  218.      * @return string containing the whole log
  219.      */
  220.     public static String getLogContent() {
  221.         try {
  222.             String text = "";
  223.             if(instance.isFileWriteEnabled()) {
  224.                 if(instance.getFileURL() == null) {
  225.                     instance.setFileURL("file:///" + FileSystemRegistry.listRoots().nextElement() + "/lwuit.log");
  226.                 }
  227.                 FileConnection con = (FileConnection) Connector.open(instance.getFileURL(),Connector.READ);
  228.                 Reader r = new InputStreamReader(con.openInputStream());
  229.                 char[] buffer = new char[1024];
  230.                 int size = r.read(buffer);
  231.                 while(size > -1) {
  232.                     text += new String(buffer, 0, size);
  233.                     size = r.read(buffer);
  234.                 }
  235.                 r.close();
  236.             } else {
  237.                 RecordStore store = RecordStore.openRecordStore("log", true);
  238.                 int size = store.getNumRecords();
  239.                 for(int iter = 1 ; iter <= size ; iter++) {
  240.                     text += new String(store.getRecord(iter));
  241.                 }
  242.                 store.closeRecordStore();
  243.             }
  244.             return text;
  245.         } catch (Exception ex) {
  246.             ex.printStackTrace();
  247.             return "";
  248.         }
  249.     }
  250.     
  251.     /**
  252.      * Places a form with the log as a TextArea on the screen, this method can
  253.      * be attached to appear at a given time or using a fixed global key. Using
  254.      * this method might cause a problem with further log output
  255.      */
  256.     public static void showLog() {
  257.         try {
  258.             String text = getLogContent();
  259.             TextArea area = new TextArea(text, 5, 20);
  260.             Form f = new Form("Log");
  261.             f.setScrollable(false);
  262.             final Form current = Display.getInstance().getCurrent();
  263.             Command back = new Command("Back") {
  264.                 public void actionPerformed(ActionEvent ev) {
  265.                     current.show();
  266.                 }
  267.             };
  268.             f.addCommand(back);
  269.             f.setBackCommand(back);
  270.             f.setLayout(new BorderLayout());
  271.             f.addComponent(BorderLayout.CENTER, area);
  272.             f.show();
  273.         } catch (Exception ex) {
  274.             ex.printStackTrace();
  275.         }
  276.     }
  277.     /**
  278.      * Returns the singleton instance of the log
  279.      * 
  280.      * @return the singleton instance of the log
  281.      */
  282.     public static Log getInstance() {
  283.         return instance;
  284.     }
  285.     /**
  286.      * Indicates whether GCF's file writing should be used to generate the log file
  287.      *
  288.      * @return the fileWriteEnabled
  289.      */
  290.     public boolean isFileWriteEnabled() {
  291.         return fileWriteEnabled;
  292.     }
  293.     /**
  294.      * Indicates whether GCF's file writing should be used to generate the log file
  295.      * 
  296.      * @param fileWriteEnabled the fileWriteEnabled to set
  297.      */
  298.     public void setFileWriteEnabled(boolean fileWriteEnabled) {
  299.         this.fileWriteEnabled = fileWriteEnabled;
  300.     }
  301.     /**
  302.      * Indicates the URL where the log file is saved
  303.      *
  304.      * @return the fileURL
  305.      */
  306.     public String getFileURL() {
  307.         return fileURL;
  308.     }
  309.     /**
  310.      * Indicates the URL where the log file is saved
  311.      *
  312.      * @param fileURL the fileURL to set
  313.      */
  314.     public void setFileURL(String fileURL) {
  315.         this.fileURL = fileURL;
  316.     }
  317. }