/* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores * CA 94065 USA or visit www.oracle.com if you need additional information or * have any questions. */ package com.sun.lwuit.util; import com.sun.lwuit.Command; import com.sun.lwuit.Display; import com.sun.lwuit.Form; import com.sun.lwuit.TextArea; import com.sun.lwuit.events.ActionEvent; import com.sun.lwuit.layouts.BorderLayout; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import javax.microedition.io.file.FileSystemRegistry; import javax.microedition.rms.RecordStore; import javax.microedition.rms.RecordStoreException; /** * Pluggable logging framework that allows a developer to log into storage * using the file connector API. It is highly recommended to use this * class coupled with Netbeans preprocessing tags to reduce its overhead * completely in runtime. * * @author Shai Almog * @deprecated use LWUIT4IO's log API instead of this class, this class will * be removed in the next iteration of LWUIT! */ public class Log { /** * Constant indicating the logging level Debug is the default and the lowest level * followed by info, warning and error */ public static final int DEBUG = 1; /** * Constant indicating the logging level Debug is the default and the lowest level * followed by info, warning and error */ public static final int INFO = 2; /** * Constant indicating the logging level Debug is the default and the lowest level * followed by info, warning and error */ public static final int WARNING = 3; /** * Constant indicating the logging level Debug is the default and the lowest level * followed by info, warning and error */ public static final int ERROR = 4; private int level = DEBUG; private static Log instance = new Log(); private long zeroTime = System.currentTimeMillis(); private Writer output; private boolean fileWriteEnabled = false;//System.getProperty("microedition.io.file.FileConnection.version") != null; private String fileURL = null; /** * Installs a log subclass that can replace the logging destination/behavior * * @param newInstance the new instance for the Log object */ public static void install(Log newInstance) { instance = newInstance; } /** * Default println method invokes the print instance method, uses DEBUG level * * @param text the text to print */ public static void p(String text) { p(text, DEBUG); } /** * Default println method invokes the print instance method, uses given level * * @param text the text to print * @param level one of DEBUG, INFO, WARNING, ERROR */ public static void p(String text, int level) { instance.print(text, level); } /** * Default log implementation prints to the console and the file connector * if applicable. Also prepends the thread information and time before * * @param text the text to print * @param level one of DEBUG, INFO, WARNING, ERROR */ protected void print(String text, int level) { if(this.level > level) { return; } text = getThreadAndTimeStamp() + " - " + text; System.out.println(text); if(isFileWriteEnabled()) { try { synchronized(this) { Writer w = getWriter(); w.write(text + "\n"); w.close(); output = null; } } catch(Throwable err) { err.printStackTrace(); setFileWriteEnabled(false); } } else { try { synchronized(this) { RecordStore outputStore = RecordStore.openRecordStore("log", true); byte[] bytes = text.getBytes(); outputStore.addRecord(bytes, 0, bytes.length); outputStore.closeRecordStore(); } } catch (RecordStoreException ex) { ex.printStackTrace(); } } } /** * Default method for creating the output writer into which we write, this method * creates a simple log file using the file connector * * @return writer object * @throws IOException when thrown by the connector */ protected Writer createWriter() throws IOException { try { if(instance.getFileURL() == null) { instance.setFileURL("file:///" + FileSystemRegistry.listRoots().nextElement() + "/lwuit.log"); } FileConnection con = (FileConnection)Connector.open(instance.getFileURL(), Connector.READ_WRITE); if(con.exists()) { return new OutputStreamWriter(con.openOutputStream(con.fileSize())); } con.create(); return new OutputStreamWriter(con.openOutputStream()); } catch(Exception err) { setFileWriteEnabled(false); // currently return a "dummy" writer so we won't fail on device return new OutputStreamWriter(new ByteArrayOutputStream()); } } private Writer getWriter() throws IOException { if(output == null) { output = createWriter(); } return output; } /** * Returns a simple string containing a timestamp and thread name. * * @return timestamp string for use in the log */ protected String getThreadAndTimeStamp() { long time = System.currentTimeMillis() - zeroTime; long milli = time % 1000; time /= 1000; long sec = time % 60; time /= 60; long min = time % 60; time /= 60; long hour = time % 60; return "[" + Thread.currentThread().getName() + "] " + hour + ":" + min + ":" + sec + "," + milli; } /** * Sets the logging level for printing log details, the lower the value * the more verbose would the printouts be * * @param level one of DEBUG, INFO, WARNING, ERROR */ public static void setLevel(int level) { instance.level = level; } /** * Returns the logging level for printing log details, the lower the value * the more verbose would the printouts be * * @return one of DEBUG, INFO, WARNING, ERROR */ public static int getLevel() { return instance.level; } /** * Returns the contents of the log as a single long string to be displayed by * the application any way it sees fit * * @return string containing the whole log */ public static String getLogContent() { try { String text = ""; if(instance.isFileWriteEnabled()) { if(instance.getFileURL() == null) { instance.setFileURL("file:///" + FileSystemRegistry.listRoots().nextElement() + "/lwuit.log"); } FileConnection con = (FileConnection) Connector.open(instance.getFileURL(),Connector.READ); Reader r = new InputStreamReader(con.openInputStream()); char[] buffer = new char[1024]; int size = r.read(buffer); while(size > -1) { text += new String(buffer, 0, size); size = r.read(buffer); } r.close(); } else { RecordStore store = RecordStore.openRecordStore("log", true); int size = store.getNumRecords(); for(int iter = 1 ; iter <= size ; iter++) { text += new String(store.getRecord(iter)); } store.closeRecordStore(); } return text; } catch (Exception ex) { ex.printStackTrace(); return ""; } } /** * Places a form with the log as a TextArea on the screen, this method can * be attached to appear at a given time or using a fixed global key. Using * this method might cause a problem with further log output */ public static void showLog() { try { String text = getLogContent(); TextArea area = new TextArea(text, 5, 20); Form f = new Form("Log"); f.setScrollable(false); final Form current = Display.getInstance().getCurrent(); Command back = new Command("Back") { public void actionPerformed(ActionEvent ev) { current.show(); } }; f.addCommand(back); f.setBackCommand(back); f.setLayout(new BorderLayout()); f.addComponent(BorderLayout.CENTER, area); f.show(); } catch (Exception ex) { ex.printStackTrace(); } } /** * Returns the singleton instance of the log * * @return the singleton instance of the log */ public static Log getInstance() { return instance; } /** * Indicates whether GCF's file writing should be used to generate the log file * * @return the fileWriteEnabled */ public boolean isFileWriteEnabled() { return fileWriteEnabled; } /** * Indicates whether GCF's file writing should be used to generate the log file * * @param fileWriteEnabled the fileWriteEnabled to set */ public void setFileWriteEnabled(boolean fileWriteEnabled) { this.fileWriteEnabled = fileWriteEnabled; } /** * Indicates the URL where the log file is saved * * @return the fileURL */ public String getFileURL() { return fileURL; } /** * Indicates the URL where the log file is saved * * @param fileURL the fileURL to set */ public void setFileURL(String fileURL) { this.fileURL = fileURL; } }