Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 4679 invoked from network); 15 Mar 2006 15:10:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 15 Mar 2006 15:10:26 -0000 Received: (qmail 26917 invoked by uid 500); 15 Mar 2006 15:09:59 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 26881 invoked by uid 500); 15 Mar 2006 15:09:59 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 26870 invoked by uid 99); 15 Mar 2006 15:09:59 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 15 Mar 2006 07:09:59 -0800 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 15 Mar 2006 07:09:56 -0800 Received: (qmail 3617 invoked by uid 65534); 15 Mar 2006 15:09:33 -0000 Message-ID: <20060315150933.3502.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r386087 [21/45] - in /incubator/harmony/enhanced/classlib/trunk: make/ make/patternsets/ modules/jndi/ modules/jndi/META-INF/ modules/jndi/make/ modules/jndi/make/common/ modules/jndi/src/ modules/jndi/src/main/ modules/jndi/src/main/java/ ... Date: Wed, 15 Mar 2006 14:57:17 -0000 To: harmony-commits@incubator.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.0.7 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/api/javax/naming/util/Util.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/api/javax/naming/util/Util.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/api/javax/naming/util/Util.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/api/javax/naming/util/Util.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,269 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package tests.api.javax.naming.util; + +import java.util.Hashtable; +import java.util.Properties; + +import javax.naming.Binding; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchResult; + +public final class Util { + + /** + * Only entry to obtain an InitialContext instance. + * + * @return a new InitialContext instance + */ + public static InitialContext getInitialContext() { + try { + Properties p = new Properties(); + p.load(Util.class.getClassLoader().getResourceAsStream( + "jndi.properties")); + /* + * Hashtable ht = new Hashtable(); ht.put( + * Context.INITIAL_CONTEXT_FACTORY, + * "dazzle.jndi.testing.spi.DazzleContextFactory"); + */ + return new InitialContext(p); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Clean up, opposite to getInitialContext(). + * + * @param ctx + * the InitialContext to clean up + */ + public static void cleanUpInitialContext(InitialContext ctx) { + + } + + /** + * Only entry to obtain an InitialDirContext instance. + * + * @return a new InitialDirContext instance + */ + public static InitialDirContext getInitialDirContext() { + try { + Properties p = new Properties(); + p.load(Util.class.getClassLoader().getResourceAsStream( + "jndi.properties")); + Hashtable ht = new Hashtable(); + ht.put(Context.INITIAL_CONTEXT_FACTORY, + "dazzle.jndi.testing.spi.DazzleContextFactory"); + return new InitialDirContext(p); + } catch (Exception e) { + // e.printStackTrace(); + return null; + } + } + + /** + * Clean up, opposite to getInitialDirContext(). + * + * @param ctx + * the InitialDirContext to clean up + */ + public static void cleanUpInitialDirContext(InitialDirContext ctx) { + + } + + /** + * Format an Attribute to String + * + * @param a + * @return the string representation + */ + public static String toString(Attribute a) { + if (a == null) { + return "NULL"; + } + + try { + StringBuffer buf = new StringBuffer(); + buf.append(a.getID()); + if (a.isOrdered()) { + buf.append("+o"); + } + buf.append("="); + if (a.size() == 0) { + buf.append("null"); + } else if (a.size() == 1) { + buf.append(a.get()); + } else { + buf.append("["); + for (int i = 0; i < a.size(); i++) { + if (i != 0) { + buf.append(","); + } + buf.append(a.get(i) == null ? "null" : a.get(i)); + } + buf.append("]"); + } + return buf.toString(); + } catch (Throwable e) { + e.printStackTrace(); + return "NULL"; + } + } + + /** + * Format an Attributes to String + * + * @param as + * @return the string representation + */ + public static String toString(Attributes as) { + if (as == null) { + return "NULL"; + } + + try { + if (as.size() == 0) { + return "{}"; + } else { + StringBuffer buf = new StringBuffer(); + buf.append("{ "); + NamingEnumeration enumeration = as.getAll(); + int i = 0; + while (enumeration.hasMoreElements()) { + Attribute a = (Attribute) enumeration.nextElement(); + if (i != 0) { + buf.append(", "); + } + buf.append(toString(a)); + i++; + } + buf.append(" }"); + return buf.toString(); + } + } catch (Throwable e) { + e.printStackTrace(); + return "NULL"; + } + } + + /** + * Format a SearchResult to String + * + * @param r + * @return the string representation + */ + public static String toString(SearchResult r) { + StringBuffer buf = new StringBuffer(); + buf.append(r.getName()); + buf.append(" "); + buf.append(toString(r.getAttributes())); + buf.append(" = "); + buf.append(r.getObject()); + return buf.toString(); + } + + /** + * Format a Context to String + * + * @param ctx + * @return the string representation + */ + public static String toString(Context ctx) { + if (ctx == null) { + return "NULL"; + } + + try { + StringBuffer buf = new StringBuffer(); + return toString(buf, 0, ctx); + } catch (Throwable e) { + e.printStackTrace(); + return "NULL"; + } + } + + /** + * Format a DirContext to String + * + * @param ctx + * @return the string representation + */ + public static String toString(DirContext ctx) { + if (ctx == null) { + return "NULL"; + } + + try { + StringBuffer buf = new StringBuffer(); + return toString(buf, 0, ctx); + } catch (Throwable e) { + e.printStackTrace(); + return "NULL"; + } + } + + private static String toString(StringBuffer buf, int i, Context ctx) + throws NamingException { + + int j = i + 4; + space(buf, i); + buf.append(ctx + " {").append("\n"); + + NamingEnumeration enumeration = ctx.listBindings(""); + while (enumeration.hasMoreElements()) { + Binding r = (Binding) enumeration.nextElement(); + space(buf, j); + if (r.getName() != null) { + buf.append(r.getName()); + if (ctx instanceof DirContext) { + buf.append(" "); + buf.append(toString(((DirContext) ctx).getAttributes(r + .getName()))); + } + } + buf.append(" = "); + if (r.getObject() instanceof Context) { + toString(buf, j, (Context) r.getObject()); + } else { + buf.append(r.getObject() == null ? "" : r.getObject()); + } + buf.append("\n"); + } + + space(buf, i); + buf.append("}"); + return buf.toString(); + } + + private static void space(StringBuffer buf, int n) { + for (int i = 0; i < n; i++) { + buf.append(' '); + } + } + + public static void main(String[] args) throws Exception { + Context ctx = Util.getInitialContext(); + ctx.bind("test", new Integer(200)); + } +} Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/jndi/AllTests.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/jndi/AllTests.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/jndi/AllTests.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/tests/jndi/AllTests.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,41 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests.jndi; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite that includes all tests for the JNDI project. + */ +public class AllTests { + + public static void main(String[] args) { + junit.textui.TestRunner.run(AllTests.suite()); + } + + public static Test suite() { + TestSuite suite = new TestSuite("All JNDI test suites"); + // $JUnit-BEGIN$ + suite.addTest(tests.api.javax.naming.AllTests.suite()); + suite.addTest(tests.api.javax.naming.directory.AllTests.suite()); + suite.addTest(tests.api.javax.naming.event.AllTests.suite()); + suite.addTest(tests.api.javax.naming.ldap.AllTests.suite()); + suite.addTest(tests.api.javax.naming.spi.AllTests.suite()); + // $JUnit-END$ + return suite; + } +} \ No newline at end of file Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/resources/libs/jnditesthelper.zip URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/resources/libs/jnditesthelper.zip?rev=386087&view=auto ============================================================================== Binary file - no diff available. Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/resources/libs/jnditesthelper.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/META-INF/MANIFEST.MF URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/META-INF/MANIFEST.MF?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/META-INF/MANIFEST.MF (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/META-INF/MANIFEST.MF Wed Mar 15 06:55:38 2006 @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Harmony Logging +Bundle-SymbolicName: org.apache.harmony.logging +Bundle-Version: 1.0.0 +Bundle-ClassPath: . +Eclipse-JREBundle: true +Export-Package: java.util.logging +Import-Package: java.lang, + java.beans, + java.io, + java.security, + java.util, + java.nio.channels, + java.text, + java.nio.charset, + java.net + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/make/build.xml URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/make/build.xml?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/make/build.xml (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/make/build.xml Wed Mar 15 06:55:38 2006 @@ -0,0 +1,115 @@ + + + + + Build for LOGGING component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/build.xml URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/build.xml?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/build.xml (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/build.xml Wed Mar 15 06:55:38 2006 @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/hyproperties.xml URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/hyproperties.xml?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/hyproperties.xml (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/make/common/hyproperties.xml Wed Mar 15 06:55:38 2006 @@ -0,0 +1,44 @@ + + + + + + +
+ + +
+ + + + + +
+ +
+ + + + + + + + + + + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ConsoleHandler.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ConsoleHandler.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ConsoleHandler.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ConsoleHandler.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,89 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +/** + * A handler that writes log messages to the standard output stream + * System.err. + *

+ * This handler reads the following properties from the log manager to + * initialize itself: + *

    + *
  • java.util.logging.ConsoleHandler.level specifies the logging level, + * defaults to Level.INFO if this property is not found or has an + * invalid value; + *
  • java.util.logging.ConsoleHandler.filter specifies the name of the filter + * class to be associated with this handler, defaults to null if + * this property is not found or has an invalid value; + *
  • java.util.logging.ConsoleHandler.formatter specifies the name of the + * formatter class to be associated with this handler, defaults to + * java.util.logging.SimpleFormatter if this property is not + * found or has an invalid value; + *
  • java.util.logging.ConsoleHandler.encoding specifies the encoding this + * handler will use to encode log messages, defaults to null if + * this property is not found or has an invalid value. + *
+ *

+ *

+ * This class is not thread-safe. + *

+ * + */ +public class ConsoleHandler extends StreamHandler { + + /* + * ------------------------------------------------------------------- + * Constructors + * ------------------------------------------------------------------- + */ + + /** + * Constructs a ConsoleHandler object. + */ + public ConsoleHandler() { + super(System.err); + } + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + /** + * Closes this handler. The System.err is flushed but not + * closed. + */ + public void close() { + super.close(false); + } + + /** + * Logs a record if necessary. A flush operation will be done. + * + * @param record + * the log record to be logged + */ + public void publish(LogRecord record) { + super.publish(record); + super.flush(); + + } + +} + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ErrorManager.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ErrorManager.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ErrorManager.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/ErrorManager.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,147 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +/** + * Handler objects can report errors to the + * ErrorManager instance attached to them when they encounter any + * exceptions or errors. + *

+ * Callers of a logger are unlikely to be interested in the exceptions occured + * during logging. Use an ErrorManager object to report these + * exceptions. + *

+ * + */ +public class ErrorManager { + + /* + * ------------------------------------------------------------------- + * Constants + * ------------------------------------------------------------------- + */ + + /** + * The error code indicating a failure that does not fit in any of the + * specific types of failures that follow. + */ + public static final int GENERIC_FAILURE = 0; + + /** + * The error code indicating a failure when writting to an output stream. + */ + public static final int WRITE_FAILURE = 1; + + /** + * The error code indicating a failure when flushing an output stream. + */ + public static final int FLUSH_FAILURE = 2; + + /** + * The error code indicating a failure when closing an output stream. + */ + public static final int CLOSE_FAILURE = 3; + + /** + * The error code indicating a failure when opening an output stream. + */ + public static final int OPEN_FAILURE = 4; + + /** + * The error code indicating a failure when formatting the error messages. + */ + public static final int FORMAT_FAILURE = 5; + + /* + * ------------------------------------------------------------------- + * Instance variables + * ------------------------------------------------------------------- + */ + + // Used to synchronize calls to the error method. + private Object lock; + + // Indicating whether the current call is the first call. + private boolean firstCall; + + /* + * ------------------------------------------------------------------- + * Constructors + * ------------------------------------------------------------------- + */ + + /** + * Constructs an instance of ErrorManager. + */ + public ErrorManager() { + lock = new Object(); + firstCall = true; + } + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + /** + * Reports an error. + *

+ * This method can be called by a Handler object when it + * encounters an exception or error. The first call to this method will do + * the exact error-reporting as desired. Subsequent calls are ignored. + * + * @param msg + * the error message which may be null + * @param ex + * the exception which may be null + * @param errorCode + * the error code indicating the type of the failure + */ + public void error(String msg, Exception ex, int errorCode) { + if (firstCall) { + // Synchronize concurrent "first" calls + synchronized (lock) { + if (firstCall) { + outputError(msg, ex, errorCode); + } + } + } + } + + //if it is the first time to call error, output it + private void outputError(String msg, Exception ex, int errorCode) { + StringBuffer sb = new StringBuffer(); + sb.append(this.getClass().getName()); + sb.append(": the error code is "); //$NON-NLS-1$ + sb.append(errorCode); + sb.append("."); //$NON-NLS-1$ + sb.append(LogManager.getSystemLineSeparator()); + if (null != msg) { + sb.append("The error message is: "); //$NON-NLS-1$ + sb.append(msg); + sb.append(LogManager.getSystemLineSeparator()); + } + if (null != ex) { + sb.append(ex.toString()); + } + System.err.println(sb); + firstCall = false; + } + +} + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/FileHandler.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/FileHandler.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/FileHandler.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/FileHandler.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,605 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Hashtable; + +/** + * A Handler writes description of logging event into a specified + * file or a rotating set of files. + *

+ * If a set of files are used, when a given amount of data has been written to + * one file, this file is closed, and another file is opened. The name of these + * files are generated by given name pattern, see below for details. + *

+ *

+ * By default the IO buffering mechanism is enabled, but when each log record is + * complete, it is flushed out. + *

+ *

+ * XMLFormatter is default formatter for FileHandler. + *

+ *

+ * MemoryHandler will read following LogManager + * properties for initialization, if given propeties are not defined or has + * invalid values, default value will be used. + *

    + *
  • java.util.logging.FileHandler.level specifies the level for this + * Handler, defaults to Level.ALL.
  • + *
  • java.util.logging.FileHandler.filter specifies the Filter + * class name, defaults to no Filter.
  • + *
  • java.util.logging.FileHandler.formatter specifies the + * Formatter class, defaults to + * java.util.logging.XMLFormatter.
  • + *
  • java.util.logging.FileHandler.encoding specifies the character set + * encoding name, defaults to the default platform encoding.
  • + *
  • java.util.logging.FileHandler.limit specifies an maximum bytes to write + * to any one file, defaults to zero, which means no limit.
  • + *
  • java.util.logging.FileHandler.count specifies how many output files to + * rotate, defaults to 1.
  • + *
  • java.util.logging.FileHandler.pattern specifies name pattern for the + * output files. See below for details. Defaults to "%h/java%u.log".
  • + *
  • java.util.logging.FileHandler.append specifies whether this + * FileHandler should append onto existing files, defaults to + * false.
  • + *
+ *

+ *

+ * Name pattern is a string that may includes some special sub-strings, which + * will be replaced to generate output files: + *

    + *
  • "/" represents the local pathname separator
  • + *
  • "%t" represents the system temporary directory
  • + *
  • "%h" represents the home directory of current user, which is specified + * by "user.home" system property
  • + *
  • "%g" represents the generation number to distinguish rotated logs
  • + *
  • "%u" represents a unique number to resolve conflicts
  • + *
  • "%%" represents percent sign character '%'
  • + *
+ *

+ * Normally, the generation numbers are not larger than given file count and + * follow the sequence 0, 1, 2.... If the file count is larger than one, but the + * generation field("%g") has not been specifed in the pattern, then the + * generation number after a dot will be added to the end of the file name, + *

+ *

+ * The "%u" unique field is used to avoid conflicts and set to 0 at first. If + * one FileHandler tries to open the filename which is currently + * in use by another process, it will repeatly increment the unique number field + * and try again. If the "%u" component has not been included in the file name + * pattern and some contention on a file does occur then a unique numerical + * value will be added to the end of the filename in question immediately to the + * right of a dot. The unique ids to avoid conflicts is only guaranteed to work + * reliably when using a local disk file system. + *

+ * + */ +public class FileHandler extends StreamHandler { + + /* + * --------------------------------------------- + * constants + * --------------------------------------------- + */ + private static final int DEFAULT_COUNT = 1; + + private static final int DEFAULT_LIMIT = 0; + + private static final boolean DEFAULT_APPEND = false; + + private static final String DEFAULT_PATTERN = "%h/java%u.log"; //$NON-NLS-1$ + + /* + * --------------------------------------------- + * class variables + * --------------------------------------------- + */ + //maintain all file locks hold by this process + private static Hashtable allLocks = new Hashtable(); + + /* + * --------------------------------------------- + * instance variables + * --------------------------------------------- + */ + + //the count of files which the output cycle through + private int count; + + //the size limitation in byte of log file + private int limit; + + //whether the FileHandler should open a existing file for output in append mode + private boolean append; + + //the pattern for output file name + private String pattern; + + //maintain a LogManager instance for convenience + private LogManager manager; + + //output stream, which can measure the output file length + private MeasureOutputStream output; + + //used output file + private File[] files; + + //output file lock + FileLock lock = null; + + //current output file name + String fileName = null; + + //current generation + int generation = 0; + + /* + * --------------------------------------------- + * constructors + * --------------------------------------------- + */ + /** + * Construct a FileHandler using LogManager + * properties or their default value + * + * @throws IOException + * if any IO exception happened + * @throws SecurityException + * if security manager exists and it determines that caller + * does not have the required permissions to control this handler, + * required permissions include LogPermission("control") + * and other permission like FilePermission("write"), + * etc. + * + */ + public FileHandler() throws IOException { + init(null, null, null, null); + } + + //init properties + private void init(String p, Boolean a, Integer l, Integer c) + throws IOException { + //check access + manager = LogManager.getLogManager(); + manager.checkAccess(); + initProperties(p, a, l, c); + initOutputFiles(); + } + + private void initOutputFiles() throws FileNotFoundException, IOException { + int uniqueID = -1; + FileOutputStream fileStream = null; + FileChannel channel = null; + while (true) { + //try to find a unique file which is not locked by other process + fileName = parseFileName(generation, ++uniqueID); + synchronized (allLocks) { + //if current process has held lock for this fileName + //continue to find next file + if (null != allLocks.get(fileName)) { + continue; + } + try { + fileStream = new FileOutputStream(fileName, true); + channel = fileStream.getChannel(); + } catch(FileNotFoundException e){ + //invalid path name, throw exception + throw e; + } + //if lock is unsupported and IOException throwed, just let the + //IOException throws out and exit + //otherwise it will go into an undead cycle + lock = channel.tryLock(); + if (null == lock) { + continue; + } + files[0] = new File(fileName); + allLocks.put(fileName, lock); + break; + } + } + for (generation = 1; generation < count; generation++) { + //cache all file names for rotation use + files[generation] = new File(parseFileName(generation, uniqueID)); + } + output = new MeasureOutputStream(new BufferedOutputStream(fileStream), + files[0].length()); + if (append && output.getLength() < limit) { + setOutputStream(output); + } else { + setOutputStream(output); + findNextGeneration(); + } + } + + private void initProperties(String p, Boolean a, Integer l, Integer c) { + super.initProperties("ALL", null, "java.util.logging.XMLFormatter", //$NON-NLS-1$//$NON-NLS-2$ + null); + String className = this.getClass().getName(); + pattern = (null == p) ? getStringProperty(className + ".pattern", //$NON-NLS-1$ + DEFAULT_PATTERN) : p; + if (null == pattern || "".equals(pattern)) { //$NON-NLS-1$ + throw new NullPointerException("Pattern cannot be empty"); //$NON-NLS-1$ + } + append = (null == a) ? getBooleanProperty(className + ".append", //$NON-NLS-1$ + DEFAULT_APPEND) : a.booleanValue(); + count = (null == c) ? getIntProperty(className + ".count", //$NON-NLS-1$ + DEFAULT_COUNT) : c.intValue(); + limit = (null == l) ? getIntProperty(className + ".limit", //$NON-NLS-1$ + DEFAULT_LIMIT) : l.intValue(); + count = count < 1 ? DEFAULT_COUNT : count; + limit = limit < 0 ? DEFAULT_LIMIT : limit; + files = new File[count]; + } + + private void findNextGeneration() { + super.close(); + for (int i = count - 1; i > 0; i--) { + if (files[i].exists()) { + files[i].delete(); + } + files[i - 1].renameTo(files[i]); + } + try { + output = new MeasureOutputStream(new BufferedOutputStream( + new FileOutputStream(files[0]))); + } catch (FileNotFoundException e1) { + this.getErrorManager().error("Error happened when open log file.", //$NON-NLS-1$ + e1, ErrorManager.OPEN_FAILURE); + } + setOutputStream(output); + + } + + //apply settings, parse pattern and open files + private String parseFileName(int gen, int uniqueID) { + int cur = 0; + int next = 0; + boolean hasUniqueID = false; + boolean hasGeneration = false; + //TODO privilege code? + String tempPath = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$ + String homePath = System.getProperty("user.home"); //$NON-NLS-1$ + StringBuffer sb = new StringBuffer(); + pattern = pattern.replace('/', File.separatorChar); + char[] value = pattern.toCharArray(); + while ((next = pattern.indexOf('%', cur)) >= 0) { + if (++next < pattern.length()) { + switch (value[next]) { + case 'g': + sb.append(value, cur, next - cur - 1).append(gen); + hasGeneration = true; + break; + case 'u': + sb.append(value, cur, next - cur - 1).append(uniqueID); + hasUniqueID = true; + break; + case 't': + sb.append(value, cur, next - cur - 1).append(tempPath); + break; + case 'h': + sb.append(value, cur, next - cur - 1).append(homePath); + break; + case '%': + sb.append(value, cur, next - cur - 1).append('%'); + break; + default: + sb.append(value, cur, next - cur); + } + cur = ++next; + } else { + + } + } + sb.append(value, cur, value.length - cur); + if (!hasGeneration && count > 1) { + sb.append(".").append(gen); //$NON-NLS-1$ + } + if (!hasUniqueID && uniqueID > 0) { + sb.append(".").append(uniqueID); //$NON-NLS-1$ + } + return sb.toString(); + } + + //get boolean LogManager property, if invalid value got, using default value + private boolean getBooleanProperty(String key, boolean defaultValue) { + String property = manager.getProperty(key); + if (null == property) { + return defaultValue; + } + boolean result = defaultValue; + if ("true".equalsIgnoreCase(property)) { //$NON-NLS-1$ + result = true; + } else if ("false".equalsIgnoreCase(property)) { //$NON-NLS-1$ + result = false; + } + return result; + } + + //get String LogManager property, if invalid value got, using default value + private String getStringProperty(String key, String defaultValue) { + String property = manager.getProperty(key); + return property == null ? defaultValue : property; + } + + //get int LogManager property, if invalid value got, using default value + private int getIntProperty(String key, int defaultValue) { + String property = manager.getProperty(key); + int result = defaultValue; + if (null != property) { + try { + result = Integer.parseInt(property); + } catch (Exception e) {//ignore + } + } + return result; + } + + /** + * Construct a FileHandler, the given name pattern is used as + * output filename, the file limit is set to zero(no limit), and the file + * count is set to one, other configuration using LogManager + * properties or their default value + * + * This handler write to only one file and no amount limit. + * + * @param pattern + * the name pattern of output file + * @throws IOException + * if any IO exception happened + * @throws SecurityException + * if security manager exists and it determines that caller + * does not have the required permissions to control this handler, + * required permissions include LogPermission("control") + * and other permission like FilePermission("write"), + * etc. + * + */ + public FileHandler(String pattern) throws IOException { + if(null == pattern || "".equals(pattern)){ //$NON-NLS-1$ + throw new NullPointerException("Pattern cannot be empty"); //$NON-NLS-1$ + } + init(pattern, null, new Integer(DEFAULT_LIMIT), new Integer( + DEFAULT_COUNT)); + } + + /** + * Construct a FileHandler, the given name pattern is used + * as output filename, the file limit is set to zero(i.e. no limit applies), + * the file count is initialized to one, and the value of + * append becomes the new instance's append mode. Other + * configuration is done using LogManager properties. + * + * This handler write to only one file and no amount limit. + * + * @param pattern + * the name pattern of output file + * @param append + * the append mode + * @throws IOException + * if any IO exception happened + * @throws SecurityException + * if security manager exists and it determines that caller does + * not have the required permissions to control this handler, + * required permissions include + * LogPermission("control") and other permission + * like FilePermission("write"), etc. + * + */ + public FileHandler(String pattern, boolean append) throws IOException { + if(null == pattern || "".equals(pattern)){ //$NON-NLS-1$ + throw new NullPointerException("Pattern cannot be empty"); //$NON-NLS-1$ + } + init(pattern, Boolean.valueOf(append), new Integer(DEFAULT_LIMIT), + new Integer(DEFAULT_COUNT)); + } + + /** + * Construct a FileHandler, the given name pattern is used as + * output filename, the file limit is set to given limit argument, and + * the file count is set to given count argument, other configuration using + * LogManager properties or their default value + * + * This handler is configured to write to a rotating set of count files, + * when the limit of bytes has been written to one output file, another file + * will be opened instead. + * + * @param pattern + * the name pattern of output file + * @param limit + * the data amount limit in bytes of one ouput file, cannot less + * than one + * @param count + * the maximum number of files can be used, cannot less than one + * @throws IOException + * if any IO exception happened + * @throws SecurityException + * if security manager exists and it determines that caller + * does not have the required permissions to control this handler, + * required permissions include LogPermission("control") + * and other permission like FilePermission("write"), + * etc. + * @throws IllegalArgumentException + * if count<1, or limit<0 + */ + public FileHandler(String pattern, int limit, int count) throws IOException { + if(null == pattern || "".equals(pattern)){ //$NON-NLS-1$ + throw new NullPointerException("Pattern cannot be empty"); //$NON-NLS-1$ + } + if (limit < 1 || count < 0) { + throw new IllegalArgumentException( + "The limit and count property must larger than 0 and 1, respctively"); //$NON-NLS-1$ + } + init(pattern, null, new Integer(limit), new Integer(count)); + } + + /** + * Construct a FileHandler, the given name pattern is used as + * output filename, the file limit is set to given limit argument, the file + * count is set to given count argument, and the append mode is set to given + * append argument, other configuration using LogManager + * properties or their default value + * + * This handler is configured to write to a rotating set of count files, + * when the limit of bytes has been written to one output file, another file + * will be opened instead. + * + * @param pattern + * the name pattern of output file + * @param limit + * the data amount limit in bytes of one ouput file, cannot less + * than one + * @param count + * the maximum number of files can be used, cannot less than one + * @param append + * the append mode + * @throws IOException + * if any IO exception happened + * @throws SecurityException + * if security manager exists and it determines that caller + * does not have the required permissions to control this handler, + * required permissions include LogPermission("control") + * and other permission like FilePermission("write"), + * etc. + * @throws IllegalArgumentException + * if count<1, or limit<0 + * + */ + public FileHandler(String pattern, int limit, int count, boolean append) + throws IOException { + if(null == pattern || "".equals(pattern)){ //$NON-NLS-1$ + throw new NullPointerException("Pattern cannot be empty"); //$NON-NLS-1$ + } + if (limit < 1 || count < 0) { + throw new IllegalArgumentException( + "The limit and count property must larger than 0 and 1, respectively"); //$NON-NLS-1$ + } + init(pattern, Boolean.valueOf(append), new Integer(limit), new Integer( + count)); + } + + /* + * --------------------------------------------- + * Methods overrides StreamHandler + * --------------------------------------------- + */ + /** + * Flush and close all opened files. + * + * @throws SecurityException + * if security manager exists and it determines that caller + * does not have the required permissions to control this handler, + * required permissions include LogPermission("control") + * and other permission like FilePermission("write"), + * etc. + */ + public void close() { + //release locks + super.close(); + // //FIXME: delete this + // System.out.println("close:"+fileName); + allLocks.remove(fileName); + try { + lock.release(); + } catch (IOException e) { + //ignore + } + } + + /** + * Publish a LogRecord + * + * @param record the log record to be published + */ + public void publish(LogRecord record) { + super.publish(record); + flush(); + if (limit > 0 && output.getLength() >= limit) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + findNextGeneration(); + return null; + } + }); + } + } + + /* + * This output stream use decorator pattern to add measure feature to OutputStream + * which can detect the total size(in bytes) of output, the initial size can be set + */ + class MeasureOutputStream extends OutputStream { + + OutputStream wrapped; + + long length; + + public MeasureOutputStream(OutputStream stream, long currentLength) { + wrapped = stream; + length = currentLength; + } + + public MeasureOutputStream(OutputStream stream) { + this(stream, 0); + } + + public void write(int oneByte) throws IOException { + wrapped.write(oneByte); + length++; + } + + public void write(byte[] bytes) throws IOException { + wrapped.write(bytes); + length += bytes.length; + } + + public void write(byte[] b, int off, int len) throws IOException { + wrapped.write(b, off, len); + length += len; + } + + public void close() throws IOException { + wrapped.close(); + } + + public void flush() throws IOException { + wrapped.flush(); + } + + public long getLength() { + return length; + } + + public void setLength(long newLength) { + length = newLength; + } + + } + +} + + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Filter.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Filter.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Filter.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Filter.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,43 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +/** + * Filter objects are used to filter loggings that are not + * desired. Handler or Logger objects can be + * attached with a filter to get finer grain control over what should be logged. + * + */ +public interface Filter { + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + /** + * Checks whether the supplied log record needs to be logged. + * + * @param record + * the log record to be checked + * @return true if the supplied log record needs to be + * logged, otherwise false + */ + boolean isLoggable(LogRecord record); +} + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Formatter.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Formatter.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Formatter.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Formatter.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,129 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +/** + * Formatter objects are used to format LogRecord + * objects into a string representation. Head and tail strings are sometime used + * to wrap a set of records. The getHead and getTail + * methods are presented for this purpose. + * + */ +public abstract class Formatter { + + /* + * ------------------------------------------------------------------- + * Constructors + * ------------------------------------------------------------------- + */ + + /** + * Constructs a Formatter object. + */ + protected Formatter() { + super(); + } + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + /** + * Formats a LogRecord object into a string representation. + * The resulted string is usually localized and includes the message field + * of the supplied LogRecord object. + * + * @param r + * the log record to be formatted into a string + * @return the string resulted from the formatting + */ + public abstract String format(LogRecord r); + + /** + * Formats a LogRecord object into a localized string + * representation. This method can be regarded as a convenience for + * subclasses of Formatter to use. + *

+ * The message string is firstly localized using the + * ResourceBundle object associated with the supplied + * LogRecord. + *

+ * + * @param r + * the log record to be formatted + * @return the string resulted from the formatting + */ + public String formatMessage(LogRecord r) { + String pattern = r.getMessage(); + ResourceBundle rb = null; + // try to localize the message string first + if (null != (rb = r.getResourceBundle())) { + try { + pattern = rb.getString(pattern); + } catch (Exception e) { + pattern = r.getMessage(); + } + } + if (null != pattern) { + Object[] params = r.getParameters(); + /* + * if the message contains "{0", use java.text.MessageFormat to + * format the string + */ + if (pattern.indexOf("{0") >= 0 && null != params //$NON-NLS-1$ + && params.length > 0) { + try { + pattern = MessageFormat.format(pattern, params); + } catch (IllegalArgumentException e) { + pattern = r.getMessage(); + } + } + } + return pattern; + } + + /** + * Gets the head string used to wrap a set of log records. This base class + * always returns the empty string. + * + * @param h + * the target handler + * @return the head string used to wrap a set of log records + */ + public String getHead(Handler h) { + return ""; //$NON-NLS-1$ + } + + /** + * Gets the tail string used to wrap a set of log records. This base class + * always returns the empty string. + * + * @param h + * the target handler + * @return the tail string used to wrap a set of log records + */ + public String getTail(Handler h) { + return ""; //$NON-NLS-1$ + } + +} + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Handler.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Handler.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Handler.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Handler.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,414 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +import java.nio.charset.Charset; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.io.UnsupportedEncodingException; + +/** + * A Handler object accepts a logging request and exports the + * desired messages to a target, for example, a file, the console, etc. It can + * be disabled by setting its logging level to Level.OFF. + * + */ +public abstract class Handler { + + /* + * ------------------------------------------------------------------- + * Constants + * ------------------------------------------------------------------- + */ + private static final Level DEFAULT_LEVEL = Level.ALL; + + /* + * ------------------------------------------------------------------- + * Instance variables + * ------------------------------------------------------------------- + */ + + // the error manager to report errors during logging + private ErrorManager errorMan; + + // the character encoding used by this handler + private String encoding; + + // the logging level + private Level level; + + // the formatter used to export messages + private Formatter formatter; + + // the filter used to filter undesired messages + private Filter filter; + + // class name, used for property reading + private String prefix; + + /* + * ------------------------------------------------------------------- + * Constructors + * ------------------------------------------------------------------- + */ + + /** + * Constructs a Handler object with a default error manager, + * the default encoding, and the default logging level + * Level.ALL. It has no filter and no formatter. + */ + protected Handler() { + this.errorMan = new ErrorManager(); + this.level = DEFAULT_LEVEL; + this.encoding = null; + this.filter = null; + this.formatter = null; + this.prefix = this.getClass().getName(); + } + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + // get a instance from given class name, using Class.forName() + private Object getDefaultInstance(String className) { + Object result = null; + if (null == className) { + return result; + } + try { + result = Class.forName(className).newInstance(); + } catch (Exception e) { + //ignore + } + return result; + } + + // get a instance from given class name, using context classloader + private Object getCustomizeInstance(final String className) + throws Exception { + Class c = (Class) AccessController + .doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + ClassLoader loader = Thread.currentThread() + .getContextClassLoader(); + if (null == loader) + loader = ClassLoader.getSystemClassLoader(); + return loader.loadClass(className); + } + }); + return c.newInstance(); + } + + // print error message in some format + void printInvalidPropMessage(String key, String value, Exception e) { + String msg = new StringBuffer().append("Invalid property value for ") //$NON-NLS-1$ + .append(prefix).append(".").append(key).append(":").append( //$NON-NLS-1$//$NON-NLS-2$ + value).toString(); + errorMan.error(msg, e, ErrorManager.GENERIC_FAILURE); + } + + /* + * init the common properties, including filter, level, formatter, and + * encoding + */ + void initProperties(String defaultLevel, String defaultFilter, + String defaultFormatter, String defaultEncoding) { + LogManager manager = LogManager.getLogManager(); + + //set filter + final String filterName = manager.getProperty(prefix + ".filter"); //$NON-NLS-1$ + if (null != filterName) { + try { + filter = (Filter) getCustomizeInstance(filterName); + } catch (Exception e1) { + printInvalidPropMessage("filter", filterName, e1); //$NON-NLS-1$ + filter = (Filter) getDefaultInstance(defaultFilter); + } + } else { + filter = (Filter) getDefaultInstance(defaultFilter); + } + + //set level + String levelName = manager.getProperty(prefix + ".level"); //$NON-NLS-1$ + if (null != levelName) { + try { + level = Level.parse(levelName); + } catch (Exception e) { + printInvalidPropMessage("level", levelName, e); //$NON-NLS-1$ + level = Level.parse(defaultLevel); + } + } else { + level = Level.parse(defaultLevel); + } + + //set formatter + final String formatterName = manager.getProperty(prefix + ".formatter"); //$NON-NLS-1$ + if (null != formatterName) { + try { + formatter = (Formatter) getCustomizeInstance(formatterName); + } catch (Exception e) { + printInvalidPropMessage("formatter", formatterName, e); //$NON-NLS-1$ + formatter = (Formatter) getDefaultInstance(defaultFormatter); + } + } else { + formatter = (Formatter) getDefaultInstance(defaultFormatter); + } + + //set encoding + final String encodingName = manager.getProperty(prefix + ".encoding"); //$NON-NLS-1$ + try { + internalSetEncoding(encodingName); + } catch (UnsupportedEncodingException e) { + printInvalidPropMessage("encoding", encodingName, e); //$NON-NLS-1$ + } + } + + /** + * Closes this handler. A flush operation will usually be performed and all + * the associated resources will be freed. Client applications should not + * use a handler after closing it. + * + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public abstract void close(); + + /** + * Flushes any buffered output. + */ + public abstract void flush(); + + /** + * Accepts an actual logging request. + * + * @param record + * the log record to be logged + */ + public abstract void publish(LogRecord record); + + /** + * Gets the character encoding used by this handler. + * + * @return the character encoding used by this handler + */ + public String getEncoding() { + return this.encoding; + } + + /** + * Gets the error manager used by this handler to report errors during + * logging. + * + * @return the error manager used by this handler + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public ErrorManager getErrorManager() { + LogManager.getLogManager().checkAccess(); + return this.errorMan; + } + + /** + * Gets the filter used by this handler. + * + * @return the filter used by this handler + */ + public Filter getFilter() { + return this.filter; + } + + /** + * Gets the fomatter used by this handler to format the logging messages. + * + * @return the fomatter used by this handler + */ + public Formatter getFormatter() { + return this.formatter; + } + + /** + * Gets the logging level of this handler. + * + * @return the logging level of this handler + */ + public Level getLevel() { + return this.level; + } + + /** + * Determines whether the supplied log record need to be logged. The logging + * levels will be checked as well as the filter. + * + * @param record + * the log record to be checked + * @return true if the supplied log record need to be logged, + * otherwise false + */ + public boolean isLoggable(LogRecord record) { + if (null == record) { + reportError( + "Null pointer of LogRecord", new NullPointerException("null"), ErrorManager.GENERIC_FAILURE); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + if (this.level.intValue() == Level.OFF.intValue()) { + return false; + } else if (record.getLevel().intValue() >= this.level.intValue()) { + return null == this.filter ? true : this.filter.isLoggable(record); + } + return false; + } + + /** + * Report an error to the error manager associated with this handler. + * + * @param msg + * the error message + * @param ex + * the associated exception + * @param code + * the error code + */ + protected void reportError(String msg, Exception ex, int code) { + this.errorMan.error(msg, ex, code); + } + + /** + * Sets the character encoding used by this handler. A null + * value indicates the using of the default encoding. This internal method + * does not check security. + * + * @param newEncoding + * the character encoding to set + * @throws UnsupportedEncodingException + * If the specified encoding is not supported by the runtime. + */ + void internalSetEncoding(String newEncoding) + throws UnsupportedEncodingException { + // accepts "null" because it indicates using default encoding + if (null == newEncoding) { + this.encoding = null; + } else { + if (Charset.isSupported(newEncoding)) { + this.encoding = newEncoding; + } else { + throw new UnsupportedEncodingException("The encoding \"" //$NON-NLS-1$ + + newEncoding + "\" is not supported."); //$NON-NLS-1$ + } + + } + } + + /** + * Sets the character encoding used by this handler. A null + * value indicates the using of the default encoding. + * + * @param encoding + * the character encoding to set + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + * @throws UnsupportedEncodingException + * If the specified encoding is not supported by the runtime. + */ + public void setEncoding(String encoding) throws SecurityException, + UnsupportedEncodingException { + LogManager.getLogManager().checkAccess(); + internalSetEncoding(encoding); + } + + /** + * Sets the error manager for this handler. + * + * @param em + * the error manager to set + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public void setErrorManager(ErrorManager em) { + LogManager.getLogManager().checkAccess(); + if (null == em) { + throw new NullPointerException("null"); //$NON-NLS-1$ + } + this.errorMan = em; + } + + /** + * Sets the filter to be used by this handler. + * + * @param newFilter + * the filter to set + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public void setFilter(Filter newFilter) { + LogManager.getLogManager().checkAccess(); + this.filter = newFilter; + } + + /** + * Sets the formatter to be used by this handler. This internal method does + * not check security. + * + * @param newFormatter + * the fomatter to set + */ + void internalSetFormatter(Formatter newFormatter) { + if (null == newFormatter) { + throw new NullPointerException("null"); //$NON-NLS-1$ + } + this.formatter = newFormatter; + } + + /** + * Sets the formatter to be used by this handler. + * + * @param newFormatter + * the fomatter to set + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public void setFormatter(Formatter newFormatter) { + LogManager.getLogManager().checkAccess(); + internalSetFormatter(newFormatter); + } + + /** + * Sets the logging level of this handler. + * + * @param newLevel + * the logging level to set + * @throws SecurityException + * If a security manager determines that the caller does not + * have the required permission. + */ + public void setLevel(Level newLevel) { + if (null == newLevel) { + throw new NullPointerException("null"); //$NON-NLS-1$ + } + LogManager.getLogManager().checkAccess(); + this.level = newLevel; + } +} + Added: incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java?rev=386087&view=auto ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java (added) +++ incubator/harmony/enhanced/classlib/trunk/modules/logging/src/main/java/java/util/logging/Level.java Wed Mar 15 06:55:38 2006 @@ -0,0 +1,359 @@ +/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package java.util.logging; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; + +/** + * Level objects are used to indicate the level of logging. There + * are a set of predefined logging levels, each associated with an integer + * value. Enabling a certain logging level also enables all logging levels with + * larger values. + *

+ * The predefined levels in ascending order are FINEST, FINER, FINE, CONFIG, + * INFO, WARNING, SEVERE. There are two additional predefined levels, which are + * ALL and OFF. ALL indicates logging all messages, and OFF indicates logging no + * messages. + *

+ * + */ +public class Level implements Serializable { + + + //for serialization compability + private static final long serialVersionUID = -8176160795706313070L; + + /* + * ------------------------------------------------------------------- + * Constants + * ------------------------------------------------------------------- + */ + + /* + * ------------------------------------------------------------------- + * Class variables + * ------------------------------------------------------------------- + */ + private static Map levels = new HashMap(); + + // The following string constants define the name of all predefined levels. + private static final String SEVERESTR = "SEVERE"; //$NON-NLS-1$ + + private static final String WARNINGSTR = "WARNING"; //$NON-NLS-1$ + + private static final String INFOSTR = "INFO"; //$NON-NLS-1$ + + private static final String CONFIGSTR = "CONFIG"; //$NON-NLS-1$ + + private static final String FINESTR = "FINE"; //$NON-NLS-1$ + + private static final String FINERSTR = "FINER"; //$NON-NLS-1$ + + private static final String FINESTSTR = "FINEST"; //$NON-NLS-1$ + + private static final String OFFSTR = "OFF"; //$NON-NLS-1$ + + private static final String ALLSTR = "ALL"; //$NON-NLS-1$ + + /** + * The SEVERE level indicates a severe failure. + */ + public static final Level SEVERE = new Level(SEVERESTR, 1000); + + /** + * The WARNING level indicates a warning. + */ + public static final Level WARNING = new Level(WARNINGSTR, 900); + + /** + * The INFO level indicates an informative message. + */ + public static final Level INFO = new Level(INFOSTR, 800); + + /** + * The CONFIG level indicates a static configuration message. + */ + public static final Level CONFIG = new Level(CONFIGSTR, 700); + + /** + * The FINE level provides tracing messages. + */ + public static final Level FINE = new Level(FINESTR, 500); + + /** + * The FINER level provides more detailed tracing messages. + */ + public static final Level FINER = new Level(FINERSTR, 400); + + /** + * The FINEST level provides highly detailed tracing messages. + */ + public static final Level FINEST = new Level(FINESTSTR, 300); + + /** + * The OFF level provides no logging messages. + */ + public static final Level OFF = new Level(OFFSTR, Integer.MAX_VALUE); + + /** + * The ALL level provides all logging messages. + */ + public static final Level ALL = new Level(ALLSTR, Integer.MIN_VALUE); + + + /* + * ------------------------------------------------------------------- + * Global initialization + * ------------------------------------------------------------------- + */ + + static { + levels.remove(null); + } + + /* + * ------------------------------------------------------------------- + * Instance variables + * ------------------------------------------------------------------- + */ + + /** + * The name of this Level. + * + * @serial + */ + private final String name; + + /** + * The integer value indicating the level. + * + * @serial + */ + private final int value; + + /** + * The name of the resource bundle used to localize the level name. + * + * @serial + */ + private final String resourceBundleName; + + /* + * The resource bundle associated with this level, used to localize the + * level name. + */ + private transient ResourceBundle rb; + + /* + * ------------------------------------------------------------------- + * Constructors + * ------------------------------------------------------------------- + */ + + /** + * Constructs an instance of Level taking the supplied name + * and level value. + * + * @param name + * name of the level + * @param level + * an integer value indicating the level + */ + protected Level(String name, int level) { + this(name, level, null); + } + + /** + * Constructs an instance of Level taking the supplied name + * and level value. + * + * @param name + * name of the level + * @param level + * an integer value indicating the level + * @param resourceBundleName + * the name of the resource bundle to use + */ + protected Level(String name, int level, String resourceBundleName) { + this.name = name; + this.value = level; + this.resourceBundleName = resourceBundleName; + //put value into known values list in Constructor + if(null==levels.get(name)){ + levels.put(name,this); + } + if(null==levels.get(String.valueOf(level))){ + levels.put(String.valueOf(this.intValue()), this); + } + } + + /* + * ------------------------------------------------------------------- + * Methods + * ------------------------------------------------------------------- + */ + + /** + * Gets the name of this Level. + * + * @return the name of this Level + */ + public String getName() { + return this.name; + } + + /** + * Gets the name of the resource bundle associated with this + * Level. + * + * @return the name of the resource bundle associated with this + * Level + */ + public String getResourceBundleName() { + return this.resourceBundleName; + } + + /** + * Gets the integer value indicating this Level. + * + * @return the integer value indicating this Level + */ + public final int intValue() { + return this.value; + } + + /** + * Parses a level name into a Level object. + * + * @param name + * the name of the desired level, which cannot be null + * @return a Level object with the specified name + * @throws NullPointerException + * If name is null. + * @throws IllegalArgumentException + * When name cannot be parsed. + */ + public static final Level parse(String name) { + if (null == name) + throw new NullPointerException("null"); //$NON-NLS-1$ + // Check if the name is a predefined one + Level result = (Level) levels.get(name); + if (null != result) { + return result; + } + // Try to parse the name as an integer + try { + int v = Integer.parseInt(name); + result = new Level(name, v); + return result; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Cannot parse this name: " //$NON-NLS-1$ + + name); + } + } + + /** + * Gets the localized name of this level. The default locale is used. If no + * resource bundle is associated with this Level, the + * original level name is returned. + * + * @return the localized name of this level + */ + public String getLocalizedName() { + String result = name; + if (null != resourceBundleName && null == rb) { + try { + rb = ResourceBundle.getBundle(resourceBundleName); + } catch (Exception e) { + rb = null; + } + } + if (null != rb) { + try { + result = rb.getString(name); + } catch (Exception e) { + result = name; + } + } + return result; + } + + /* + * Maintains the Object uniqueness property across serialization. + */ + private Object readResolve() { + String levelName = this.getName(); + Level result = (Level) levels.get(levelName); + + if (null != result) { + boolean sameResourceBundle = (this.resourceBundleName == null ? result + .getResourceBundleName() == null + : this.resourceBundleName.equals(result + .getResourceBundleName())); + if (result.intValue() == this.value && sameResourceBundle) { + return result; + } + } + return this; + } + + /* + * ------------------------------------------------------------------- + * Methods overriding parent class Object + * ------------------------------------------------------------------- + */ + + /** + * Compares two Level objects for equality. They are + * considered to be equal if they have the same value. + * + * @param o + * the other object to be compared with + * @return true if this object equals to the supplied object, + * otherwise false + */ + public boolean equals(Object o) { + if (!(o instanceof Level)) { + return false; + } + return ((Level) o).intValue() == this.value; + } + + /** + * Returns the hash code of this Level object. + * + * @return the hash code of this Level object + */ + public int hashCode() { + return this.value; + } + + /** + * Returns the string representation of this Level object. + * Usually this will include its name. + * + * @return the string representation of this Level object + */ + public final String toString() { + return this.name; + } + +} +