summaryrefslogtreecommitdiffstats
path: root/logging/src
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:28:47 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:28:47 -0800
commitadc854b798c1cfe3bfd4c27d68d5cee38ca617da (patch)
tree6aed8b4923ca428942cbaa7e848d50237a3d31e0 /logging/src
parent1c0fed63c71ddb230f3b304aac12caffbedf2f21 (diff)
downloadlibcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.zip
libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.gz
libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'logging/src')
-rw-r--r--logging/src/main/java/java/util/logging/ConsoleHandler.java83
-rw-r--r--logging/src/main/java/java/util/logging/ErrorManager.java132
-rw-r--r--logging/src/main/java/java/util/logging/FileHandler.java655
-rw-r--r--logging/src/main/java/java/util/logging/Filter.java38
-rw-r--r--logging/src/main/java/java/util/logging/Formatter.java145
-rw-r--r--logging/src/main/java/java/util/logging/Handler.java453
-rw-r--r--logging/src/main/java/java/util/logging/Level.java403
-rw-r--r--logging/src/main/java/java/util/logging/LogManager.java631
-rw-r--r--logging/src/main/java/java/util/logging/LogRecord.java539
-rw-r--r--logging/src/main/java/java/util/logging/Logger.java1495
-rw-r--r--logging/src/main/java/java/util/logging/LoggingMXBean.java85
-rw-r--r--logging/src/main/java/java/util/logging/LoggingPermission.java74
-rw-r--r--logging/src/main/java/java/util/logging/MemoryHandler.java295
-rw-r--r--logging/src/main/java/java/util/logging/SimpleFormatter.java81
-rw-r--r--logging/src/main/java/java/util/logging/SocketHandler.java181
-rw-r--r--logging/src/main/java/java/util/logging/StreamHandler.java367
-rw-r--r--logging/src/main/java/java/util/logging/XMLFormatter.java221
-rw-r--r--logging/src/main/java/java/util/logging/logging.properties65
-rw-r--r--logging/src/main/java/java/util/logging/package.html10
-rw-r--r--logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java147
-rw-r--r--logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties52
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java52
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java685
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java125
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java1176
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java69
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java254
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java780
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java645
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java34
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java1512
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java777
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java4776
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java125
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java101
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java554
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java121
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java181
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java1039
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java1324
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java294
-rw-r--r--logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/util/EnvironmentHelper.java53
-rw-r--r--logging/src/test/java/tests/logging/AllTests.java39
-rw-r--r--logging/src/test/resources/bundles/java/util/logging/res.properties12
-rw-r--r--logging/src/test/resources/bundles/java/util/logging/res2.properties13
-rw-r--r--logging/src/test/resources/bundles/java/util/logging/res3.properties13
-rw-r--r--logging/src/test/resources/bundles/java/util/logging/res_en_US.properties12
-rw-r--r--logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties13
-rw-r--r--logging/src/test/resources/config/java/util/logging/logging.config3
-rw-r--r--logging/src/test/resources/config/java/util/logging/logging.properties3
-rw-r--r--logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LevelTest.golden.serbin0 -> 377 bytes
-rw-r--r--logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.golden.serbin0 -> 2139 bytes
-rw-r--r--logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.golden.serbin0 -> 177 bytes
53 files changed, 20937 insertions, 0 deletions
diff --git a/logging/src/main/java/java/util/logging/ConsoleHandler.java b/logging/src/main/java/java/util/logging/ConsoleHandler.java
new file mode 100644
index 0000000..a88cf0c
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/ConsoleHandler.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ * {@code System.err}.
+ * <p>
+ * This handler reads the following properties from the log manager to
+ * initialize itself:
+ * <ul>
+ * <li>java.util.logging.ConsoleHandler.level specifies the logging level,
+ * defaults to {@code Level.INFO} if this property is not found or has an
+ * invalid value.
+ * <li>java.util.logging.ConsoleHandler.filter specifies the name of the filter
+ * class to be associated with this handler, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * <li>java.util.logging.ConsoleHandler.formatter specifies the name of the
+ * formatter class to be associated with this handler, defaults to
+ * {@code java.util.logging.SimpleFormatter} if this property is not found or
+ * has an invalid value.
+ * <li>java.util.logging.ConsoleHandler.encoding specifies the encoding this
+ * handler will use to encode log messages, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * </ul>
+ * </p>
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class ConsoleHandler extends StreamHandler {
+
+ /**
+ * Constructs a {@code ConsoleHandler} object.
+ *
+ * @since Android 1.0
+ */
+ public ConsoleHandler() {
+ super(System.err);
+ }
+
+ /**
+ * Closes this handler. The {@code System.err} is flushed but not closed.
+ *
+ * @since Android 1.0
+ */
+ @Override
+ 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.
+ *
+ * @since Android 1.0
+ */
+ @Override
+ public void publish(LogRecord record) {
+ super.publish(record);
+ super.flush();
+
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/ErrorManager.java b/logging/src/main/java/java/util/logging/ErrorManager.java
new file mode 100644
index 0000000..6f5084c
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/ErrorManager.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * An error reporting facility for {@link Handler} implementations to record any
+ * error that may happen during logging. {@code Handlers} should report errors
+ * to an {@code ErrorManager}, instead of throwing exceptions, which would
+ * interfere with the log issuer's execution.
+ *
+ * @since Android 1.0
+ */
+public class ErrorManager {
+
+ /**
+ * The error code indicating a failure that does not fit in any of the
+ * specific types of failures that follow.
+ *
+ * @since Android 1.0
+ */
+ public static final int GENERIC_FAILURE = 0;
+
+ /**
+ * The error code indicating a failure when writing to an output stream.
+ *
+ * @since Android 1.0
+ */
+ public static final int WRITE_FAILURE = 1;
+
+ /**
+ * The error code indicating a failure when flushing an output stream.
+ *
+ * @since Android 1.0
+ */
+ public static final int FLUSH_FAILURE = 2;
+
+ /**
+ * The error code indicating a failure when closing an output stream.
+ *
+ * @since Android 1.0
+ */
+ public static final int CLOSE_FAILURE = 3;
+
+ /**
+ * The error code indicating a failure when opening an output stream.
+ *
+ * @since Android 1.0
+ */
+ public static final int OPEN_FAILURE = 4;
+
+ /**
+ * The error code indicating a failure when formatting the error messages.
+ *
+ * @since Android 1.0
+ */
+ public static final int FORMAT_FAILURE = 5;
+
+ @SuppressWarnings("nls")
+ private static final String[] FAILURES = new String[] { "GENERIC_FAILURE",
+ "WRITE_FAILURE", "FLUSH_FAILURE", "CLOSE_FAILURE", "OPEN_FAILURE",
+ "FORMAT_FAILURE" };
+
+ /**
+ * An indicator for determining if the error manager has been called at
+ * least once before.
+ */
+ private boolean called;
+
+ /**
+ * Constructs an instance of {@code ErrorManager}.
+ *
+ * @since Android 1.0
+ */
+ public ErrorManager() {
+ super();
+ }
+
+ /**
+ * <p>
+ * Reports an error using the given message, exception and error code. This
+ * implementation will write out the message to {@link System#err} on the
+ * first call and all subsequent calls are ignored. A subclass of this class
+ * should override this method.
+ * </p>
+ *
+ * @param message
+ * the error message, which may be {@code null}.
+ * @param exception
+ * the exception associated with the error, which may be
+ * {@code null}.
+ * @param errorCode
+ * the error code that identifies the type of error; see the
+ * constant fields of this class for possible values.
+ *
+ * @since Android 1.0
+ */
+ public void error(String message, Exception exception, int errorCode) {
+ synchronized (this) {
+ if (called) {
+ return;
+ }
+ called = true;
+ }
+ System.err.println(this.getClass().getName()
+ + ": " + FAILURES[errorCode]); //$NON-NLS-1$
+ if (message != null) {
+ // logging.1E=Error message - {0}
+ System.err.println(Messages.getString("logging.1E", message)); //$NON-NLS-1$
+ }
+ if (exception != null) {
+ // logging.1F=Exception - {0}
+ System.err.println(Messages.getString("logging.1F", exception)); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/FileHandler.java b/logging/src/main/java/java/util/logging/FileHandler.java
new file mode 100644
index 0000000..af71a6d
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/FileHandler.java
@@ -0,0 +1,655 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * A {@code FileHandler} writes logging records into a specified file or a
+ * rotating set of files.
+ * <p>
+ * When a set of files is used and a given amount of data has been written to
+ * one file, then this file is closed and another file is opened. The name of
+ * these files are generated by given name pattern, see below for details.
+ * </p>
+ * <p>
+ * By default, the I/O buffering mechanism is enabled, but when each log record
+ * is complete, it is flushed out.
+ * </p>
+ * <p>
+ * {@code XMLFormatter} is the default formatter for {@code FileHandler}.
+ * </p>
+ * <p>
+ * {@code FileHandler} reads the following {@code LogManager} properties for
+ * initialization; if a property is not defined or has an invalid value, a
+ * default value is used.
+ * <ul>
+ * <li>java.util.logging.FileHandler.level specifies the level for this
+ * {@code Handler}, defaults to {@code Level.ALL}.</li>
+ * <li>java.util.logging.FileHandler.filter specifies the {@code Filter} class
+ * name, defaults to no {@code Filter}.</li>
+ * <li>java.util.logging.FileHandler.formatter specifies the {@code Formatter}
+ * class, defaults to {@code java.util.logging.XMLFormatter}.</li>
+ * <li>java.util.logging.FileHandler.encoding specifies the character set
+ * encoding name, defaults to the default platform encoding.</li>
+ * <li>java.util.logging.FileHandler.limit specifies the maximum number of
+ * bytes to write to any one file, defaults to zero, which means no limit.</li>
+ * <li>java.util.logging.FileHandler.count specifies how many output files to
+ * rotate, defaults to 1.</li>
+ * <li>java.util.logging.FileHandler.pattern specifies name pattern for the
+ * output files. See below for details. Defaults to "%h/java%u.log".</li>
+ * <li>java.util.logging.FileHandler.append specifies whether this
+ * {@code FileHandler} should append onto existing files, defaults to
+ * {@code false}.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Name pattern is a string that may include some special substrings, which will
+ * be replaced to generate output files:
+ * </p>
+ * <ul>
+ * <li>"/" represents the local pathname separator</li>
+ * <li>"%t" represents the system's temporary directory</li>
+ * <li>"%h" represents the home directory of the current user, which is
+ * specified by "user.home" system property</li>
+ * <li>"%g" represents the generation number to distinguish rotated logs</li>
+ * <li>"%u" represents a unique number to resolve conflicts</li>
+ * <li>"%%" represents the percent sign character '%'</li>
+ * </ul>
+ * <p>
+ * Normally, the generation numbers are not larger than the 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 specified in the pattern, then the
+ * generation number after a dot will be added to the end of the file name.
+ * </p>
+ * <p>
+ * The "%u" unique field is used to avoid conflicts and is set to 0 at first. If
+ * one {@code FileHandler} tries to open the filename which is currently in use
+ * by another process, it will repeatedly 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 generation of unique IDs for avoiding conflicts is only
+ * guaranteed to work reliably when using a local disk file system.
+ * </p>
+ * @since Android 1.0
+ */
+public class FileHandler extends StreamHandler {
+
+ private static final String LCK_EXT = ".lck"; //$NON-NLS-1$
+
+ 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$
+
+ // maintain all file locks hold by this process
+ private static final Hashtable<String, FileLock> allLocks = new Hashtable<String, FileLock>();
+
+ // 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 unique ID
+ int uniqueID = -1;
+
+ /**
+ * Construct a {@code FileHandler} using {@code LogManager} properties or
+ * their default value.
+ *
+ * @throws IOException
+ * if any I/O error occurs.
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @since Android 1.0
+ */
+ 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 {
+ while (true) {
+ // try to find a unique file which is not locked by other process
+ uniqueID++;
+ // FIXME: improve performance here
+ for (int generation = 0; generation < count; generation++) {
+ // cache all file names for rotation use
+ files[generation] = new File(parseFileName(generation));
+ }
+ fileName = files[0].getAbsolutePath();
+ synchronized (allLocks) {
+ /*
+ * if current process has held lock for this fileName continue
+ * to find next file
+ */
+ if (null != allLocks.get(fileName)) {
+ continue;
+ }
+ if (files[0].exists()
+ && (!append || files[0].length() >= limit)) {
+ for (int i = count - 1; i > 0; i--) {
+ if (files[i].exists()) {
+ files[i].delete();
+ }
+ files[i - 1].renameTo(files[i]);
+ }
+ }
+ FileOutputStream fileStream = new FileOutputStream(fileName
+ + LCK_EXT);
+ FileChannel channel = fileStream.getChannel();
+ /*
+ * if lock is unsupported and IOException thrown, just let the
+ * IOException throws out and exit otherwise it will go into an
+ * undead cycle
+ */
+ lock = channel.tryLock();
+ if (null == lock) {
+ try {
+ fileStream.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ continue;
+ }
+ allLocks.put(fileName, lock);
+ break;
+ }
+ }
+ // BEGIN android-modified
+ output = new MeasureOutputStream(
+ new BufferedOutputStream(
+ new FileOutputStream(fileName, append), 8192),
+ files[0].length());
+ // END android-modified
+ setOutputStream(output);
+ }
+
+ 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$
+ // logging.19=Pattern cannot be empty
+ throw new NullPointerException(Messages.getString("logging.19")); //$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];
+ }
+
+ 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 {
+ // BEGIN android-modified
+ output = new MeasureOutputStream(
+ new BufferedOutputStream(
+ new FileOutputStream(files[0]),
+ 8192));
+ // END android-modified
+ } catch (FileNotFoundException e1) {
+ // logging.1A=Error happened when open log file.
+ this.getErrorManager().error(Messages.getString("logging.1A"), //$NON-NLS-1$
+ e1, ErrorManager.OPEN_FAILURE);
+ }
+ setOutputStream(output);
+ }
+
+ /**
+ * Transform the pattern to the valid file name, replacing any patterns, and
+ * applying generation and uniqueID if present.
+ *
+ * @param gen
+ * generation of this file
+ * @return transformed filename ready for use.
+ */
+ private String parseFileName(int gen) {
+ 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$
+ boolean tempPathHasSepEnd = (tempPath == null ? false : tempPath
+ .endsWith(File.separator));
+
+ String homePath = System.getProperty("user.home"); //$NON-NLS-1$
+ boolean homePathHasSepEnd = (homePath == null ? false : homePath
+ .endsWith(File.separator));
+
+ StringBuilder sb = new StringBuilder();
+ 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':
+ /*
+ * we should probably try to do something cute here like
+ * lookahead for adjacent '/'
+ */
+ sb.append(value, cur, next - cur - 1).append(tempPath);
+ if (!tempPathHasSepEnd) {
+ sb.append(File.separator);
+ }
+ break;
+ case 'h':
+ sb.append(value, cur, next - cur - 1).append(homePath);
+ if (!homePathHasSepEnd) {
+ sb.append(File.separator);
+ }
+ break;
+ case '%':
+ sb.append(value, cur, next - cur - 1).append('%');
+ break;
+ default:
+ sb.append(value, cur, next - cur);
+ }
+ cur = ++next;
+ } else {
+ // fail silently
+ }
+ }
+
+ 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;
+ }
+
+ /**
+ * Constructs a new {@code FileHandler}. The given name pattern is used as
+ * output filename, the file limit is set to zero (no limit), the file count
+ * is set to one; the remaining configuration is done using
+ * {@code LogManager} properties or their default values. This handler write
+ * to only one file without size limit.
+ *
+ * @param pattern
+ * the name pattern for the output file.
+ * @throws IOException
+ * if any I/O error occurs.
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @throws IllegalArgumentException
+ * if the pattern is empty.
+ * @throws NullPointerException
+ * if the pattern is {@code null}.
+ * @since Android 1.0
+ */
+ public FileHandler(String pattern) throws IOException {
+ if (pattern.equals("")) { //$NON-NLS-1$
+ // logging.19=Pattern cannot be empty
+ throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+ }
+ init(pattern, null, Integer.valueOf(DEFAULT_LIMIT), Integer
+ .valueOf(DEFAULT_COUNT));
+ }
+
+ /**
+ * Construct a new {@code FileHandler}. The given name pattern is used as
+ * output filename, the file limit is set to zero (no limit), the file count
+ * is initialized to one and the value of {@code append} becomes the new
+ * instance's append mode. The remaining configuration is done using
+ * {@code LogManager} properties. This handler write to only one file
+ * without size limit.
+ *
+ * @param pattern
+ * the name pattern for the output file.
+ * @param append
+ * the append mode.
+ * @throws IOException
+ * if any I/O error occurs.
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @throws IllegalArgumentException
+ * if {@code pattern} is empty.
+ * @throws NullPointerException
+ * if {@code pattern} is {@code null}.
+ * @since Android 1.0
+ */
+ public FileHandler(String pattern, boolean append) throws IOException {
+ if (pattern.equals("")) { //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+ }
+
+ init(pattern, Boolean.valueOf(append), Integer.valueOf(DEFAULT_LIMIT),
+ Integer.valueOf(DEFAULT_COUNT));
+ }
+
+ /**
+ * Construct a new {@code FileHandler}. The given name pattern is used as
+ * output filename, the maximum file size is set to {@code limit} and the
+ * file count is initialized to {@code count}. The remaining configuration
+ * is done using {@code LogManager} properties. 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 for the output file.
+ * @param limit
+ * the data amount limit in bytes of one output file, can not be
+ * negative.
+ * @param count
+ * the maximum number of files to use, can not be less than one.
+ * @throws IOException
+ * if any I/O error occurs.
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @throws IllegalArgumentException
+ * if {@code pattern} is empty, {@code limit < 0} or
+ * {@code count < 1}.
+ * @throws NullPointerException
+ * if {@code pattern} is {@code null}.
+ * @since Android 1.0
+ */
+ public FileHandler(String pattern, int limit, int count) throws IOException {
+ if (pattern.equals("")) { //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+ }
+ if (limit < 0 || count < 1) {
+ // logging.1B=The limit and count property must be larger than 0 and
+ // 1, respectively
+ throw new IllegalArgumentException(Messages.getString("logging.1B")); //$NON-NLS-1$
+ }
+ init(pattern, null, Integer.valueOf(limit), Integer.valueOf(count));
+ }
+
+ /**
+ * Construct a new {@code FileHandler}. The given name pattern is used as
+ * output filename, the maximum file size is set to {@code limit}, the file
+ * count is initialized to {@code count} and the append mode is set to
+ * {@code append}. The remaining configuration is done using
+ * {@code LogManager} properties. 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 for the output file.
+ * @param limit
+ * the data amount limit in bytes of one output file, can not be
+ * negative.
+ * @param count
+ * the maximum number of files to use, can not be less than one.
+ * @param append
+ * the append mode.
+ * @throws IOException
+ * if any I/O error occurs.
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @throws IllegalArgumentException
+ * if {@code pattern} is empty, {@code limit < 0} or
+ * {@code count < 1}.
+ * @throws NullPointerException
+ * if {@code pattern} is {@code null}.
+ * @since Android 1.0
+ */
+ public FileHandler(String pattern, int limit, int count, boolean append)
+ throws IOException {
+ if (pattern.equals("")) { //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+ }
+ if (limit < 0 || count < 1) {
+ // logging.1B=The limit and count property must be larger than 0 and
+ // 1, respectively
+ throw new IllegalArgumentException(Messages.getString("logging.1B")); //$NON-NLS-1$
+ }
+ init(pattern, Boolean.valueOf(append), Integer.valueOf(limit), Integer
+ .valueOf(count));
+ }
+
+ /**
+ * Flushes and closes all opened files.
+ *
+ * @throws SecurityException
+ * if a security manager exists and it determines that the
+ * caller does not have the required permissions to control this
+ * handler; required permissions include
+ * {@code LogPermission("control")},
+ * {@code FilePermission("write")} etc.
+ * @since Android 1.0
+ */
+ @Override
+ public void close() {
+ // release locks
+ super.close();
+ allLocks.remove(fileName);
+ try {
+ FileChannel channel = lock.channel();
+ lock.release();
+ channel.close();
+ File file = new File(fileName + LCK_EXT);
+ file.delete();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Publish a {@code LogRecord}.
+ *
+ * @param record
+ * the log record to publish.
+ * @since Android 1.0
+ */
+ @Override
+ public void publish(LogRecord record) {
+ super.publish(record);
+ flush();
+ if (limit > 0 && output.getLength() >= limit) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ findNextGeneration();
+ return null;
+ }
+ });
+ }
+ }
+
+ /**
+ * This output stream uses the decorator pattern to add measurement features
+ * to OutputStream which can detect the total size(in bytes) of output, the
+ * initial size can be set.
+ */
+ static 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);
+ }
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ wrapped.write(oneByte);
+ length++;
+ }
+
+ @Override
+ public void write(byte[] bytes) throws IOException {
+ wrapped.write(bytes);
+ length += bytes.length;
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ wrapped.write(b, off, len);
+ length += len;
+ }
+
+ @Override
+ public void close() throws IOException {
+ wrapped.close();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ wrapped.flush();
+ }
+
+ public long getLength() {
+ return length;
+ }
+
+ public void setLength(long newLength) {
+ length = newLength;
+ }
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/Filter.java b/logging/src/main/java/java/util/logging/Filter.java
new file mode 100644
index 0000000..e81f216
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/Filter.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 {@code Filter} provides a mechanism for exercising fine-grained control
+ * over which records get logged.
+ *
+ * @since Android 1.0
+ */
+public interface Filter {
+
+ /**
+ * Checks {@code record} to determine if it should be logged.
+ *
+ * @param record
+ * the {@link LogRecord} to be checked.
+ * @return {@code true} if the supplied log record needs to be logged,
+ * {@code false} otherwise.
+ * @since Android 1.0
+ */
+ boolean isLoggable(LogRecord record);
+}
diff --git a/logging/src/main/java/java/util/logging/Formatter.java b/logging/src/main/java/java/util/logging/Formatter.java
new file mode 100644
index 0000000..2941c24
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/Formatter.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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;
+
+/**
+ * {@code Formatter} objects are used to format {@link LogRecord} objects into a
+ * string representation. Head and tail strings are sometimes used to wrap a set
+ * of records. The {@code getHead} and {@code getTail} methods are used for this
+ * purpose.
+ *
+ * @since Android 1.0
+ */
+public abstract class Formatter {
+
+ /*
+ * -------------------------------------------------------------------
+ * Constructors
+ * -------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a {@code Formatter} object.
+ *
+ * @since Android 1.0
+ */
+ protected Formatter() {
+ super();
+ }
+
+ /*
+ * -------------------------------------------------------------------
+ * Methods
+ * -------------------------------------------------------------------
+ */
+
+ /**
+ * Converts a {@link LogRecord} object into a string representation. The
+ * resulted string is usually localized and includes the message field of
+ * the record.
+ *
+ * @param r
+ * the log record to be formatted into a string.
+ * @return the formatted string.
+ * @since Android 1.0
+ */
+ public abstract String format(LogRecord r);
+
+ /**
+ * Formats a {@code LogRecord} object into a localized string
+ * representation. This is a convenience method for subclasses of {@code
+ * Formatter}.
+ * <p>
+ * The message string is firstly localized using the {@code ResourceBundle}
+ * object associated with the supplied {@code LogRecord}.
+ * </p>
+ * <p>
+ * Notice : if message contains "{0", then java.text.MessageFormat is used.
+ * Otherwise no formatting is performed.
+ * </p>
+ *
+ * @param r
+ * the log record to be formatted.
+ * @return the string resulted from the formatting.
+ * @since Android 1.0
+ */
+ 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 an empty string.
+ *
+ * @param h
+ * the target handler.
+ * @return the head string used to wrap a set of log records, empty in this
+ * implementation.
+ * @since Android 1.0
+ */
+ @SuppressWarnings("unused")
+ 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, empty in this
+ * implementation.
+ * @since Android 1.0
+ */
+ @SuppressWarnings("unused")
+ public String getTail(Handler h) {
+ return ""; //$NON-NLS-1$
+ }
+
+}
+
diff --git a/logging/src/main/java/java/util/logging/Handler.java b/logging/src/main/java/java/util/logging/Handler.java
new file mode 100644
index 0000000..d28bce0
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/Handler.java
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * A {@code 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 {@code Level.OFF}.
+ *
+ * @since Android 1.0
+ */
+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 {@code Handler} object with a default error manager instance
+ * {@code ErrorManager}, the default encoding, and the default logging
+ * level {@code Level.ALL}. It has no filter and no formatter.
+ *
+ * @since Android 1.0
+ */
+ 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 = AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+ public Class<?> 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) {
+ // logging.12=Invalid property value for
+ String msg = new StringBuilder().append(Messages.getString("logging.12")) //$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
+ */
+ @SuppressWarnings("unused")
+ 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 be performed and all the
+ * associated resources will be freed. Client applications should not use
+ * this handler after closing it.
+ *
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ *
+ * @since Android 1.0
+ */
+ public abstract void close();
+
+ /**
+ * Flushes any buffered output.
+ *
+ * @since Android 1.0
+ */
+ public abstract void flush();
+
+ /**
+ * Accepts a logging request and sends it to the the target.
+ *
+ * @param record
+ * the log record to be logged; {@code null} records are ignored.
+ * @since Android 1.0
+ */
+ public abstract void publish(LogRecord record);
+
+ /**
+ * Gets the character encoding used by this handler, {@code null} for
+ * default encoding.
+ *
+ * @return the character encoding used by this handler.
+ * @since Android 1.0
+ */
+ 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.
+ * @since Android 1.0
+ */
+ public ErrorManager getErrorManager() {
+ LogManager.getLogManager().checkAccess();
+ return this.errorMan;
+ }
+
+ /**
+ * Gets the filter used by this handler.
+ *
+ * @return the filter used by this handler (possibly {@code null}).
+ * @since Android 1.0
+ */
+ public Filter getFilter() {
+ return this.filter;
+ }
+
+ /**
+ * Gets the formatter used by this handler to format the logging messages.
+ *
+ * @return the formatter used by this handler (possibly {@code null}).
+ * @since Android 1.0
+ */
+ public Formatter getFormatter() {
+ return this.formatter;
+ }
+
+ /**
+ * Gets the logging level of this handler, records with levels lower than
+ * this value will be dropped.
+ *
+ * @return the logging level of this handler.
+ * @since Android 1.0
+ */
+ public Level getLevel() {
+ return this.level;
+ }
+
+ /**
+ * Determines whether the supplied log record needs to be logged. The
+ * logging levels will be checked as well as the filter.
+ *
+ * @param record
+ * the log record to be checked.
+ * @return {@code true} if the supplied log record needs to be logged,
+ * otherwise {@code false}.
+ * @since Android 1.0
+ */
+ public boolean isLoggable(LogRecord record) {
+ if (null == record) {
+ throw new NullPointerException();
+ }
+ if (this.level.intValue() == Level.OFF.intValue()) {
+ return false;
+ } else if (record.getLevel().intValue() >= this.level.intValue()) {
+ return null == this.filter || this.filter.isLoggable(record);
+ }
+ return false;
+ }
+
+ /**
+ * Reports an error to the error manager associated with this handler,
+ * {@code ErrorManager} is used for that purpose. No security checks are
+ * done, therefore this is compatible with environments where the caller
+ * is non-privileged.
+ *
+ * @param msg
+ * the error message, may be {@code null}.
+ * @param ex
+ * the associated exception, may be {@code null}.
+ * @param code
+ * an {@code ErrorManager} error code.
+ * @since Android 1.0
+ */
+ protected void reportError(String msg, Exception ex, int code) {
+ this.errorMan.error(msg, ex, code);
+ }
+
+ /**
+ * Sets the character encoding used by this handler. A {@code null} value
+ * indicates the use 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.
+ * @since Android 1.0
+ */
+ 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 {
+ // logging.13=The encoding "{0}" is not supported.
+ throw new UnsupportedEncodingException(Messages.getString(
+ "logging.13", //$NON-NLS-1$
+ newEncoding));
+ }
+
+ }
+ }
+
+ /**
+ * Sets the character encoding used by this handler, {@code null} indicates
+ * a 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.
+ * @since Android 1.0
+ */
+ 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 NullPointerException
+ * if {@code em} is {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setErrorManager(ErrorManager em) {
+ LogManager.getLogManager().checkAccess();
+ if (null == em) {
+ throw new NullPointerException();
+ }
+ this.errorMan = em;
+ }
+
+ /**
+ * Sets the filter to be used by this handler.
+ *
+ * @param newFilter
+ * the filter to set, may be {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ 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 formatter to set.
+ */
+ void internalSetFormatter(Formatter newFormatter) {
+ if (null == newFormatter) {
+ throw new NullPointerException();
+ }
+ this.formatter = newFormatter;
+ }
+
+ /**
+ * Sets the formatter to be used by this handler.
+ *
+ * @param newFormatter
+ * the formatter to set.
+ * @throws NullPointerException
+ * if {@code newFormatter} is {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setFormatter(Formatter newFormatter) {
+ LogManager.getLogManager().checkAccess();
+ internalSetFormatter(newFormatter);
+ }
+
+ /**
+ * Sets the logging level of the messages logged by this handler, levels
+ * lower than this value will be dropped.
+ *
+ * @param newLevel
+ * the logging level to set.
+ * @throws NullPointerException
+ * if {@code newLevel} is {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setLevel(Level newLevel) {
+ if (null == newLevel) {
+ throw new NullPointerException();
+ }
+ LogManager.getLogManager().checkAccess();
+ this.level = newLevel;
+ }
+}
+
diff --git a/logging/src/main/java/java/util/logging/Level.java b/logging/src/main/java/java/util/logging/Level.java
new file mode 100644
index 0000000..32ba017
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/Level.java
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+// BEGIN android-changed
+import dalvik.system.VMStack;
+// END android-changed
+
+/**
+ * {@code 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.
+ * <p>
+ * 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.
+ * </p>
+ * @since Android 1.0
+ */
+public class Level implements Serializable {
+
+ private static final long serialVersionUID = -8176160795706313070L;
+
+ private static final List<Level> levels = new ArrayList<Level>(9);
+
+ /**
+ * The OFF level provides no logging messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level OFF = new Level("OFF", Integer.MAX_VALUE); //$NON-NLS-1$
+
+ /**
+ * The SEVERE level provides severe failure messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level SEVERE = new Level("SEVERE", 1000); //$NON-NLS-1$
+
+ /**
+ * The WARNING level provides warnings.
+ *
+ * @since Android 1.0
+ */
+ public static final Level WARNING = new Level("WARNING", 900); //$NON-NLS-1$
+
+ /**
+ * The INFO level provides informative messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level INFO = new Level("INFO", 800); //$NON-NLS-1$
+
+ /**
+ * The CONFIG level provides static configuration messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level CONFIG = new Level("CONFIG", 700); //$NON-NLS-1$
+
+ /**
+ * The FINE level provides tracing messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level FINE = new Level("FINE", 500); //$NON-NLS-1$
+
+ /**
+ * The FINER level provides more detailed tracing messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level FINER = new Level("FINER", 400); //$NON-NLS-1$
+
+ /**
+ * The FINEST level provides highly detailed tracing messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level FINEST = new Level("FINEST", 300); //$NON-NLS-1$
+
+ /**
+ * The ALL level provides all logging messages.
+ *
+ * @since Android 1.0
+ */
+ public static final Level ALL = new Level("ALL", Integer.MIN_VALUE); //$NON-NLS-1$
+
+ /**
+ * Parses a level name into a {@code Level} object.
+ *
+ * @param name
+ * the name of the desired {@code level}, which cannot be
+ * {@code null}.
+ * @return the level with the specified name.
+ * @throws NullPointerException
+ * if {@code name} is {@code null}.
+ * @throws IllegalArgumentException
+ * if {@code name} is not valid.
+ * @since Android 1.0
+ */
+ public static Level parse(String name) throws IllegalArgumentException {
+ // BEGIN android-note
+ // final modifier removed and IAE added to get closer to the RI
+ // copied from newer version of harmony
+ // END android-note
+ if (name == null) {
+ // logging.1C=The 'name' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.1C")); //$NON-NLS-1$
+ }
+
+ boolean isNameAnInt;
+ int nameAsInt;
+ try {
+ nameAsInt = Integer.parseInt(name);
+ isNameAnInt = true;
+ } catch (NumberFormatException e) {
+ nameAsInt = 0;
+ isNameAnInt = false;
+ }
+
+ synchronized (levels) {
+ for (Level level : levels) {
+ if (name.equals(level.getName())) {
+ return level;
+ }
+ }
+
+ if (isNameAnInt) {
+ /*
+ * Loop through levels a second time, so that the
+ * returned instance will be passed on the order of construction.
+ */
+ for (Level level : levels) {
+ if (nameAsInt == level.intValue()) {
+ return level;
+ }
+ }
+ }
+ }
+
+ if (!isNameAnInt) {
+ // logging.1D=Cannot parse this name: {0}
+ throw new IllegalArgumentException(Messages.getString("logging.1D", name)); //$NON-NLS-1$
+ }
+
+ return new Level(name, nameAsInt);
+ }
+
+ /**
+ * 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;
+
+ /**
+ * Constructs an instance of {@code Level} taking the supplied name and
+ * level value.
+ *
+ * @param name
+ * the name of the level.
+ * @param level
+ * an integer value indicating the level.
+ * @throws NullPointerException
+ * if {@code name} is {@code null}.
+ * @since Android 1.0
+ */
+ protected Level(String name, int level) {
+ this(name, level, null);
+ }
+
+ /**
+ * Constructs an instance of {@code Level} taking the supplied name, level
+ * value and resource bundle name.
+ *
+ * @param name
+ * the name of the level.
+ * @param level
+ * an integer value indicating the level.
+ * @param resourceBundleName
+ * the name of the resource bundle to use.
+ * @throws NullPointerException
+ * if {@code name} is {@code null}.
+ * @since Android 1.0
+ */
+ protected Level(String name, int level, String resourceBundleName) {
+ if (name == null) {
+ // logging.1C=The 'name' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.1C")); //$NON-NLS-1$
+ }
+ this.name = name;
+ this.value = level;
+ this.resourceBundleName = resourceBundleName;
+ if (resourceBundleName != null) {
+ try {
+ rb = ResourceBundle.getBundle(resourceBundleName,
+ // BEGIN android-changed
+ Locale.getDefault(), VMStack.getCallingClassLoader());
+ // BEGIN android-changed
+ } catch (MissingResourceException e) {
+ rb = null;
+ }
+ }
+ synchronized (levels) {
+ levels.add(this);
+ }
+ }
+
+ /**
+ * Gets the name of this level.
+ *
+ * @return this level's name.
+ * @since Android 1.0
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Gets the name of the resource bundle associated with this level.
+ *
+ * @return the name of this level's resource bundle.
+ * @since Android 1.0
+ */
+ public String getResourceBundleName() {
+ return this.resourceBundleName;
+ }
+
+ /**
+ * Gets the integer value indicating this level.
+ *
+ * @return this level's integer value.
+ * @since Android 1.0
+ */
+ public final int intValue() {
+ return this.value;
+ }
+
+ /**
+ * <p>
+ * Serialization helper method to maintain singletons and add any new
+ * levels.
+ * </p>
+ *
+ * @return the resolved instance.
+ */
+ private Object readResolve() {
+ synchronized (levels) {
+ for (Level level : levels) {
+ if (value != level.value) {
+ continue;
+ }
+ if (!name.equals(name)) {
+ continue;
+ }
+ if (resourceBundleName == level.resourceBundleName) {
+ return level;
+ } else if (resourceBundleName != null
+ && resourceBundleName.equals(level.resourceBundleName)) {
+ return level;
+ }
+ }
+ // This is a new value, so add it.
+ levels.add(this);
+ return this;
+ }
+ }
+
+ /**
+ * Serialization helper to setup transient resource bundle instance.
+ *
+ * @param in
+ * the input stream to read the instance data from.
+ * @throws IOException
+ * if an IO error occurs.
+ * @throws ClassNotFoundException
+ * if a class is not found.
+ */
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ if (resourceBundleName != null) {
+ try {
+ rb = ResourceBundle.getBundle(resourceBundleName);
+ } catch (MissingResourceException e) {
+ rb = null;
+ }
+ }
+ }
+
+ /**
+ * Gets the localized name of this level. The default locale is used. If no
+ * resource bundle is associated with this level then the original level
+ * name is returned.
+ *
+ * @return the localized name of this level.
+ * @since Android 1.0
+ */
+ public String getLocalizedName() {
+ if (rb == null) {
+ return name;
+ }
+
+ try {
+ return rb.getString(name);
+ } catch (MissingResourceException e) {
+ return name;
+ }
+ }
+
+ /**
+ * Compares two {@code Level} objects for equality. They are considered to
+ * be equal if they have the same level value.
+ *
+ * @param o
+ * the other object to compare this level to.
+ * @return {@code true} if this object equals to the supplied object,
+ * {@code false} otherwise.
+ * @since Android 1.0
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof Level)) {
+ return false;
+ }
+
+ return ((Level) o).intValue() == this.value;
+ }
+
+ /**
+ * Returns the hash code of this {@code Level} object.
+ *
+ * @return this level's hash code.
+ * @since Android 1.0
+ */
+ @Override
+ public int hashCode() {
+ return this.value;
+ }
+
+ /**
+ * Returns the string representation of this {@code Level} object. In
+ * this case, it is the level's name.
+ *
+ * @return the string representation of this level.
+ * @since Android 1.0
+ */
+ @Override
+ public final String toString() {
+ return this.name;
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/LogManager.java b/logging/src/main/java/java/util/logging/LogManager.java
new file mode 100644
index 0000000..8409b81
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/LogManager.java
@@ -0,0 +1,631 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+// BEGIN android-removed
+// import java.lang.management.ManagementFactory;
+// import java.lang.reflect.Method;
+// import javax.management.MBeanServer;
+// import javax.management.ObjectName;
+// import javax.management.ObjectInstance;
+// import javax.management.MalformedObjectNameException;
+// END android-removed
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * {@code LogManager} is used to maintain configuration properties of the
+ * logging framework, and to manage a hierarchical namespace of all named
+ * {@code Logger} objects.
+ * <p>
+ *
+ * There is only one global {@code LogManager} instance in the
+ * application, which can be get by calling static method
+ * {@link #getLogManager()}. This instance is created and
+ * initialized during class initialization and cannot be changed.
+ * </p>
+ * <p>
+ * The {@code LogManager} class can be specified by
+ * java.util.logging.manager system property, if the property is unavailable or
+ * invalid, the default class {@link java.util.logging.LogManager} will
+ * be used.
+ * </p>
+ * <p>
+ * When initialization, {@code LogManager} read its configuration from a
+ * properties file, which by default is the "lib/logging.properties" in the JRE
+ * directory.
+ * </p>
+ * <p>
+ * However, two optional system properties can be used to customize the initial
+ * configuration process of {@code LogManager}.
+ * <ul>
+ * <li>"java.util.logging.config.class"</li>
+ * <li>"java.util.logging.config.file"</li>
+ * </ul>
+ * </p>
+ * <p>
+ * These two properties can be set in three ways, by the Preferences API, by the
+ * "java" command line property definitions, or by system property definitions
+ * passed to JNI_CreateJavaVM.
+ * </p>
+ * <p>
+ * The "java.util.logging.config.class" should specifies a class name. If it is
+ * set, this given class will be loaded and instantiated during
+ * {@code LogManager} initialization, so that this object's default
+ * constructor can read the initial configuration and define properties for
+ * {@code LogManager}.
+ * </p>
+ * <p>
+ * If "java.util.logging.config.class" property is not set, or it is invalid, or
+ * some exception is thrown during the instantiation, then the
+ * "java.util.logging.config.file" system property can be used to specify a
+ * properties file. The {@code LogManager} will read initial
+ * configuration from this file.
+ * </p>
+ * <p>
+ * If neither of these properties is defined, or some exception is thrown
+ * during these two properties using, the {@code LogManager} will read
+ * its initial configuration from default properties file, as described above.
+ * </p>
+ * <p>
+ * The global logging properties may include:
+ * <ul>
+ * <li>"handlers". This property's values should be a list of class names for
+ * handler classes separated by whitespace, these classes must be subclasses of
+ * {@code Handler} and each must have a default constructor, these
+ * classes will be loaded, instantiated and registered as handlers on the root
+ * {@code Logger} (the {@code Logger} named ""). These
+ * {@code Handler}s maybe initialized lazily.</li>
+ * <li>"config". The property defines a list of class names separated by
+ * whitespace. Each class must have a default constructor, in which it can
+ * update the logging configuration, such as levels, handlers, or filters for
+ * some logger, etc. These classes will be loaded and instantiated during
+ * {@code LogManager} configuration</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This class, together with any handler and configuration classes associated
+ * with it, <b>must</b> be loaded from the system classpath when
+ * {@code LogManager} configuration occurs.
+ * </p>
+ * <p>
+ * Besides global properties, the properties for loggers and Handlers can be
+ * specified in the property files. The names of these properties will start
+ * with the complete dot separated names for the handlers or loggers.
+ * </p>
+ * <p>
+ * In the {@code LogManager}'s hierarchical namespace,
+ * {@code Loggers} are organized based on their dot separated names. For
+ * example, "x.y.z" is child of "x.y".
+ * </p>
+ * <p>
+ * Levels for {@code Loggers} can be defined by properties whose name end
+ * with ".level". Thus "alogger.level" defines a level for the logger named as
+ * "alogger" and for all its children in the naming hierarchy. Log levels
+ * properties are read and applied in the same order as they are specified in
+ * the property file. The root logger's level can be defined by the property
+ * named as ".level".
+ * </p>
+ * <p>
+ * All methods on this type can be taken as being thread safe.
+ * </p>
+ *
+ */
+public class LogManager {
+ /*
+ * -------------------------------------------------------------------
+ * Class variables
+ * -------------------------------------------------------------------
+ */
+
+ // The line separator of the underlying OS
+ // Use privileged code to read the line.separator system property
+ private static final String lineSeparator =
+ getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
+
+ // The shared logging permission
+ private static final LoggingPermission perm = new LoggingPermission(
+ "control", null); //$NON-NLS-1$
+
+ // the singleton instance
+ static LogManager manager;
+
+ /**
+ * The {@code String} value of the {@link LoggingMXBean}'s ObjectName.
+ *
+ * @since Android 1.0
+ */
+ public static final String LOGGING_MXBEAN_NAME =
+ "java.util.logging:type=Logging"; //$NON-NLS-1$
+
+ /**
+ * Get the {@code LoggingMXBean} instance. this implementation always throws
+ * an UnsupportedOperationException.
+ *
+ * @return the {@code LoggingMXBean} instance
+ */
+ public static LoggingMXBean getLoggingMXBean() {
+ // BEGIN android-added
+ throw new UnsupportedOperationException();
+ // END android-added
+ // BEGIN android-removed
+ // try {
+ // ObjectName loggingMXBeanName = new ObjectName(LOGGING_MXBEAN_NAME);
+ // MBeanServer platformBeanServer =
+ // ManagementFactory.getPlatformMBeanServer();
+ // Set loggingMXBeanSet = platformBeanServer.queryMBeans(
+ // loggingMXBeanName, null);
+ //
+ // if (loggingMXBeanSet.size() != 1) {
+ // // logging.21=There Can Be Only One logging MX bean.
+ // throw new AssertionError(Messages.getString("logging.21"));
+ // }
+ //
+ // Iterator i = loggingMXBeanSet.iterator();
+ // ObjectInstance loggingMXBeanOI = (ObjectInstance) i.next();
+ // String lmxbcn = loggingMXBeanOI.getClassName();
+ // Class lmxbc = Class.forName(lmxbcn);
+ // Method giMethod = lmxbc.getDeclaredMethod("getInstance");
+ // giMethod.setAccessible(true);
+ // LoggingMXBean lmxb = (LoggingMXBean)
+ // giMethod.invoke(null, new Object[] {});
+ //
+ // return lmxb;
+ // } catch (Exception e) {
+ // //TODO
+ // //e.printStackTrace();
+ // }
+ // // logging.22=Exception occurred while getting the logging MX bean.
+ // throw new AssertionError(Messages.getString("logging.22")); //$NON-NLS-1$
+ // END android-removed
+ }
+
+ /*
+ * -------------------------------------------------------------------
+ * Instance variables
+ * -------------------------------------------------------------------
+ */
+ //FIXME: use weak reference to avoid heap memory leak
+ private Hashtable<String, Logger> loggers;
+
+ // the configuration properties
+ private Properties props;
+
+ // the property change listener
+ private PropertyChangeSupport listeners;
+
+ /*
+ * -------------------------------------------------------------------
+ * Global initialization
+ * -------------------------------------------------------------------
+ */
+
+ static {
+ // init LogManager singleton instance
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ String className = System.getProperty(
+ "java.util.logging.manager"); //$NON-NLS-1$
+
+ if (null != className) {
+ manager = (LogManager) getInstanceByClass(className);
+ }
+ if (null == manager) {
+ manager = new LogManager();
+ }
+
+ // read configuration
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // if global logger has been initialized, set root as its parent
+ Logger root = new Logger("", null); //$NON-NLS-1$
+ root.setLevel(Level.INFO);
+ Logger.global.setParent(root);
+
+ manager.addLogger(root);
+ manager.addLogger(Logger.global);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Default constructor. This is not public because there should be only one
+ * {@code LogManager} instance, which can be get by
+ * {@code LogManager.getLogManager(}. This is protected so that
+ * application can subclass the object.
+ */
+ protected LogManager() {
+ loggers = new Hashtable<String, Logger>();
+ props = new Properties();
+ listeners = new PropertyChangeSupport(this);
+ // add shutdown hook to ensure that the associated resource will be
+ // freed when JVM exits
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ reset();
+ }
+ });
+ return null;
+ }
+ });
+ }
+
+ /*
+ * -------------------------------------------------------------------
+ * Methods
+ * -------------------------------------------------------------------
+ */
+ /*
+ * Package private utilities Returns the line separator of the underlying
+ * OS.
+ */
+ static String getSystemLineSeparator() {
+ return lineSeparator;
+ }
+
+ /**
+ * Check that the caller has {@code LoggingPermission("control")} so
+ * that it is trusted to modify the configuration for logging framework. If
+ * the check passes, just return, otherwise {@code SecurityException}
+ * will be thrown.
+ *
+ * @throws SecurityException
+ * if there is a security manager in operation and the invoker
+ * of this method does not have the required security permission
+ * {@code LoggingPermission("control")}
+ */
+ public void checkAccess() {
+ if (null != System.getSecurityManager()) {
+ System.getSecurityManager().checkPermission(perm);
+ }
+ }
+
+ /**
+ * Add a given logger into the hierarchical namespace. The
+ * {@code Logger.addLogger()} factory methods call this method to add newly
+ * created Logger. This returns false if a logger with the given name has
+ * existed in the namespace
+ * <p>
+ * Note that the {@code LogManager} may only retain weak references to
+ * registered loggers. In order to prevent {@code Logger} objects from being
+ * unexpectedly garbage collected it is necessary for <i>applications</i>
+ * to maintain references to them.
+ * </p>
+ *
+ * @param logger
+ * the logger to be added.
+ * @return true if the given logger is added into the namespace
+ * successfully, false if the given logger exists in the namespace.
+ */
+ public synchronized boolean addLogger(Logger logger) {
+ String name = logger.getName();
+ if (null != loggers.get(name)) {
+ return false;
+ }
+ addToFamilyTree(logger, name);
+ loggers.put(name, logger);
+ logger.setManager(this);
+ return true;
+ }
+
+
+ private void addToFamilyTree(Logger logger, String name) {
+ Logger parent = null;
+ // find parent
+ int lastSeparator;
+ String parentName = name;
+ while ((lastSeparator = parentName.lastIndexOf('.')) != -1) {
+ parentName = parentName.substring(0, lastSeparator);
+ parent = loggers.get(parentName);
+ if (parent != null) {
+ logger.internalSetParent(parent);
+ break;
+ } else if (getProperty(parentName+".level") != null || //$NON-NLS-1$
+ getProperty(parentName+".handlers") != null) { //$NON-NLS-1$
+ parent = Logger.getLogger(parentName);
+ logger.internalSetParent(parent);
+ break;
+ }
+ }
+ if (parent == null && null != (parent = loggers.get(""))) { //$NON-NLS-1$
+ logger.internalSetParent(parent);
+ }
+
+ // find children
+ //TODO: performance can be improved here?
+ Collection<Logger> allLoggers = loggers.values();
+ for (Logger child : allLoggers) {
+ Logger oldParent = child.getParent();
+ if (parent == oldParent
+ && (name.length() == 0 || child.getName().startsWith(
+ name + '.'))) {
+ child.setParent(logger);
+ if (null != oldParent) {
+ //-- remove from old parent as the parent has been changed
+ oldParent.removeChild(child);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the logger with the given name.
+ *
+ * @param name
+ * name of logger
+ * @return logger with given name, or {@code null} if nothing is found.
+ */
+ public synchronized Logger getLogger(String name) {
+ return loggers.get(name);
+ }
+
+ /**
+ * Get a {@code Enumeration} of all registered logger names.
+ *
+ * @return enumeration of registered logger names
+ */
+ public synchronized Enumeration<String> getLoggerNames() {
+ return loggers.keys();
+ }
+
+ /**
+ * Get the global {@code LogManager} instance.
+ *
+ * @return the global {@code LogManager} instance
+ */
+ public static LogManager getLogManager() {
+ return manager;
+ }
+
+ /**
+ * Get the value of property with given name.
+ *
+ * @param name
+ * the name of property
+ * @return the value of property
+ */
+ public String getProperty(String name) {
+ return props.getProperty(name);
+ }
+
+ /**
+ * Re-initialize the properties and configuration. The initialization
+ * process is same as the {@code LogManager} instantiation.
+ * <p>
+ * Notice : No {@code PropertyChangeEvent} are fired.
+ * </p>
+ *
+ * @throws IOException
+ * if any IO related problems happened.
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to perform this action.
+ */
+ public void readConfiguration() throws IOException {
+ checkAccess();
+ // check config class
+ String configClassName = System.getProperty(
+ "java.util.logging.config.class"); //$NON-NLS-1$
+ if (null == configClassName || null == getInstanceByClass(configClassName)) {
+ // if config class failed, check config file
+ String configFile = System.getProperty(
+ "java.util.logging.config.file"); //$NON-NLS-1$
+
+ if (null == configFile) {
+ // if cannot find configFile, use default logging.properties
+ configFile = new StringBuilder().append(
+ System.getProperty("java.home")).append(File.separator) //$NON-NLS-1$
+ .append("lib").append(File.separator).append( //$NON-NLS-1$
+ "logging.properties").toString(); //$NON-NLS-1$
+ }
+
+ InputStream input = null;
+ try {
+ // BEGIN android-removed
+ // input = new BufferedInputStream(new FileInputStream(configFile));
+ // END android-removed
+
+ // BEGIN android-added
+ try {
+ input = new BufferedInputStream(
+ new FileInputStream(configFile), 8192);
+ } catch (Exception ex) {
+ // consult fixed resource as a last resort
+ input = new BufferedInputStream(
+ getClass().getResourceAsStream(
+ "logging.properties"), 8192);
+ }
+ // END android-added
+ readConfigurationImpl(input);
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (Exception e) {// ignore
+ }
+ }
+ }
+ }
+ }
+
+ // use privilege code to get system property
+ static String getPrivilegedSystemProperty(final String key) {
+ return AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ }
+
+ // use SystemClassLoader to load class from system classpath
+ static Object getInstanceByClass(final String className) {
+ try {
+ Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(
+ className);
+ return clazz.newInstance();
+ } catch (Exception e) {
+ try {
+ Class<?> clazz = Thread.currentThread()
+ .getContextClassLoader().loadClass(className);
+ return clazz.newInstance();
+ } catch (Exception innerE) {
+ //logging.20=Loading class "{0}" failed
+ System.err.println(Messages.getString(
+ "logging.20", className)); //$NON-NLS-1$
+ System.err.println(innerE);
+ return null;
+ }
+ }
+
+ }
+
+ // actual initialization process from a given input stream
+ private synchronized void readConfigurationImpl(InputStream ins)
+ throws IOException {
+ reset();
+ props.load(ins);
+
+ // parse property "config" and apply setting
+ String configs = props.getProperty("config"); //$NON-NLS-1$
+ if (null != configs) {
+ StringTokenizer st = new StringTokenizer(configs, " "); //$NON-NLS-1$
+ while (st.hasMoreTokens()) {
+ String configerName = st.nextToken();
+ getInstanceByClass(configerName);
+ }
+ }
+
+ // set levels for logger
+ Collection<Logger> allLoggers = loggers.values();
+ for(Logger logger : allLoggers){
+ String property = props.getProperty(
+ logger.getName()+".level"); //$NON-NLS-1$
+ if(null != property){
+ logger.setLevel(Level.parse(property));
+ }
+ }
+ listeners.firePropertyChange(null, null, null);
+ }
+
+
+ /**
+ * Re-initialize the properties and configuration from the given
+ * {@code InputStream}
+ * <p>
+ * Notice : No {@code PropertyChangeEvent} are fired.
+ * </p>
+ *
+ * @param ins
+ * the input stream
+ * @throws IOException
+ * if any IO related problems happened.
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to perform this action.
+ */
+ public void readConfiguration(InputStream ins) throws IOException {
+ checkAccess();
+ readConfigurationImpl(ins);
+ }
+
+ /**
+ * Reset configuration.
+ * <p>
+ * All handlers are closed and removed from any named loggers. All loggers'
+ * level is set to null, except the root logger's level is set to
+ * {@code Level.INFO}.
+ * </p>
+ *
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to perform this action.
+ */
+ public void reset() {
+ checkAccess();
+ props = new Properties();
+ Enumeration<String> names = getLoggerNames();
+ while(names.hasMoreElements()){
+ String name = names.nextElement();
+ Logger logger = getLogger(name);
+ if(logger != null){
+ logger.reset();
+ }
+ }
+ Logger root = loggers.get(""); //$NON-NLS-1$
+ if (null != root) {
+ root.setLevel(Level.INFO);
+ }
+ }
+
+ /**
+ * Add a {@code PropertyChangeListener}, which will be invoked when
+ * the properties are reread.
+ *
+ * @param l
+ * the {@code PropertyChangeListener} to be added.
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to perform this action.
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ if(l == null){
+ throw new NullPointerException();
+ }
+ checkAccess();
+ listeners.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Remove a {@code PropertyChangeListener}, do nothing if the given
+ * listener is not found.
+ *
+ * @param l
+ * the {@code PropertyChangeListener} to be removed.
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to perform this action.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ checkAccess();
+ listeners.removePropertyChangeListener(l);
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/LogRecord.java b/logging/src/main/java/java/util/logging/LogRecord.java
new file mode 100644
index 0000000..b8a98ef
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/LogRecord.java
@@ -0,0 +1,539 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * A {@code LogRecord} object represents a logging request. It is passed between
+ * the logging framework and individual logging handlers. Client applications
+ * should not modify a {@code LogRecord} object that has been passed into the
+ * logging framework.
+ * <p>
+ * The {@code LogRecord} class will infer the source method name and source
+ * class name the first time they are accessed if the client application didn't
+ * specify them explicitly. This automatic inference is based on the analysis of
+ * the call stack and is not guaranteed to be precise. Client applications
+ * should force the initialization of these two fields by calling
+ * {@code getSourceClassName} or {@code getSourceMethodName} if they expect to
+ * use them after passing the {@code LogRecord} object to another thread or
+ * transmitting it over RMI.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class LogRecord implements Serializable {
+
+ private static final long serialVersionUID = 5372048053134512534L;
+
+ // The major byte used in serialization.
+ private static final int MAJOR = 1;
+
+ // The minor byte used in serialization.
+ private static final int MINOR = 4;
+
+ // Store the current value for the sequence number.
+ private static long currentSequenceNumber = 0;
+
+ // Store the id for each thread.
+ private static ThreadLocal<Integer> currentThreadId = new ThreadLocal<Integer>();
+
+ // The base id as the starting point for thread ID allocation.
+ private static int initThreadId = 0;
+
+ /**
+ * The logging level.
+ *
+ * @serial
+ */
+ private Level level;
+
+ /**
+ * The sequence number.
+ *
+ * @serial
+ */
+ private long sequenceNumber;
+
+ /**
+ * The name of the class that issued the logging call.
+ *
+ * @serial
+ */
+ private String sourceClassName;
+
+ /**
+ * The name of the method that issued the logging call.
+ *
+ * @serial
+ */
+ private String sourceMethodName;
+
+ /**
+ * The original message text.
+ *
+ * @serial
+ */
+ private String message;
+
+ /**
+ * The ID of the thread that issued the logging call.
+ *
+ * @serial
+ */
+ private int threadID;
+
+ /**
+ * The time that the event occurred, in milliseconds since 1970.
+ *
+ * @serial
+ */
+ private long millis;
+
+ /**
+ * The associated {@code Throwable} object if any.
+ *
+ * @serial
+ */
+ private Throwable thrown;
+
+ /**
+ * The name of the source logger.
+ *
+ * @serial
+ */
+ private String loggerName;
+
+ /**
+ * The name of the resource bundle used to localize the log message.
+ *
+ * @serial
+ */
+ private String resourceBundleName;
+
+ // The associated resource bundle if any.
+ private transient ResourceBundle resourceBundle;
+
+ // The parameters.
+ private transient Object[] parameters;
+
+ // If the source method and source class has been initialized
+ private transient boolean sourceInited;
+
+ /**
+ * Constructs a {@code LogRecord} object using the supplied the logging
+ * level and message. The millis property is set to the current time. The
+ * sequence property is set to a new unique value, allocated in increasing
+ * order within the virtual machine. The thread ID is set to a unique value
+ * for the current thread. All other properties are set to {@code null}.
+ *
+ * @param level
+ * the logging level, may not be {@code null}.
+ * @param msg
+ * the raw message.
+ * @throws NullPointerException
+ * if {@code level} is {@code null}.
+ * @since Android 1.0
+ */
+ public LogRecord(Level level, String msg) {
+ if (null == level) {
+ // logging.4=The 'level' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.4")); //$NON-NLS-1$
+ }
+ this.level = level;
+ this.message = msg;
+ this.millis = System.currentTimeMillis();
+
+ synchronized (LogRecord.class) {
+ this.sequenceNumber = currentSequenceNumber++;
+ Integer id = currentThreadId.get();
+ if (null == id) {
+ this.threadID = initThreadId;
+ currentThreadId.set(Integer.valueOf(initThreadId++));
+ } else {
+ this.threadID = id.intValue();
+ }
+ }
+
+ this.sourceClassName = null;
+ this.sourceMethodName = null;
+ this.loggerName = null;
+ this.parameters = null;
+ this.resourceBundle = null;
+ this.resourceBundleName = null;
+ this.thrown = null;
+ }
+
+ /**
+ * Gets the logging level.
+ *
+ * @return the logging level.
+ * @since Android 1.0
+ */
+ public Level getLevel() {
+ return level;
+ }
+
+ /**
+ * Sets the logging level.
+ *
+ * @param level
+ * the level to set.
+ * @throws NullPointerException
+ * if {@code level} is {@code null}.
+ * @since Android 1.0
+ */
+ public void setLevel(Level level) {
+ if (null == level) {
+ // logging.4=The 'level' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.4")); //$NON-NLS-1$
+ }
+ this.level = level;
+ }
+
+ /**
+ * Gets the name of the logger.
+ *
+ * @return the logger name.
+ * @since Android 1.0
+ */
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ /**
+ * Sets the name of the logger.
+ *
+ * @param loggerName
+ * the logger name to set.
+ * @since Android 1.0
+ */
+ public void setLoggerName(String loggerName) {
+ this.loggerName = loggerName;
+ }
+
+ /**
+ * Gets the raw message.
+ *
+ * @return the raw message, may be {@code null}.
+ * @since Android 1.0
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Sets the raw message. When this record is formatted by a logger that has
+ * a localization resource bundle that contains an entry for {@code message},
+ * then the raw message is replaced with its localized version.
+ *
+ * @param message
+ * the raw message to set, may be {@code null}.
+ * @since Android 1.0
+ */
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ /**
+ * Gets the time when this event occurred, in milliseconds since 1970.
+ *
+ * @return the time when this event occurred, in milliseconds since 1970.
+ * @since Android 1.0
+ */
+ public long getMillis() {
+ return millis;
+ }
+
+ /**
+ * Sets the time when this event occurred, in milliseconds since 1970.
+ *
+ * @param millis
+ * the time when this event occurred, in milliseconds since 1970.
+ * @since Android 1.0
+ */
+ public void setMillis(long millis) {
+ this.millis = millis;
+ }
+
+ /**
+ * Gets the parameters.
+ *
+ * @return the array of parameters or {@code null} if there are no
+ * parameters.
+ * @since Android 1.0
+ */
+ public Object[] getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Sets the parameters.
+ *
+ * @param parameters
+ * the array of parameters to set, may be {@code null}.
+ * @since Android 1.0
+ */
+ public void setParameters(Object[] parameters) {
+ this.parameters = parameters;
+ }
+
+ /**
+ * Gets the resource bundle used to localize the raw message during
+ * formatting.
+ *
+ * @return the associated resource bundle, {@code null} if none is
+ * available or the message is not localizable.
+ * @since Android 1.0
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /**
+ * Sets the resource bundle.
+ *
+ * @param resourceBundle
+ * the resource bundle to set, may be {@code null}.
+ * @since Android 1.0
+ */
+ public void setResourceBundle(ResourceBundle resourceBundle) {
+ this.resourceBundle = resourceBundle;
+ }
+
+ /**
+ * Gets the name of the resource bundle.
+ *
+ * @return the name of the resource bundle, {@code null} if none is
+ * available or the message is not localizable.
+ * @since Android 1.0
+ */
+ public String getResourceBundleName() {
+ return resourceBundleName;
+ }
+
+ /**
+ * Sets the name of the resource bundle.
+ *
+ * @param resourceBundleName
+ * the name of the resource bundle to set.
+ * @since Android 1.0
+ */
+ public void setResourceBundleName(String resourceBundleName) {
+ this.resourceBundleName = resourceBundleName;
+ }
+
+ /**
+ * Gets the sequence number.
+ *
+ * @return the sequence number.
+ * @since Android 1.0
+ */
+ public long getSequenceNumber() {
+ return sequenceNumber;
+ }
+
+ /**
+ * Sets the sequence number. It is usually not necessary to call this method
+ * to change the sequence number because the number is allocated when this
+ * instance is constructed.
+ *
+ * @param sequenceNumber
+ * the sequence number to set.
+ * @since Android 1.0
+ */
+ public void setSequenceNumber(long sequenceNumber) {
+ this.sequenceNumber = sequenceNumber;
+ }
+
+ /**
+ * Gets the name of the class that is the source of this log record. This
+ * information can be changed, may be {@code null} and is untrusted.
+ *
+ * @return the name of the source class of this log record (possiblity {@code null})
+ * @since Android 1.0
+ */
+ public String getSourceClassName() {
+ initSource();
+ return sourceClassName;
+ }
+
+ /*
+ * Init the sourceClass and sourceMethod fields.
+ */
+ private void initSource() {
+ if (!sourceInited) {
+ StackTraceElement[] elements = (new Throwable()).getStackTrace();
+ int i = 0;
+ String current = null;
+ FINDLOG: for (; i < elements.length; i++) {
+ current = elements[i].getClassName();
+ if (current.equals(Logger.class.getName())) {
+ break FINDLOG;
+ }
+ }
+ while(++i<elements.length && elements[i].getClassName().equals(current)) {
+ // do nothing
+ }
+ if (i < elements.length) {
+ this.sourceClassName = elements[i].getClassName();
+ this.sourceMethodName = elements[i].getMethodName();
+ }
+ sourceInited = true;
+ }
+ }
+
+ /**
+ * Sets the name of the class that is the source of this log record.
+ *
+ * @param sourceClassName
+ * the name of the source class of this log record, may be
+ * {@code null}.
+ * @since Android 1.0
+ */
+ public void setSourceClassName(String sourceClassName) {
+ sourceInited = true;
+ this.sourceClassName = sourceClassName;
+ }
+
+ /**
+ * Gets the name of the method that is the source of this log record.
+ *
+ * @return the name of the source method of this log record.
+ * @since Android 1.0
+ */
+ public String getSourceMethodName() {
+ initSource();
+ return sourceMethodName;
+ }
+
+ /**
+ * Sets the name of the method that is the source of this log record.
+ *
+ * @param sourceMethodName
+ * the name of the source method of this log record, may be
+ * {@code null}.
+ * @since Android 1.0
+ */
+ public void setSourceMethodName(String sourceMethodName) {
+ sourceInited = true;
+ this.sourceMethodName = sourceMethodName;
+ }
+
+ /**
+ * Gets a unique ID of the thread originating the log record. Every thread
+ * becomes a different ID.
+ * <p>
+ * Notice : the ID doesn't necessary map the OS thread ID
+ * </p>
+ *
+ * @return the ID of the thread originating this log record.
+ * @since Android 1.0
+ */
+ public int getThreadID() {
+ return threadID;
+ }
+
+ /**
+ * Sets the ID of the thread originating this log record.
+ *
+ * @param threadID
+ * the new ID of the thread originating this log record.
+ * @since Android 1.0
+ */
+ public void setThreadID(int threadID) {
+ this.threadID = threadID;
+ }
+
+ /**
+ * Gets the {@code Throwable} object associated with this log record.
+ *
+ * @return the {@code Throwable} object associated with this log record.
+ * @since Android 1.0
+ */
+ public Throwable getThrown() {
+ return thrown;
+ }
+
+ /**
+ * Sets the {@code Throwable} object associated with this log record.
+ *
+ * @param thrown
+ * the new {@code Throwable} object to associate with this log
+ * record.
+ * @since Android 1.0
+ */
+ public void setThrown(Throwable thrown) {
+ this.thrown = thrown;
+ }
+
+ /*
+ * Customized serialization.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeByte(MAJOR);
+ out.writeByte(MINOR);
+ if (null == parameters) {
+ out.writeInt(-1);
+ } else {
+ out.writeInt(parameters.length);
+ for (Object element : parameters) {
+ out.writeObject(null == element ? null : element.toString());
+ }
+ }
+ }
+
+ /*
+ * Customized deserialization.
+ */
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ byte major = in.readByte();
+ byte minor = in.readByte();
+ //only check MAJOR version
+ if (major != MAJOR) {
+ // logging.5=Different version - {0}.{1}
+ throw new IOException(Messages.getString("logging.5", major, minor)); //$NON-NLS-1$
+ }
+
+ int length = in.readInt();
+ if (length >= 0) {
+ parameters = new Object[length];
+ for (int i = 0; i < parameters.length; i++) {
+ parameters[i] = in.readObject();
+ }
+ }
+ if (null != resourceBundleName) {
+ try {
+ resourceBundle = Logger.loadResourceBundle(resourceBundleName);
+ } catch (MissingResourceException e) {
+ // Cannot find the specified resource bundle
+ resourceBundle = null;
+ }
+ }
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/Logger.java b/logging/src/main/java/java/util/logging/Logger.java
new file mode 100644
index 0000000..cd88ca0
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/Logger.java
@@ -0,0 +1,1495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * Loggers are used to log records to certain outputs, including file, console,
+ * etc. They use various handlers to actually do the output-dependent
+ * operations.
+ * <p>
+ * Client applications can get named loggers by calling the {@code getLogger}
+ * methods. They can also get anonymous loggers by calling the
+ * {@code getAnonymousLogger} methods. Named loggers are organized in a
+ * namespace hierarchy managed by a log manager. The naming convention is
+ * usually the same as java package's naming convention, that is using
+ * dot-separated strings. Anonymous loggers do not belong to any namespace.
+ * </p>
+ * <p>
+ * Loggers "inherit" log level setting from their parent if their own level is
+ * set to {@code null}. This is also true for the resource bundle. The logger's
+ * resource bundle is used to localize the log messages if no resource bundle
+ * name is given when a log method is called. If {@code getUseParentHandlers()}
+ * returns {@code true}, loggers also inherit their parent's handlers. In this
+ * context, "inherit" only means that "behavior" is inherited. The internal
+ * field values will not change, for example, {@code getLevel()} still returns
+ * {@code null}.
+ * </p>
+ * <p>
+ * When loading a given resource bundle, the logger first tries to use the
+ * context classloader. If that fails, it tries the system classloader. And if
+ * that still fails, it searches up the class stack and uses each class's
+ * classloader to try to locate the resource bundle.
+ * </p>
+ * <p>
+ * Some log methods accept log requests that do not specify the source class and
+ * source method. In these cases, the logging framework will automatically infer
+ * the calling class and method, but this is not guaranteed to be accurate.
+ * </p>
+ * <p>
+ * Once a {@code LogRecord} object has been passed into the logging framework,
+ * it is owned by the logging framework and the client applications should not
+ * use it any longer.
+ * </p>
+ * <p>
+ * All methods of this class are thread-safe.
+ * </p>
+ *
+ * @see LogManager
+ * @since Android 1.0
+ */
+public class Logger {
+
+ /**
+ * The global logger is provided as convenience for casual use.
+ *
+ * @since Android 1.0
+ */
+ public final static Logger global = new Logger("global", null); //$NON-NLS-1$
+
+ // the name of this logger
+ private volatile String name;
+
+ // the parent logger of this logger
+ private Logger parent;
+
+ // the logging level of this logger
+ private volatile Level levelObjVal;
+
+ // the logging level as int of this logger
+ private volatile int levelIntVal;
+
+ // the filter
+ private Filter filter;
+
+ // the name of the resource bundle used to localize logging messages
+ private String resBundleName;
+
+ // the loaded resource bundle according to the specified name
+ private ResourceBundle resBundle;
+
+ // the handlers attached to this logger
+ private List<Handler> handlers;
+
+ /*
+ * flag indicating whether to notify parent's handlers on receiving a log
+ * request
+ */
+ private boolean notifyParentHandlers;
+
+ // flag indicating whether this logger is named or anonymous
+ private boolean isNamed;
+
+ private List<Logger> childs;
+
+ private LogManager manager;
+
+ // BEGIN android-changed
+ private volatile boolean handlerInited;
+ // END android-changed
+
+
+ /*
+ * -------------------------------------------------------------------
+ * Constructors
+ * -------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a {@code Logger} object with the supplied name and resource
+ * bundle name; {@code notifiyParentHandlers} is set to {@code true}.
+ * <p>
+ * Notice : Loggers use a naming hierarchy. Thus "z.x.y" is a child of "z.x".
+ * </p>
+ *
+ * @param name
+ * the name of this logger, may be {@code null} for anonymous
+ * loggers.
+ * @param resourceBundleName
+ * the name of the resource bundle used to localize logging
+ * messages, may be {@code null}.
+ * @throws MissingResourceException
+ * if the specified resource bundle can not be loaded.
+ * @since Android 1.0
+ */
+ protected Logger(String name, String resourceBundleName) {
+ // try to load the specified resource bundle first
+ if (null == resourceBundleName) {
+ this.resBundleName = null;
+ this.resBundle = null;
+ } else {
+ this.resBundle = loadResourceBundle(resourceBundleName);
+ this.resBundleName = resourceBundleName;
+ }
+ this.name = name;
+ this.parent = null;
+ this.filter = null;
+ this.childs = new ArrayList<Logger>();
+ this.notifyParentHandlers = true;
+ // any logger is not anonymous by default
+ this.isNamed = true;
+
+ //-- 'null' means that level will be inherited from parent (see getLevel)
+ //-- Level.INFO is default level if we don't set it. It will be
+ //-- changed to parent level or to configLevel after adding to the
+ //-- family tree. As of this, actually, setting to Level.INFO is
+ //-- not needed here.
+ this.levelObjVal = null;
+ this.levelIntVal = Level.INFO.intValue();
+ }
+
+ //-- should be called under the lm lock
+ private void setLevelImpl(Level newLevel) {
+ // update levels for the whole hierarchy
+ int oldVal = levelIntVal;
+ levelObjVal = newLevel;
+ if (null == newLevel) {
+ levelIntVal = null != parent
+ ? parent.levelIntVal
+ : Level.INFO.intValue();
+ } else {
+ levelIntVal = newLevel.intValue();
+ }
+ if (oldVal != levelIntVal) {
+ forceChildsToInherit();
+ }
+ }
+
+ //-- should be called under the lm lock
+ private void forceChildsToInherit() {
+ for (Logger child : childs) {
+ if (null == child.levelObjVal) { // should inherit
+ child.setLevelImpl(null);
+ }
+ }
+ }
+
+ /*
+ * -------------------------------------------------------------------
+ * Methods
+ * -------------------------------------------------------------------
+ */
+
+ /**
+ * Load the specified resource bundle, use privileged code.
+ *
+ * @param resourceBundleName
+ * the name of the resource bundle to load, cannot be {@code null}.
+ * @return the loaded resource bundle.
+ * @throws MissingResourceException
+ * if the specified resource bundle can not be loaded.
+ */
+ static ResourceBundle loadResourceBundle(String resourceBundleName) {
+ // try context class loader to load the resource
+ ClassLoader cl = AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ if (null != cl) {
+ try {
+ return ResourceBundle.getBundle(resourceBundleName, Locale
+ .getDefault(), cl);
+ } catch (MissingResourceException e) {
+ // Failed to load using context classloader, ignore
+ }
+ }
+ // try system class loader to load the resource
+ cl = AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return ClassLoader.getSystemClassLoader();
+ }
+ });
+ if (null != cl) {
+ try {
+ return ResourceBundle.getBundle(resourceBundleName, Locale
+ .getDefault(), cl);
+ } catch (MissingResourceException e) {
+ // Failed to load using system classloader, ignore
+ }
+ }
+ // try all class loaders up the class stack
+ final Class<?>[] classes = AccessController
+ .doPrivileged(new PrivilegedAction<Class<?>[]>() {
+ public Class<?>[] run() {
+ return (new PrivateSecurityManager())
+ .privateGetClassContext();
+ }
+ });
+ // the first class, which is PrivateSecurityManager, is skipped
+ for (int i = 1; i < classes.length; i++) {
+ final int index = i;
+ try {
+ cl = AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return classes[index].getClassLoader();
+ }
+ });
+ if (null == cl) {
+ continue;
+ }
+ return ResourceBundle.getBundle(resourceBundleName, Locale
+ .getDefault(), cl);
+ } catch (MissingResourceException e) {
+ // Failed to load using the current class's classloader, ignore
+ }
+ }
+ // logging.8=Failed to load the specified resource bundle "{0}".
+ throw new MissingResourceException(Messages.getString("logging.8", //$NON-NLS-1$
+ resourceBundleName), resourceBundleName, null);
+ }
+
+ /**
+ * Gets an anonymous logger to use internally in a thread. Anonymous loggers
+ * are not registered in the log manager's namespace. No security checks
+ * will be performed when updating an anonymous logger's control settings.
+ * <p>
+ * The anonymous loggers' parent is set to be the root logger. This way it
+ * inherits the default logging level and handlers from the root logger.
+ * </p>
+ *
+ * @return a new instance of anonymous logger.
+ * @since Android 1.0
+ */
+ public static Logger getAnonymousLogger() {
+ return getAnonymousLogger(null);
+ }
+
+ /**
+ * Gets an anonymous logger to use internally in a thread. Anonymous loggers
+ * are not registered in the log manager's namespace. No security checks
+ * will be performed when updating an anonymous logger's control settings.
+ * <p>
+ * The anonymous loggers' parent is set to be the root logger. This way it
+ * inherits default logging level and handlers from the root logger.
+ * </p>
+ *
+ * @param resourceBundleName
+ * the name of the resource bundle used to localize log messages.
+ * @return a new instance of anonymous logger.
+ * @throws MissingResourceException
+ * if the specified resource bundle can not be loaded.
+ * @since Android 1.0
+ */
+ public static Logger getAnonymousLogger(String resourceBundleName) {
+ final Logger l = new Logger(null, resourceBundleName);
+ l.isNamed = false;
+ l.internalSetParent(LogManager.getLogManager().getLogger("")); //$NON-NLS-1$
+ return l;
+ }
+
+ /*
+ * Check whether the same resource bundle has been specified.
+ * Synchronize to ensure the consistency between resource bundle
+ * and its name.
+ */
+ private static void updateResourceBundle(Logger l, String resourceBundleName) {
+ synchronized (l) {
+ if (null == l.getResourceBundleName()) {
+ if(null == resourceBundleName){
+ return;
+ }
+ /*
+ * load the resource bundle if none is specified
+ * before
+ */
+ l.resBundle = loadResourceBundle(resourceBundleName);
+ l.resBundleName = resourceBundleName;
+ } else if (!l.getResourceBundleName().equals(resourceBundleName)) {
+ /*
+ * throw exception if the specified resource bundles
+ * are inconsistent with each other, i.e., different
+ * names
+ */
+ // logging.9=The specified resource bundle name "{0}" is
+ // inconsistent with the existing one "{1}".
+ throw new IllegalArgumentException(Messages.getString(
+ "logging.9", //$NON-NLS-1$
+ resourceBundleName, l.getResourceBundleName()));
+ }
+ }
+ }
+
+ /*
+ * Gets a named logger associated with the supplied resource bundle. This
+ * method accepts null resource bundle name. The method body is synchronized
+ * on the instance of the LogManager to insure the consistency of the whole
+ * operation.
+ */
+ private static Logger getLoggerWithRes(String name,
+ String resourceBundleName, boolean hasResourceName) {
+ LogManager man = LogManager.getLogManager();
+ Logger l = null;
+ synchronized (man) {
+ // Try to find an existing logger with the specified name
+ l = man.getLogger(name);
+ // If no existing logger with the same name, create a new one
+ if (null == l) {
+ l = new Logger(name, resourceBundleName);
+ man.addLogger(l);
+ return l;
+ }
+ }
+ if (hasResourceName) {
+ updateResourceBundle(l, resourceBundleName);
+ }
+ return l;
+ }
+
+ /**
+ * Gets a named logger. The returned logger may already exist or may be
+ * newly created. In the latter case, its level will be set to the
+ * configured level according to the {@code LogManager}'s properties.
+ *
+ * @param name
+ * the name of the logger to get, cannot be {@code null}.
+ * @return a named logger.
+ * @since Android 1.0
+ */
+ public static Logger getLogger(String name) {
+ return getLoggerWithRes(name, null, false);
+ }
+
+ /**
+ * Gets a named logger associated with the supplied resource bundle. The
+ * resource bundle will be used to localize logging messages.
+ *
+ * @param name
+ * the name of the logger to get, cannot be {@code null}.
+ * @param resourceBundleName
+ * the name of the resource bundle, may be {@code null}.
+ * @throws IllegalArgumentException
+ * if the logger identified by {@code name} is associated with a
+ * resource bundle and its name is not equal to
+ * {@code resourceBundleName}.
+ * @throws MissingResourceException
+ * if the name of the resource bundle cannot be found.
+ * @return a named logger.
+ * @since Android 1.0
+ */
+ public static Logger getLogger(String name, String resourceBundleName) {
+ return getLoggerWithRes(name, resourceBundleName, true);
+ }
+
+ /**
+ * Adds a handler to this logger. The {@code name} will be fed with log
+ * records received by this logger.
+ *
+ * @param handler
+ * the handler object to add, cannot be {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void addHandler(Handler handler) {
+ if (null == handler) {
+ // logging.A=The 'handler' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.A")); //$NON-NLS-1$
+ }
+ // Anonymous loggers can always add handlers
+ if (this.isNamed) {
+ LogManager.getLogManager().checkAccess();
+ }
+ initHandler();
+ synchronized(this){
+ this.handlers.add(handler);
+ }
+ }
+
+ /*
+ * Be cautious to avoid deadlock when using this method, it gets lock on manager
+ * at first, and then gets lock on this Logger, so any methods should not hold
+ * lock on this Logger when invoking this method.
+ */
+ private void initHandler() {
+ if(!handlerInited){
+ synchronized (this) {
+ if (!handlerInited) {
+ // BEGIN android-added
+ /*
+ * Force LogManager to be initialized, since its
+ * class init code performs necessary one-time setup.
+ */
+ LogManager.getLogManager();
+ // END android-added
+ if (handlers == null) {
+ handlers = new ArrayList<Handler>();
+ }
+ if (manager == null) {
+ return;
+ }
+
+ String handlerStr = manager
+ .getProperty("".equals(name) ? "handlers" : name + ".handlers"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (null == handlerStr) {
+ return;
+ }
+ StringTokenizer st = new StringTokenizer(handlerStr, " "); //$NON-NLS-1$
+ while (st.hasMoreTokens()) {
+ String handlerName = st.nextToken();
+ // BEGIN android-changed
+ // deal with non-existing handler
+ try {
+ Handler handler = (Handler) LogManager
+ .getInstanceByClass(handlerName);
+ handlers.add(handler);
+ String level = manager.getProperty(handlerName
+ + ".level"); //$NON-NLS-1$
+ if (null != level) {
+ handler.setLevel(Level.parse(level));
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ // END android-changed
+ }
+ handlerInited = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets all the handlers associated with this logger.
+ *
+ * @return an array of all the handlers associated with this logger.
+ * @since Android 1.0
+ */
+ public Handler[] getHandlers() {
+ initHandler();
+ synchronized(this){
+ return handlers.toArray(new Handler[handlers.size()]);
+ }
+ }
+
+ /**
+ * Removes a handler from this logger. If the specified handler does not
+ * exist then this method has no effect.
+ *
+ * @param handler
+ * the handler to be removed.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void removeHandler(Handler handler) {
+ // Anonymous loggers can always remove handlers
+ if (this.isNamed) {
+ LogManager.getLogManager().checkAccess();
+ }
+ if (null == handler) {
+ return;
+ }
+ initHandler();
+ synchronized(this){
+ this.handlers.remove(handler);
+ }
+ }
+
+ /**
+ * Gets the filter used by this logger.
+ *
+ * @return the filter used by this logger, may be {@code null}.
+ * @since Android 1.0
+ */
+ public Filter getFilter() {
+ return this.filter;
+ }
+
+ /**
+ * Sets the filter used by this logger.
+ *
+ * @param newFilter
+ * the filter to set, may be {@code null}.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setFilter(Filter newFilter) {
+ // Anonymous loggers can always set the filter
+ if (this.isNamed) {
+ LogManager.getLogManager().checkAccess();
+ }
+ filter = newFilter;
+ }
+
+ /**
+ * Gets the logging level of this logger. A {@code null} level indicates
+ * that this logger inherits its parent's level.
+ *
+ * @return the logging level of this logger.
+ * @since Android 1.0
+ */
+ public Level getLevel() {
+ return levelObjVal;
+ }
+
+ /**
+ * Sets the logging level for this logger. A {@code null} level indicates
+ * that this logger will inherit its parent's level.
+ *
+ * @param newLevel
+ * the logging level to set.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setLevel(Level newLevel) {
+ // Anonymous loggers can always set the level
+ if (this.isNamed) {
+ LogManager.getLogManager().checkAccess();
+ }
+ synchronized (LogManager.getLogManager()) {
+ setLevelImpl(newLevel);
+ }
+ }
+
+ /**
+ * Gets the flag which indicates whether to use the handlers of this
+ * logger's parent to publish incoming log records, potentially recursively
+ * up the namespace.
+ *
+ * @return {@code true} if set to use parent's handlers, {@code false}
+ * otherwise.
+ * @since Android 1.0
+ */
+ public boolean getUseParentHandlers() {
+ return this.notifyParentHandlers;
+ }
+
+ /**
+ * Sets the flag which indicates whether to use the handlers of this
+ * logger's parent, potentially recursively up the namespace.
+ *
+ * @param notifyParentHandlers
+ * the new flag indicating whether to use the parent's handlers.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setUseParentHandlers(boolean notifyParentHandlers) {
+ // Anonymous loggers can always set the useParentHandlers flag
+ if (this.isNamed) {
+ LogManager.getLogManager().checkAccess();
+ }
+ this.notifyParentHandlers = notifyParentHandlers;
+ }
+
+ /**
+ * Gets the nearest parent of this logger in the namespace, a {@code null}
+ * value will be returned if called on the root logger.
+ *
+ * @return the parent of this logger in the namespace.
+ * @since Android 1.0
+ */
+ public Logger getParent() {
+ return parent;
+ }
+
+ /**
+ * Sets the parent of this logger in the namespace. This method should
+ * usually be used by the {@code LogManager} object only. This method does
+ * not check security.
+ *
+ * @param newParent
+ * the parent logger to set.
+ * @since Android 1.0
+ */
+ void internalSetParent(Logger newParent) {
+ //All hierarchy related modifications should get LogManager lock at first
+ synchronized(LogManager.getLogManager()){
+ parent = newParent;
+ // -- update level after setting a parent.
+ // -- if level == null we should inherit the parent's level
+ if (null == levelObjVal) {
+ setLevelImpl(levelObjVal);
+ }
+ newParent.addChild(this);
+ }
+ }
+
+ /**
+ * Sets the parent of this logger in the namespace. This method should be
+ * used by the {@code LogManager} object only.
+ *
+ * @param parent
+ * the parent logger to set.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @since Android 1.0
+ */
+ public void setParent(Logger parent) {
+ if (null == parent) {
+ // logging.B=The 'parent' parameter is null.
+ throw new NullPointerException(Messages.getString("logging.B")); //$NON-NLS-1$
+ }
+ // even anonymous loggers are checked
+ LogManager.getLogManager().checkAccess();
+ internalSetParent(parent);
+ }
+
+ final void addChild(Logger logger) {
+ childs.add(logger);
+ }
+
+ final void removeChild(Logger child) {
+ childs.remove(child);
+ }
+
+
+ /**
+ * Gets the name of this logger, {@code null} for anonymous loggers.
+ *
+ * @return the name of this logger.
+ * @since Android 1.0
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Gets the loaded resource bundle used by this logger to localize logging
+ * messages. If the value is {@code null}, the parent's resource bundle will be
+ * inherited.
+ *
+ * @return the loaded resource bundle used by this logger.
+ * @since Android 1.0
+ */
+ public ResourceBundle getResourceBundle() {
+ return this.resBundle;
+ }
+
+ /**
+ * Gets the name of the loaded resource bundle used by this logger to
+ * localize logging messages. If the value is {@code null}, the parent's resource
+ * bundle name will be inherited.
+ *
+ * @return the name of the loaded resource bundle used by this logger.
+ * @since Android 1.0
+ */
+ public String getResourceBundleName() {
+ return this.resBundleName;
+ }
+
+ /**
+ * This method is for compatibility. Tests written to the reference
+ * implementation API imply that the isLoggable() method is not called
+ * directly. This behavior is important because subclass may override
+ * isLoggable() method, so that affect the result of log methods.
+ */
+ private boolean internalIsLoggable(Level l) {
+ int effectiveLevel = levelIntVal;
+ if (effectiveLevel == Level.OFF.intValue()) {
+ // always return false if the effective level is off
+ return false;
+ }
+ return l.intValue() >= effectiveLevel;
+ }
+
+ /**
+ * Determines whether this logger will actually log messages of the
+ * specified level. The effective level used to do the determination may be
+ * inherited from its parent. The default level is {@code Level.INFO}.
+ *
+ * @param l
+ * the level to check.
+ * @return {@code true} if this logger will actually log this level,
+ * otherwise {@code false}.
+ * @since Android 1.0
+ */
+ public boolean isLoggable(Level l) {
+ return internalIsLoggable(l);
+ }
+
+ /*
+ * Sets the resource bundle and its name for a supplied LogRecord object.
+ * This method first tries to use this logger's resource bundle if any,
+ * otherwise try to inherit from this logger's parent, recursively up the
+ * namespace. Synchronize to ensure the consistency between resource bundle
+ * and its name.
+ */
+ private void setResourceBundle(LogRecord record) {
+ if (null != this.resBundleName) {
+ record.setResourceBundle(this.resBundle);
+ record.setResourceBundleName(this.resBundleName);
+ } else {
+ Logger anyParent = this.parent;
+ // no need to synchronize here, because if resBundleName
+ // is not null, there is no chance to modify it
+ while (null != anyParent) {
+ if (null != anyParent.resBundleName) {
+ record.setResourceBundle(anyParent.resBundle);
+ record.setResourceBundleName(anyParent.resBundleName);
+ return;
+ }
+ anyParent = anyParent.parent;
+ }
+ }
+ }
+
+ /**
+ * Logs a message indicating that a method has been entered. A log record
+ * with log level {@code Level.FINER}, log message "ENTRY", the specified
+ * source class name and source method name is submitted for logging.
+ *
+ * @param sourceClass
+ * the calling class name.
+ * @param sourceMethod
+ * the method name.
+ * @since Android 1.0
+ */
+ public void entering(String sourceClass, String sourceMethod) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, "ENTRY"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message indicating that a method has been entered. A log record
+ * with log level {@code Level.FINER}, log message "ENTRY", the specified
+ * source class name, source method name and one parameter is submitted for
+ * logging.
+ *
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param param
+ * the parameter for the method call.
+ * @since Android 1.0
+ */
+ public void entering(String sourceClass, String sourceMethod, Object param) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, "ENTRY" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message indicating that a method has been entered. A log record
+ * with log level {@code Level.FINER}, log message "ENTRY", the specified
+ * source class name, source method name and array of parameters is
+ * submitted for logging.
+ *
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param params
+ * an array of parameters for the method call.
+ * @since Android 1.0
+ */
+ public void entering(String sourceClass, String sourceMethod,
+ Object[] params) {
+ if (internalIsLoggable(Level.FINER)) {
+ String msg = "ENTRY"; //$NON-NLS-1$
+ if (null != params) {
+ StringBuilder msgBuffer = new StringBuilder("ENTRY"); //$NON-NLS-1$
+ for (int i = 0; i < params.length; i++) {
+ msgBuffer.append(" {" + i + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ msg = msgBuffer.toString();
+ }
+ LogRecord record = new LogRecord(Level.FINER, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message indicating that a method is exited. A log record with log
+ * level {@code Level.FINER}, log message "RETURN", the specified source
+ * class name and source method name is submitted for logging.
+ *
+ * @param sourceClass
+ * the calling class name.
+ * @param sourceMethod
+ * the method name.
+ * @since Android 1.0
+ */
+ public void exiting(String sourceClass, String sourceMethod) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, "RETURN"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message indicating that a method is exited. A log record with log
+ * level {@code Level.FINER}, log message "RETURN", the specified source
+ * class name, source method name and return value is submitted for logging.
+ *
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param result
+ * the return value of the method call.
+ * @since Android 1.0
+ */
+ public void exiting(String sourceClass, String sourceMethod, Object result) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, "RETURN" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { result });
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message indicating that an exception is thrown. A log record with
+ * log level {@code Level.FINER}, log message "THROW", the specified source
+ * class name, source method name and the {@code Throwable} object is
+ * submitted for logging.
+ *
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param thrown
+ * the {@code Throwable} object.
+ * @since Android 1.0
+ */
+ public void throwing(String sourceClass, String sourceMethod,
+ Throwable thrown) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, "THROW"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.SEVERE}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void severe(String msg) {
+ if (internalIsLoggable(Level.SEVERE)) {
+ LogRecord record = new LogRecord(Level.SEVERE, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.WARNING}; the message is
+ * transmitted to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void warning(String msg) {
+ if (internalIsLoggable(Level.WARNING)) {
+ LogRecord record = new LogRecord(Level.WARNING, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.INFO}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void info(String msg) {
+ if (internalIsLoggable(Level.INFO)) {
+ LogRecord record = new LogRecord(Level.INFO, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.CONFIG}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void config(String msg) {
+ if (internalIsLoggable(Level.CONFIG)) {
+ LogRecord record = new LogRecord(Level.CONFIG, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.FINE}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void fine(String msg) {
+ if (internalIsLoggable(Level.FINE)) {
+ LogRecord record = new LogRecord(Level.FINE, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.FINER}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void finer(String msg) {
+ if (internalIsLoggable(Level.FINER)) {
+ LogRecord record = new LogRecord(Level.FINER, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of level {@code Level.FINEST}; the message is transmitted
+ * to all subscribed handlers.
+ *
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void finest(String msg) {
+ if (internalIsLoggable(Level.FINEST)) {
+ LogRecord record = new LogRecord(Level.FINEST, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the specified level. The message is transmitted to all
+ * subscribed handlers.
+ *
+ * @param logLevel
+ * the level of the specified message.
+ * @param msg
+ * the message to log.
+ * @since Android 1.0
+ */
+ public void log(Level logLevel, String msg) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the specified level with the supplied parameter. The
+ * message is then transmitted to all subscribed handlers.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param msg
+ * the message to log.
+ * @param param
+ * the parameter associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void log(Level logLevel, String msg, Object param) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the specified level with the supplied parameter array.
+ * The message is then transmitted to all subscribed handlers.
+ *
+ * @param logLevel
+ * the level of the given message
+ * @param msg
+ * the message to log.
+ * @param params
+ * the parameter array associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void log(Level logLevel, String msg, Object[] params) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the specified level with the supplied {@code Throwable}
+ * object. The message is then transmitted to all subscribed handlers.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param msg
+ * the message to log.
+ * @param thrown
+ * the {@code Throwable} object associated with the event that is
+ * logged.
+ * @since Android 1.0
+ */
+ public void log(Level logLevel, String msg, Throwable thrown) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a given log record. Only records with a logging level that is equal
+ * or greater than this logger's level will be submitted to this logger's
+ * handlers for logging. If {@code getUseParentHandlers()} returns {@code
+ * true}, the log record will also be submitted to the handlers of this
+ * logger's parent, potentially recursively up the namespace.
+ * <p>
+ * Since all other log methods call this method to actually perform the
+ * logging action, subclasses of this class can override this method to
+ * catch all logging activities.
+ * </p>
+ *
+ * @param record
+ * the log record to be logged.
+ * @since Android 1.0
+ */
+ public void log(LogRecord record) {
+ if (internalIsLoggable(record.getLevel())) {
+ // apply the filter if any
+ Filter f = filter;
+ if (null != f && !f.isLoggable(record)) {
+ return;
+ }
+ initHandler();
+ /*
+ * call the handlers of this logger, throw any exception that
+ * occurs
+ */
+ Handler[] allHandlers = getHandlers();
+ for (Handler element : allHandlers) {
+ element.publish(record);
+ }
+ // call the parent's handlers if set useParentHandlers
+ Logger temp = this;
+ Logger theParent = temp.parent;
+ while (theParent != null && temp.getUseParentHandlers()) {
+ Handler[] ha = theParent.getHandlers();
+ for (Handler element : ha) {
+ element.publish(record);
+ }
+ temp = theParent;
+ theParent = temp.parent;
+ }
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name
+ * and source method name.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param msg
+ * the message to be logged.
+ * @since Android 1.0
+ */
+ public void logp(Level logLevel, String sourceClass, String sourceMethod,
+ String msg) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and parameter.
+ *
+ * @param logLevel
+ * the level of the given message
+ * @param sourceClass
+ * the source class name
+ * @param sourceMethod
+ * the source method name
+ * @param msg
+ * the message to be logged
+ * @param param
+ * the parameter associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void logp(Level logLevel, String sourceClass, String sourceMethod,
+ String msg, Object param) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and parameter array.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param msg
+ * the message to be logged.
+ * @param params
+ * the parameter array associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void logp(Level logLevel, String sourceClass, String sourceMethod,
+ String msg, Object[] params) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and {@code Throwable} object.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param msg
+ * the message to be logged.
+ * @param thrown
+ * the {@code Throwable} object.
+ * @since Android 1.0
+ */
+ public void logp(Level logLevel, String sourceClass, String sourceMethod,
+ String msg, Throwable thrown) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name
+ * and source method name, using the given resource bundle to localize the
+ * message. If {@code bundleName} is null, the empty string or not valid then
+ * the message is not localized.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param bundleName
+ * the name of the resource bundle used to localize the message.
+ * @param msg
+ * the message to be logged.
+ * @since Android 1.0
+ */
+ public void logrb(Level logLevel, String sourceClass, String sourceMethod,
+ String bundleName, String msg) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (null != bundleName) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and parameter, using the given resource bundle to
+ * localize the message. If {@code bundleName} is null, the empty string
+ * or not valid then the message is not localized.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param bundleName
+ * the name of the resource bundle used to localize the message.
+ * @param msg
+ * the message to be logged.
+ * @param param
+ * the parameter associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void logrb(Level logLevel, String sourceClass, String sourceMethod,
+ String bundleName, String msg, Object param) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (null != bundleName) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and parameter array, using the given resource bundle
+ * to localize the message. If {@code bundleName} is null, the empty string
+ * or not valid then the message is not localized.
+ *
+ * @param logLevel
+ * the level of the given message.
+ * @param sourceClass
+ * the source class name.
+ * @param sourceMethod
+ * the source method name.
+ * @param bundleName
+ * the name of the resource bundle used to localize the message.
+ * @param msg
+ * the message to be logged.
+ * @param params
+ * the parameter array associated with the event that is logged.
+ * @since Android 1.0
+ */
+ public void logrb(Level logLevel, String sourceClass, String sourceMethod,
+ String bundleName, String msg, Object[] params) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (null != bundleName) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ log(record);
+ }
+ }
+
+ /**
+ * Logs a message of the given level with the specified source class name,
+ * source method name and {@code Throwable} object, using the given resource
+ * bundle to localize the message. If {@code bundleName} is null, the empty
+ * string or not valid then the message is not localized.
+ *
+ * @param logLevel
+ * the level of the given message
+ * @param sourceClass
+ * the source class name
+ * @param sourceMethod
+ * the source method name
+ * @param bundleName
+ * the name of the resource bundle used to localize the message.
+ * @param msg
+ * the message to be logged.
+ * @param thrown
+ * the {@code Throwable} object.
+ * @since Android 1.0
+ */
+ public void logrb(Level logLevel, String sourceClass, String sourceMethod,
+ String bundleName, String msg, Throwable thrown) {
+ if (internalIsLoggable(logLevel)) {
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (null != bundleName) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ log(record);
+ }
+ }
+
+ /*
+ * This security manager is used to access the class context.
+ */
+ static class PrivateSecurityManager extends SecurityManager {
+ public Class<?>[] privateGetClassContext() {
+ return super.getClassContext();
+ }
+ }
+
+ void setManager(LogManager manager) {
+ if(this.manager != manager){
+ this.manager = manager;
+ handlerInited = false;
+ }
+ //init level here, but let handlers be for lazy loading
+ String configedLevel = manager.getProperty(name+ ".level"); //$NON-NLS-1$
+ if (null != configedLevel) {
+ try {
+ setLevel(Level.parse(configedLevel));
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+ }
+ }
+
+ synchronized void reset() {
+ levelObjVal = null;
+ levelIntVal = Level.INFO.intValue();
+ if(handlers != null){
+ for (Handler element : handlers) {
+ // close all handlers, when unknown exceptions happen,
+ // ignore them and go on
+ try {
+ element.close();
+ } catch (Exception e) {
+ // Ignored.
+ }
+ }
+ handlers.clear();
+ }
+ handlerInited = false;
+ }
+}
+
diff --git a/logging/src/main/java/java/util/logging/LoggingMXBean.java b/logging/src/main/java/java/util/logging/LoggingMXBean.java
new file mode 100644
index 0000000..f6b49a6
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/LoggingMXBean.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.util.List;
+
+/**
+ * {@code LoggingMXBean} is the management interface for the logging sub-system.
+ * <p>
+ * The ObjectName for identifying the {@code LoggingMXBean} in a bean server is
+ * {@link LogManager#LOGGING_MXBEAN_NAME}.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public interface LoggingMXBean {
+ /**
+ * Gets the string value of the logging level of a logger. An empty string
+ * is returned when the logger's level is defined by its parent. A
+ * {@code null} is returned if the specified logger does not exist.
+ *
+ * @param loggerName
+ * the name of the logger lookup.
+ * @return a {@code String} if the logger is found, otherwise {@code null}.
+ * @see Level#getName()
+ * @since Android 1.0
+ */
+ String getLoggerLevel(String loggerName);
+
+ /**
+ * Gets a list of all currently registered logger names. This is performed
+ * using the {@link LogManager#getLoggerNames()}.
+ *
+ * @return a list of logger names.
+ * @since Android 1.0
+ */
+ List<String> getLoggerNames();
+
+ /**
+ * Gets the name of the parent logger of a logger. If the logger doesn't
+ * exist then {@code null} is returned. If the logger is the root logger,
+ * then an empty {@code String} is returned.
+ *
+ * @param loggerName
+ * the name of the logger to lookup.
+ * @return a {@code String} if the logger was found, otherwise {@code null}.
+ * @since Android 1.0
+ */
+ String getParentLoggerName(String loggerName);
+
+ /**
+ * Sets the log level of a logger. LevelName set to {@code null} means the
+ * level is inherited from the nearest non-null ancestor.
+ *
+ * @param loggerName
+ * the name of the logger to set the level on, which must not be
+ * {@code null}.
+ * @param levelName
+ * the level to set on the logger, which may be {@code null}.
+ * @throws IllegalArgumentException
+ * if {@code loggerName} is not a registered logger or if
+ * {@code levelName} is not null and not valid.
+ * @throws SecurityException
+ * if a security manager exists and the caller doesn't have
+ * LoggingPermission("control").
+ * @see Level#parse(String)
+ * @since Android 1.0
+ */
+ void setLoggerLevel(String loggerName, String levelName);
+}
diff --git a/logging/src/main/java/java/util/logging/LoggingPermission.java b/logging/src/main/java/java/util/logging/LoggingPermission.java
new file mode 100644
index 0000000..fb6d4f8
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/LoggingPermission.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.security.BasicPermission;
+import java.security.Guard;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * The permission required to control the logging when run with a
+ * {@code SecurityManager}.
+ *
+ */
+public final class LoggingPermission extends BasicPermission implements Guard,
+ Serializable {
+
+ //for serialization compatibility with J2SE 1.4.2
+ private static final long serialVersionUID =63564341580231582L;
+
+
+ /*
+ * -------------------------------------------------------------------
+ * Constructors
+ * -------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a {@code LoggingPermission} object required to control the
+ * logging. The {@code SecurityManager} checks the permissions.
+ * <p>
+ * {@code LoggingPermission} objects are created by the security policy code
+ * and depends on the security policy file, therefore programmers shouldn't
+ * normally use them directly.
+ * </p>
+ *
+ * @param name
+ * currently must be "control".
+ * @param actions
+ * currently must be either {@code null} or the empty string.
+ * @throws IllegalArgumentException
+ * if name null or different from {@code string} control.
+ */
+ public LoggingPermission(String name, String actions) {
+ super(name, actions);
+ if (!"control".equals(name)) { //$NON-NLS-1$
+ // logging.6=Name must be "control".
+ throw new IllegalArgumentException(Messages.getString("logging.6")); //$NON-NLS-1$
+ }
+ if (null != actions && !"".equals(actions)) { //$NON-NLS-1$
+ // logging.7=Actions must be either null or the empty string.
+ throw new IllegalArgumentException(Messages.getString("logging.7")); //$NON-NLS-1$
+ }
+ }
+
+}
+
diff --git a/logging/src/main/java/java/util/logging/MemoryHandler.java b/logging/src/main/java/java/util/logging/MemoryHandler.java
new file mode 100644
index 0000000..c1e8670
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/MemoryHandler.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+
+/**
+ * A {@code Handler} put the description of log events into a cycled memory
+ * buffer.
+ * <p>
+ * Mostly this {@code MemoryHandler} just puts the given {@code LogRecord} into
+ * the internal buffer and doesn't perform any formatting or any other process.
+ * When the buffer is full, the earliest buffered records will be discarded.
+ * </p>
+ * <p>
+ * Every {@code MemoryHandler} has a target handler, and push action can be
+ * triggered so that all buffered records will be output to the target handler
+ * and normally the latter will publish the records. After the push action, the
+ * buffer will be cleared.
+ * </p>
+ * <p>
+ * The push action can be triggered in three ways:
+ * <ul>
+ * <li>The push method is called explicitly</li>
+ * <li>When a new {@code LogRecord} is put into the internal buffer, and it has
+ * a level which is not less than the specified push level.</li>
+ * <li>A subclass extends this {@code MemoryHandler} and call push method
+ * implicitly according to some criteria.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * {@code MemoryHandler} will read following {@code LogManager} properties for
+ * initialization, if given properties are not defined or has invalid values,
+ * default value will be used.
+ * <ul>
+ * <li>java.util.logging.MemoryHandler.level specifies the level for this
+ * {@code Handler}, defaults to {@code Level.ALL}.</li>
+ * <li>java.util.logging.MemoryHandler.filter specifies the {@code Filter}
+ * class name, defaults to no {@code Filter}.</li>
+ * <li>java.util.logging.MemoryHandler.size specifies the buffer size in number
+ * of {@code LogRecord}, defaults to 1000.</li>
+ * <li>java.util.logging.MemoryHandler.push specifies the push level, defaults
+ * to level.SEVERE.</li>
+ * <li>java.util.logging.MemoryHandler.target specifies the class of the target
+ * {@code Handler}, no default value, which means this property must be
+ * specified either by property setting or by constructor.</li>
+ * </ul>
+ * </p>
+ */
+public class MemoryHandler extends Handler {
+
+ //default maximum buffered number of LogRecord
+ private static final int DEFAULT_SIZE = 1000;
+ //target handler
+ private Handler target;
+
+ //buffer size
+ private int size = DEFAULT_SIZE;
+
+ //push level
+ private Level push = Level.SEVERE;
+
+ //LogManager instance for convenience
+ private final LogManager manager = LogManager.getLogManager();
+
+ //buffer
+ private LogRecord[] buffer;
+
+ //current position in buffer
+ private int cursor;
+
+ /**
+ * Default constructor, construct and init a {@code MemoryHandler} using
+ * {@code LogManager} properties or default values.
+ *
+ * @throws RuntimeException
+ * if property value are invalid and no default value could be
+ * used.
+ */
+ public MemoryHandler() {
+ super();
+ String className = this.getClass().getName();
+ //init target
+ final String targetName = manager.getProperty(className+".target"); //$NON-NLS-1$
+ try {
+ Class<?> targetClass = AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>(){
+ public Class<?> run() throws Exception{
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if(loader == null){
+ loader = ClassLoader.getSystemClassLoader();
+ }
+ return loader.loadClass(targetName);
+ }
+ });
+ target = (Handler) targetClass.newInstance();
+ } catch (Exception e) {
+ // logging.10=Cannot load target handler:{0}
+ throw new RuntimeException(Messages.getString("logging.10", //$NON-NLS-1$
+ targetName));
+ }
+ //init size
+ String sizeString = manager.getProperty(className+".size"); //$NON-NLS-1$
+ if (null != sizeString) {
+ try {
+ size = Integer.parseInt(sizeString);
+ if(size <= 0){
+ size = DEFAULT_SIZE;
+ }
+ } catch (Exception e) {
+ printInvalidPropMessage(className+".size", sizeString, e); //$NON-NLS-1$
+ }
+ }
+ //init push level
+ String pushName = manager.getProperty(className+".push"); //$NON-NLS-1$
+ if (null != pushName) {
+ try {
+ push = Level.parse(pushName);
+ } catch (Exception e) {
+ printInvalidPropMessage(className+".push", pushName, e); //$NON-NLS-1$
+ }
+ }
+ //init other properties which are common for all Handler
+ initProperties("ALL", null, "java.util.logging.SimpleFormatter", null); //$NON-NLS-1$//$NON-NLS-2$
+ buffer = new LogRecord[size];
+ }
+
+ /**
+ * Construct and init a {@code MemoryHandler} using given target, size and
+ * push level, other properties using {@code LogManager} properties or
+ * default values.
+ *
+ * @param target
+ * the given {@code Handler} to output
+ * @param size
+ * the maximum number of buffered {@code LogRecord}, greater than
+ * zero
+ * @param pushLevel
+ * the push level
+ * @throws IllegalArgumentException
+ * if {@code size}<=0
+ * @throws RuntimeException
+ * if property value are invalid and no default value could be
+ * used.
+ */
+ public MemoryHandler(Handler target, int size, Level pushLevel) {
+ if (size <= 0) {
+ // logging.11=Size must be positive.
+ throw new IllegalArgumentException(Messages.getString("logging.11")); //$NON-NLS-1$
+ }
+ target.getLevel();
+ pushLevel.intValue();
+ this.target = target;
+ this.size = size;
+ this.push = pushLevel;
+ initProperties("ALL", null, "java.util.logging.SimpleFormatter", null); //$NON-NLS-1$//$NON-NLS-2$
+ buffer = new LogRecord[size];
+ }
+
+ /**
+ * Close this handler and target handler, free all associated resources.
+ *
+ * @throws SecurityException
+ * if security manager exists and it determines that caller does
+ * not have the required permissions to control this handler.
+ */
+ @Override
+ public void close() {
+ manager.checkAccess();
+ target.close();
+ setLevel(Level.OFF);
+ }
+
+ /**
+ * Call target handler to flush any buffered output. Note that this doesn't
+ * cause this {@code MemoryHandler} to push.
+ */
+ @Override
+ public void flush() {
+ target.flush();
+ }
+
+ /**
+ * Put a given {@code LogRecord} into internal buffer. If given record is
+ * not loggable, just return. Otherwise it is stored in the buffer.
+ * Furthermore if the record's level is not less than the push level, the
+ * push action is triggered to output all the buffered records to the target
+ * handler, and the target handler will publish them.
+ *
+ * @param record
+ * the log record
+ */
+ @Override
+ public synchronized void publish(LogRecord record) {
+ if (!isLoggable(record)) {
+ return;
+ }
+ if (cursor >= size) {
+ cursor = 0;
+ }
+ buffer[cursor++] = record;
+ if (record.getLevel().intValue() >= push.intValue()) {
+ push();
+ }
+ return;
+ }
+
+ /**
+ * Return the push level.
+ *
+ * @return the push level
+ */
+ public Level getPushLevel() {
+ return push;
+ }
+
+ /**
+ * <p>
+ * Check if given {@code LogRecord} would be put into this
+ * {@code MemoryHandler}'s internal buffer.
+ * </p>
+ * <p>
+ * The given {@code LogRecord} is loggable if and only if it has appropriate
+ * level and it pass any associated filter's check.
+ * </p>
+ * <p>
+ * Note that the push level is not used for this check.
+ * </p>
+ *
+ * @param record
+ * the given {@code LogRecord}
+ * @return the given {@code LogRecord} if it should be logged, {@code false}
+ * if {@code LogRecord} is {@code null}.
+ */
+ @Override
+ public boolean isLoggable(LogRecord record) {
+ return super.isLoggable(record);
+ }
+
+ /**
+ * Triggers a push action to output all buffered records to the target handler,
+ * and the target handler will publish them. Then the buffer is cleared.
+ */
+ public void push() {
+ for (int i = cursor; i < size; i++) {
+ if(null != buffer[i]) {
+ target.publish(buffer[i]);
+ }
+ buffer[i] = null;
+ }
+ for (int i = 0; i < cursor; i++) {
+ if(null != buffer[i]) {
+ target.publish(buffer[i]);
+ }
+ buffer[i] = null;
+ }
+ cursor = 0;
+ }
+
+ /**
+ * Set the push level. The push level is used to check the push action
+ * triggering. When a new {@code LogRecord} is put into the internal
+ * buffer and its level is not less than the push level, the push action
+ * will be triggered. Note that set new push level won't trigger push action.
+ *
+ * @param newLevel
+ * the new level to set.
+ * @throws SecurityException
+ * if security manager exists and it determines that caller
+ * does not have the required permissions to control this handler.
+ */
+ public void setPushLevel(Level newLevel) {
+ manager.checkAccess();
+ newLevel.intValue();
+ this.push = newLevel;
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/SimpleFormatter.java b/logging/src/main/java/java/util/logging/SimpleFormatter.java
new file mode 100644
index 0000000..1595796
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/SimpleFormatter.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.PrintWriter;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.Date;
+
+/**
+ * {@code SimpleFormatter} can be used to print a summary of the information
+ * contained in a {@code LogRecord} object in a human readable format.
+ * @since Android 1.0
+ */
+public class SimpleFormatter extends Formatter {
+ /**
+ * Constructs a new {@code SimpleFormatter}.
+ *
+ * @since Android 1.0
+ */
+ public SimpleFormatter() {
+ super();
+ }
+
+ /**
+ * Converts a {@link LogRecord} object into a human readable string
+ * representation.
+ *
+ * @param r
+ * the log record to be formatted into a string.
+ * @return the formatted string.
+ * @since Android 1.0
+ */
+ @Override
+ public String format(LogRecord r) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(MessageFormat.format("{0, date} {0, time} ", //$NON-NLS-1$
+ new Object[] { new Date(r.getMillis()) }));
+ sb.append(r.getSourceClassName()).append(" "); //$NON-NLS-1$
+ sb.append(r.getSourceMethodName()).append(LogManager.getSystemLineSeparator()); //$NON-NLS-1$
+ sb.append(r.getLevel().getName()).append(": "); //$NON-NLS-1$
+ sb.append(formatMessage(r)).append(LogManager.getSystemLineSeparator());
+ if (null != r.getThrown()) {
+ sb.append("Throwable occurred: "); //$NON-NLS-1$
+ Throwable t = r.getThrown();
+ PrintWriter pw = null;
+ try {
+ StringWriter sw = new StringWriter();
+ pw = new PrintWriter(sw);
+ t.printStackTrace(pw);
+ sb.append(sw.toString());
+ } finally {
+ if(pw != null){
+ try {
+ pw.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
+
diff --git a/logging/src/main/java/java/util/logging/SocketHandler.java b/logging/src/main/java/java/util/logging/SocketHandler.java
new file mode 100644
index 0000000..8626007
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/SocketHandler.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.net.Socket;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * A handler that writes log messages to a socket connection.
+ * <p>
+ * This handler reads the following properties from the log manager to
+ * initialize itself:
+ * <ul>
+ * <li>java.util.logging.ConsoleHandler.level specifies the logging level,
+ * defaults to {@code Level.ALL} if this property is not found or has an invalid
+ * value.
+ * <li>java.util.logging.SocketHandler.filter specifies the name of the filter
+ * class to be associated with this handler, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * <li>java.util.logging.SocketHandler.formatter specifies the name of the
+ * formatter class to be associated with this handler, defaults to
+ * {@code java.util.logging.XMLFormatter} if this property is not found or has
+ * an invalid value.
+ * <li>java.util.logging.SocketHandler.encoding specifies the encoding this
+ * handler will use to encode log messages, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * <li>java.util.logging.SocketHandler.host specifies the name of the host that
+ * this handler should connect to. There's no default value for this property.
+ * <li>java.util.logging.SocketHandler.encoding specifies the port number that
+ * this handler should connect to. There's no default value for this property.
+ * </ul>
+ * </p>
+ * <p>
+ * This handler buffers the outgoing messages, but flushes each time a log
+ * record has been published.
+ * </p>
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ */
+public class SocketHandler extends StreamHandler {
+ // default level
+ private static final String DEFAULT_LEVEL = "ALL"; //$NON-NLS-1$
+
+ // default formatter
+ private static final String DEFAULT_FORMATTER = "java.util.logging.XMLFormatter"; //$NON-NLS-1$
+
+ // the socket connection
+ private Socket socket;
+
+ /**
+ * Constructs a {@code SocketHandler} object using the properties read by
+ * the log manager, including the host name and port number. Default
+ * formatting uses the XMLFormatter class and level is set to ALL.
+ *
+ * @throws IOException
+ * if failed to connect to the specified host and port.
+ * @throws IllegalArgumentException
+ * if the host name or port number is illegal.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission to control this handler.
+ */
+ public SocketHandler() throws IOException {
+ super(DEFAULT_LEVEL, null, DEFAULT_FORMATTER, null);
+ initSocket(LogManager.getLogManager().getProperty(
+ "java.util.logging.SocketHandler.host"), LogManager //$NON-NLS-1$
+ .getLogManager().getProperty(
+ "java.util.logging.SocketHandler.port")); //$NON-NLS-1$
+ }
+
+ /**
+ * Constructs a {@code SocketHandler} object using the specified host name
+ * and port number together with other properties read by the log manager.
+ * Default formatting uses the XMLFormatter class and level is set to ALL.
+ *
+ * @param host
+ * the host name
+ * @param port
+ * the port number
+ * @throws IOException
+ * if failed to connect to the specified host and port.
+ * @throws IllegalArgumentException
+ * if the host name or port number is illegal.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission to control this handler.
+ */
+ public SocketHandler(String host, int port) throws IOException {
+ super(DEFAULT_LEVEL, null, DEFAULT_FORMATTER, null);
+ initSocket(host, String.valueOf(port));
+ }
+
+ // Initialize the socket connection and prepare the output stream
+ private void initSocket(String host, String port) throws IOException {
+ // check the validity of the host name
+ if (null == host || "".equals(host)) { //$NON-NLS-1$
+ // logging.C=Illegal host argument.
+ throw new IllegalArgumentException(Messages.getString("logging.C")); //$NON-NLS-1$
+ }
+ // check the validity of the port number
+ int p = 0;
+ try {
+ p = Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ // logging.D=Illegal port argument.
+ throw new IllegalArgumentException(Messages.getString("logging.D")); //$NON-NLS-1$
+ }
+ if (p <= 0) {
+ // logging.D=Illegal port argument.
+ throw new IllegalArgumentException(Messages.getString("logging.D")); //$NON-NLS-1$
+ }
+ // establish the network connection
+ try {
+ this.socket = new Socket(host, p);
+ } catch (IOException e) {
+ // logging.E=Failed to establish the network connection.
+ getErrorManager().error(Messages.getString("logging.E"), e, //$NON-NLS-1$
+ ErrorManager.OPEN_FAILURE);
+ throw e;
+ }
+ // BEGIN android-modified
+ super.internalSetOutputStream(new BufferedOutputStream(this.socket
+ .getOutputStream(), 8192));
+ // END android-modified
+ }
+
+ /**
+ * Closes this handler. The network connection to the host is also closed.
+ *
+ * @throws SecurityException
+ * If a security manager determines that the caller does not
+ * have the required permission to control this handler.
+ */
+ @Override
+ public void close() {
+ try {
+ super.close();
+ if (null != this.socket) {
+ this.socket.close();
+ this.socket = null;
+ }
+ } catch (Exception e) {
+ // logging.F=Exception occurred when closing the socket handler.
+ getErrorManager().error(Messages.getString("logging.F"), e, //$NON-NLS-1$
+ ErrorManager.CLOSE_FAILURE);
+ }
+ }
+
+ /**
+ * Logs a record if necessary. A flush operation will be done afterwards.
+ *
+ * @param record
+ * the log record to be logged.
+ */
+ @Override
+ public void publish(LogRecord record) {
+ super.publish(record);
+ super.flush();
+ }
+
+}
diff --git a/logging/src/main/java/java/util/logging/StreamHandler.java b/logging/src/main/java/java/util/logging/StreamHandler.java
new file mode 100644
index 0000000..ee12190
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/StreamHandler.java
@@ -0,0 +1,367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+/**
+ * A {@code StreamHandler} object writes log messages to an output stream, that
+ * is, objects of the class {@link java.io.OutputStream}.
+ * <p>
+ * A {@code StreamHandler} object reads the following properties from the log
+ * manager to initialize itself:
+ * <ul>
+ * <li>java.util.logging.StreamHandler.level specifies the logging level,
+ * defaults to {@code Level.INFO} if this property is not found or has an
+ * invalid value.
+ * <li>java.util.logging.StreamHandler.filter specifies the name of the filter
+ * class to be associated with this handler, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * <li>java.util.logging.StreamHandler.formatter specifies the name of the
+ * formatter class to be associated with this handler, defaults to
+ * {@code java.util.logging.SimpleFormatter} if this property is not found or
+ * has an invalid value.
+ * <li>java.util.logging.StreamHandler.encoding specifies the encoding this
+ * handler will use to encode log messages, defaults to {@code null} if this
+ * property is not found or has an invalid value.
+ * </ul>
+ * </p>
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class StreamHandler extends Handler {
+ // the output stream this handler writes to
+ private OutputStream os;
+
+ // the writer that writes to the output stream
+ private Writer writer;
+
+ // the flag indicating whether the writer has been initialized
+ private boolean writerNotInitialized;
+
+ /**
+ * Constructs a {@code StreamHandler} object. The new stream handler
+ * does not have an associated output stream.
+ *
+ * @since Android 1.0
+ */
+ public StreamHandler() {
+ initProperties("INFO", null, "java.util.logging.SimpleFormatter", //$NON-NLS-1$//$NON-NLS-2$
+ null);
+ this.os = null;
+ this.writer = null;
+ this.writerNotInitialized = true;
+ }
+
+ /**
+ * Constructs a {@code StreamHandler} object with the supplied output
+ * stream. Default properties are read.
+ *
+ * @param os
+ * the output stream this handler writes to.
+ */
+ StreamHandler(OutputStream os) {
+ this();
+ this.os = os;
+ }
+
+ /**
+ * Constructs a {@code StreamHandler} object. The specified default values
+ * will be used if the corresponding properties are not found in the log
+ * manager's properties.
+ */
+ StreamHandler(String defaultLevel, String defaultFilter,
+ String defaultFormatter, String defaultEncoding) {
+ initProperties(defaultLevel, defaultFilter, defaultFormatter,
+ defaultEncoding);
+ this.os = null;
+ this.writer = null;
+ this.writerNotInitialized = true;
+ }
+
+ /**
+ * Constructs a {@code StreamHandler} object with the supplied output stream
+ * and formatter.
+ *
+ * @param os
+ * the output stream this handler writes to.
+ * @param formatter
+ * the formatter this handler uses to format the output.
+ * @throws NullPointerException
+ * if {@code os} or {@code formatter} is {@code null}.
+ * @since Android 1.0
+ */
+ public StreamHandler(OutputStream os, Formatter formatter) {
+ this();
+ if (os == null) {
+ // logging.2=The OutputStream parameter is null
+ throw new NullPointerException(Messages.getString("logging.2")); //$NON-NLS-1$
+ }
+ if (formatter == null) {
+ // logging.3=The Formatter parameter is null.
+ throw new NullPointerException(Messages.getString("logging.3")); //$NON-NLS-1$
+ }
+ this.os = os;
+ internalSetFormatter(formatter);
+ }
+
+ // initialize the writer
+ private void initializeWritter() {
+ this.writerNotInitialized = false;
+ if (null == getEncoding()) {
+ this.writer = new OutputStreamWriter(this.os);
+ } else {
+ try {
+ this.writer = new OutputStreamWriter(this.os, getEncoding());
+ } catch (UnsupportedEncodingException e) {
+ /*
+ * Should not happen because it's checked in
+ * super.initProperties().
+ */
+ }
+ }
+ write(getFormatter().getHead(this));
+ }
+
+ // Write a string to the output stream.
+ private void write(String s) {
+ try {
+ this.writer.write(s);
+ } catch (Exception e) {
+ // logging.14=Exception occurred when writing to the output stream.
+ getErrorManager().error(Messages.getString("logging.14"), e, //$NON-NLS-1$
+ ErrorManager.WRITE_FAILURE);
+ }
+ }
+
+ /**
+ * Sets the output stream this handler writes to. Note it does nothing else.
+ *
+ * @param newOs
+ * the new output stream
+ */
+ void internalSetOutputStream(OutputStream newOs) {
+ this.os = newOs;
+ }
+
+
+ /**
+ * Sets the output stream this handler writes to. If there's an existing
+ * output stream, the tail string of the associated formatter will be
+ * written to it. Then it will be flushed, closed and replaced with
+ * {@code os}.
+ *
+ * @param os
+ * the new output stream.
+ * @throws SecurityException
+ * if a security manager determines that the caller does not
+ * have the required permission.
+ * @throws NullPointerException
+ * if {@code os} is {@code null}.
+ */
+ protected void setOutputStream(OutputStream os) {
+ if (null == os) {
+ throw new NullPointerException();
+ }
+ LogManager.getLogManager().checkAccess();
+ close(true);
+ this.writer = null;
+ this.os = os;
+ this.writerNotInitialized = true;
+ }
+
+ /**
+ * Sets the character encoding used by this handler. A {@code null} value
+ * indicates that the default encoding should be used.
+ *
+ * @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.
+ * @since Android 1.0
+ */
+ @Override
+ public void setEncoding(String encoding) throws SecurityException,
+ UnsupportedEncodingException {
+ //flush first before set new encoding
+ this.flush();
+ super.setEncoding(encoding);
+ // renew writer only if the writer exists
+ if (null != this.writer) {
+ if (null == getEncoding()) {
+ this.writer = new OutputStreamWriter(this.os);
+ } else {
+ try {
+ this.writer = new OutputStreamWriter(this.os, getEncoding());
+ } catch (UnsupportedEncodingException e) {
+ /*
+ * Should not happen because it's checked in
+ * super.initProperties().
+ */
+ throw new AssertionError(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes this handler, but the underlying output stream is only closed if
+ * {@code closeStream} is {@code true}. Security is not checked.
+ *
+ * @param closeStream
+ * whether to close the underlying output stream.
+ */
+ void close(boolean closeStream) {
+ if (null != this.os) {
+ if (this.writerNotInitialized) {
+ initializeWritter();
+ }
+ write(getFormatter().getTail(this));
+ try {
+ this.writer.flush();
+ if (closeStream) {
+ this.writer.close();
+ this.writer = null;
+ this.os = null;
+ }
+ } catch (Exception e) {
+ // logging.15=Exception occurred when closing the output stream.
+ getErrorManager().error(Messages.getString("logging.15"), e, //$NON-NLS-1$
+ ErrorManager.CLOSE_FAILURE);
+ }
+ }
+ }
+
+ /**
+ * Closes this handler. The tail string of the formatter associated with
+ * this handler is written out. A flush operation and a subsequent close
+ * operation is then performed upon the output stream. 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.
+ * @since Android 1.0
+ */
+ @Override
+ public void close() {
+ LogManager.getLogManager().checkAccess();
+ close(true);
+ }
+
+ /**
+ * Flushes any buffered output.
+ *
+ * @since Android 1.0
+ */
+ @Override
+ public void flush() {
+ if (null != this.os) {
+ try {
+ if (null != this.writer) {
+ this.writer.flush();
+ } else {
+ this.os.flush();
+ }
+ } catch (Exception e) {
+ // logging.16=Exception occurred while flushing the output stream.
+ getErrorManager().error(Messages.getString("logging.16"), //$NON-NLS-1$
+ e, ErrorManager.FLUSH_FAILURE);
+ }
+ }
+ }
+
+ /**
+ * Accepts a logging request. The log record is formatted and written to the
+ * output stream if the following three conditions are met:
+ * <ul>
+ * <li>the supplied log record has at least the required logging level;
+ * <li>the supplied log record passes the filter associated with this
+ * handler, if any;
+ * <li>the output stream associated with this handler is not {@code null}.
+ * </ul>
+ * If it is the first time a log record is written out, the head string of
+ * the formatter associated with this handler is written out first.
+ *
+ * @param record
+ * the log record to be logged.
+ * @since Android 1.0
+ */
+ @Override
+ public synchronized void publish(LogRecord record) {
+ try {
+ if (this.isLoggable(record)) {
+ if (this.writerNotInitialized) {
+ initializeWritter();
+ }
+ String msg = null;
+ try {
+ msg = getFormatter().format(record);
+ } catch (Exception e) {
+ // logging.17=Exception occurred while formatting the log record.
+ getErrorManager().error(Messages.getString("logging.17"), //$NON-NLS-1$
+ e, ErrorManager.FORMAT_FAILURE);
+ }
+ write(msg);
+ }
+ } catch (Exception e) {
+ // logging.18=Exception occurred while logging the record.
+ getErrorManager().error(Messages.getString("logging.18"), e, //$NON-NLS-1$
+ ErrorManager.GENERIC_FAILURE);
+ }
+ }
+
+ /**
+ * Determines whether the supplied log record needs to be logged. The
+ * logging levels are checked as well as the filter. The output stream of
+ * this handler is also checked. If it is {@code null}, this method returns
+ * {@code false}.
+ * <p>
+ * Notice : Case of no output stream will return {@code false}.
+ * </p>
+ *
+ * @param record
+ * the log record to be checked.
+ * @return {@code true} if {@code record} needs to be logged, {@code false}
+ * otherwise.
+ * @since Android 1.0
+ */
+ @Override
+ public boolean isLoggable(LogRecord record) {
+ if (null == record) {
+ return false;
+ }
+ if (null != this.os && super.isLoggable(record)) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/logging/src/main/java/java/util/logging/XMLFormatter.java b/logging/src/main/java/java/util/logging/XMLFormatter.java
new file mode 100644
index 0000000..6279d8c
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/XMLFormatter.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.ResourceBundle;
+
+/**
+ * Formatter to convert a {@link LogRecord} into an XML string. The DTD
+ * specified in Appendix A to the Java Logging APIs specification is used.
+ * {@code XMLFormatter} uses the output handler's encoding if it is specified,
+ * otherwise the default platform encoding is used instead. UTF-8 is the
+ * recommended encoding.
+ *
+ * @since Android 1.0
+ */
+public class XMLFormatter extends Formatter {
+
+ private static final String lineSeperator = LogManager
+ .getSystemLineSeparator();
+
+ private static final String indent = " "; //$NON-NLS-1$
+
+ /**
+ * Constructs a new {@code XMLFormatter}.
+ *
+ * @since Android 1.0
+ */
+ public XMLFormatter() {
+ super();
+ }
+
+ /**
+ * Converts a {@code LogRecord} into an XML string.
+ *
+ * @param r
+ * the log record to be formatted.
+ * @return the log record formatted as an XML string.
+ * @since Android 1.0
+ */
+ @Override
+ public String format(LogRecord r) {
+ //call a method of LogRecord to ensure not null
+ long time = r.getMillis();
+ //format to date
+ String date = MessageFormat.format("{0, date} {0, time}", //$NON-NLS-1$
+ new Object[] { new Date(time) });
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(("<record>")).append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(("<date>")).append(date).append(("</date>")) //$NON-NLS-1$ //$NON-NLS-2$
+ .append(lineSeperator);
+ sb.append(indent).append(("<millis>")).append(time).append( //$NON-NLS-1$
+ ("</millis>")).append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(("<sequence>")).append(r.getSequenceNumber()) //$NON-NLS-1$
+ .append(("</sequence>")).append(lineSeperator); //$NON-NLS-1$
+ if (null != r.getLoggerName()) {
+ sb.append(indent).append(("<logger>")).append(r.getLoggerName()) //$NON-NLS-1$
+ .append(("</logger>")).append(lineSeperator); //$NON-NLS-1$
+ }
+ sb.append(indent).append(("<level>")).append(r.getLevel().getName()) //$NON-NLS-1$
+ .append(("</level>")).append(lineSeperator); //$NON-NLS-1$
+ if (null != r.getSourceClassName()) {
+ sb.append(indent).append(("<class>")) //$NON-NLS-1$
+ .append(r.getSourceClassName()).append(("</class>")) //$NON-NLS-1$
+ .append(lineSeperator);
+ }
+ if (null != r.getSourceMethodName()) {
+ sb.append(indent).append(("<method>")).append( //$NON-NLS-1$
+ r.getSourceMethodName()).append(("</method>")).append( //$NON-NLS-1$
+ lineSeperator);
+ }
+ sb.append(indent).append(("<thread>")).append(r.getThreadID()).append( //$NON-NLS-1$
+ ("</thread>")).append(lineSeperator); //$NON-NLS-1$
+ formatMessages(r, sb);
+ Object[] params;
+ if ((params = r.getParameters()) != null) {
+ for (Object element : params) {
+ sb.append(indent).append(("<param>")).append(element).append( //$NON-NLS-1$
+ ("</param>")).append(lineSeperator); //$NON-NLS-1$
+ }
+ }
+ formatThrowable(r, sb);
+ sb.append(("</record>")).append(lineSeperator); //$NON-NLS-1$
+ return sb.toString();
+ }
+
+ private void formatMessages(LogRecord r, StringBuilder sb) {
+ //get localized message if has, but don't call Formatter.formatMessage to parse pattern string
+ ResourceBundle rb = r.getResourceBundle();
+ String pattern = r.getMessage();
+ if (null != rb && null != pattern) {
+ String message;
+ try {
+ message = rb.getString(pattern);
+ } catch (Exception e) {
+ message = null;
+ }
+
+ if (message == null) {
+ message = pattern;
+ sb.append(indent).append(("<message>")).append(message).append( //$NON-NLS-1$
+ ("</message>")).append(lineSeperator); //$NON-NLS-1$
+ } else {
+ sb.append(indent).append(("<message>")).append(message).append( //$NON-NLS-1$
+ ("</message>")).append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(("<key>")).append(pattern).append( //$NON-NLS-1$
+ ("</key>")).append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(("<catalog>")).append( //$NON-NLS-1$
+ r.getResourceBundleName()).append(("</catalog>")) //$NON-NLS-1$
+ .append(lineSeperator);
+ }
+ } else if(null != pattern){
+ sb.append(indent).append(("<message>")).append(pattern).append( //$NON-NLS-1$
+ ("</message>")).append(lineSeperator); //$NON-NLS-1$
+ } else{
+ sb.append(indent).append(("<message/>")); //$NON-NLS-1$
+ }
+ }
+
+ private void formatThrowable(LogRecord r, StringBuilder sb) {
+ Throwable t;
+ if ((t = r.getThrown()) != null) {
+ sb.append(indent).append("<exception>").append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(indent).append("<message>").append( //$NON-NLS-1$
+ t.toString()).append("</message>").append(lineSeperator); //$NON-NLS-1$
+ //format throwable's stack trace
+ StackTraceElement[] elements = t.getStackTrace();
+ for (StackTraceElement e : elements) {
+ sb.append(indent).append(indent).append("<frame>").append( //$NON-NLS-1$
+ lineSeperator);
+ sb.append(indent).append(indent).append(indent).append(
+ "<class>").append(e.getClassName()).append("</class>") //$NON-NLS-1$//$NON-NLS-2$
+ .append(lineSeperator);
+ sb.append(indent).append(indent).append(indent).append(
+ "<method>").append(e.getMethodName()).append( //$NON-NLS-1$
+ "</method>").append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(indent).append(indent)
+ .append("<line>").append(e.getLineNumber()).append( //$NON-NLS-1$
+ "</line>").append(lineSeperator); //$NON-NLS-1$
+ sb.append(indent).append(indent).append("</frame>").append( //$NON-NLS-1$
+ lineSeperator);
+ }
+ sb.append(indent).append("</exception>").append(lineSeperator); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Returns the header string for a set of log records formatted as XML
+ * strings, using the output handler's encoding if it is defined, otherwise
+ * using the default platform encoding.
+ *
+ * @param h
+ * the output handler, may be {@code null}.
+ * @return the header string for log records formatted as XML strings.
+ * @since Android 1.0
+ */
+ @Override
+ public String getHead(Handler h) {
+ String encoding = null;
+ if(null != h) {
+ encoding = h.getEncoding();
+ }
+ if (null == encoding) {
+ encoding = getSystemProperty("file.encoding"); //$NON-NLS-1$
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append("<?xml version=\"1.0\" encoding=\"").append(encoding).append( //$NON-NLS-1$
+ "\" standalone=\"no\"?>").append(lineSeperator); //$NON-NLS-1$
+ sb.append("<!DOCTYPE log SYSTEM \"logger.dtd\">").append(lineSeperator); //$NON-NLS-1$
+ sb.append(("<log>")); //$NON-NLS-1$
+ return sb.toString();
+ }
+
+ /**
+ * Returns the tail string for a set of log records formatted as XML
+ * strings.
+ *
+ * @param h
+ * the output handler, may be {@code null}.
+ * @return the tail string for log records formatted as XML strings.
+ * @since Android 1.0
+ */
+ @Override
+ @SuppressWarnings("unused")
+ public String getTail(Handler h) {
+ return "</log>"; //$NON-NLS-1$
+ }
+
+ //use privilege code to get system property
+ private static String getSystemProperty(final String key) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ }
+
+}
+
+
diff --git a/logging/src/main/java/java/util/logging/logging.properties b/logging/src/main/java/java/util/logging/logging.properties
new file mode 100644
index 0000000..f99fe3f
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/logging.properties
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+#------------------------------------------------------------------------------
+# Default logging property file.
+# This file is used by java.util.logging package as default settings, users can
+# specify another file instead with java.util.logging.config.file system
+# property, this property can be set via the Preference API, or as VM arguments
+# passed to "java" command, or as property definition passed to JNI_CreateJavaVM.
+# You can refer to JavaDoc of java.util.logging package for more information
+# about this file.
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# Global settings
+#------------------------------------------------------------------------------
+
+# Specify default level for global logger, the event whose level is below won't
+# be logged. You can specify level for every logger, otherwise the level of parent
+# logger will be used. You can also set the level for every handler, as below for
+# java.util.logging.ConsoleHandler.
+.level=INFO
+
+# Specify handler classes list, these classes will be instantiated during the
+# logging framework initialization. The list should be white space separated.
+# For example, use the line below to add SocketHandler. Note that the handler
+# classes must be in the classpath.
+#
+# handlers=java.util.logging.ConsoleHandler java.util.logging.SocketHandler
+#
+handlers=java.util.logging.ConsoleHandler
+
+# Specify a class names list, these classes' default constructor will be executed
+# during logging package initialization, which may contain some code to set the
+# logging configuration. The list should be white space separated, and the
+# classes must be in the classpath.
+#
+# config=
+
+
+#------------------------------------------------------------------------------
+# Handler settings
+#------------------------------------------------------------------------------
+
+# The properties below are samples for handler settings.
+#java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
+#java.util.logging.ConsoleHandler.level=INFO
+#java.util.logging.FileHandler.limit=100000
+#java.util.logging.FileHandler.count=1
+#java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter
+#java.util.logging.FileHandler.pattern=%h/java%u.log
+
diff --git a/logging/src/main/java/java/util/logging/package.html b/logging/src/main/java/java/util/logging/package.html
new file mode 100644
index 0000000..c523c7a
--- /dev/null
+++ b/logging/src/main/java/java/util/logging/package.html
@@ -0,0 +1,10 @@
+<html>
+ <body>
+ <p>
+ This package allows to add logging to any application. It
+ supports different levels of importance of a message that needs to be
+ logged. The output written to the target can be filtered by this level.
+ </p>
+ @since Android 1.0
+ </body>
+</html>
diff --git a/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java b/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java
new file mode 100644
index 0000000..87535ae
--- /dev/null
+++ b/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+// BEGIN android-note
+// Redundant code has been removed and is now called from MsgHelp.
+// END android-note
+
+package org.apache.harmony.logging.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+// BEGIN android-changed
+import org.apache.harmony.luni.util.MsgHelp;
+// END android-changed
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ * org.apache.harmony.logging.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ *
+ */
+public class Messages {
+
+ // BEGIN android-changed
+ private static final String sResource =
+ "org.apache.harmony.logging.internal.nls.messages"; //$NON-NLS-1$
+ // END android-changed
+
+ /**
+ * Retrieves a message which has no arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg) {
+ // BEGIN android-changed
+ return MsgHelp.getString(sResource, msg);
+ // END android-changed
+ }
+
+ /**
+ * Retrieves a message which takes 1 argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * Object the object to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object arg) {
+ return getString(msg, new Object[] { arg });
+ }
+
+ /**
+ * Retrieves a message which takes 1 integer argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * int the integer to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, int arg) {
+ return getString(msg, new Object[] { Integer.toString(arg) });
+ }
+
+ /**
+ * Retrieves a message which takes 1 character argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * char the character to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, char arg) {
+ return getString(msg, new Object[] { String.valueOf(arg) });
+ }
+
+ /**
+ * Retrieves a message which takes 2 arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg1
+ * Object an object to insert in the formatted output.
+ * @param arg2
+ * Object another object to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object arg1, Object arg2) {
+ return getString(msg, new Object[] { arg1, arg2 });
+ }
+
+ /**
+ * Retrieves a message which takes several arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param args
+ * Object[] the objects to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object[] args) {
+ // BEGIN android-changed
+ return MsgHelp.getString(sResource, msg, args);
+ // END android-changed
+ }
+
+ // BEGIN android-note
+ // Duplicate code was dropped in favor of using MsgHelp.
+ // END android-note
+}
diff --git a/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties b/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties
new file mode 100644
index 0000000..da3945e
--- /dev/null
+++ b/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+# messages for EN locale
+logging.0=This method is not currently implemented.
+logging.1=Invalid level name: {0}.
+logging.10=Cannot load target handler:{0}
+logging.11=Size must be positive.
+logging.12=Invalid property value for
+logging.13=The encoding "{0}" is not supported.
+logging.14=Exception occurred when writing to the output stream.
+logging.15=Exception occurred when closing the output stream.
+logging.16=Exception occurred while flushing the output stream.
+logging.17=Exception occurred while formatting the log record.
+logging.18=Exception occurred while logging the record.
+logging.19=Pattern cannot be empty
+logging.1A=Error happened when open log file.
+logging.1B=The limit and count property must be larger than 0 and 1, respectively
+logging.1C=The 'name' parameter is null.
+logging.1D=Cannot parse this name: {0}
+logging.1E=Error message - {0}
+logging.1F=Exception - {0}
+logging.2=The OutputStream parameter is null
+logging.20=Loading class "{0}" failed
+logging.21=There Can Be Only One logging MX bean.
+logging.22=Exception occurred while getting the logging MX bean.
+logging.3=The Formatter parameter is null.
+logging.4=The 'level' parameter is null.
+logging.5=Different version - {0}.{1}
+logging.6=Name must be "control".
+logging.7=Actions must be either null or the empty string.
+logging.8=Failed to load the specified resource bundle "{0}".
+logging.9=The specified resource bundle name "{0}" is inconsistent with the existing one "{1}".
+logging.A=The 'handler' parameter is null.
+logging.B=The 'parent' parameter is null.
+logging.C=Illegal host argument.
+logging.D=Illegal port argument.
+logging.E=Failed to establish the network connection.
+logging.F=Exception occured when closing the socket handler.
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java
new file mode 100644
index 0000000..1094f25
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ */
+public class AllTests {
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite(
+ "Suite for org.apache.harmony.logging.tests.java.util.logging");
+ // $JUnit-BEGIN$
+ suite.addTestSuite(ConsoleHandlerTest.class);
+ suite.addTestSuite(ErrorManagerTest.class);
+ suite.addTestSuite(FileHandlerTest.class);
+ suite.addTestSuite(FilterTest.class);
+ suite.addTestSuite(FormatterTest.class);
+ suite.addTestSuite(HandlerTest.class);
+ suite.addTestSuite(LevelTest.class);
+ suite.addTestSuite(LoggerTest.class);
+ suite.addTestSuite(LoggingMXBeanTest.class);
+ suite.addTestSuite(LoggingPermissionTest.class);
+ suite.addTestSuite(LogManagerTest.class);
+ suite.addTestSuite(LogRecordTest.class);
+ suite.addTestSuite(MemoryHandlerTest.class);
+ suite.addTestSuite(SimpleFormatterTest.class);
+ suite.addTestSuite(SocketHandlerTest.class);
+ suite.addTestSuite(StreamHandlerTest.class);
+ suite.addTestSuite(XMLFormatterTest.class);
+ suite.addTestSuite(MessagesTest.class);
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java
new file mode 100644
index 0000000..91de2a5
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java
@@ -0,0 +1,685 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.Permission;
+import java.util.Currency;
+import java.util.Properties;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.SimpleFormatter;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+import tests.util.CallVerificationStack;
+
+/**
+ * Test class java.util.logging.ConsoleHandler
+ */
+@TestTargetClass(ConsoleHandler.class)
+public class ConsoleHandlerTest extends TestCase {
+
+ private final static String INVALID_LEVEL = "impossible_level";
+
+ private final PrintStream err = System.err;
+
+ private OutputStream errSubstituteStream = null;
+
+ private static String className = ConsoleHandlerTest.class.getName();
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ errSubstituteStream = new MockOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ LogManager.getLogManager().reset();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ LogManager.getLogManager().reset();
+ CallVerificationStack.getInstance().clear();
+ System.setErr(err);
+ }
+
+ /*
+ * Test the constructor with no relevant log manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no relevant log manager properties are set.",
+ method = "ConsoleHandler",
+ args = {}
+ )
+ public void testConstructor_NoProperties() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.encoding"));
+
+ ConsoleHandler h = new ConsoleHandler();
+ assertSame(h.getLevel(), Level.INFO);
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertSame(h.getEncoding(), null);
+ }
+
+ /*
+ * Test the constructor with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with insufficient privilege.",
+ method = "ConsoleHandler",
+ args = {}
+ )
+ public void testConstructor_InsufficientPrivilege() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.encoding"));
+
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ // set a normal value
+ try {
+ ConsoleHandler h = new ConsoleHandler();
+ assertSame(h.getLevel(), Level.INFO);
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertSame(h.getEncoding(), null);
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test the constructor with valid relevant log manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with valid relevant log manager properties are set.",
+ method = "ConsoleHandler",
+ args = {}
+ )
+ public void testConstructor_ValidProperties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.level", "FINE");
+ p.put("java.util.logging.ConsoleHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.ConsoleHandler.encoding", "iso-8859-1");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.level"), "FINE");
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.encoding"), "iso-8859-1");
+ ConsoleHandler h = new ConsoleHandler();
+ assertSame(h.getLevel(), Level.parse("FINE"));
+ assertTrue(h.getFormatter() instanceof MockFormatter);
+ assertTrue(h.getFilter() instanceof MockFilter);
+ assertEquals(h.getEncoding(), "iso-8859-1");
+ }
+
+ /*
+ * Test the constructor with invalid relevant log manager properties are
+ * set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with invalid relevant log manager properties are set.",
+ method = "ConsoleHandler",
+ args = {}
+ )
+ public void testConstructor_InvalidProperties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.level", INVALID_LEVEL);
+ p.put("java.util.logging.ConsoleHandler.filter", className);
+ p.put("java.util.logging.ConsoleHandler.formatter", className);
+ p.put("java.util.logging.ConsoleHandler.encoding", "XXXX");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.level"), INVALID_LEVEL);
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.ConsoleHandler.encoding"), "XXXX");
+ ConsoleHandler h = new ConsoleHandler();
+ assertSame(h.getLevel(), Level.INFO);
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.publish(new LogRecord(Level.SEVERE, "test"));
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and a record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_NormalClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ h.publish(new LogRecord(Level.SEVERE,
+ "testClose_SufficientPrivilege_NormalClose msg"));
+ h.close();
+ assertEquals("flush", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ assertNull(CallVerificationStack.getInstance().pop());
+ h.close();
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and an output stream that
+ * always throws exceptions.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and an output stream that always throws exceptions",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_Exception() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+
+ h.publish(new LogRecord(Level.SEVERE,
+ "testClose_SufficientPrivilege_Exception msg"));
+ h.flush();
+ h.close();
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and no record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks close() when having sufficient privilege, and no record has been written to the output stream",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_DirectClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+
+ h.close();
+ assertEquals("flush", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test close() when having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when insufficient privilege is set up.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_InsufficientPrivilege() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ h.close();
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test publish(), use no filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use no filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NoFilter() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
+ this.errSubstituteStream.toString());
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
+ this.errSubstituteStream.toString());
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+ + "testPublish_NoFilter", this.errSubstituteStream.toString());
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+ + "testPublish_NoFilter", this.errSubstituteStream.toString());
+ }
+
+ /*
+ * Test publish(), after system err is reset.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), after system err is reset.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_AfterResetSystemErr() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ h.setFilter(new MockFilter());
+
+ System.setErr(new PrintStream(new ByteArrayOutputStream()));
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertEquals("", this.errSubstituteStream.toString());
+ }
+
+ /*
+ * Test publish(), use a filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use a filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_WithFilter() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ h.setFilter(new MockFilter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertEquals("", this.errSubstituteStream.toString());
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertEquals("", this.errSubstituteStream.toString());
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertEquals("", this.errSubstituteStream.toString());
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertEquals("", this.errSubstituteStream.toString());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test publish(), null log record, having output stream, spec said
+ * rather than throw exception, handler should call errormanager to handle
+ * exception case, so NullPointerException shouldn't be thrown.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), null log record, having output stream, spec said rather than throw exception, handler should call errormanager to handle exception case, so NullPointerException shouldn't be thrown.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_Null() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ h.publish(null);
+ }
+
+ /*
+ * Test publish(), a log record with empty msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), a log record with empty msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_EmptyMsg() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ LogRecord r = new LogRecord(Level.INFO, "");
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head", this.errSubstituteStream.toString());
+ }
+
+ /*
+ * Test publish(), a log record with null msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), a log record with null msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NullMsg() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ LogRecord r = new LogRecord(Level.INFO, null);
+ h.publish(r);
+ h.flush();
+ // assertEquals("MockFormatter_Head",
+ // this.errSubstituteStream.toString());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish method after close.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_AfterClose() throws Exception {
+ PrintStream backup = System.err;
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(bos));
+ Properties p = new Properties();
+ p.put("java.util.logging.ConsoleHandler.level", "FINE");
+ p.put("java.util.logging.ConsoleHandler.formatter", className
+ + "$MockFormatter");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+ ConsoleHandler h = new ConsoleHandler();
+ assertSame(h.getLevel(), Level.FINE);
+ LogRecord r1 = new LogRecord(Level.INFO, "testPublish_Record1");
+ LogRecord r2 = new LogRecord(Level.INFO, "testPublish_Record2");
+ assertTrue(h.isLoggable(r1));
+ h.publish(r1);
+ assertTrue(bos.toString().indexOf("testPublish_Record1") >= 0);
+ h.close();
+ // assertFalse(h.isLoggable(r));
+ assertTrue(h.isLoggable(r2));
+ h.publish(r2);
+ assertTrue(bos.toString().indexOf("testPublish_Record2") >= 0);
+ h.flush();
+ // assertEquals("MockFormatter_Head",
+ // this.errSubstituteStream.toString());
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ System.setErr(backup);
+ }
+ }
+
+ /*
+ * Test setOutputStream() under normal condition.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies setOutputStream() under normal condition.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testSetOutputStream_Normal() {
+ MockStreamHandler h = new MockStreamHandler();
+ h.setFormatter(new MockFormatter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+ h.publish(r);
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal",
+ this.errSubstituteStream.toString());
+
+ ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+ h.setOutputStream(aos2);
+
+ // assertEquals("close", DelegationParameterStack.getInstance()
+ // .getCurrentSourceMethod());
+ // assertNull(DelegationParameterStack.getInstance().pop());
+ // assertEquals("flush", DelegationParameterStack.getInstance()
+ // .getCurrentSourceMethod());
+ // assertNull(DelegationParameterStack.getInstance().pop());
+ // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ // + "MockFormatter_Tail", this.errSubstituteStream.toString());
+ // r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+ // h.publish(r);
+ // assertSame(r, DelegationParameterStack.getInstance().pop());
+ // assertTrue(DelegationParameterStack.getInstance().empty());
+ // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2",
+ // aos2
+ // .toString());
+ // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ // + "MockFormatter_Tail", this.errSubstituteStream.toString());
+ }
+
+ /*
+ * A mock filter, always return false.
+ */
+ public static class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ // System.out.println("filter called...");
+ return false;
+ }
+ }
+
+ /*
+ * A mock formatter.
+ */
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord r) {
+ // System.out.println("formatter called...");
+ return super.formatMessage(r);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
+ */
+ public String getHead(Handler h) {
+ return "MockFormatter_Head";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
+ */
+ public String getTail(Handler h) {
+ return "MockFormatter_Tail";
+ }
+ }
+
+ /*
+ * A mock output stream.
+ */
+ public static class MockOutputStream extends ByteArrayOutputStream {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#close()
+ */
+ public void close() throws IOException {
+ CallVerificationStack.getInstance().push(null);
+ super.close();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#flush()
+ */
+ public void flush() throws IOException {
+ CallVerificationStack.getInstance().push(null);
+ super.flush();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int oneByte) {
+ // TODO Auto-generated method stub
+ super.write(oneByte);
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockSecurityManager extends SecurityManager {
+
+ public MockSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ /*
+ * A mock stream handler, expose setOutputStream.
+ */
+ public static class MockStreamHandler extends ConsoleHandler {
+ public MockStreamHandler() {
+ super();
+ }
+
+ public void setOutputStream(OutputStream out) {
+ super.setOutputStream(out);
+ }
+
+ public boolean isLoggable(LogRecord r) {
+ CallVerificationStack.getInstance().push(r);
+ return super.isLoggable(r);
+ }
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java
new file mode 100644
index 0000000..3185351
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.logging.ErrorManager;
+
+@TestTargetClass(ErrorManager.class)
+public class ErrorManagerTest extends TestCase {
+
+
+ private final PrintStream err = System.err;
+ private final PrintStream out = System.out;
+
+ private OutputStream errSubstituteStream = null;
+
+ public void setUp() throws Exception{
+ super.setUp();
+ errSubstituteStream = new NullOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ }
+
+ public void tearDown() throws Exception{
+ System.setErr(err);
+ System.setOut(out);
+ super.tearDown();
+ }
+
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive case only with ErrorManager.GENERIC_FAILURE, impove MockStream",
+ method = "error",
+ args = {java.lang.String.class, java.lang.Exception.class, int.class}
+ )
+ public void test_errorCheck() {
+ ErrorManager em = new ErrorManager();
+ MockStream aos = new MockStream();
+ PrintStream st = new PrintStream(aos);
+ System.setErr(st);
+ System.setOut(st);
+ em.error("supertest", null, ErrorManager.GENERIC_FAILURE);
+ st.flush();
+
+ assertTrue("message appears (supertest)", aos.getWrittenData().indexOf("supertest") != -1);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive case only with ErrorManager.GENERIC_FAILURE",
+ method = "error",
+ args = {java.lang.String.class, java.lang.Exception.class, int.class}
+ )
+ public void test_errorStringStringint() {
+ ErrorManager em = new ErrorManager();
+ em.error(null, new NullPointerException(),
+ ErrorManager.GENERIC_FAILURE);
+ em.error("An error message.", null, ErrorManager.GENERIC_FAILURE);
+ em.error(null, null, ErrorManager.GENERIC_FAILURE);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ErrorManager",
+ args = {}
+ )
+ public void test_constants() {
+ assertEquals(3, ErrorManager.CLOSE_FAILURE);
+ assertEquals(2, ErrorManager.FLUSH_FAILURE);
+ assertEquals(5, ErrorManager.FORMAT_FAILURE);
+ assertEquals(0, ErrorManager.GENERIC_FAILURE);
+ assertEquals(4, ErrorManager.OPEN_FAILURE);
+ assertEquals(1, ErrorManager.WRITE_FAILURE);
+ }
+
+ public class MockStream extends ByteArrayOutputStream {
+
+ private StringBuffer linesWritten = new StringBuffer();
+
+ public void flush() {}
+ public void close() {}
+
+ @Override
+ public void write(byte[] buffer) {
+ linesWritten.append(new String(buffer));
+ }
+
+ @Override
+ public synchronized void write(byte[] buffer, int offset, int len) {
+ linesWritten.append(new String(buffer, offset, len));
+ }
+
+ public String getWrittenData() {return linesWritten.toString();}
+
+ }
+
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
new file mode 100644
index 0000000..3ff1fc9
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
@@ -0,0 +1,1176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.security.Permission;
+import java.util.Properties;
+import java.util.logging.FileHandler;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.XMLFormatter;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+/**
+ */
+@TestTargetClass(FileHandler.class)
+public class FileHandlerTest extends TestCase {
+
+ static LogManager manager = LogManager.getLogManager();
+
+ final static Properties props = new Properties();
+
+ final static String className = FileHandlerTest.class.getName();
+
+ final static StringWriter writer = new StringWriter();
+
+ final static SecurityManager securityManager = new MockLogSecurityManager();
+
+ final static String SEP = File.separator;
+
+ private String oldHomePath = System.getProperty("user.home");
+
+ // The HOMEPATH can't be used in android.
+ final static String HOMEPATH = System.getProperty("java.io.tmpdir") + SEP + "home";
+
+ final static String TEMPPATH = System.getProperty("java.io.tmpdir");
+
+ private final PrintStream err = System.err;
+
+ private OutputStream errSubstituteStream = null;
+
+ FileHandler handler;
+
+ LogRecord r;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ manager.reset();
+
+ //initProp
+ props.clear();
+ props.put("java.util.logging.FileHandler.level", "FINE");
+ props.put("java.util.logging.FileHandler.filter", className
+ + "$MockFilter");
+ props.put("java.util.logging.FileHandler.formatter", className
+ + "$MockFormatter");
+ props.put("java.util.logging.FileHandler.encoding", "iso-8859-1");
+ // limit to only two message
+ props.put("java.util.logging.FileHandler.limit", "1000");
+ // rotation count is 2
+ props.put("java.util.logging.FileHandler.count", "2");
+ // using append mode
+ props.put("java.util.logging.FileHandler.append", "true");
+ props.put("java.util.logging.FileHandler.pattern",
+ "%t/log/java%u.test");
+
+ File home = new File(HOMEPATH);
+ if (!home.exists()) {
+ home.mkdirs();
+ } else if (!home.isDirectory()) {
+ home.delete();
+ home.mkdirs();
+ }
+ if(!home.isDirectory()) {
+ fail("unable to create temp path");
+ }
+ System.setProperty("user.home", HOMEPATH);
+
+ File file = new File(TEMPPATH + SEP + "log");
+ file.mkdir();
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new FileHandler();
+ r = new LogRecord(Level.CONFIG, "msg");
+ errSubstituteStream = new NullOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ }
+
+
+ /*
+ * @see TestCase#tearDown()
+ */
+
+ protected void tearDown() throws Exception {
+ if (null != handler) {
+ handler.close();
+ }
+ reset(TEMPPATH + SEP + "log", "");
+ System.setErr(err);
+ System.setProperty("user.home", oldHomePath);
+ new File(HOMEPATH).delete();
+ super.tearDown();
+ }
+
+ /*
+ * test for constructor void FileHandler()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify exceptions.",
+ method = "FileHandler",
+ args = {}
+ )
+ public void testFileHandler() throws Exception {
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler();
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "java0.test.0",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ }
+
+ /*
+ * test for constructor void FileHandler(String)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify security exception.",
+ method = "FileHandler",
+ args = {java.lang.String.class}
+ )
+ public void testFileHandler_1params() throws Exception {
+
+ handler = new FileHandler("%t/log/string");
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string");
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
+ r, null, r, null, r, null, r }, new MockFormatter());
+
+ // test if unique ids not specified, it will append at the end
+ // no generation number is used
+ FileHandler h = new FileHandler("%t/log/string");
+ FileHandler h2 = new FileHandler("%t/log/string");
+ FileHandler h3 = new FileHandler("%t/log/string");
+ FileHandler h4 = new FileHandler("%t/log/string");
+ h.publish(r);
+ h2.publish(r);
+ h3.publish(r);
+ h4.publish(r);
+ h.close();
+ h2.close();
+ h3.close();
+ h4.close();
+ assertFileContent(TEMPPATH + SEP + "log", "string", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.1", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.2", h.getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "string.3", h.getFormatter());
+
+ // default is append mode
+ FileHandler h6 = new FileHandler("%t/log/string%u.log");
+ h6.publish(r);
+ h6.close();
+ FileHandler h7 = new FileHandler("%t/log/string%u.log");
+ h7.publish(r);
+ h7.close();
+ try {
+ assertFileContent(TEMPPATH + SEP + "log", "string0.log", h
+ .getFormatter());
+ fail("should assertion failed");
+ } catch (Error e) {
+ }
+ File file = new File(TEMPPATH + SEP + "log");
+ assertTrue("length list of file is incorrect", file.list().length <= 2);
+
+ // test unique ids
+ FileHandler h8 = new FileHandler("%t/log/%ustring%u.log");
+ h8.publish(r);
+ FileHandler h9 = new FileHandler("%t/log/%ustring%u.log");
+ h9.publish(r);
+ h9.close();
+ h8.close();
+ assertFileContent(TEMPPATH + SEP + "log", "0string0.log", h
+ .getFormatter());
+ assertFileContent(TEMPPATH + SEP + "log", "1string1.log", h
+ .getFormatter());
+ file = new File(TEMPPATH + SEP + "log");
+ assertTrue("length list of file is incorrect", file.list().length <= 2);
+
+ try {
+ new FileHandler("");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /*
+ * test for constructor void FileHandler(String pattern, boolean append)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify security exception.",
+ method = "FileHandler",
+ args = {java.lang.String.class, boolean.class}
+ )
+ public void testFileHandler_2params() throws Exception {
+ boolean append = false;
+ do {
+ append = !append;
+ handler = new FileHandler("%t/log/string", append);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", append);
+ handler.publish(r);
+ handler.close();
+ }
+ if (append) {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ } else {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r }, new MockFormatter());
+ }
+ } while (append);
+
+ try {
+ new FileHandler("", true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /*
+ * test for constructor void FileHandler(String pattern, int limit, int
+ * count)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verifysecurity exception.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class}
+ )
+ public void testFileHandler_3params() throws Exception {
+ int limit = 120;
+ int count = 1;
+ handler = new FileHandler("%t/log/string", limit, count);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", limit, count);
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(TEMPPATH + SEP + "log", "/string", new LogRecord[] {
+ r, null, r, null, r, null, r }, new MockFormatter());
+
+ try {
+ new FileHandler("", limit, count);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", -1, count);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", limit, 0);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /*
+ * test for constructor public FileHandler(String pattern, int limit, int
+ * count, boolean append)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify security exception.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class, boolean.class}
+ )
+ public void testFileHandler_4params() throws Exception {
+ int limit = 120;
+ int count = 1;
+ boolean append = false;
+ do {
+ append = !append;
+ handler = new FileHandler("%t/log/string", limit, count, append);
+ assertEquals("character encoding is non equal to actual value",
+ "iso-8859-1", handler.getEncoding());
+ assertNotNull("Filter is null", handler.getFilter());
+ assertNotNull("Formatter is null", handler.getFormatter());
+ assertEquals("is non equal to actual value", Level.FINE, handler
+ .getLevel());
+ assertNotNull("ErrorManager is null", handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and all records left
+ // append mode is true
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler("%t/log/string", limit, count, append);
+ handler.publish(r);
+ handler.close();
+ }
+ if (append) {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r, null, r, null, r, null, r },
+ new MockFormatter());
+ } else {
+ assertFileContent(TEMPPATH + SEP + "log", "/string",
+ new LogRecord[] { r }, new MockFormatter());
+ }
+ } while (append);
+
+ try {
+ new FileHandler("", limit, count, true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", -1, count, false);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ try {
+ new FileHandler("%t/log/string", limit, 0, true);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getEncoding",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getFormatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getErrorManager",
+ args = {}
+ )
+ })
+ public void testDefaultValue() throws Exception {
+ handler.publish(r);
+ handler.close();
+ props.clear();
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new FileHandler();
+ assertNull(handler.getEncoding());
+ assertNull(handler.getFilter());
+ assertTrue(handler.getFormatter() instanceof XMLFormatter);
+ assertEquals(handler.getLevel(), Level.ALL);
+ assertNotNull(handler.getErrorManager());
+ handler.publish(r);
+ handler.close();
+ // output 3 times, and only one record left
+ // default append mode is false
+ for (int i = 0; i < 3; i++) {
+ handler = new FileHandler();
+ handler.publish(r);
+ handler.close();
+ }
+ assertFileContent(HOMEPATH, "java0.log", new XMLFormatter());
+ }
+
+ private void assertFileContent(String homepath, String filename,
+ Formatter formatter) throws Exception {
+ assertFileContent(homepath, filename, new LogRecord[] { r }, formatter);
+ }
+
+ private void assertFileContent(String homepath, String filename,
+ LogRecord[] lr, Formatter formatter) throws Exception {
+ handler.close();
+ String msg = "";
+ // if formatter is null, the file content should be empty
+ // else the message should be formatted given records
+ if (null != formatter) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(formatter.getHead(handler));
+ for (int i = 0; i < lr.length; i++) {
+ if (null == lr[i] && i < lr.length - 1) {
+ // if one record is null and is not the last record, means
+ // here is
+ // output completion point, should output tail, then output
+ // head
+ // (ready for next output)
+ sb.append(formatter.getTail(handler));
+ sb.append(formatter.getHead(handler));
+ } else {
+ sb.append(formatter.format(lr[i]));
+ }
+ }
+ sb.append(formatter.getTail(handler));
+ msg = sb.toString();
+ }
+ char[] chars = new char[msg.length()];
+ Reader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(homepath + SEP
+ + filename));
+ reader.read(chars);
+ assertEquals(msg, new String(chars));
+ // assert has reached the end of the file
+ assertEquals(-1, reader.read());
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (Exception e) {
+ // don't care
+ }
+ reset(homepath, filename);
+ }
+ }
+
+ /**
+ * Does a cleanup of given file
+ *
+ * @param homepath
+ * @param filename
+ */
+ private void reset(String homepath, String filename) {
+ File file = null;
+ try {
+ file = new File(homepath + SEP + filename);
+ if (file.isFile()) {
+ file.delete();
+ } else if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ files[i].delete();
+ }
+ file.delete();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ try {
+ file = new File(homepath + SEP + filename + ".lck");
+ file.delete();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class, boolean.class}
+ )
+ public void testLimitAndCount() throws Exception {
+ handler.close();
+ // very small limit value, count=2
+ // output, rename current output file to the second generation file
+ // close it and open a new file as rotation output
+ handler = new FileHandler("%t/testLimitCount%g", 1, 2, false);
+ handler.publish(r);
+ handler.close();
+ assertFileContent(TEMPPATH, "testLimitCount1", handler.getFormatter());
+
+ // very small limit value, count=1
+ // output once, rotate(equals to nothing output)
+ handler = new FileHandler("%t/testLimitCount%g", 1, 1, false);
+ handler.publish(r);
+ handler.close();
+ assertFileContent(TEMPPATH, "testLimitCount0", new LogRecord[0],
+ handler.getFormatter());
+
+ // normal case, limit is 60(>2*msg length <3*msg length), append is
+ // false
+ handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
+ LogRecord[] rs = new LogRecord[10];
+ // batch output twice to test the append mode
+ for (int i = 0; i < 5; i++) {
+ rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
+ handler.publish(rs[i]);
+ }
+ handler.close();
+ handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
+ for (int i = 5; i < 10; i++) {
+ rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
+ handler.publish(rs[i]);
+ }
+
+ assertFileContent(TEMPPATH, "testLimitCount0.1", new LogRecord[] {
+ rs[5], rs[6], rs[7] }, handler.getFormatter());
+ assertFileContent(TEMPPATH, "testLimitCount0.0", new LogRecord[] {
+ rs[8], rs[9] }, handler.getFormatter());
+
+ // normal case, limit is 60(>2*msg length <3*msg length), append is true
+ handler = new FileHandler("%t/testLimitCount%u", 60, 3, false);
+ // batch output twice to test the append mode
+ for (int i = 0; i < 5; i++) {
+ rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
+ handler.publish(rs[i]);
+ }
+ handler.close();
+ handler = new FileHandler("%t/testLimitCount%u", 60, 3, true);
+ for (int i = 5; i < 10; i++) {
+ rs[i] = new LogRecord(Level.SEVERE, "msg" + i);
+ handler.publish(rs[i]);
+ }
+ handler.close();
+ assertFileContent(TEMPPATH, "testLimitCount0.2", new LogRecord[] {
+ rs[3], rs[4], null, rs[5] }, handler.getFormatter());
+ assertFileContent(TEMPPATH, "testLimitCount0.1", new LogRecord[] {
+ rs[6], rs[7], rs[8] }, handler.getFormatter());
+ assertFileContent(TEMPPATH, "testLimitCount0.0",
+ new LogRecord[] { rs[9] }, handler.getFormatter());
+
+ String oldUserDir = System.getProperty("user.dir");
+ System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
+ FileHandler h1 = null;
+ FileHandler h2 = null;
+ try {
+ File logDir = new File("log");
+ reset("log", "");
+ logDir.mkdir();
+ h1 = new FileHandler("log/a", 0, 1);
+ assertNotNull(h1);
+ h2 = new FileHandler("log/a", 0, 1, false);
+ assertNotNull(h2);
+ } finally {
+ try {
+ h1.close();
+ } catch (Exception e) {
+ }
+ try {
+ h2.close();
+ } catch (Exception e) {
+ }
+ reset("log", "");
+ System.setProperty("user.dir", oldUserDir);
+ }
+ }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "close",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {java.lang.String.class, boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class, boolean.class}
+ )
+ })
+ public void testSecurity() throws IOException {
+ SecurityManager currentManager = System.getSecurityManager();
+
+ try {
+ System.setSecurityManager(new MockLogSecurityManager());
+ try {
+ handler.close();
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ handler.publish(new LogRecord(Level.SEVERE, "msg"));
+
+ try {
+ handler = new FileHandler();
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+
+ try {
+ handler = new FileHandler("pattern1");
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern2", true);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern3", 1000, 1);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern4", 1000, 1, true);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ } finally {
+ System.setSecurityManager(currentManager);
+ }
+
+ }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "close",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "FileHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "FileHandler",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class, boolean.class}
+ )
+ })
+ public void testFileSecurity() throws IOException {
+ SecurityManager currentManager = System.getSecurityManager();
+
+ try {
+ System.setSecurityManager(new MockFileSecurityManager());
+ handler.publish(new LogRecord(Level.SEVERE, "msg"));
+ try {
+ handler.close();
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+
+ try {
+ handler = new FileHandler();
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+
+ try {
+ handler = new FileHandler("pattern1");
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern2", true);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern3", 1000, 1);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler = new FileHandler("pattern4", 1000, 1, true);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ } finally {
+ System.setSecurityManager(currentManager);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies FileHandler when configuration file is invalid.",
+ method = "FileHandler",
+ args = {}
+ )
+ public void testInvalidProperty() throws Exception {
+ props.put("java.util.logging.FileHandler.level", "null");
+ props.put("java.util.logging.FileHandler.filter", className
+ + "$MockFilte");
+ props.put("java.util.logging.FileHandler.formatter", className
+ + "$MockFormatte");
+ props.put("java.util.logging.FileHandler.encoding", "ut");
+ // limit to only two message
+ props.put("java.util.logging.FileHandler.limit", "-1");
+ // rotation count is 2
+ props.put("java.util.logging.FileHandler.count", "-1");
+ // using append mode
+ props.put("java.util.logging.FileHandler.append", "bad");
+
+ handler.close();
+
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new FileHandler();
+ assertEquals(Level.ALL, handler.getLevel());
+ assertNull(handler.getFilter());
+ assertTrue(handler.getFormatter() instanceof XMLFormatter);
+ assertNull(handler.getEncoding());
+ handler.close();
+
+ props.put("java.util.logging.FileHandler.pattern", "");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ try {
+ handler = new FileHandler();
+ fail("shouldn't open file with empty name");
+ } catch (NullPointerException e) {
+ }
+ }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ })
+ @AndroidOnly("This test fails on RI. Doesn't parse special pattern \"%t/%h.")
+ public void testInvalidParams() throws IOException {
+
+ // %t and %p parsing can add file separator automatically
+ FileHandler h1 = new FileHandler("%taaa");
+ h1.close();
+ File file = new File(TEMPPATH + SEP + "aaa");
+ assertTrue(file.exists());
+ reset(TEMPPATH, "aaa");
+
+ h1 = new FileHandler("%t%g");
+ h1.close();
+ file = new File(TEMPPATH + SEP + "0");
+ assertTrue(file.exists());
+ reset(TEMPPATH, "0");
+ h1 = new FileHandler("%t%u%g");
+ h1.close();
+ file = new File(TEMPPATH + SEP + "00");
+ assertTrue(file.exists());
+ reset(TEMPPATH, "00");
+
+ // this is normal case
+ h1 = new FileHandler("%t/%u%g%%g");
+ h1.close();
+ file = new File(TEMPPATH + SEP + "00%g");
+ assertTrue(file.exists());
+ reset(TEMPPATH, "00%g");
+
+ // multi separator has no effect
+ h1 = new FileHandler("//%t//multi%g");
+ h1.close();
+ file = new File(TEMPPATH + SEP + "multi0");
+ assertTrue(file.exists());
+ reset(TEMPPATH, "multi0");
+
+ // bad directory, IOException
+ try {
+ h1 = new FileHandler("%t/baddir/multi%g");
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+ // bad directory, IOException, append
+ try {
+ h1 = new FileHandler("%t/baddir/multi%g", true);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+ try {
+ h1 = new FileHandler("%t/baddir/multi%g", false);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+ try {
+ h1 = new FileHandler("%t/baddir/multi%g", 12, 4);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+ try {
+ h1 = new FileHandler("%t/baddir/multi%g", 12, 4, true);
+ fail("should throw IO exception");
+ } catch (IOException e) {
+ }
+ file = new File(TEMPPATH + SEP + "baddir" + SEP + "multi0");
+ assertFalse(file.exists());
+
+
+ try {
+ new FileHandler(null);
+ fail("should throw null exception");
+ } catch (NullPointerException e) {
+ }
+ try {
+ handler.publish(null);
+ } catch (NullPointerException e) {
+ fail("should not throw NPE");
+ }
+ try {
+ new FileHandler(null, false);
+ fail("should throw null exception");
+ } catch (NullPointerException e) {
+ }
+ try {
+ new FileHandler("");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ new FileHandler("%t/java%u", 0, 0);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ new FileHandler("%t/java%u", -1, 1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new FileHandler("%t/java%u", -1, -1);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // always parse special pattern
+ System.setProperty("user.home", "home");
+ try {
+ h1 = new FileHandler("%t/%h.txt");
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ }
+ }
+
+ /*
+ * test for method public void publish(LogRecord record)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish() throws Exception {
+ LogRecord[] r = new LogRecord[] { new LogRecord(Level.CONFIG, "msg__"),
+ new LogRecord(Level.WARNING, "message"),
+ new LogRecord(Level.INFO, "message for"),
+ new LogRecord(Level.FINE, "message for test") };
+ for (int i = 0; i < r.length; i++) {
+ handler = new FileHandler("%t/log/stringPublish");
+ handler.publish(r[i]);
+ handler.close();
+ assertFileContent(TEMPPATH + SEP + "log", "stringPublish",
+ new LogRecord[] { r[i] }, handler.getFormatter());
+ }
+ }
+
+ /*
+ * test for method public void close()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "close",
+ args = {}
+ )
+ public void testClose() throws Exception {
+ FileHandler h = new FileHandler("%t/log/stringPublish");
+ h.publish(r);
+ h.close();
+ assertFileContent(TEMPPATH + SEP + "log", "stringPublish", h
+ .getFormatter());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify SecurityException.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ // set output stream still works, just like super StreamHandler
+ public void testSetOutputStream() throws Exception {
+ MockFileHandler handler = new MockFileHandler("%h/setoutput.log");
+ handler.setFormatter(new MockFormatter());
+ handler.publish(r);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ handler.publicSetOutputStream(out);
+ handler.publish(r);
+ handler.close();
+ String msg = new String(out.toByteArray());
+ Formatter f = handler.getFormatter();
+ assertEquals(msg, f.getHead(handler) + f.format(r) + f.getTail(handler));
+ assertFileContent(HOMEPATH, "setoutput.log", handler.getFormatter());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class}
+ )
+ public void testEmptyPattern_3params() throws SecurityException,
+ IOException {
+ try {
+ new FileHandler(new String(), 1, 1);
+ fail("Expected an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, boolean.class}
+ )
+ public void testEmptyPattern_2params() throws SecurityException,
+ IOException {
+ try {
+ new FileHandler(new String(), true);
+ fail("Expected an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IllegalArgumentException.",
+ method = "FileHandler",
+ args = {java.lang.String.class, int.class, int.class, boolean.class}
+ )
+ public void testEmptyPattern_4params() throws SecurityException,
+ IOException {
+ try {
+ new FileHandler(new String(), 1, 1, true);
+ fail("Expected an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /*
+ * mock classes
+ */
+ public static class MockFilter implements Filter {
+ public boolean isLoggable(LogRecord record) {
+ return !record.getMessage().equals("false");
+ }
+ }
+
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord r) {
+ if (null == r) {
+ return "";
+ }
+ return r.getMessage() + " by MockFormatter\n";
+ }
+
+ public String getTail(Handler h) {
+ return "tail\n";
+ }
+
+ public String getHead(Handler h) {
+ return "head\n";
+ }
+ }
+
+ public static class MockLogSecurityManager extends SecurityManager {
+ public void checkPermission(Permission perm) {
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ return;
+ }
+ }
+
+ public static class MockFileSecurityManager extends SecurityManager {
+ public void checkPermission(Permission perm) {
+ if (perm instanceof FilePermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ public static class MockFileHandler extends FileHandler {
+ public MockFileHandler() throws IOException {
+ super();
+ }
+
+ public MockFileHandler(String pattern) throws IOException {
+ super(pattern);
+ }
+
+ public void publicSetOutputStream(OutputStream stream) {
+ super.setOutputStream(stream);
+ }
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java
new file mode 100644
index 0000000..d7ce843
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+//TODO :
+/*
+ * 1. Don't forget to write tests for org.apache.harmony.logging.internal.nls/Messages.java this file is in logging/src/main/java folder
+ * 2. inrteface filter / LoggingMXBean tests machen
+ * 3. XMLFormatter.java should be finish for Monday (not a lot to do) but as I beginn want to finish.
+ * 3. In my case
+ * I didn't use the PARTIAL_OK, so I believe that 98% of COMPLETE are PARTIAL_OK
+ * COMPLETE = Tests finish and should be working. If error check the test before to make a ticket.
+ * PARTIAL = Tests finish, but need special reviewing
+ * TODO = A test to do (or not). Mostly a test to complete
+ * 4. For questions christian.wiederseiner
+ */
+
+package org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.logging.Filter;
+import java.util.logging.LogRecord;
+
+import junit.framework.TestCase;
+
+/**
+ * This testcase verifies the signature of the interface Filter.
+ *
+ */
+@TestTargetClass(Filter.class)
+public class FilterTest extends TestCase {
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies interface.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testFilter() {
+ MockFilter f = new MockFilter();
+ assertFalse(f.isLoggable(null));
+ }
+
+ /*
+ * This inner class implements the interface Filter to verify the signature.
+ */
+ private class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ return false;
+ }
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
new file mode 100644
index 0000000..ba2345d
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.logging.FileHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+@TestTargetClass(Formatter.class)
+public class FormatterTest extends TestCase {
+ Formatter f;
+
+ LogRecord r;
+
+ FileHandler h;
+
+ static String MSG = "msg, pls. ignore it";
+
+ static LogManager manager = LogManager.getLogManager();
+
+ final static Properties props = new Properties();
+
+ final static String className = FormatterTest.class.getName();
+
+ final static String TEMPPATH = System.getProperty("java.io.tmpdir");
+
+ final static String SEP = File.separator;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ manager.reset();
+
+ //initProp
+ props.clear();
+ props.put("java.util.logging.FileHandler.level", "FINE");
+ props.put("java.util.logging.FileHandler.filter", className
+ + "$MockFilter");
+ props.put("java.util.logging.FileHandler.formatter", className
+ + "$MockFormatter");
+ props.put("java.util.logging.FileHandler.encoding", "iso-8859-1");
+ // limit to only two message
+ props.put("java.util.logging.FileHandler.limit", "1000");
+ // rotation count is 2
+ props.put("java.util.logging.FileHandler.count", "2");
+ // using append mode
+ props.put("java.util.logging.FileHandler.append", "true");
+ props.put("java.util.logging.FileHandler.pattern",
+ "%t/log/java%u.test");
+
+ File file = new File(TEMPPATH + SEP + "log");
+ file.mkdir();
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+
+ f = new MockFormatter();
+ r = new LogRecord(Level.FINE, MSG);
+ h = new FileHandler();
+ }
+
+ /*
+ * test for constructor protected Formatter()
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "Formatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {java.util.logging.Handler.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ )
+ })
+ public void testFormatter() {
+ assertEquals("head string is not empty", "", f.getHead(null));
+ assertEquals("tail string is not empty", "", f.getTail(null));
+
+ }
+
+ /*
+ * test for method public String getHead(Handler h)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {Handler.class}
+ )
+ public void testGetHead() {
+ assertEquals("head string is not empty", "", f.getHead(null));
+ assertEquals("head string is not empty", "", f.getHead(h));
+ h.publish(r);
+ assertEquals("head string is not empty", "", f.getHead(h));
+ }
+
+ /*
+ * test for method public String getTail(Handler h)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {Handler.class}
+ )
+ public void testGetTail() {
+ assertEquals("tail string is not empty", "", f.getTail(null));
+ assertEquals("tail string is not empty", "", f.getTail(h));
+ h.publish(r);
+ assertEquals("tail string is not empty", "", f.getTail(h));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "formatMessage",
+ args = {LogRecord.class}
+ )
+ @AndroidOnly("The RI fails in this test because it uses a MessageFormat " +
+ "to format the message even though it doesn't contain \"{0\". " +
+ "The spec says that this would indicate that a MessageFormat " +
+ "should be used and else no formatting should be done.")
+ public void testFormatMessage() {
+ assertEquals(MSG, f.formatMessage(r));
+
+ String pattern = "test formatter {0, number}";
+ r.setMessage(pattern);
+ assertEquals(pattern, f.formatMessage(r));
+
+ Object[] oa = new Object[0];
+ r.setParameters(oa);
+ assertEquals(pattern, f.formatMessage(r));
+
+ oa = new Object[] { new Integer(100), new Float(1.2), new Float(2.2) };
+ r.setParameters(oa);
+ assertEquals(MessageFormat.format(pattern, oa), f.formatMessage(r));
+
+ r.setMessage(MSG);
+ assertEquals(MSG, f.formatMessage(r));
+
+ pattern = "wrong pattern {0, asdfasfd}";
+ r.setMessage(pattern);
+ assertEquals(pattern, f.formatMessage(r));
+
+ pattern = null;
+ r.setMessage(pattern);
+ assertNull(f.formatMessage(r));
+
+ // The RI fails in this test because it uses a MessageFormat to format
+ // the message even though it doesn't contain "{0". The spec says that
+ // this would indicate that a MessageFormat should be used and else no
+ // formatting should be done.
+ pattern = "pattern without 0 {1, number}";
+ r.setMessage(pattern);
+ assertEquals(pattern, f.formatMessage(r));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "formatMessage",
+ args = {LogRecord.class}
+ )
+ public void testLocalizedFormatMessage() {
+ // normal case
+ r.setMessage("msg");
+ ResourceBundle rb = ResourceBundle
+ .getBundle("bundles/java/util/logging/res");
+ r.setResourceBundle(rb);
+ assertEquals(rb.getString("msg"), f.formatMessage(r));
+
+ // local message is a pattern
+ r.setMessage("pattern");
+ Object[] oa = new Object[] { new Integer(3) };
+ r.setParameters(oa);
+ assertEquals(MessageFormat.format(rb.getString("pattern"), oa), f
+ .formatMessage(r));
+
+ // key is a pattern, but local message is not
+ r.setMessage("pattern{0,number}");
+ oa = new Object[] { new Integer(3) };
+ r.setParameters(oa);
+ assertEquals(rb.getString("pattern{0,number}"), f.formatMessage(r));
+
+ // another bundle
+ rb = ResourceBundle.getBundle("bundles/java/util/logging/res",
+ Locale.US);
+ r.setMessage("msg");
+ r.setResourceBundle(rb);
+ assertEquals(rb.getString("msg"), f.formatMessage(r));
+
+ // cannot find local message in bundle
+ r.setMessage("msg without locale");
+ assertEquals("msg without locale", f.formatMessage(r));
+
+ // set bundle name but not bundle
+ r.setResourceBundle(null);
+ r.setResourceBundleName("bundles/java/util/logging/res");
+ r.setMessage("msg");
+ assertEquals("msg", f.formatMessage(r));
+ }
+
+ public static class MockFormatter extends Formatter {
+
+ public String format(LogRecord arg0) {
+ return "format";
+ }
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
new file mode 100644
index 0000000..5868b1f
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
@@ -0,0 +1,780 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.Permission;
+import java.util.EmptyStackException;
+import java.util.Properties;
+import java.util.logging.ErrorManager;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.SimpleFormatter;
+
+import junit.framework.TestCase;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+import tests.util.CallVerificationStack;
+
+/**
+ * Test suite for the class java.util.logging.Handler.
+ *
+ */
+@TestTargetClass(Handler.class)
+public class HandlerTest extends TestCase {
+ private static String className = HandlerTest.class.getName();
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ CallVerificationStack.getInstance().clear();
+ }
+
+ /*
+ * Test the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "Handler",
+ args = {}
+ )
+ public void testConstructor() {
+ MockHandler h = new MockHandler();
+ assertSame(h.getLevel(), Level.ALL);
+ assertNull(h.getFormatter());
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ assertTrue(h.getErrorManager() instanceof ErrorManager);
+ }
+
+ /*
+ * Test the constructor, with properties set
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "Handler",
+ args = {}
+ )
+ public void testConstructor_Properties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.MockHandler.level", "FINE");
+ p.put("java.util.logging.MockHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.Handler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.MockHandler.encoding", "utf-8");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.MockHandler.level"), "FINE");
+ assertEquals(LogManager.getLogManager().getProperty(
+ "java.util.logging.MockHandler.encoding"), "utf-8");
+ MockHandler h = new MockHandler();
+ assertSame(h.getLevel(), Level.ALL);
+ assertNull(h.getFormatter());
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ assertTrue(h.getErrorManager() instanceof ErrorManager);
+ LogManager.getLogManager().reset();
+ }
+
+ /*
+ * Test getEncoding & setEncoding methods with supported encoding.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify exceptions.",
+ method = "getEncoding",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify exceptions.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetEncoding_Normal() throws Exception {
+ MockHandler h = new MockHandler();
+ h.setEncoding("iso-8859-1");
+ assertEquals("iso-8859-1", h.getEncoding());
+ }
+
+ /*
+ * Test getEncoding & setEncoding methods with null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "getEncoding",
+ args = {}
+ )
+ public void testGetSetEncoding_Null() throws Exception {
+ MockHandler h = new MockHandler();
+ h.setEncoding(null);
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test getEncoding & setEncoding methods with unsupported encoding.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies UnsupportedEncodingException.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testGetSetEncoding_Unsupported() {
+ MockHandler h = new MockHandler();
+ try {
+ h.setEncoding("impossible");
+ fail("Should throw UnsupportedEncodingException!");
+ } catch (UnsupportedEncodingException e) {
+ }
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test setEncoding with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify UnsupportedEncodingException.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ // set a normal value
+ try {
+ h.setEncoding("iso-8859-1");
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ assertNull(h.getEncoding());
+ System.setSecurityManager(new MockSecurityManager());
+ // set an invalid value
+ try {
+
+ h.setEncoding("impossible");
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test getErrorManager & setErrorManager methods with non-null value.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "setErrorManager",
+ args = {java.util.logging.ErrorManager.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getErrorManager",
+ args = {}
+ )
+ })
+ public void testGetSetErrorManager_Normal() throws Exception {
+ MockHandler h = new MockHandler();
+ ErrorManager man = new ErrorManager();
+ h.setErrorManager(man);
+ assertSame(man, h.getErrorManager());
+ }
+
+ /*
+ * Test getErrorManager & setErrorManager methods with null.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "getErrorManager",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "setErrorManager",
+ args = {java.util.logging.ErrorManager.class}
+ )
+ })
+ public void testGetSetErrorManager_Null() throws Exception {
+ MockHandler h = new MockHandler();
+ // test set null
+ try {
+ h.setErrorManager(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+
+ // test reset null
+ try {
+ h.setErrorManager(new ErrorManager());
+ h.setErrorManager(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test getErrorManager with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "getErrorManager",
+ args = {}
+ )
+ public void testGetErrorManager_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ h.getErrorManager();
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setErrorManager with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setErrorManager with insufficient privilege.",
+ method = "setErrorManager",
+ args = {java.util.logging.ErrorManager.class}
+ )
+ public void testSetErrorManager_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ // set null
+ try {
+
+ h.setErrorManager(null);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ // set a normal value
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+
+ h.setErrorManager(new ErrorManager());
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getFilter & setFilter methods with non-null value.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "getFilter",
+ args = {}
+ )
+ })
+ public void testGetSetFilter_Normal() throws Exception {
+ MockHandler h = new MockHandler();
+ Filter f = new MockFilter();
+ h.setFilter(f);
+ assertSame(f, h.getFilter());
+ }
+
+ /*
+ * Test getFilter & setFilter methods with null.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testGetSetFilter_Null() throws Exception {
+ MockHandler h = new MockHandler();
+ // test set null
+ h.setFilter(null);
+
+ // test reset null
+ h.setFilter(new MockFilter());
+ h.setFilter(null);
+ }
+
+ /*
+ * Test setFilter with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ public void testSetFilter_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ // set null
+ try {
+
+ h.setFilter(null);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ // set a normal value
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+
+ h.setFilter(new MockFilter());
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getFormatter & setFormatter methods with non-null value.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "getFormatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "setFormatter",
+ args = {java.util.logging.Formatter.class}
+ )
+ })
+ public void testGetSetFormatter_Normal() throws Exception {
+ MockHandler h = new MockHandler();
+ Formatter f = new SimpleFormatter();
+ h.setFormatter(f);
+ assertSame(f, h.getFormatter());
+ }
+
+ /*
+ * Test getFormatter & setFormatter methods with null.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "getFormatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "setFormatter",
+ args = {java.util.logging.Formatter.class}
+ )
+ })
+ public void testGetSetFormatter_Null() throws Exception {
+ MockHandler h = new MockHandler();
+ // test set null
+ try {
+ h.setFormatter(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+
+ // test reset null
+ try {
+ h.setFormatter(new SimpleFormatter());
+ h.setFormatter(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test setFormatter with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "getFormatter",
+ args = {}
+ )
+ public void testSetFormatter_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ // set null
+ try {
+
+ h.setFormatter(null);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ // set a normal value
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+
+ h.setFormatter(new SimpleFormatter());
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getLevel & setLevel methods with non-null value.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testGetSetLevel_Normal() throws Exception {
+ MockHandler h = new MockHandler();
+ Level f = Level.CONFIG;
+ h.setLevel(f);
+ assertSame(f, h.getLevel());
+ }
+
+ /*
+ * Test getLevel & setLevel methods with null.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLevel & setLevel methods with null.",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLevel & setLevel methods with null.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testGetSetLevel_Null() throws Exception {
+ MockHandler h = new MockHandler();
+ // test set null
+ try {
+ h.setLevel(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+
+ // test reset null
+ try {
+ h.setLevel(Level.CONFIG);
+ h.setLevel(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test setLevel with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException, SecurityException.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ public void testSetLevel_InsufficientPrivilege() throws Exception {
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ // set null
+ try {
+
+ h.setLevel(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ // set a normal value
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+
+ h.setLevel(Level.CONFIG);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Use no filter
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_NoFilter() {
+ MockHandler h = new MockHandler();
+ LogRecord r = new LogRecord(Level.CONFIG, null);
+ assertTrue(h.isLoggable(r));
+
+ h.setLevel(Level.CONFIG);
+ assertTrue(h.isLoggable(r));
+
+ h.setLevel(Level.SEVERE);
+ assertFalse(h.isLoggable(r));
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ assertFalse(h.isLoggable(r));
+ }
+
+ /*
+ * Use a filter
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies isLoggable method with filter.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_WithFilter() {
+ MockHandler h = new MockHandler();
+ LogRecord r = new LogRecord(Level.CONFIG, null);
+ LogRecord r1 = new LogRecord(Level.CONFIG, null);
+ LogRecord r2 = new LogRecord(Level.CONFIG, null);
+
+ h.setFilter(new MockFilter());
+ assertFalse(h.isLoggable(r));
+ assertSame(r,CallVerificationStack.getInstance().pop());
+
+ h.setLevel(Level.CONFIG);
+ assertFalse(h.isLoggable(r1));
+ assertSame(r1, CallVerificationStack.getInstance().pop());
+
+ h.setLevel(Level.SEVERE);
+ assertFalse(h.isLoggable(r2));
+
+ try{
+ CallVerificationStack.getInstance().pop();
+ }catch(EmptyStackException e){
+ //normal
+ }
+ }
+
+ /**
+ * @tests java.util.logging.Handler#isLoggable(LogRecord)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_Null() {
+ MockHandler h = new MockHandler();
+ try {
+ h.isLoggable(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test whether the error manager is actually called with expected
+ * parameters.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "reportError",
+ args = {java.lang.String.class, java.lang.Exception.class, int.class}
+ )
+ public void testReportError() {
+ MockHandler h = new MockHandler();
+ h.setErrorManager(new MockErrorManager());
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ Exception ex = new Exception("test exception");
+ // with non-null parameters
+ h.reportError("test msg", ex, -1);
+ assertEquals(-1, CallVerificationStack.getInstance().popInt());
+ assertSame(ex, CallVerificationStack.getInstance().pop());
+ assertEquals("test msg", CallVerificationStack.getInstance().pop());
+ // with null parameters
+ h.reportError(null, null, 0);
+ assertEquals(0, CallVerificationStack.getInstance().popInt());
+ assertSame(null, CallVerificationStack.getInstance().pop());
+ assertNull(CallVerificationStack.getInstance().pop());
+ } catch (SecurityException e) {
+ fail("Should not throw SecurityException!");
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Used to enable the testing of Handler because Handler is an abstract
+ * class.
+ */
+ public static class MockHandler extends Handler {
+
+ public void close() {
+ }
+
+ public void flush() {
+ }
+
+ public void publish(LogRecord record) {
+ }
+
+ public void reportError(String msg, Exception ex, int code) {
+ super.reportError(msg, ex, code);
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockSecurityManager extends SecurityManager {
+
+ public MockSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ /*
+ * A mock filter, always return false.
+ */
+ public static class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ return false;
+ }
+ }
+
+ /*
+ * A mock error manager, used to validate the expected method is called with
+ * the expected parameters.
+ */
+ public static class MockErrorManager extends ErrorManager {
+
+ public void error(String msg, Exception ex, int errorCode) {
+ CallVerificationStack.getInstance().push(msg);
+ CallVerificationStack.getInstance().push(ex);
+ CallVerificationStack.getInstance().push(errorCode);
+ }
+ }
+
+ public static class NullOutputStream extends OutputStream{
+ @Override
+ public void write(int arg0) throws IOException {
+ }
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java
new file mode 100644
index 0000000..1fee1ba
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java
@@ -0,0 +1,645 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+
+import java.io.Serializable;
+import java.util.ResourceBundle;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+/*
+ * This class implements Serializable, so that the non-static inner class
+ * MockLevel can be Serializable.
+ */
+@TestTargetClass(Level.class)
+public class LevelTest extends TestCase implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Test the constructor without resource bundle parameter using normal
+ * values. As byproducts, getName & intValue are also tested.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using normal values.",
+ method = "Level",
+ args = {java.lang.String.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using normal values.",
+ method = "getName",
+ args = {}
+ )
+ })
+ public void testConstructorNoResBundle_Normal() {
+ MockLevel l = new MockLevel("level1", 1);
+ assertEquals("level1", l.getName());
+ assertEquals(1, l.intValue());
+ assertNull(l.getResourceBundleName());
+ }
+
+ /**
+ * Test the constructor without resource bundle parameter using null name.
+ * As byproducts, getName & intValue are also tested.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using null name.",
+ method = "Level",
+ args = {java.lang.String.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using null name.",
+ method = "getName",
+ args = {}
+ )
+ })
+ public void testConstructorNoResBundle_NullName() {
+ try {
+ new MockLevel(null, -2);
+ fail("No expected NullPointerException");
+ } catch (NullPointerException ignore) {
+ // expected
+ }
+ }
+
+ /*
+ * Test the constructor without resource bundle parameter using empty name.
+ * As byproducts, getName & intValue are also tested.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using empty name.",
+ method = "Level",
+ args = {java.lang.String.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks the constructor without resource bundle parameter using empty name.",
+ method = "getName",
+ args = {}
+ )
+ })
+ public void testConstructorNoResBundle_EmptyName() {
+ MockLevel l = new MockLevel("", -3);
+ assertEquals("", l.getName());
+ assertEquals(-3, l.intValue());
+ assertNull(l.getResourceBundleName());
+ }
+
+ /*
+ * Test the constructor having resource bundle parameter using normal
+ * values. As byproducts, getName & intValue are also tested.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "Level",
+ args = {java.lang.String.class, int.class, java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getName",
+ args = {}
+ )
+ })
+ public void testConstructorHavingResBundle_Normal() {
+ MockLevel l = new MockLevel("level1", 1, "resourceBundle");
+ assertEquals("level1", l.getName());
+ assertEquals(1, l.intValue());
+ assertEquals("resourceBundle", l.getResourceBundleName());
+ }
+
+ /*
+ * Test the constructor having resource bundle parameter using null names.
+ * As byproducts, getName & intValue are also tested.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks NullPointerException.",
+ method = "Level",
+ args = {java.lang.String.class, int.class, java.lang.String.class}
+ )
+ public void testConstructorHavingResBundle_NullName() {
+ try {
+ new MockLevel(null, -123, "qwe");
+ fail("No expected NullPointerException");
+ } catch (NullPointerException ignore) {
+ // expected
+ }
+ }
+
+ /*
+ * Test the constructor having resource bundle parameter using empty
+ names.
+ * As byproducts, getName & intValue are also tested.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor having resource bundle parameter using empty names.",
+ method = "Level",
+ args = {java.lang.String.class, int.class, java.lang.String.class}
+ )
+ public void testConstructorHavingResBundle_EmptyName() {
+ MockLevel l = new MockLevel("", -1000, "");
+ assertEquals("", l.getName());
+ assertEquals(-1000, l.intValue());
+ assertEquals("", l.getResourceBundleName());
+ }
+
+ /*
+ * Test method parse, with the pre-defined string consts.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies parse, with the pre-defined string consts.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_PredefinedConstStrings() {
+ assertSame(Level.SEVERE, Level.parse("SEVERE"));
+ assertSame(Level.WARNING, Level.parse("WARNING"));
+ assertSame(Level.INFO, Level.parse("INFO"));
+ assertSame(Level.CONFIG, Level.parse("CONFIG"));
+ assertSame(Level.FINE, Level.parse("FINE"));
+ assertSame(Level.FINER, Level.parse("FINER"));
+ assertSame(Level.FINEST, Level.parse("FINEST"));
+ assertSame(Level.OFF, Level.parse("OFF"));
+ assertSame(Level.ALL, Level.parse("ALL"));
+ }
+
+ /*
+ * Test method parse, with an undefined string.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "IllegalArgumentException is verified.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_IllegalConstString() {
+ try {
+ Level.parse("SEVERe");
+ fail("Should throw IllegalArgumentException if undefined string.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test method parse, with a null string.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_NullString() {
+ try {
+ Level.parse(null);
+ fail("Should throw NullPointerException.");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test method parse, with pre-defined valid number strings.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies parse, with pre-defined valid number strings.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_PredefinedNumber() {
+ assertSame(Level.SEVERE, Level.parse("SEVERE"));
+ assertSame(Level.WARNING, Level.parse("WARNING"));
+ assertSame(Level.INFO, Level.parse("INFO"));
+ assertSame(Level.CONFIG, Level.parse("CONFIG"));
+ assertSame(Level.FINE, Level.parse("FINE"));
+ assertSame(Level.FINER, Level.parse("FINER"));
+ assertSame(Level.FINEST, Level.parse("FINEST"));
+ assertSame(Level.OFF, Level.parse("OFF"));
+ assertSame(Level.ALL, Level.parse("ALL"));
+ assertSame(Level.SEVERE, Level.parse("1000"));
+ assertSame(Level.WARNING, Level.parse("900"));
+ assertSame(Level.INFO, Level.parse("800"));
+ assertSame(Level.CONFIG, Level.parse("700"));
+ assertSame(Level.FINE, Level.parse("500"));
+ assertSame(Level.FINER, Level.parse("400"));
+ assertSame(Level.FINEST, Level.parse("300"));
+ assertSame(Level.OFF, Level.parse(String.valueOf(Integer.MAX_VALUE)));
+ assertSame(Level.ALL, Level.parse(String.valueOf(Integer.MIN_VALUE)));
+ }
+
+ /*
+ * Test method parse, with an undefined valid number strings.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies parse, with an undefined valid number strings.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_UndefinedNumber() {
+ Level l = Level.parse("0");
+ assertEquals(0, l.intValue());
+ assertEquals("0", l.getName());
+ assertNull(l.getResourceBundleName());
+ }
+
+ /*
+ * Test method parse, with an undefined valid number strings with spaces.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies parse, with an undefined valid number strings with spaces.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_UndefinedNumberWithSpaces() {
+ try {
+ Level.parse(" 0");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies negative number.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_NegativeNumber() {
+ Level l = Level.parse("-4");
+ assertEquals(-4, l.intValue());
+ assertEquals("-4", l.getName());
+ assertNull(l.getResourceBundleName());
+ }
+
+ /*
+ * Test method parse, expecting the same objects will be returned given the
+ * same name, even for non-predefined levels.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies parse, expecting the same objects will be returned given the same name, even for non-predefined levels.",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testParse_SameObject() {
+ Level l = Level.parse("-100");
+ assertSame(l, Level.parse("-100"));
+ }
+
+ /*
+ * Test method hashCode, with normal fields.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "hashCode",
+ args = {}
+ )
+ public void testHashCode_Normal() {
+ assertEquals(100, Level.parse("100").hashCode());
+ assertEquals(-1, Level.parse("-1").hashCode());
+ assertEquals(0, Level.parse("0").hashCode());
+ assertEquals(Integer.MIN_VALUE, Level.parse("ALL").hashCode());
+ }
+
+ /*
+ * Test equals when two objects are equal.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't check negative case.",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals_Equal() {
+ MockLevel l1 = new MockLevel("level1", 1);
+ MockLevel l2 = new MockLevel("level2", 1);
+ assertEquals(l1, l2);
+ assertEquals(l2, l1);
+ }
+
+ /*
+ * Test equals when two objects are not equal.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks negative case.",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals_NotEqual() {
+ MockLevel l1 = new MockLevel("level1", 1);
+ MockLevel l2 = new MockLevel("level1", 2);
+ assertFalse(l1.equals(l2));
+ assertFalse(l2.equals(l1));
+ }
+
+ /*
+ * Test equals when the other object is null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks null as a parameter.",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals_Null() {
+ assertFalse(Level.ALL.equals(null));
+ }
+
+ /*
+ * Test equals when the other object is not an instance of Level.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks negative case.",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals_NotLevel() {
+ assertFalse(Level.ALL.equals(new Object()));
+ }
+
+ /*
+ * Test equals when the other object is itself.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks equals when the other object is itself.",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals_Itself() {
+ assertTrue(Level.ALL.equals(Level.ALL));
+ }
+
+ /*
+ * Test toString of a normal Level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "toString",
+ args = {}
+ )
+ public void testToString_Normal() {
+ assertEquals("ALL", Level.ALL.toString());
+
+ MockLevel l = new MockLevel("name", 2);
+ assertEquals("name", l.toString());
+
+ MockLevel emptyLevel = new MockLevel("", 3);
+ assertEquals("", emptyLevel.toString());
+ }
+
+ // comparator for Level objects:
+ // is used because Level.equals() method only takes into account
+ // 'level' value but ignores 'name' and 'resourceBundleName' values
+ private static final SerializableAssert LEVEL_COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ Level init = (Level) initial;
+ Level dser = (Level) deserialized;
+
+ assertEquals("Class", init.getClass(), dser.getClass());
+ assertEquals("Name", init.getName(), dser.getName());
+ assertEquals("Value", init.intValue(), dser.intValue());
+ assertEquals("ResourceBundleName", init.getResourceBundleName(),
+ dser.getResourceBundleName());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ *
+ * Test serialization of pre-defined const levels. It is expected that the
+ * deserialized cost level should be the same instance as the existing one.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Serialization of pre-defined const levels. ",
+ method = "!SerializationSelf",
+ args = {}
+ )
+ public void testSerialization_ConstLevel() throws Exception {
+
+ SerializationTest.verifySelf(Level.ALL,
+ SerializationTest.SAME_COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ *
+ * Test serialization of normal instance of Level. It is expected that the
+ * deserialized level object should be equal to the original one.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Test serialization of normal instance of Level.",
+ method = "!SerializationSelf",
+ args = {}
+ )
+ public void testSerialization_InstanceLevel() throws Exception {
+
+ // tests that objects are the same
+ Level[] objectsToTest = new Level[] { Level.parse("550")};
+
+ SerializationTest.verifySelf(objectsToTest,
+ SerializationTest.SAME_COMPARATOR);
+
+ // tests that objects are the equals
+ objectsToTest = new Level[] {
+ new MockLevel("123", 123, "bundle"),
+ new MockLevel("123", 123, null) };
+
+ SerializationTest.verifySelf(objectsToTest, LEVEL_COMPARATOR);
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Serialization/deserialization compatibility",
+ method = "!SerializationGolden",
+ args = {}
+ )
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this,
+ new MockLevel("123", 123, "bundle"), LEVEL_COMPARATOR);
+ }
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLocalizedName",
+ args = {}
+ )
+ public void testGetLocalName() {
+ ResourceBundle rb = ResourceBundle.getBundle("bundles/java/util/logging/res");
+ Level l = new MockLevel("level1", 120,
+ "bundles/java/util/logging/res");
+ assertEquals(rb.getString("level1"), l.getLocalizedName());
+
+ // regression test for HARMONY-2415
+ rb = ResourceBundle.getBundle(
+ "org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
+ l = new MockLevel("Level_error", 120,
+ "org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
+ assertEquals(rb.getString("Level_error"), l.getLocalizedName());
+
+ l = new MockLevel("bad name", 120, "res");
+ assertEquals("bad name", l.getLocalizedName());
+
+ l = new MockLevel("level1", 11120, "bad name");
+ assertEquals("level1", l.getLocalizedName());
+
+ l = new MockLevel("level1", 1120);
+ assertEquals("level1", l.getLocalizedName());
+ }
+
+ /*
+ * test for method public String getResourceBundleName()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getResourceBundleName",
+ args = {}
+ )
+ public void testGetResourceBundleName() {
+ String bundleName = "bundles/java/util/logging/res";
+ Level l = new MockLevel("level1", 120);
+ assertNull("level's localization resource bundle name is not null", l
+ .getResourceBundleName());
+ l = new MockLevel("level1", 120, bundleName);
+ assertEquals("bundleName is non equal to actual value", bundleName, l
+ .getResourceBundleName());
+ l = new MockLevel("level1", 120, bundleName + "+abcdef");
+ assertEquals("bundleName is non equal to actual value", bundleName
+ + "+abcdef", l.getResourceBundleName());
+ }
+
+ /*
+ * test for method public final int intValue()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "intValue",
+ args = {}
+ )
+ public void testIntValue() {
+ int value1 = 120;
+ Level l = new MockLevel("level1", value1);
+ assertEquals(
+ "integer value for this level is non equal to actual value",
+ value1, l.intValue());
+ }
+
+ /*
+ * Test defining new levels in subclasses of Level
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Test defining new levels in subclasses of Level",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ public void testSubclassNewLevel() {
+ MyLevel.DUPLICATENAME.getName();// just to load MyLevel class
+
+ // test duplicated name and num
+ assertEquals("INFO", MyLevel.parse("800").getName());
+ assertEquals(800, MyLevel.parse("INFO").intValue());
+ // test duplicated name
+ assertEquals("FINE", MyLevel.parse("499").getName());
+ assertEquals("FINE", MyLevel.parse("500").getName());
+ assertEquals(500, MyLevel.parse("FINE").intValue());
+ // test duplicated number
+ assertEquals("FINEST", MyLevel.parse("300").getName());
+ assertEquals(300, MyLevel.parse("FINEST").intValue());
+ assertEquals(300, MyLevel.parse("MYLEVEL1").intValue());
+ // test a normal new level, without duplicated elements
+ assertEquals("MYLEVEL2", MyLevel.parse("299").getName());
+ assertEquals(299, MyLevel.parse("MYLEVEL2").intValue());
+ }
+
+ /*
+ * This subclass is to test whether subclasses of Level can add new defined
+ * levels.
+ */
+ static class MyLevel extends Level implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public MyLevel(String name, int value) {
+ super(name, value);
+ }
+
+ public static final Level DUPLICATENAMENUM = new MyLevel("INFO", 800);
+
+ public static final Level DUPLICATENAME = new MyLevel("FINE", 499);
+
+ public static final Level DUPLICATENUM = new MyLevel("MYLEVEL1", 300);
+
+ public static final Level NORMAL = new MyLevel("MYLEVEL2", 299);
+ }
+
+ /*
+ * This Mock is used to expose the protected constructors.
+ */
+ public class MockLevel extends Level implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public MockLevel(String name, int value) {
+ super(name, value);
+ }
+
+ public MockLevel(String name, int value, String resourceBundleName) {
+ super(name, value, resourceBundleName);
+ }
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
new file mode 100644
index 0000000..9b41a9d
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ListResourceBundle;
+import java.util.logging.Level;
+
+//@TestTargetClass = No test needed, just test class helper
+public class LevelTestResource extends ListResourceBundle {
+ public Object[][] getContents() {
+ return contents;
+ }
+
+ @SuppressWarnings("nls")
+ static final Object[][] contents = { { "Level_error", "Name" },
+ { "Localized", "Localized message" }, };
+} \ No newline at end of file
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
new file mode 100644
index 0000000..4e8e034
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
@@ -0,0 +1,1512 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+
+
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.security.Permission;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
+
+/**
+ *
+ * add/get logger(dot)
+ *
+ */
+@TestTargetClass(LogManager.class)
+public class LogManagerTest extends TestCase {
+
+ private static final String FOO = "LogManagerTestFoo";
+
+ LogManager mockManager;
+
+ LogManager manager = LogManager.getLogManager();
+
+ // MockPropertyChangeListener listener;
+
+ Properties props;
+
+ private static String className = LogManagerTest.class.getName();
+
+ static Handler handler = null;
+
+ static final String CONFIG_CLASS = "java.util.logging.config.class";
+
+ static final String CONFIG_FILE = "java.util.logging.config.file";
+
+ static final String MANAGER_CLASS = "java.util.logging.config.manager";
+
+ static final SecurityManager securityManager = System.getSecurityManager();
+
+ static final String clearPath = System.getProperty("clearpath");
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ mockManager = new MockLogManager();
+ // listener = new MockPropertyChangeListener();
+ handler = new MockHandler();
+ props = new Properties();
+ props.put("handlers", className + "$MockHandler " + className + "$MockHandler");
+ props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
+ props.put("java.util.logging.FileHandler.limit", "50000");
+ props.put("java.util.logging.FileHandler.count", "5");
+ props.put("java.util.logging.FileHandler.formatter", "java.util.logging.XMLFormatter");
+ props.put(".level", "FINE");
+ props.put("java.util.logging.ConsoleHandler.level", "OFF");
+ props.put("java.util.logging.ConsoleHandler.formatter","java.util.logging.SimpleFormatter");
+ props.put("LogManagerTestFoo.handlers", "java.util.logging.ConsoleHandler");
+ props.put("LogManagerTestFoo.level", "WARNING");
+ }
+
+
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ handler = null;
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "LogManager",
+ args = {}
+ )
+ public void testLogManager() {
+ class TestLogManager extends LogManager {
+ public TestLogManager() {
+ super();
+ }
+ }
+ TestLogManager tlm = new TestLogManager();
+ assertNotNull(tlm.toString());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException.",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddGetLogger() {
+ Logger log = new MockLogger(FOO, null);
+ Logger foo = mockManager.getLogger(FOO);
+ assertNull(foo);
+ assertTrue(mockManager.addLogger(log));
+ foo = mockManager.getLogger(FOO);
+ assertSame(foo, log);
+ assertNull(foo.getParent());
+
+ try {
+ mockManager.addLogger(null);
+ fail("add null should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ mockManager.getLogger(null);
+ fail("get null should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ assertNull(mockManager.getLogger("bad name"));
+
+ Enumeration<String> enumar = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar.hasMoreElements()) {
+ String name = (String)enumar.nextElement();
+ i++;
+ assertEquals(FOO, name);
+ }
+ assertEquals(i, 1);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddGetLogger_duplicateName() {
+ // add logger with duplicate name has no effect
+ Logger foo = new MockLogger(FOO, null);
+ Logger foo2 = new MockLogger(FOO, null);
+ assertTrue(mockManager.addLogger(foo));
+ assertSame(foo, mockManager.getLogger(FOO));
+ assertFalse(mockManager.addLogger(foo2));
+ assertSame(foo, mockManager.getLogger(FOO));
+ Enumeration<String> enumar = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar.hasMoreElements()) {
+ enumar.nextElement();
+ i++;
+ }
+ assertEquals(1, i);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddGetLogger_Hierachy() {
+ Logger foo = new MockLogger("testAddGetLogger_Hierachy.foo", null);
+ Logger child = new MockLogger("testAddGetLogger_Hierachy.foo.child", null);
+ Logger fakeChild = new MockLogger("testAddGetLogger_Hierachy.foo2.child", null);
+ Logger grandson = new MockLogger("testAddGetLogger_Hierachy.foo.child.grandson", null);
+ Logger otherChild = new MockLogger("testAddGetLogger_Hierachy.foo.child", null);
+ assertNull(foo.getParent());
+ assertNull(child.getParent());
+ assertNull(grandson.getParent());
+ assertNull(otherChild.getParent());
+
+ // whenever a logger is added to a LogManager, hierarchy will be updated
+ // accordingly
+ assertTrue(mockManager.addLogger(child));
+ assertNull(child.getParent());
+
+ assertTrue(mockManager.addLogger(fakeChild));
+ assertNull(fakeChild.getParent());
+
+ assertTrue(mockManager.addLogger(grandson));
+ assertSame(child, grandson.getParent());
+
+ assertTrue(mockManager.addLogger(foo));
+ assertSame(foo, child.getParent());
+ assertNull(foo.getParent());
+ assertNull(fakeChild.getParent());
+
+ // but for non-mock LogManager, foo's parent should be root
+ assertTrue(manager.addLogger(foo));
+ assertSame(manager.getLogger(""), manager.getLogger("testAddGetLogger_Hierachy.foo")
+ .getParent());
+
+ // if we add one logger to two LogManager, parent will changed
+ assertTrue(manager.addLogger(otherChild));
+ assertTrue(manager.addLogger(grandson));
+ assertSame(foo, otherChild.getParent());
+ assertSame(otherChild, grandson.getParent());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddLoggerReverseOrder() {
+ Logger root = new MockLogger("testAddLoggerReverseOrder", null);
+ Logger foo = new MockLogger("testAddLoggerReverseOrder.foo", null);
+ Logger fooChild = new MockLogger("testAddLoggerReverseOrder.foo.child", null);
+ Logger fooGrandChild = new MockLogger("testAddLoggerReverseOrder.foo.child.grand", null);
+ Logger fooGrandChild2 = new MockLogger("testAddLoggerReverseOrder.foo.child.grand2", null);
+
+ Logger realRoot = manager.getLogger("");
+
+ manager.addLogger(fooGrandChild);
+ assertEquals(realRoot, fooGrandChild.getParent());
+
+ manager.addLogger(root);
+ assertSame(root, fooGrandChild.getParent());
+ assertSame(realRoot, root.getParent());
+
+ manager.addLogger(foo);
+ assertSame(root, foo.getParent());
+ assertSame(foo, fooGrandChild.getParent());
+
+ manager.addLogger(fooGrandChild2);
+ assertSame(foo, fooGrandChild2.getParent());
+ assertSame(foo, fooGrandChild.getParent());
+
+ manager.addLogger(fooChild);
+ assertSame(fooChild, fooGrandChild2.getParent());
+ assertSame(fooChild, fooGrandChild.getParent());
+ assertSame(foo, fooChild.getParent());
+ assertSame(root, foo.getParent());
+ assertSame(realRoot, root.getParent());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testAddSimiliarLogger() {
+ Logger root = new MockLogger("testAddSimiliarLogger", null);
+ Logger foo = new MockLogger("testAddSimiliarLogger.foo", null);
+ Logger similiarFoo = new MockLogger("testAddSimiliarLogger.fop", null);
+ Logger fooo = new MockLogger("testAddSimiliarLogger.fooo", null);
+ Logger fooChild = new MockLogger("testAddSimiliarLogger.foo.child", null);
+ Logger similiarFooChild = new MockLogger("testAddSimiliarLogger.fop.child", null);
+ Logger foooChild = new MockLogger("testAddSimiliarLogger.fooo.child", null);
+
+ manager.addLogger(root);
+ manager.addLogger(fooChild);
+ manager.addLogger(similiarFooChild);
+ manager.addLogger(foooChild);
+ assertSame(root, fooChild.getParent());
+ assertSame(root, similiarFooChild.getParent());
+ assertSame(root, foooChild.getParent());
+
+ manager.addLogger(foo);
+ assertSame(foo, fooChild.getParent());
+ assertSame(root, similiarFooChild.getParent());
+ assertSame(root, foooChild.getParent());
+
+ manager.addLogger(similiarFoo);
+ assertSame(foo, fooChild.getParent());
+ assertSame(similiarFoo, similiarFooChild.getParent());
+ assertSame(root, foooChild.getParent());
+
+ manager.addLogger(fooo);
+ assertSame(fooo, foooChild.getParent());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddGetLogger_nameWithSpace() {
+ Logger foo = new MockLogger(FOO, null);
+ Logger fooBeforeSpace = new MockLogger(FOO + " ", null);
+ Logger fooAfterSpace = new MockLogger(" " + FOO, null);
+ Logger fooWithBothSpace = new MockLogger(" " + FOO + " ", null);
+ assertTrue(mockManager.addLogger(foo));
+ assertTrue(mockManager.addLogger(fooBeforeSpace));
+ assertTrue(mockManager.addLogger(fooAfterSpace));
+ assertTrue(mockManager.addLogger(fooWithBothSpace));
+
+ assertSame(foo, mockManager.getLogger(FOO));
+ assertSame(fooBeforeSpace, mockManager.getLogger(FOO + " "));
+ assertSame(fooAfterSpace, mockManager.getLogger(" " + FOO));
+ assertSame(fooWithBothSpace, mockManager.getLogger(" " + FOO + " "));
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify NullPointerException",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testAddGetLogger_addRoot() throws IOException {
+ Logger foo = new MockLogger(FOO, null);
+ Logger fooChild = new MockLogger(FOO + ".child", null);
+ Logger other = new MockLogger("other", null);
+ Logger root = new MockLogger("", null);
+ assertNull(foo.getParent());
+ assertNull(root.getParent());
+ assertNull(other.getParent());
+
+ // add root to mock logmanager and it works as "root" logger
+ assertTrue(mockManager.addLogger(foo));
+ assertTrue(mockManager.addLogger(other));
+ assertTrue(mockManager.addLogger(fooChild));
+ assertNull(foo.getParent());
+ assertNull(other.getParent());
+ assertSame(foo, fooChild.getParent());
+
+ assertTrue(mockManager.addLogger(root));
+ assertSame(root, foo.getParent());
+ assertSame(root, other.getParent());
+ assertNull(root.getParent());
+
+ // try to add root logger to non-mock LogManager, no effect
+ assertFalse(manager.addLogger(root));
+ assertNotSame(root, manager.getLogger(""));
+ }
+
+ /**
+ * @tests java.util.logging.LogManager#addLogger(Logger)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addLogger",
+ args = {java.util.logging.Logger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogManager",
+ args = {}
+ )
+ })
+ public void test_addLoggerLLogger_Security() throws Exception {
+ // regression test for Harmony-1286
+ SecurityManager originalSecurityManager = System.getSecurityManager();
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+
+ }
+ });
+ try {
+ LogManager manager = LogManager.getLogManager();
+ manager.addLogger(new MockLogger("mock", null));
+ manager.addLogger(new MockLogger("mock.child", null));
+ } finally {
+ System.setSecurityManager(originalSecurityManager);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testDefaultLoggerProperties() throws Exception {
+ // mock LogManager has no default logger
+ assertNull(mockManager.getLogger(""));
+ assertNull(mockManager.getLogger("global"));
+
+ // non-mock LogManager has two default logger
+ Logger global = manager.getLogger("global");
+ Logger root = manager.getLogger("");
+
+ assertSame(global, Logger.global);
+ assertSame(root, global.getParent());
+
+ // root properties
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertNull(root.getFilter());
+ assertEquals(2, root.getHandlers().length);
+ assertEquals(Level.FINE, root.getLevel());
+ assertEquals("", root.getName());
+ assertSame(root.getParent(), null);
+ // This test sometimes fails if other tests are run before this one.
+ assertNull(root.getResourceBundle());
+ assertNull(root.getResourceBundleName());
+ assertTrue(root.getUseParentHandlers());
+
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ * test covers following usecases:
+ * case 1: test default and valid value
+ * case 2: test throw NullPointerException
+ * case 3: test bad name
+ * case 4: check correct tested value
+ */
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLoggerNames",
+ args = {}
+ )
+ })
+ public void testGetLogger() throws Exception {
+
+ // case 1: test default and valid value
+ Logger log = new MockLogger(FOO, null);
+ Logger foo = mockManager.getLogger(FOO);
+ assertNull("Logger should be null", foo);
+ assertTrue("logger was't registered successfully", mockManager.addLogger(log));
+ foo = mockManager.getLogger(FOO);
+ assertSame("two loggers not refer to the same object", foo, log);
+ assertNull("logger foo should not haven parent", foo.getParent());
+
+ // case 2: test throw NullPointerException
+ try {
+ mockManager.getLogger(null);
+ fail("get null should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ // case 3: test bad name
+ assertNull("LogManager should not have logger with unforeseen name", mockManager
+ .getLogger("bad name"));
+
+ // case 4: check correct tested value
+ Enumeration<String> enumar = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar.hasMoreElements()) {
+ String name = (String)enumar.nextElement();
+ i++;
+ assertEquals("name logger should be equal to foreseen name", FOO, name);
+ }
+ assertEquals("LogManager should contain one element", 1, i);
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "",
+ method = "getLoggerNames",
+ args = {}
+ )
+ })
+ public void testGetLogger_duplicateName() throws Exception {
+ // test duplicate name
+ // add logger with duplicate name has no effect
+ mockManager.reset();
+ Logger foo2 = new MockLogger(FOO, null);
+ Logger foo3 = new MockLogger(FOO, null);
+ mockManager.addLogger(foo2);
+ assertSame(foo2, mockManager.getLogger(FOO));
+ mockManager.addLogger(foo3);
+ assertSame(foo2, mockManager.getLogger(FOO));
+
+ Enumeration<String> enumar2 = mockManager.getLoggerNames();
+ int i = 0;
+ while (enumar2.hasMoreElements()) {
+ enumar2.nextElement();
+ i++;
+ }
+ assertEquals(1, i);
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_hierachy() throws Exception {
+ // test hierachy
+ Logger foo = new MockLogger("testGetLogger_hierachy.foo", null);
+ // but for non-mock LogManager, foo's parent should be root
+ assertTrue(manager.addLogger(foo));
+ assertSame(manager.getLogger(""), manager.getLogger("testGetLogger_hierachy.foo")
+ .getParent());
+ }
+
+ /*
+ * test for method public Logger getLogger(String name)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_nameSpace() throws Exception {
+ // test name with space
+ Logger foo = new MockLogger(FOO, null);
+ Logger fooBeforeSpace = new MockLogger(FOO + " ", null);
+ Logger fooAfterSpace = new MockLogger(" " + FOO, null);
+ Logger fooWithBothSpace = new MockLogger(" " + FOO + " ", null);
+ assertTrue(mockManager.addLogger(foo));
+ assertTrue(mockManager.addLogger(fooBeforeSpace));
+ assertTrue(mockManager.addLogger(fooAfterSpace));
+ assertTrue(mockManager.addLogger(fooWithBothSpace));
+
+ assertSame(foo, mockManager.getLogger(FOO));
+ assertSame(fooBeforeSpace, mockManager.getLogger(FOO + " "));
+ assertSame(fooAfterSpace, mockManager.getLogger(" " + FOO));
+ assertSame(fooWithBothSpace, mockManager.getLogger(" " + FOO + " "));
+ }
+
+ /*
+ * test for method public void checkAccess() throws SecurityException
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "checkAccess",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLogManager",
+ args = {}
+ )
+ })
+ public void testCheckAccess() {
+ try {
+ manager.checkAccess();
+ } catch (SecurityException e) {
+ fail("securityException should not be thrown");
+ }
+ System.setSecurityManager(new MockSecurityManagerLogPermission());
+ mockManager.addLogger(new MockLogger("abc", null));
+ mockManager.getLogger("");
+ mockManager.getLoggerNames();
+ mockManager.getProperty(".level");
+ LogManager.getLogManager();
+ try {
+ manager.checkAccess();
+ fail("should throw securityException");
+ } catch (SecurityException e) {
+ }
+
+ System.setSecurityManager(securityManager);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "readConfiguration",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "checkAccess",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "reset",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "getLogManager",
+ args = {}
+ )
+ })
+ public void testLoggingPermission() throws IOException {
+ System.setSecurityManager(new MockSecurityManagerLogPermission());
+ mockManager.addLogger(new MockLogger("abc", null));
+ mockManager.getLogger("");
+ mockManager.getLoggerNames();
+ mockManager.getProperty(".level");
+ LogManager.getLogManager();
+ try {
+ manager.checkAccess();
+ fail("should throw securityException");
+ } catch (SecurityException e) {
+ }
+ try {
+ mockManager.readConfiguration();
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
+ try {
+ mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
+ try {
+ mockManager.readConfiguration(null);
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
+ // try {
+ // mockManager
+ // .addPropertyChangeListener(new MockPropertyChangeListener());
+ // fail("should throw SecurityException");
+ // } catch (SecurityException e) {
+ // }
+ // try {
+ // mockManager.addPropertyChangeListener(null);
+ // fail("should throw NPE");
+ // } catch (NullPointerException e) {
+ // }
+ // try {
+ // mockManager.removePropertyChangeListener(null);
+ // fail("should throw SecurityException");
+ // } catch (SecurityException e) {
+ // }
+ try {
+ mockManager.reset();
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
+ System.setSecurityManager(securityManager);
+ }
+
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getProperty",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testMockGetProperty() throws Exception {
+ // mock manager doesn't read configuration until you call
+ // readConfiguration()
+ Logger root = new MockLogger("", null);
+ assertTrue(mockManager.addLogger(root));
+ root = mockManager.getLogger("");
+ checkPropertyNull(mockManager);
+ assertEquals(0, root.getHandlers().length);
+ assertNull(root.getLevel());
+ mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(Level.FINE, root.getLevel());
+ checkProperty(mockManager);
+ mockManager.reset();
+ checkPropertyNull(mockManager);
+ assertEquals(Level.INFO, root.getLevel());
+ assertEquals(0, mockManager.getLogger("").getHandlers().length);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProperty",
+ args = {java.lang.String.class}
+ )
+ public void testGetProperty() throws SecurityException, IOException {
+
+ Logger root = manager.getLogger("");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ checkProperty(manager);
+ assertEquals(2, root.getHandlers().length);
+ assertEquals(Level.FINE, root.getLevel());
+
+ manager.reset();
+ checkPropertyNull(manager);
+ assertEquals(0, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ manager.reset();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException.",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testReadConfiguration_null() throws SecurityException, IOException {
+ try {
+ manager.readConfiguration(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ }
+
+ private static void checkPropertyNull(LogManager m) {
+ // assertNull(m.getProperty(".level"));
+ assertNull(m.getProperty("java.util.logging.FileHandler.limit"));
+ assertNull(m.getProperty("java.util.logging.ConsoleHandler.formatter"));
+ // assertNull(m.getProperty("handlers"));
+ assertNull(m.getProperty("java.util.logging.FileHandler.count"));
+ assertNull(m.getProperty("com.xyz.foo.level"));
+ assertNull(m.getProperty("java.util.logging.FileHandler.formatter"));
+ assertNull(m.getProperty("java.util.logging.ConsoleHandler.level"));
+ assertNull(m.getProperty("java.util.logging.FileHandler.pattern"));
+ }
+
+ private static void checkProperty(LogManager m) {
+ // assertEquals(m.getProperty(".level"), "INFO");
+ assertEquals(m.getProperty("java.util.logging.FileHandler.limit"), "50000");
+ assertEquals(m.getProperty("java.util.logging.ConsoleHandler.formatter"),
+ "java.util.logging.SimpleFormatter");
+ // assertEquals(m.getProperty("handlers"),
+ // "java.util.logging.ConsoleHandler");
+ assertEquals(m.getProperty("java.util.logging.FileHandler.count"), "5");
+ assertEquals(m.getProperty("LogManagerTestFoo.level"), "WARNING");
+ assertEquals(m.getProperty("java.util.logging.FileHandler.formatter"),
+ "java.util.logging.XMLFormatter");
+ assertEquals(m.getProperty("java.util.logging.ConsoleHandler.level"), "OFF");
+ assertEquals(m.getProperty("java.util.logging.FileHandler.pattern"), "%h/java%u.log");
+ }
+
+ // public void testReadConfiguration() throws SecurityException, IOException {
+ // FIXME: move the support_exec
+ // Logger foo = new MockLogger("foo", null);
+ // assertNull(foo.getLevel());
+ // assertTrue(mockManager.addLogger(foo));
+ //
+ // Logger fo = new MockLogger("foo2", null);
+ // fo.setLevel(Level.ALL);
+ // assertTrue(mockManager.addLogger(fo));
+ //
+ // Handler h = new ConsoleHandler();
+ // Level l = h.getLevel();
+ // assertNotSame(Level.OFF, h.getLevel());
+ //
+ // // read configuration
+ // mockManager.readConfiguration();
+ // // level DO has effect
+ // assertEquals(Level.WARNING, foo.getLevel());
+ // // for non specified logger, level is reset to null
+ // assertNull(fo.getLevel());
+ //
+ // // read properties don't affect handler
+ // assertNotSame(Level.OFF, h.getLevel());
+ // assertSame(l, h.getLevel());
+ //
+ // }
+
+ /*
+ * Class under test for void readConfiguration(InputStream)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testReadConfigurationInputStream() throws IOException {
+
+ Logger foo = new MockLogger(FOO, null);
+ assertNull(foo.getLevel());
+ assertTrue(mockManager.addLogger(foo));
+
+ Logger fo = new MockLogger(FOO + "2", null);
+ fo.setLevel(Level.ALL);
+ assertTrue(mockManager.addLogger(fo));
+
+ Handler h = new ConsoleHandler();
+ Level l = h.getLevel();
+ assertSame(Level.INFO, h.getLevel());
+
+ // read configuration from stream
+ InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
+ mockManager.readConfiguration(stream);
+ stream.close();
+
+ // level DOES have an effect on LogManagerTestFoo
+ assertEquals(Level.WARNING, foo.getLevel());
+
+ // for non specified logger, level is reset to null
+ assertNull(fo.getLevel());
+
+ // read properties don't affect handler
+ assertSame(Level.INFO, h.getLevel());
+ assertSame(l, h.getLevel());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException.",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testReadConfigurationInputStream_null() throws SecurityException, IOException {
+ try {
+ mockManager.readConfiguration(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IOException.",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testReadConfigurationInputStream_IOException_1parm() throws SecurityException {
+ try {
+ mockManager.readConfiguration(new MockInputStream());
+ fail("should throw IOException");
+ } catch (IOException e) {
+ //ignore
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testReadConfigurationInputStream_root() throws IOException {
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+
+ Logger logger = new MockLogger("testReadConfigurationInputStream_root.foo", null);
+ Logger root = manager.getLogger("");
+ Logger logger2 = Logger.getLogger("testReadConfigurationInputStream_root.foo2");
+
+ manager.addLogger(logger);
+ assertNull(logger.getLevel());
+ assertEquals(0, logger.getHandlers().length);
+ assertSame(root, logger.getParent());
+
+ assertNull(logger2.getLevel());
+ assertEquals(0, logger2.getHandlers().length);
+ assertSame(root, logger2.getParent());
+ // if (!hasConfigClass) {
+ assertEquals(Level.FINE, root.getLevel());
+ assertEquals(2, root.getHandlers().length);
+ // }
+
+ // after read stream
+ InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
+ manager.readConfiguration(stream);
+ stream.close();
+ assertEquals(Level.FINE, root.getLevel());
+ assertEquals(2, root.getHandlers().length);
+ assertNull(logger.getLevel());
+ assertEquals(0, logger.getHandlers().length);
+ manager.reset();
+ }
+
+ // public void testAddRemovePropertyChangeListener() throws Exception {
+ // MockPropertyChangeListener listener1 = new MockPropertyChangeListener();
+ // MockPropertyChangeListener listener2 = new MockPropertyChangeListener();
+ // // add same listener1 two times
+ // mockManager.addPropertyChangeListener(listener1);
+ // mockManager.addPropertyChangeListener(listener1);
+ // mockManager.addPropertyChangeListener(listener2);
+ //
+ // assertNull(listener1.getEvent());
+ // assertNull(listener2.getEvent());
+ // mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ // // if (!hasConfigClass) {
+ // assertNotNull(listener1.getEvent());
+ // assertNotNull(listener2.getEvent());
+ // // }
+ //
+ // listener1.reset();
+ // listener2.reset();
+ //
+ // // remove listener1, no effect
+ // mockManager.removePropertyChangeListener(listener1);
+ // mockManager.readConfiguration(EnvironmentHelper
+ // .PropertiesToInputStream(props));
+ // assertNotNull(listener1.getEvent());
+ // assertNotNull(listener2.getEvent());
+ // listener1.reset();
+ // listener2.reset();
+ //
+ // // remove listener1 again and it works
+ // mockManager.removePropertyChangeListener(listener1);
+ // mockManager.readConfiguration(EnvironmentHelper
+ // .PropertiesToInputStream(props));
+ // assertNull(listener1.getEvent());
+ // assertNotNull(listener2.getEvent());
+ // listener2.reset();
+ //
+ // // reset don't produce event
+ // mockManager.reset();
+ // assertNull(listener2.getEvent());
+ //
+ // mockManager.removePropertyChangeListener(listener2);
+ // mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ // assertNull(listener1.getEvent());
+ // assertNull(listener2.getEvent());
+ // }
+ //
+ // public void testAddRemovePropertyChangeListener_null() {
+ // // seems nothing happened
+ // try{
+ // mockManager.addPropertyChangeListener(null);
+ // fail("Should throw NPE");
+ // }catch(NullPointerException e){
+ // }
+ // mockManager.removePropertyChangeListener(null);
+ // }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "reset",
+ args = {}
+ )
+ public void testReset() throws SecurityException, IOException {
+ // mock LogManager
+ mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertNotNull(mockManager.getProperty("handlers"));
+ Logger foo = new MockLogger(FOO, null);
+ assertNull(foo.getLevel());
+ assertEquals(0, foo.getHandlers().length);
+ foo.setLevel(Level.ALL);
+ foo.addHandler(new ConsoleHandler());
+ assertTrue(mockManager.addLogger(foo));
+ assertEquals(Level.WARNING, foo.getLevel());
+ assertEquals(2, foo.getHandlers().length);
+
+ // reset
+ mockManager.reset();
+
+ // properties is cleared
+ assertNull(mockManager.getProperty("handlers"));
+
+ // level is null
+ assertNull(foo.getLevel());
+ // handlers are all closed
+ assertEquals(0, foo.getHandlers().length);
+
+ // for root logger
+ manager.reset();
+ assertNull(manager.getProperty("handlers"));
+ Logger root = manager.getLogger("");
+ // level reset to info
+ assertEquals(Level.INFO, root.getLevel());
+ // also close root's handler
+ assertEquals(0, root.getHandlers().length);
+ }
+
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify SecurityException.",
+ method = "readConfiguration",
+ args = {java.io.InputStream.class}
+ )
+ public void testGlobalPropertyConfig() throws Exception {
+ PrintStream err = System.err;
+ try {
+ System.setErr(new PrintStream(new NullOutputStream()));
+ // before add config property, root has two handler
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(2, manager.getLogger("").getHandlers().length);
+
+ // one valid config class
+ props.setProperty("config", className + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(3, manager.getLogger("").getHandlers().length);
+
+ // two config class take effect orderly
+ props.setProperty("config", className + "$MockValidConfig " + className
+ + "$MockValidConfig2");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(2, manager.getLogger("").getHandlers().length);
+
+ props.setProperty("config", className + "$MockValidConfig2 " + className
+ + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(3, manager.getLogger("").getHandlers().length);
+
+ // invalid config class which throw exception, just print exception
+ // and
+ // message
+ props.setProperty("config", className + "$MockInvalidConfigException");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+
+ // invalid config class without default constructor, just print
+ // exception and message
+ props.setProperty("config", className + "$MockInvalidConfigNoDefaultConstructor");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+
+ // bad config class name, just print exception and message
+ props.setProperty("config", "badname");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+
+ // invalid separator, nothing happened
+ props.setProperty("config", className + "$MockValidConfig2;" + className
+ + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(2, manager.getLogger("").getHandlers().length);
+ props.setProperty("config", className + "$MockValidConfig2;" + className
+ + "$MockValidConfig " + className + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(3, manager.getLogger("").getHandlers().length);
+
+ // duplicate config class, take effect twice
+ props.setProperty("config", className + "$MockValidConfig " + className
+ + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(4, manager.getLogger("").getHandlers().length);
+
+ // invalid config classes mixed with valid config classes, valid
+ // config
+ // classes take effect
+ props.setProperty("config", "badname " + className + "$MockValidConfig " + className
+ + "$MockInvalidConfigNoDefaultConstructor " + className + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(4, manager.getLogger("").getHandlers().length);
+
+ // global property take effect before logger specified property
+ props.setProperty("config", className + "$MockValidConfig");
+ manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertEquals(Level.FINE, manager.getLogger("").getLevel());
+ } finally {
+ System.setErr(err);
+ manager.reset();
+ }
+
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "readConfiguration",
+ args = {}
+ )
+ public void testValidConfigClass() throws Exception {
+ String oldProperty = System.getProperty("java.util.logging.config.class");
+ try {
+ // System.setProperty("java.util.logging.config.class", "org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$ConfigClass");
+ System.setProperty("java.util.logging.config.class", this.getClass().getName()
+ + "$ConfigClass");
+ assertNull(manager.getLogger("testConfigClass.foo"));
+
+ manager.readConfiguration();
+ assertNull(manager.getLogger("testConfigClass.foo"));
+ Logger l = Logger.getLogger("testConfigClass.foo.child");
+ assertSame(Level.FINEST, manager.getLogger("").getLevel());
+ assertEquals(0, manager.getLogger("").getHandlers().length);
+ assertEquals("testConfigClass.foo", l.getParent().getName());
+ } finally {
+ if (oldProperty != null) {
+ System.setProperty("java.util.logging.config.class", oldProperty);
+ }
+ }
+ }
+
+ /*
+ * ----------------------------------------------------
+ * mock classes
+ * ----------------------------------------------------
+ */
+
+
+ public static class ConfigClass {
+ public ConfigClass() throws Exception {
+ LogManager man = LogManager.getLogManager();
+ Properties props = new Properties();
+ props.put("handlers", className + "$MockHandler " + className + "$MockHandler");
+ props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
+ props.put("java.util.logging.FileHandler.limit", "50000");
+ props.put("java.util.logging.FileHandler.count", "5");
+ props.put("java.util.logging.FileHandler.formatter", "java.util.logging.XMLFormatter");
+ props.put(".level", "FINE");
+ props.put("java.util.logging.ConsoleHandler.level", "OFF");
+ props.put("java.util.logging.ConsoleHandler.formatter","java.util.logging.SimpleFormatter");
+ props.put("LogManagerTestFoo.handlers", "java.util.logging.ConsoleHandler");
+ props.put("LogManagerTestFoo.level", "WARNING");
+ props.put("testConfigClass.foo.level", "OFF");
+ props.put("testConfigClass.foo.handlers", "java.util.logging.ConsoleHandler");
+ props.put(".level", "FINEST");
+ props.remove("handlers");
+ InputStream in = EnvironmentHelper.PropertiesToInputStream(props);
+ man.readConfiguration(in);
+ }
+ }
+
+ public static class MockInvalidInitClass {
+ public MockInvalidInitClass() {
+ throw new RuntimeException();
+ }
+ }
+
+ public static class TestInvalidConfigFile {
+ public static void main(String[] args) {
+ LogManager manager = LogManager.getLogManager();
+ Logger root = manager.getLogger("");
+ checkPropertyNull(manager);
+ assertEquals(0, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ checkProperty(manager);
+ assertNull(root.getHandlers()[0].getLevel());
+ assertEquals(1, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+
+ manager.reset();
+ checkProperty(manager);
+ assertEquals(0, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ manager.reset();
+ }
+ }
+
+ public static class TestValidConfigFile {
+ public static void main(String[] args) {
+ LogManager manager = LogManager.getLogManager();
+ Logger root = manager.getLogger("");
+ checkPropertyNull(manager);
+ assertEquals(2, root.getHandlers().length);
+ assertEquals(root.getHandlers()[0].getLevel(), Level.OFF);
+ assertEquals(Level.ALL, root.getLevel());
+
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ checkPropertyNull(manager);
+ assertEquals(root.getHandlers()[0].getLevel(), Level.OFF);
+ assertEquals(2, root.getHandlers().length);
+ assertEquals(Level.ALL, root.getLevel());
+
+ manager.reset();
+ checkPropertyNull(manager);
+ assertEquals(0, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ manager.reset();
+ }
+ }
+
+ public static class TestMockLogManager {
+ public static void main(String[] args) {
+ LogManager manager = LogManager.getLogManager();
+ assertTrue(manager instanceof MockLogManager);
+ }
+ }
+
+ public static class TestValidConfigClass {
+ public static void main(String[] args) {
+ LogManager manager = LogManager.getLogManager();
+ Logger root = manager.getLogger("");
+ checkPropertyNull(manager);
+ assertEquals(1, root.getHandlers().length);
+ assertEquals(Level.OFF, root.getLevel());
+
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ checkPropertyNull(manager);
+ assertEquals(1, root.getHandlers().length);
+ assertEquals(Level.OFF, root.getLevel());
+
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ checkPropertyNull(manager);
+ assertEquals(1, root.getHandlers().length);
+ assertEquals(Level.OFF, root.getLevel());
+
+ manager.reset();
+ checkPropertyNull(manager);
+ assertEquals(0, root.getHandlers().length);
+ assertEquals(Level.INFO, root.getLevel());
+ try {
+ manager.readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ manager.reset();
+ }
+ }
+
+ public static class MockLogger extends Logger {
+ public MockLogger(String name, String rbName) {
+ super(name, rbName);
+ }
+ }
+
+ public static class MockLogManager extends LogManager {
+ }
+
+ public static class MockHandler extends Handler {
+ static int number = 0;
+
+ public MockHandler() {
+ addNumber();
+ // System.out.println(this + ":start:" + number);
+ }
+
+ private synchronized void addNumber() {
+ number++;
+ }
+
+ public void close() {
+ minusNumber();
+ // System.out.println(this + ":close:" + number);
+ }
+
+ private synchronized void minusNumber() {
+ number--;
+ }
+
+ public void flush() {
+ // System.out.println(this + ":flush");
+ }
+
+ public void publish(LogRecord record) {
+ }
+
+ }
+
+ public static class MockValidInitClass {
+ public MockValidInitClass() {
+ Properties p = new Properties();
+ p.put("handlers", className + "$MockHandler");
+ p.put(".level", "OFF");
+ InputStream in = null;
+ try {
+ in = EnvironmentHelper.PropertiesToInputStream(p);
+ LogManager manager = LogManager.getLogManager();
+ manager.readConfiguration(in);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ public static class MockValidConfig {
+ public MockValidConfig() {
+ handler = new MockHandler();
+ LogManager manager = LogManager.getLogManager();
+ Logger root = null;
+ if (null != manager) {
+ root = manager.getLogger("");
+ } else {
+ System.out.println("null manager");
+ }
+ if (null != root) {
+ root.addHandler(handler);
+ root.setLevel(Level.OFF);
+ }
+ }
+ }
+
+ public static class MockValidConfig2 {
+
+ static Logger root = null;
+
+ public MockValidConfig2() {
+ root = LogManager.getLogManager().getLogger("");
+ root.removeHandler(handler);
+ }
+ }
+
+ public static class MockInvalidConfigException {
+ public MockInvalidConfigException() {
+ throw new RuntimeException("invalid config class - throw exception");
+ }
+ }
+
+ public static class MockInvalidConfigNoDefaultConstructor {
+ public MockInvalidConfigNoDefaultConstructor(int i) {
+ throw new RuntimeException("invalid config class - no default constructor");
+ }
+ }
+
+ // public static class MockPropertyChangeListener implements
+ // IPropertyChangeListener {
+ //
+ // IPropertyChangeEvent event = null;
+ //
+ // public void propertyChange(IPropertyChangeEvent event) {
+ // this.event = event;
+ // }
+ //
+ // public IPropertyChangeEvent getEvent() {
+ // return event;
+ // }
+ //
+ // public void reset() {
+ // event = null;
+ // }
+ //
+ // }
+
+ public static class MockSecurityManagerLogPermission extends SecurityManager {
+
+ public void checkPermission(Permission permission, Object context) {
+ if (permission instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission permission) {
+ if (permission instanceof LoggingPermission) {
+ StackTraceElement[] stack = (new Throwable()).getStackTrace();
+ for (int i = 0; i < stack.length; i++) {
+ if (stack[i].getClassName().equals("java.util.logging.Logger")) {
+ return;
+ }
+ }
+ throw new SecurityException("Found LogManager checkAccess()");
+ }
+ }
+ }
+
+ public static class MockSecurityManagerOtherPermission extends SecurityManager {
+
+ public void checkPermission(Permission permission, Object context) {
+ if (permission instanceof LoggingPermission) {
+ return;
+ }
+ if (permission.getName().equals("setSecurityManager")) {
+ return;
+ }
+ // throw new SecurityException();
+ super.checkPermission(permission, context);
+ }
+
+ public void checkPermission(Permission permission) {
+ if (permission instanceof LoggingPermission) {
+ return;
+ }
+ if (permission.getName().equals("setSecurityManager")) {
+ return;
+ }
+ super.checkPermission(permission);
+ }
+ }
+
+ /*
+ * Test config class loading
+ * java -Djava.util.logging.config.class=badConfigClassName ClassLoadingTest
+ */
+ public static class ClassLoadingTest {
+ public static void main(String[] args) {
+ Thread.currentThread().setContextClassLoader(new MockErrorClassLoader());
+ try {
+ LogManager.getLogManager();
+ fail("Should throw mock error");
+ } catch (MockError e) {
+ }
+ }
+
+ static class MockErrorClassLoader extends ClassLoader {
+ public Class<?> loadClass(String name) {
+ throw new MockError();
+ }
+ }
+
+ static class MockError extends Error {
+ }
+ }
+
+ public static class MockInputStream extends InputStream {
+
+ @Override
+ public int read() throws IOException {
+ throw new IOException();
+ }
+
+
+ }
+
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
new file mode 100644
index 0000000..5b21099
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
@@ -0,0 +1,777 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+@TestTargetClass(LogRecord.class)
+public class LogRecordTest extends TestCase {
+
+ static final String MSG = "test msg, pls. ignore itb";
+
+ private LogRecord lr;
+
+ private static String className = LogRecordTest.class.getName();
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ lr = new LogRecord(Level.CONFIG, MSG);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "LogRecord",
+ args = {java.util.logging.Level.class, java.lang.String.class}
+ )
+ public void testLogRecordWithNullPointers() {
+ try {
+ new LogRecord(null, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ new LogRecord(null, MSG);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ LogRecord r = new LogRecord(Level.WARNING, null);
+ assertSame(r.getLevel(), Level.WARNING);
+ assertNull(r.getMessage());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "normally set/get don't need to be tested",
+ method = "getLoggerName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "normally set/get don't need to be tested",
+ method = "setLoggerName",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetLoggerName() {
+ assertNull(lr.getLoggerName());
+ lr.setLoggerName(null);
+ assertNull(lr.getLoggerName());
+ lr.setLoggerName("test logger name");
+ assertEquals("test logger name", lr.getLoggerName());
+ }
+
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getResourceBundle",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setResourceBundle",
+ args = {java.util.ResourceBundle.class}
+ )
+ })
+ public void testGetSetResourceBundle() {
+ assertNull(lr.getResourceBundleName());
+ assertNull(lr.getResourceBundle());
+
+ lr.setResourceBundle(null);
+ assertNull(lr.getResourceBundle());
+
+ lr.setResourceBundleName("bundles/java/util/logging/res");
+ assertNull(lr.getResourceBundle());
+
+ lr.setResourceBundleName(null);
+ ResourceBundle rb = ResourceBundle
+ .getBundle("bundles/java/util/logging/res");
+ lr.setResourceBundle(rb);
+ assertEquals(rb, lr.getResourceBundle());
+ assertNull(lr.getResourceBundleName());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getResourceBundleName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setResourceBundleName",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetResourceBundleName() {
+ assertNull(lr.getResourceBundleName());
+ lr.setResourceBundleName(null);
+ assertNull(lr.getResourceBundleName());
+ lr.setResourceBundleName("test");
+ assertEquals("test", lr.getResourceBundleName());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "normal behavior of getter/setter don't need to be tested (normally)",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "normal behavior of getter/setter don't need to be tested (normally)",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testGetSetLevelNormal() {
+ assertSame(lr.getLevel(), Level.CONFIG);
+ lr.setLevel(Level.ALL);
+ assertSame(lr.getLevel(), Level.ALL);
+ lr.setLevel(Level.FINEST);
+ assertSame(lr.getLevel(), Level.FINEST);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testGetSetLevelNullPointerException() {
+ try {
+ lr.setLevel(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ assertSame(lr.getLevel(), Level.CONFIG);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSequenceNumber",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setSequenceNumber",
+ args = {long.class}
+ )
+ })
+ public void testGetSetSequenceNumber() {
+ long l = lr.getSequenceNumber();
+ lr.setSequenceNumber(-111);
+ assertEquals(lr.getSequenceNumber(), -111L);
+ lr.setSequenceNumber(0);
+ assertEquals(lr.getSequenceNumber(), 0L);
+ lr = new LogRecord(Level.ALL, null); //sequenceNumber is updated to a private static counter
+ assertEquals(lr.getSequenceNumber(), l + 1);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSourceClassName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setSourceClassName",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetSourceClassName() {
+ lr.setSourceClassName(null);
+ assertNull(lr.getSourceClassName());
+ lr.setSourceClassName("bad class name");
+ assertEquals("bad class name", lr.getSourceClassName());
+ lr.setSourceClassName(this.getClass().getName());
+ assertEquals(this.getClass().getName(), lr.getSourceClassName());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getSourceMethodName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "setSourceMethodName",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetSourceMethodName() {
+ lr.setSourceMethodName(null);
+ assertNull(lr.getSourceMethodName());
+ lr.setSourceMethodName("bad class name");
+ assertEquals("bad class name", lr.getSourceMethodName());
+ lr.setSourceMethodName(this.getClass().getName());
+ assertEquals(this.getClass().getName(), lr.getSourceMethodName());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getSourceMethodName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "setSourceMethodName",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getSourceClassName",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "setSourceClassName",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSourceDefaultValue() {
+ assertNull(lr.getSourceMethodName());
+ assertNull(lr.getSourceClassName());
+
+ // find class and method who called logger
+ Logger logger = Logger.global;
+ MockHandler handler = new MockHandler();
+ logger.addHandler(handler);
+ logger.log(Level.SEVERE, MSG);
+ assertEquals(this.getClass().getName(), handler.getSourceClassName());
+ assertEquals("testGetSourceDefaultValue", handler.getSourceMethodName());
+
+ // only set source method to null
+ lr = new LogRecord(Level.SEVERE, MSG);
+ lr.setSourceMethodName(null);
+ logger.log(lr);
+ assertNull(handler.getSourceClassName());
+ assertNull(handler.getSourceMethodName());
+
+ // only set source class to null
+ lr = new LogRecord(Level.SEVERE, MSG);
+ lr.setSourceClassName(null);
+ logger.log(lr);
+ assertNull(handler.getSourceClassName());
+ assertNull(handler.getSourceMethodName());
+
+ // set both
+ lr = new LogRecord(Level.SEVERE, MSG);
+ lr.setSourceClassName("className");
+ lr.setSourceMethodName("methodName");
+ logger.log(lr);
+ assertEquals("className", handler.getSourceClassName());
+ assertEquals("methodName", handler.getSourceMethodName());
+
+ // test if LogRecord is constructed in another class, and is published
+ // by Logger
+ logger.log(RecordFactory.getDefaultRecord());
+ assertEquals(this.getClass().getName(), handler.getSourceClassName());
+ assertEquals("testGetSourceDefaultValue", handler.getSourceMethodName());
+
+ lr = RecordFactory.getDefaultRecord();
+ RecordFactory.log(logger, lr);
+ assertEquals(RecordFactory.class.getName(), handler
+ .getSourceClassName());
+ assertEquals("log", handler.getSourceMethodName());
+
+ // only try once to get the default value
+ lr = RecordFactory.getDefaultRecord();
+ assertNull(lr.getSourceClassName());
+ assertNull(lr.getSourceMethodName());
+ RecordFactory.log(logger, lr);
+ assertNull(handler.getSourceClassName());
+ assertNull(handler.getSourceMethodName());
+
+ MockLogger ml = new MockLogger("foo", null);
+ ml.addHandler(handler);
+ ml.info(MSG);
+ assertEquals(className + "$MockLogger", handler.getSourceClassName());
+ assertEquals("info", handler.getSourceMethodName());
+
+ ml = new MockLogger("foo", null);
+ ml.addHandler(handler);
+ ml.log(Level.SEVERE, MSG);
+ assertNull(handler.getSourceClassName());
+ assertNull(handler.getSourceMethodName());
+
+ lr = new LogRecord(Level.SEVERE, MSG);
+ handler.publish(lr);
+ assertNull(handler.getSourceClassName());
+ assertNull(handler.getSourceMethodName());
+ logger.removeHandler(handler);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMessage",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setMessage",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetSetMessage() {
+ assertEquals(MSG, lr.getMessage());
+ lr.setMessage(null);
+ assertNull(lr.getMessage());
+ lr.setMessage("");
+ assertEquals("", lr.getMessage());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getParameters",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParameters",
+ args = {java.lang.Object[].class}
+ )
+ })
+ public void testGetSetParameters() {
+ assertNull(lr.getParameters());
+ lr.setParameters(null);
+ assertNull(lr.getParameters());
+ Object[] oa = new Object[0];
+ lr.setParameters(oa);
+ assertEquals(oa, lr.getParameters());
+ oa = new Object[] {new Object(), new Object()};
+ lr.setParameters(oa);
+ assertSame(oa, lr.getParameters());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMillis",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setMillis",
+ args = {long.class}
+ )
+ })
+ public void testGetSetMillis() {
+ long milli = lr.getMillis();
+ assertTrue(milli > 0);
+ lr.setMillis(-1);
+ assertEquals(-1, lr.getMillis());
+ lr.setMillis(0);
+ assertEquals(0, lr.getMillis());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMillis",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setMillis",
+ args = {long.class}
+ )
+ })
+ public void testGetSetTimeCheck() {
+ long before = lr.getMillis();
+ try {
+ Thread.sleep(2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ LogRecord lr2 = new LogRecord(Level.CONFIG, "MSG2");
+ long after = lr2.getMillis();
+ assertTrue(after-before>0);
+ }
+
+
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getThreadID",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setThreadID",
+ args = {int.class}
+ )
+ })
+ public void testGetSetThreadID() {
+ int id = lr.getThreadID();
+ lr = new LogRecord(Level.ALL, "a1");
+ assertEquals(id, lr.getThreadID());
+ lr.setThreadID(id + 10);
+ assertEquals(id + 10, lr.getThreadID());
+ lr = new LogRecord(Level.ALL, "a1");
+ assertEquals(id, lr.getThreadID());
+ }
+
+ /*
+ * Check threadID are different
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getThreadID",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setThreadID",
+ args = {int.class}
+ )
+ })
+ public void testGetSetThreadID_DifferentThread() {
+ int id = lr.getThreadID();
+ // Create and start the thread
+ MockThread thread = new MockThread();
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // Create and start the thread2
+ MockThread thread2 = new MockThread();
+ thread2.start();
+ try {
+ thread2.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ //All threadID must be different, based on the ThreadLocal.java ID
+ assertTrue(lr.getThreadID() != thread.lr.getThreadID());
+ assertTrue(lr.getThreadID() != thread2.lr.getThreadID());
+ assertTrue(thread.lr.getThreadID() != thread2.lr.getThreadID());
+ }
+
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getThrown",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setThrown",
+ args = {java.lang.Throwable.class}
+ )
+ })
+ public void testGetSetThrown() {
+ assertNull(lr.getThrown());
+ lr.setThrown(null);
+ assertNull(lr.getThrown());
+ Throwable e = new Exception();
+ lr.setThrown(e);
+ assertEquals(e, lr.getThrown());
+ Throwable n = new NullPointerException();
+ lr.setThrown(n);
+ assertEquals(n, lr.getThrown());
+ }
+
+ // comparator for LogRecord objects
+ private static final SerializableAssert LOGRECORD_COMPARATOR = new SerializableAssert() {
+ public void assertDeserialized(Serializable initial,
+ Serializable deserialized) {
+
+ LogRecord init = (LogRecord) initial;
+ LogRecord dser = (LogRecord) deserialized;
+
+ assertEquals("Class", init.getClass(), dser.getClass());
+ assertEquals("Level", init.getLevel(), dser.getLevel());
+ assertEquals("LoggerName", init.getLoggerName(), dser
+ .getLoggerName());
+ assertEquals("Message", init.getMessage(), dser.getMessage());
+ assertEquals("Millis", init.getMillis(), dser.getMillis());
+
+ // compare parameters
+ Object[] paramInit = init.getParameters();
+ Object[] paramDser = dser.getParameters();
+ assertEquals("Parameters length", paramInit.length,
+ paramDser.length);
+ for (int i = 0; i < paramInit.length; i++) {
+ assertEquals("Param: " + i, paramInit[i].toString(),
+ paramDser[i]);
+ }
+
+ // don't check ResourceBundle object
+ // verify only bundle's name
+ assertEquals("ResourceBundleName", init.getResourceBundleName(),
+ dser.getResourceBundleName());
+ assertEquals("SequenceNumber", init.getSequenceNumber(), dser
+ .getSequenceNumber());
+ assertEquals("SourceClassName", init.getSourceClassName(), dser
+ .getSourceClassName());
+ assertEquals("SourceMethodName", init.getSourceMethodName(), dser
+ .getSourceMethodName());
+ assertEquals("ThreadID", init.getThreadID(), dser.getThreadID());
+
+ SerializationTest.THROWABLE_COMPARATOR.assertDeserialized(init
+ .getThrown(), dser.getThrown());
+ }
+ };
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "serialisation/deserialization",
+ method = "!SerializationSelf",
+ args = {}
+ )
+ public void testSerializationSelf() throws Exception {
+ LogRecord r = new LogRecord(Level.ALL, "msg");
+ r.setLoggerName("LoggerName");
+ r.setMillis(123456789);
+ r.setResourceBundleName("ResourceBundleName");
+ r.setSequenceNumber(987654321);
+ r.setSourceClassName("SourceClassName");
+ r.setSourceMethodName("SourceMethodName");
+ r.setParameters(new Object[] {"test string", new Exception("ex-msg")});
+ r.setThreadID(3232);
+ r.setThrown(new Exception("ExceptionMessage"));
+
+ SerializationTest.verifySelf(r, LOGRECORD_COMPARATOR);
+ }
+
+ /**
+ * @tests resolution of resource bundle for serialization/deserialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "tests resolution of resource bundle during deserialization",
+ method = "!Serialization",
+ args = {}
+ )
+ public void testSerializationResourceBundle() throws Exception {
+
+ // test case: valid resource bundle name
+ lr.setResourceBundleName("bundles/java/util/logging/res2");
+ lr.setResourceBundle(ResourceBundle.getBundle(
+ "bundles/java/util/logging/res", Locale.US));
+
+ LogRecord result = (LogRecord) SerializationTest.copySerializable(lr);
+ assertNotNull(result.getResourceBundle());
+
+ // test case: invalid resource bundle name, it is not resolved during
+ // deserialization LogRecord object so check for returned null value
+ lr.setResourceBundleName("bad bundle name");
+ lr.setResourceBundle(ResourceBundle.getBundle(
+ "bundles/java/util/logging/res", Locale.US));
+
+ result = (LogRecord) SerializationTest.copySerializable(lr);
+ assertNull(result.getResourceBundle());
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "!SerializationGolden",
+ args = {}
+ )
+ public void testSerializationCompatibility() throws Exception {
+ LogRecord r = new LogRecord(Level.ALL, "msg");
+ r.setLoggerName("LoggerName");
+ r.setMillis(123456789);
+ r.setResourceBundleName("ResourceBundleName");
+ r.setSequenceNumber(987654321);
+ r.setSourceClassName("SourceClassName");
+ r.setSourceMethodName("SourceMethodName");
+ r.setParameters(new Object[] {"test string", new Exception("ex-msg")});
+ r.setThreadID(3232);
+ r.setThrown(new Exception("ExceptionMessage"));
+
+ SerializationTest.verifyGolden(this, r, LOGRECORD_COMPARATOR);
+ }
+
+ public static class MockHandler extends Handler {
+ private String className;
+
+ private String methodName;
+
+ public void close() {
+ }
+
+ public void flush() {
+ }
+
+ public void publish(LogRecord record) {
+ className = record.getSourceClassName();
+ methodName = record.getSourceMethodName();
+ }
+
+ public String getSourceMethodName() {
+ return methodName;
+ }
+
+ public String getSourceClassName() {
+ return className;
+ }
+ }
+
+ // mock class, try to test when the sourceclass and sourcemethod of
+ // LogRecord is initiated
+ public static class RecordFactory {
+
+ public static LogRecord getDefaultRecord() {
+ return new LogRecord(Level.SEVERE, MSG);
+ }
+
+ public static void log(Logger logger, LogRecord lr) {
+ logger.log(lr);
+ }
+ }
+
+ public static class MockLogger extends Logger {
+
+ /**
+ * @param name
+ * @param resourceBundleName
+ */
+ public MockLogger(String name, String resourceBundleName) {
+ super(name, resourceBundleName);
+ }
+
+ public void log(Level l, String s) {
+ this.log(new LogRecord(l, s));
+ }
+
+ public void info(String s) {
+ super.info(s);
+ }
+
+ public void log(LogRecord record) {
+ if (isLoggable(record.getLevel())) {
+ // call the handlers of this logger
+ // TODO: What if an exception occurred in handler?
+ Handler[] ha = this.getHandlers();
+ for (int i = 0; i < ha.length; i++) {
+ ha[i].publish(record);
+ }
+ // call the parent's handlers if set useParentHandlers
+ if (getUseParentHandlers()) {
+ Logger anyParent = this.getParent();
+ while (null != anyParent) {
+ ha = anyParent.getHandlers();
+ for (int i = 0; i < ha.length; i++) {
+ ha[i].publish(record);
+ }
+ if (anyParent.getUseParentHandlers()) {
+ anyParent = anyParent.getParent();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public class MockThread extends Thread {
+
+ public LogRecord lr = null; //will be update by the thread
+
+ public MockThread(){
+ super();
+ }
+
+ public void run() {
+ update();
+ }
+
+ public synchronized void update(){
+ lr = new LogRecord(Level.CONFIG, "msg thread");
+ }
+
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
new file mode 100644
index 0000000..4ec01ed
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
@@ -0,0 +1,4776 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+import tests.util.CallVerificationStack;
+
+import java.security.Permission;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
+
+/**
+ * Test suite for the class java.util.logging.Logger.
+ */
+@TestTargetClass(Logger.class)
+public class LoggerTest extends TestCase {
+
+ private final static String VALID_RESOURCE_BUNDLE = "bundles/java/util/logging/res";
+
+ private final static String VALID_RESOURCE_BUNDLE2 = "bundles/java/util/logging/res2";
+
+ private final static String VALID_RESOURCE_BUNDLE3 = "bundles/java/util/logging/res3";
+
+ private final static String INVALID_RESOURCE_BUNDLE = "impossible_not_existing";
+
+ private final static String LOGGING_CONFIG_FILE = "src/test/resources/config/java/util/logging/logging.config";
+
+ private final static String VALID_KEY = "LOGGERTEST";
+
+ private final static String VALID_VALUE = "Test_ZH_CN";
+
+ private final static String VALID_VALUE2 = "Test_NoLocale2";
+
+ private Logger sharedLogger = null;
+
+ private Locale oldLocale = null;
+
+ /*
+ * @see TestCase#setUp() Notice : Logger constructor is protected =>
+ * MockLogger
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ oldLocale = Locale.getDefault();
+ Locale.setDefault(new Locale("zh", "CN"));
+ sharedLogger = new MockLogger("SharedLogger", VALID_RESOURCE_BUNDLE);
+ sharedLogger.addHandler(new MockHandler());
+ }
+
+ /*
+ * Reset the log manager.
+ */
+ protected void tearDown() throws Exception {
+ CallVerificationStack.getInstance().clear();
+ Locale.setDefault(oldLocale);
+ LogManager.getLogManager().reset();
+ super.tearDown();
+ }
+
+ /*
+ * Test the global logger
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGlobalLogger() {
+ assertNull(Logger.global.getFilter());
+ assertEquals(0, Logger.global.getHandlers().length);
+ assertNull(Logger.global.getLevel());
+ assertEquals("global", Logger.global.getName());
+ assertNull(Logger.global.getParent().getParent());
+ assertNull(Logger.global.getResourceBundle());
+ assertNull(Logger.global.getResourceBundleName());
+ assertTrue(Logger.global.getUseParentHandlers());
+ assertSame(Logger.global, Logger.getLogger("global"));
+ assertSame(Logger.global, LogManager.getLogManager()
+ .getLogger("global"));
+ }
+
+ /*
+ * Test constructor under normal conditions.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies constructor under normal conditions.",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testConstructor_Normal() {
+ MockLogger mlog = new MockLogger("myname", VALID_RESOURCE_BUNDLE);
+ assertNull(mlog.getFilter());
+ assertEquals(0, mlog.getHandlers().length);
+ assertNull(mlog.getLevel());
+ assertEquals("myname", mlog.getName());
+ assertNull(mlog.getParent());
+ ResourceBundle rb = mlog.getResourceBundle();
+ assertEquals(VALID_VALUE, rb.getString(VALID_KEY));
+ assertEquals(mlog.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(mlog.getUseParentHandlers());
+ }
+
+ /*
+ * Test constructor with null parameters.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies constructor with null parameters.",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testConstructor_Null() {
+ MockLogger mlog = new MockLogger(null, null);
+ assertNull(mlog.getFilter());
+ assertEquals(0, mlog.getHandlers().length);
+ assertNull(mlog.getLevel());
+ assertNull(mlog.getName());
+ assertNull(mlog.getParent());
+ assertNull(mlog.getResourceBundle());
+ assertNull(mlog.getResourceBundleName());
+ assertTrue(mlog.getUseParentHandlers());
+ }
+
+ /*
+ * Test constructor with invalid name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies constructor with invalid name.",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testConstructor_InvalidName() {
+ MockLogger mlog = new MockLogger("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|",
+ null);
+ assertEquals("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|", mlog.getName());
+ }
+
+ /*
+ * Test constructor with empty name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies constructor with empty name.",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testConstructor_EmptyName() {
+ MockLogger mlog = new MockLogger("", null);
+ assertEquals("", mlog.getName());
+ }
+
+ /*
+ * Test constructor with invalid resource bundle name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies MissingResourceException.",
+ method = "Logger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testConstructor_InvalidResourceBundle() {
+
+ // try anonymous with invalid resource
+ try {
+ new MockLogger(null, INVALID_RESOURCE_BUNDLE);
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ // ok !
+ }
+ // try named Logger with invalid resource
+ try {
+ new MockLogger("testConstructor_InvalidResourceBundle",
+ INVALID_RESOURCE_BUNDLE);
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ // ok !
+ }
+ // try empty string
+ try {
+ new MockLogger(null, "");
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ // ok !
+ }
+ }
+
+ /*
+ * Test getAnonymousLogger()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAnonymousLogger",
+ args = {}
+ )
+ public void testGetAnonymousLogger() {
+ Logger alog = Logger.getAnonymousLogger();
+ assertNotSame(alog, Logger.getAnonymousLogger());
+ assertNull(alog.getFilter());
+ assertEquals(0, alog.getHandlers().length);
+ assertNull(alog.getLevel());
+ assertNull(alog.getName());
+ assertEquals("", alog.getParent().getName());
+ assertNull(alog.getParent().getParent());
+ assertNull(alog.getResourceBundle());
+ assertNull(alog.getResourceBundleName());
+ assertTrue(alog.getUseParentHandlers());
+ }
+
+ /*
+ * Test getAnonymousLogger(String resourceBundleName) with valid resource
+ * bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getAnonymousLogger(String resourceBundleName) with valid resource bundle.",
+ method = "getAnonymousLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetAnonymousLogger_ValidResourceBundle() {
+ Logger alog = Logger.getAnonymousLogger(VALID_RESOURCE_BUNDLE);
+ assertNotSame(alog, Logger.getAnonymousLogger(VALID_RESOURCE_BUNDLE));
+ assertNull(alog.getFilter());
+ assertEquals(0, alog.getHandlers().length);
+ assertNull(alog.getLevel());
+ assertNull(alog.getName());
+ assertEquals("", alog.getParent().getName());
+ assertNull(alog.getParent().getParent());
+ assertEquals(VALID_VALUE, alog.getResourceBundle().getString(VALID_KEY));
+ assertEquals(alog.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(alog.getUseParentHandlers());
+ }
+
+ /*
+ * Test getAnonymousLogger(String resourceBundleName) with null resource
+ * bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getAnonymousLogger(String resourceBundleName) with null resource bundle.",
+ method = "getAnonymousLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetAnonymousLogger_NullResourceBundle() {
+ Logger alog = Logger.getAnonymousLogger(null);
+ assertNotSame(alog, Logger.getAnonymousLogger(null));
+ assertNull(alog.getFilter());
+ assertEquals(0, alog.getHandlers().length);
+ assertNull(alog.getLevel());
+ assertNull(alog.getName());
+ assertEquals("", alog.getParent().getName());
+ assertNull(alog.getParent().getParent());
+ assertNull(alog.getResourceBundle());
+ assertNull(alog.getResourceBundleName());
+ assertTrue(alog.getUseParentHandlers());
+ }
+
+ /*
+ * Test getAnonymousLogger(String resourceBundleName) with invalid resource
+ * bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getAnonymousLogger(String resourceBundleName) with invalid resource bundle.",
+ method = "getAnonymousLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetAnonymousLogger_InvalidResourceBundle() {
+ try {
+ Logger.getAnonymousLogger(INVALID_RESOURCE_BUNDLE);
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ }
+ // try empty name
+ try {
+ Logger.getAnonymousLogger("");
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ }
+ }
+
+ /*
+ * Test getLogger(String), getting a logger with no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String), getting a logger with no parent.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_Normal() throws Exception {
+ // config the level
+ Properties p = new Properties();
+ p.put("testGetLogger_Normal_ANewLogger.level", "ALL");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_Normal_ANewLogger"));
+ // create a new logger
+ Logger log = Logger.getLogger("testGetLogger_Normal_ANewLogger");
+ // get an existing logger
+ assertSame(log, Logger.getLogger("testGetLogger_Normal_ANewLogger"));
+ // check it has been registered
+ assertSame(log, LogManager.getLogManager().getLogger(
+ "testGetLogger_Normal_ANewLogger"));
+
+ assertNull(log.getFilter());
+ assertEquals(0, log.getHandlers().length);
+ // check it's set to the preconfigured level
+ assertSame(Level.ALL, log.getLevel());
+ assertEquals("testGetLogger_Normal_ANewLogger", log.getName());
+ assertNull(log.getParent().getParent());
+ assertNull(log.getResourceBundle());
+ assertNull(log.getResourceBundleName());
+ assertTrue(log.getUseParentHandlers());
+
+
+ }
+
+ /*
+ * Test getLogger(String), getting a logger with invalid level configured.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String), getting a logger with invalid level configured.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_InvalidLevel() throws Exception {
+ // config the level
+ Properties p = new Properties();
+ p
+ .put("testGetLogger_InvalidLevel_ANewLogger.level",
+ "impossible_level");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_InvalidLevel_ANewLogger"));
+ // create a new logger
+ Logger log = Logger.getLogger("testGetLogger_InvalidLevel_ANewLogger");
+ // get an existing logger
+ assertSame(log, Logger
+ .getLogger("testGetLogger_InvalidLevel_ANewLogger"));
+ // check it has been registered
+ assertSame(log, LogManager.getLogManager().getLogger(
+ "testGetLogger_InvalidLevel_ANewLogger"));
+ assertNull(log.getLevel());
+ }
+
+ /*
+ * Test getLogger(String) with null name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String) with null name.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_Null() {
+ try {
+ Logger.getLogger(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // ok !
+ }
+ try {
+ Logger.getLogger(null, null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // ok !
+ }
+ }
+
+ /*
+ * Test getLogger(String) with invalid name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String) with invalid name.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void testGetLogger_Invalid() {
+ Logger log = Logger.getLogger("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|");
+ assertEquals("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|", log.getName());
+ }
+
+ /*
+ * Test getLogger(String) with empty name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String) with empty name.",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ @BrokenTest("This fails on RI and Android." +
+ "getResourceBundle and getResourceBundleName methods return " +
+ "null on RI for Logger with empty string name. On the RI " +
+ "getHandlers() returns a non empty array.")
+ public void testGetLogger_Empty() {
+ assertNotNull(LogManager.getLogManager().getLogger(""));
+ Logger log = Logger.getLogger("");
+ assertSame(log, LogManager.getLogManager().getLogger(""));
+ assertNull(log.getFilter());
+ assertEquals(0, log.getHandlers().length);
+ // check it's set to the preconfigured level
+ assertSame(Level.INFO, log.getLevel());
+ assertEquals("", log.getName());
+ assertNull(log.getParent());
+ assertTrue(log.getUseParentHandlers());
+ assertNull(log.getResourceBundle());
+ assertNull(log.getResourceBundleName());
+ }
+
+ /*
+ * Test getLogger(String), getting a logger with existing parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String), getting a logger with existing parent.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLogger_WithParent() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_WithParent_ParentLogger"));
+
+ // get root of hierarchy
+ Logger root = Logger.getLogger("");
+ // create the parent logger
+ Logger pLog = Logger.getLogger("testGetLogger_WithParent_ParentLogger",
+ VALID_RESOURCE_BUNDLE);
+ pLog.setLevel(Level.CONFIG);
+ pLog.addHandler(new MockHandler());
+ pLog.setFilter(new MockFilter());
+ pLog.setUseParentHandlers(false);
+ // check root parent
+ assertEquals("testGetLogger_WithParent_ParentLogger", pLog.getName());
+ assertSame(pLog.getParent(), root);
+
+ // child part
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_WithParent_ParentLogger.child"));
+ // create the child logger
+ Logger child = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger.child");
+ assertNull(child.getFilter());
+ assertEquals(0, child.getHandlers().length);
+ assertNull(child.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger.child", child
+ .getName());
+ assertSame(child.getParent(), pLog);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+ assertTrue(child.getUseParentHandlers());
+
+ // create not valid child
+ Logger notChild = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger1.child");
+ assertNull(notChild.getFilter());
+ assertEquals(0, notChild.getHandlers().length);
+ assertNull(notChild.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger1.child", notChild
+ .getName());
+ assertNotSame(notChild.getParent(), pLog);
+ assertNull(notChild.getResourceBundle());
+ assertNull(notChild.getResourceBundleName());
+ assertTrue(notChild.getUseParentHandlers());
+ // verify two level root.parent
+ assertEquals("testGetLogger_WithParent_ParentLogger.child", child
+ .getName());
+ assertSame(child.getParent().getParent(), root);
+
+
+ // create three level child
+ Logger childOfChild = Logger
+ .getLogger("testGetLogger_WithParent_ParentLogger.child.child");
+ assertNull(childOfChild.getFilter());
+ assertEquals(0, childOfChild.getHandlers().length);
+ assertSame(child.getParent().getParent(), root);
+ assertNull(childOfChild.getLevel());
+ assertEquals("testGetLogger_WithParent_ParentLogger.child.child",
+ childOfChild.getName());
+
+ assertSame(childOfChild.getParent(), child);
+ assertSame(childOfChild.getParent().getParent(), pLog);
+ assertSame(childOfChild.getParent().getParent().getParent(), root);
+ assertNull(childOfChild.getResourceBundle());
+ assertNull(childOfChild.getResourceBundleName());
+ assertTrue(childOfChild.getUseParentHandlers());
+
+ // abnormal case : lookup to root parent in a hierarchy without a logger
+ // parent created between
+ assertEquals("testGetLogger_WithParent_ParentLogger1.child", notChild
+ .getName());
+ assertSame(child.getParent().getParent(), root);
+ assertNotSame(child.getParent(), root);
+
+ // abnormal cases
+ assertNotSame(root.getParent(), root);
+ Logger twoDot = Logger.getLogger("..");
+ assertSame(twoDot.getParent(), root);
+
+ }
+
+
+ /*
+ * Test getLogger(String, String), getting a logger with no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String), getting a logger with no parent.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_Normal() throws Exception {
+ // config the level
+ Properties p = new Properties();
+ p.put("testGetLoggerWithRes_Normal_ANewLogger.level", "ALL");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_Normal_ANewLogger"));
+ // create a new logger
+ Logger log = Logger.getLogger("testGetLoggerWithRes_Normal_ANewLogger",
+ VALID_RESOURCE_BUNDLE);
+ // get an existing logger
+ assertSame(log, Logger
+ .getLogger("testGetLoggerWithRes_Normal_ANewLogger"));
+ // check it has been registered
+ assertSame(log, LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_Normal_ANewLogger"));
+
+ assertNull(log.getFilter());
+ assertEquals(0, log.getHandlers().length);
+ // check it's set to the preconfigured level
+ assertSame(Level.ALL, log.getLevel());
+ assertEquals("testGetLoggerWithRes_Normal_ANewLogger", log.getName());
+ assertNull(log.getParent().getParent());
+ assertEquals(VALID_VALUE, log.getResourceBundle().getString(VALID_KEY));
+ assertEquals(log.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(log.getUseParentHandlers());
+ }
+
+ /*
+ * Test getLogger(String, String) with null parameters.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with null parameters.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_Null() {
+ Logger.getLogger("testGetLoggerWithRes_Null_ANewLogger", null);
+ try {
+ Logger.getLogger(null, VALID_RESOURCE_BUNDLE);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+
+ /*
+ * Test getLogger(String, String) with invalid resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with invalid resource bundle.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ @KnownFailure("IllegalArgumentException is thrown instead of " +
+ "MissingResourceException if resource bundle with specified " +
+ "name can't be found.")
+ public void testGetLoggerWithRes_InvalidResourceBundle() {
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testMissingResourceException"));
+
+ try {
+ Logger.getLogger("testMissingResourceException",
+ INVALID_RESOURCE_BUNDLE);
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ // correct
+ }
+ assertNull(Logger.getLogger("testMissingResourceException")
+ .getResourceBundle());
+ assertNull(Logger.getLogger("testMissingResourceException")
+ .getResourceBundleName());
+ // try empty string
+ try {
+ Logger.getLogger("testMissingResourceException", "");
+ fail("Should throw MissingResourceException!");
+ } catch (MissingResourceException e) {
+ // correct
+ }
+
+ assertNotNull(LogManager.getLogManager().getLogger(""));
+ // The root logger always exists TODO
+ try {
+ Logger.getLogger("", INVALID_RESOURCE_BUNDLE);
+ } catch (MissingResourceException e) {
+ //correct
+ }
+ }
+
+ /*
+ * Test getLogger(String, String) with valid resource bundle, to get an
+ * existing logger with no associated resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with no associated resource bundle.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_ExistingLoggerWithNoRes() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithNoRes_ANewLogger"));
+ // create a new logger
+ Logger log1 = Logger
+ .getLogger("testGetLoggerWithRes_ExistingLoggerWithNoRes_ANewLogger");
+ // get an existing logger
+ Logger log2 = Logger.getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithNoRes_ANewLogger",
+ VALID_RESOURCE_BUNDLE);
+ assertSame(log1, log2);
+ assertEquals(VALID_VALUE, log1.getResourceBundle().getString(VALID_KEY));
+ assertEquals(log1.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+
+ }
+
+ /*
+ * Test getLogger(String, String) with valid resource bundle, to get an
+ * existing logger with the same associated resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with the same associated resource bundle.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_ExistingLoggerWithSameRes() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithSameRes_ANewLogger"));
+ // create a new logger
+ Logger log1 = Logger.getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithSameRes_ANewLogger",
+ VALID_RESOURCE_BUNDLE);
+ // get an existing logger
+ Logger log2 = Logger.getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithSameRes_ANewLogger",
+ VALID_RESOURCE_BUNDLE);
+ assertSame(log1, log2);
+ assertEquals(VALID_VALUE, log1.getResourceBundle().getString(VALID_KEY));
+ assertEquals(log1.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ }
+
+ /*
+ * Test getLogger(String, String) with valid resource bundle, to get an
+ * existing logger with different associated resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with different associated resource bundle.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_ExistingLoggerWithDiffRes() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithDiffRes_ANewLogger"));
+ // create a new logger
+ Logger log1 = Logger.getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithDiffRes_ANewLogger",
+ VALID_RESOURCE_BUNDLE);
+ assertNotNull(log1);
+ // get an existing logger
+ try {
+ Logger
+ .getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithDiffRes_ANewLogger",
+ VALID_RESOURCE_BUNDLE2);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Logger
+ .getLogger(
+ "testGetLoggerWithRes_ExistingLoggerWithDiffRes_ANewLogger",
+ null);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Test getLogger(String, String) with invalid name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with invalid name.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_InvalidName() {
+ Logger log = Logger.getLogger(
+ "...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|WithRes",
+ VALID_RESOURCE_BUNDLE);
+ assertEquals("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|WithRes", log
+ .getName());
+ }
+
+ /*
+ * Test getLogger(String, String) with empty name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String) with empty name.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_Empty() {
+ Logger log = Logger.getLogger("", VALID_RESOURCE_BUNDLE);
+ assertSame(log, LogManager.getLogManager().getLogger(""));
+ assertNull(log.getFilter());
+ assertEquals(0, log.getHandlers().length);
+ // check it's set to the preconfigured level
+ assertSame(Level.INFO, log.getLevel());
+ assertEquals("", log.getName());
+ assertNull(log.getParent());
+ assertEquals(VALID_VALUE, log.getResourceBundle().getString(VALID_KEY));
+ assertEquals(log.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(log.getUseParentHandlers());
+ }
+
+ /*
+ * Test getLogger(String, String), getting a logger with existing parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getLogger(String, String), getting a logger with existing parent.",
+ method = "getLogger",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetLoggerWithRes_WithParentNormal() {
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_WithParent_ParentLogger"));
+ // create the parent logger
+ Logger pLog = Logger
+ .getLogger("testGetLoggerWithRes_WithParent_ParentLogger");
+ pLog.setLevel(Level.CONFIG);
+ pLog.addHandler(new MockHandler());
+ pLog.setFilter(new MockFilter());
+ pLog.setUseParentHandlers(false);
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLoggerWithRes_WithParent_ParentLogger.child"));
+ // create the child logger
+ Logger log = Logger.getLogger(
+ "testGetLoggerWithRes_WithParent_ParentLogger.child",
+ VALID_RESOURCE_BUNDLE);
+ assertNull(log.getFilter());
+ assertEquals(0, log.getHandlers().length);
+ assertNull(log.getLevel());
+ assertEquals("testGetLoggerWithRes_WithParent_ParentLogger.child", log
+ .getName());
+ assertSame(log.getParent(), pLog);
+ assertEquals(VALID_VALUE, log.getResourceBundle().getString(VALID_KEY));
+ assertEquals(log.getResourceBundleName(), VALID_RESOURCE_BUNDLE);
+ assertTrue(log.getUseParentHandlers());
+ }
+
+ /*
+ * Test addHandler(Handler) for a named logger with sufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_NamedLoggerSufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testAddHandler_NamedLoggerSufficientPrivilege");
+ MockHandler h = new MockHandler();
+ assertEquals(log.getHandlers().length, 0);
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+
+ }
+
+ /*
+ * Test addHandler(Handler) for a named logger with sufficient privilege,
+ * add duplicate handlers.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_NamedLoggerSufficientPrivilegeDuplicate() {
+ Logger log = Logger
+ .getLogger("testAddHandler_NamedLoggerSufficientPrivilegeDuplicate");
+ MockHandler h = new MockHandler();
+ assertEquals(log.getHandlers().length, 0);
+ for (int i = 0; i < 12; i++) {
+ log.addHandler(h);
+ }
+ assertEquals(log.getHandlers().length, 12);
+ assertSame(log.getHandlers()[0], h);
+ assertSame(log.getHandlers()[5], h);
+ assertSame(log.getHandlers()[11], h);
+ }
+
+ /*
+ * Test addHandler(Handler) with a null handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NullPointerException.",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_Null() {
+ Logger log = Logger.getLogger("testAddHandler_Null");
+ try {
+ log.addHandler(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test addHandler(Handler) for a named logger with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_NamedLoggerInsufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testAddHandler_NamedLoggerInsufficientPrivilege");
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ log.addHandler(h);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test addHandler(Handler) for a named logger with insufficient privilege,
+ * using a null handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_NamedLoggerInsufficientPrivilegeNull() {
+ Logger log = Logger
+ .getLogger("testAddHandler_NamedLoggerInsufficientPrivilege");
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ log.addHandler(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test addHandler(Handler) for an anonymous logger with sufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_AnonyLoggerSufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ MockHandler h = new MockHandler();
+ assertEquals(log.getHandlers().length, 0);
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+ assertSame(log.getHandlers()[0], h);
+ }
+
+ /*
+ * Test addHandler(Handler) for an anonymous logger with insufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ assertEquals(log.getHandlers().length, 0);
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+ assertSame(log.getHandlers()[0], h);
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test addHandler(Handler) for a null-named mock logger with insufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies addHandler(Handler) for a null-named mock logger with insufficient privilege, SecurityException.",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testAddHandler_NullNamedMockLoggerInsufficientPrivilege() {
+ MockLogger mlog = new MockLogger(null, null);
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ mlog.addHandler(h);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test removeHandler(Handler) for a named logger with sufficient privilege,
+ * remove an existing handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "addHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_NamedLoggerSufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testRemoveHandler_NamedLoggerSufficientPrivilege");
+ MockHandler h = new MockHandler();
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+ log.removeHandler(h);
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test removeHandler(Handler) for a named logger with sufficient privilege,
+ * remove a non-existing handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_NamedLoggerSufficientPrivilegeNotExisting() {
+ Logger log = Logger
+ .getLogger("testRemoveHandler_NamedLoggerSufficientPrivilegeNotExisting");
+ MockHandler h = new MockHandler();
+ assertEquals(log.getHandlers().length, 0);
+ log.removeHandler(h);
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test removeHandler(Handler) with a null handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_Null() {
+ Logger log = Logger.getLogger("testRemoveHandler_Null");
+ log.removeHandler(null);
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test removeHandler(Handler) for a named logger with insufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_NamedLoggerInsufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testRemoveHandler_NamedLoggerInsufficientPrivilege");
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ log.removeHandler(h);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test removeHandler(Handler) for a named logger with insufficient
+ * privilege, using a null handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_NamedLoggerInsufficientPrivilegeNull() {
+ Logger log = Logger
+ .getLogger("testRemoveHandler_NamedLoggerInsufficientPrivilege");
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ log.removeHandler(null);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test removeHandler(Handler) for an anonymous logger with sufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_AnonyLoggerSufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ MockHandler h = new MockHandler();
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+ log.removeHandler(h);
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test removeHandler(Handler) for an anonymous logger with insufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.addHandler(h);
+ assertEquals(log.getHandlers().length, 1);
+ log.removeHandler(h);
+ assertEquals(log.getHandlers().length, 0);
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test removeHandler(Handler) for a null-named mock logger with
+ * insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removeHandler",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testRemoveHandler_NullNamedMockLoggerInsufficientPrivilege() {
+ MockLogger mlog = new MockLogger(null, null);
+ MockHandler h = new MockHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ mlog.removeHandler(h);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getHandlers() when there's no handler.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getHandlers() when there's no handler.",
+ method = "getHandlers",
+ args = {}
+ )
+ public void testGetHandlers_None() {
+ Logger log = Logger.getLogger("testGetHandlers_None");
+ assertEquals(log.getHandlers().length, 0);
+ }
+
+ /*
+ * Test getHandlers() when there are several handlers.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getHandlers() when there are several handlers.",
+ method = "getHandlers",
+ args = {}
+ )
+ public void testGetHandlers_Several() {
+ Logger log = Logger.getLogger("testGetHandlers_None");
+ assertEquals(log.getHandlers().length, 0);
+ MockHandler h1 = new MockHandler();
+ MockHandler h2 = new MockHandler();
+ MockHandler h3 = new MockHandler();
+ log.addHandler(h1);
+ log.addHandler(h2);
+ log.addHandler(h3);
+ assertEquals(log.getHandlers().length, 3);
+ assertSame(log.getHandlers()[0], h1);
+ assertSame(log.getHandlers()[1], h2);
+ assertSame(log.getHandlers()[2], h3);
+ // remove one
+ log.removeHandler(h2);
+ assertEquals(log.getHandlers().length, 2);
+ assertSame(log.getHandlers()[0], h1);
+ assertSame(log.getHandlers()[1], h3);
+
+ }
+
+ /*
+ * Test getFilter & setFilter with normal value for a named logger, having
+ * sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getFilter & setFilter with normal value for a named logger, having sufficient privilege.",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getFilter & setFilter with normal value for a named logger, having sufficient privilege.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testGetSetFilter_NamedLoggerSufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetFilter_NamedLoggerSufficientPrivilege");
+ Filter f = new MockFilter();
+
+ assertNull(log.getFilter());
+ log.setFilter(f);
+ assertSame(f, log.getFilter());
+ }
+
+ /*
+ * Test getFilter & setFilter with null value, having sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getFilter & setFilter with null value, having sufficient privilege.",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getFilter & setFilter with null value, having sufficient privilege.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testGetSetFilter_Null() {
+ Logger log = Logger.getLogger("testGetSetFilter_Null");
+
+ assertNull(log.getFilter());
+ log.setFilter(null);
+ assertNull(log.getFilter());
+ log.setFilter(new MockFilter());
+ log.setFilter(null);
+ assertNull(log.getFilter());
+ }
+
+ /*
+ * Test setFilter with normal value for a named logger, having insufficient
+ * privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies setFilter with normal value for a named logger, having insufficient privilege.",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies setFilter with normal value for a named logger, having insufficient privilege.",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testGetSetFilter_NamedLoggerInsufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetFilter_NamedLoggerInsufficientPrivilege");
+ Filter f = new MockFilter();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setFilter(f);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setFilter for an anonymous logger with sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testSetFilter_AnonyLoggerSufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ Filter f = new MockFilter();
+ assertNull(log.getFilter());
+ log.setFilter(f);
+ assertSame(f, log.getFilter());
+ }
+
+ /*
+ * Test setFilter for an anonymous logger with insufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testSetFilter_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ Filter f = new MockFilter();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ assertNull(log.getFilter());
+ log.setFilter(f);
+ assertSame(f, log.getFilter());
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setFilter for a null-named mock logger with insufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getFilter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setFilter",
+ args = {java.util.logging.Filter.class}
+ )
+ })
+ public void testSetFilter_NullNamedMockLoggerInsufficientPrivilege() {
+ MockLogger mlog = new MockLogger(null, null);
+ Filter f = new MockFilter();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ mlog.setFilter(f);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getLevel & setLevel with normal value for a named logger, having
+ * sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getLevel & setLevel with normal value for a named logger, having sufficient privilege.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getLevel & setLevel with normal value for a named logger, having sufficient privilege.",
+ method = "getLevel",
+ args = {}
+ )
+ })
+ public void testGetSetLevel_NamedLoggerSufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetLevel_NamedLoggerSufficientPrivilege");
+
+ assertNull(log.getLevel());
+ log.setLevel(Level.CONFIG);
+ assertSame(Level.CONFIG, log.getLevel());
+ }
+
+ /*
+ * Test getLevel & setLevel with null value, having sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getLevel & setLevel with null value, having sufficient privilege.",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies getLevel & setLevel with null value, having sufficient privilege.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testGetSetLevel_Null() {
+ Logger log = Logger.getLogger("testGetSetLevel_Null");
+
+ assertNull(log.getLevel());
+ log.setLevel(null);
+ assertNull(log.getLevel());
+ log.setLevel(Level.CONFIG);
+ log.setLevel(null);
+ assertNull(log.getLevel());
+ }
+
+ /*
+ * Test setLevel with normal value for a named logger, having insufficient
+ * privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies setLevel with normal value for a named logger, having insufficient privilege.",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies setLevel with normal value for a named logger, having insufficient privilege.",
+ method = "getLevel",
+ args = {}
+ )
+ })
+ public void testGetSetLevel_NamedLoggerInsufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetLevel_NamedLoggerInsufficientPrivilege");
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setLevel(Level.CONFIG);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setLevel for an anonymous logger with sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testSetLevel_AnonyLoggerSufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ assertNull(log.getLevel());
+ log.setLevel(Level.CONFIG);
+ assertSame(Level.CONFIG, log.getLevel());
+ }
+
+ /*
+ * Test setLevel for an anonymous logger with insufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testSetLevel_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ assertNull(log.getLevel());
+ log.setLevel(Level.CONFIG);
+ assertSame(Level.CONFIG, log.getLevel());
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setLevel for a null-named mock logger with insufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setLevel",
+ args = {java.util.logging.Level.class}
+ )
+ })
+ public void testSetLevel_NullNamedMockLoggerInsufficientPrivilege() {
+ MockLogger mlog = new MockLogger(null, null);
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ mlog.setLevel(Level.CONFIG);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getUseParentHandlers & setUseParentHandlers with normal value for a
+ * named logger, having sufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getUseParentHandlers",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setUseParentHandlers",
+ args = {boolean.class}
+ )
+ })
+ public void testGetSetUseParentHandlers_NamedLoggerSufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetUseParentHandlers_NamedLoggerSufficientPrivilege");
+
+ assertTrue(log.getUseParentHandlers());
+ log.setUseParentHandlers(false);
+ assertFalse(log.getUseParentHandlers());
+ }
+
+ /*
+ * Test setUseParentHandlers with normal value for a named logger, having
+ * insufficient privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getUseParentHandlers",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setUseParentHandlers",
+ args = {boolean.class}
+ )
+ })
+ public void testGetSetUseParentHandlers_NamedLoggerInsufficientPrivilege() {
+ Logger log = Logger
+ .getLogger("testGetSetUseParentHandlers_NamedLoggerInsufficientPrivilege");
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setUseParentHandlers(true);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setUseParentHandlers for an anonymous logger with sufficient
+ * privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getUseParentHandlers",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setUseParentHandlers",
+ args = {boolean.class}
+ )
+ })
+ public void testSetUseParentHandlers_AnonyLoggerSufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ assertTrue(log.getUseParentHandlers());
+ log.setUseParentHandlers(false);
+ assertFalse(log.getUseParentHandlers());
+ }
+
+ /*
+ * Test setUseParentHandlers for an anonymous logger with insufficient
+ * privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getUseParentHandlers",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setUseParentHandlers",
+ args = {boolean.class}
+ )
+ })
+ public void testSetUseParentHandlers_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ assertTrue(log.getUseParentHandlers());
+ log.setUseParentHandlers(false);
+ assertFalse(log.getUseParentHandlers());
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setUseParentHandlers for a null-named mock logger with insufficient
+ * privilege.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getUseParentHandlers",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setUseParentHandlers",
+ args = {boolean.class}
+ )
+ })
+ public void testSetUseParentHandlers_NullNamedMockLoggerInsufficientPrivilege() {
+ MockLogger mlog = new MockLogger(null, null);
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ mlog.setUseParentHandlers(true);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getParent() for root logger.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getParent() for root logger.",
+ method = "getParent",
+ args = {}
+ )
+ public void testGetParent_Root() {
+ assertNull(Logger.getLogger("").getParent());
+ }
+
+ /*
+ * Test getParent() for normal named loggers.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getParent() for normal named loggers.",
+ method = "getParent",
+ args = {}
+ )
+ public void testGetParent_NormalNamed() {
+ Logger log = Logger.getLogger("testGetParent_NormalNamed");
+ assertSame(log.getParent(), Logger.getLogger(""));
+ Logger child = Logger.getLogger("testGetParent_NormalNamed.child");
+ assertSame(child.getParent(), log);
+ Logger child2 = Logger.getLogger("testGetParent_NormalNamed.a.b.c");
+ assertSame(child2.getParent(), log);
+ }
+
+ /*
+ * Test getParent() for anonymous loggers.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getParent() for anonymous loggers.",
+ method = "getParent",
+ args = {}
+ )
+ public void testGetParent_Anonymous() {
+ assertSame(Logger.getAnonymousLogger().getParent(), Logger
+ .getLogger(""));
+ }
+
+ /*
+ * Test setParent(Logger) for the mock logger since it is advised not to
+ * call this method on named loggers. Test normal conditions.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParent",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testSetParent_Normal() {
+ Logger log = new MockLogger(null, null);
+ Logger parent = new MockLogger(null, null);
+ assertNull(log.getParent());
+ log.setParent(parent);
+ assertSame(log.getParent(), parent);
+ }
+
+ /*
+ * Test setParent(Logger) with null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParent",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testSetParent_Null() {
+ try {
+ (new MockLogger(null, null)).setParent(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test setParent(Logger), having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParent",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testSetParent_InsufficientPrivilege() {
+ MockLogger log = new MockLogger(null, null);
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setParent(log);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setParent(Logger) with null, having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParent",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testSetParent_InsufficientPrivilegeNull() {
+ MockLogger log = new MockLogger(null, null);
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setParent(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test setParent(Logger) for an anonymous logger with insufficient
+ * privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setParent",
+ args = {java.util.logging.Logger.class}
+ )
+ public void testSetParent_AnonyLoggerInsufficientPrivilege() {
+ Logger log = Logger.getAnonymousLogger();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ log.setParent(log);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test getName() for normal names.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getName() for normal names.",
+ method = "getName",
+ args = {}
+ )
+ public void testGetName_Normal() {
+ Logger log = Logger.getLogger("testGetName_Normal");
+ assertEquals("testGetName_Normal", log.getName());
+
+ Logger mlog = new MockLogger("testGetName_Normal", null);
+ assertEquals("testGetName_Normal", mlog.getName());
+ }
+
+ /*
+ * Test getName() for empty name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getName() for empty name.",
+ method = "getName",
+ args = {}
+ )
+ public void testGetName_Empty() {
+ Logger log = Logger.getLogger("");
+ assertEquals("", log.getName());
+
+ Logger mlog = new MockLogger("", null);
+ assertEquals("", mlog.getName());
+ }
+
+ /*
+ * Test getName() for null name.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getName() for null name.",
+ method = "getName",
+ args = {}
+ )
+ public void testGetName_Null() {
+ Logger log = Logger.getAnonymousLogger();
+ assertNull(log.getName());
+
+ Logger mlog = new MockLogger(null, null);
+ assertNull(mlog.getName());
+ }
+
+ /*
+ * Test getResourceBundle() when it it not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getResourceBundle() when it it not null.",
+ method = "getResourceBundle",
+ args = {}
+ )
+ public void testGetResourceBundle_Normal() {
+ Logger log = Logger.getLogger("testGetResourceBundle_Normal",
+ VALID_RESOURCE_BUNDLE);
+ assertEquals(VALID_VALUE, log.getResourceBundle().getString(VALID_KEY));
+
+ Logger mlog = new MockLogger(null, VALID_RESOURCE_BUNDLE);
+ assertEquals(VALID_VALUE, mlog.getResourceBundle().getString(VALID_KEY));
+ }
+
+ /*
+ * Test getResourceBundle() when it it null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getResourceBundle() when it it null.",
+ method = "getResourceBundle",
+ args = {}
+ )
+ public void testGetResourceBundle_Null() {
+ Logger log = Logger.getLogger("testGetResourceBundle_Null", null);
+ assertNull(log.getResourceBundle());
+
+ Logger mlog = new MockLogger(null, null);
+ assertNull(mlog.getResourceBundle());
+ }
+
+
+ /*
+ * Test getResourceBundleName() when it it not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getResourceBundleName() when it it not null.",
+ method = "getResourceBundleName",
+ args = {}
+ )
+ public void testGetResourceBundleName_Normal() {
+ Logger log = Logger.getLogger("testGetResourceBundleName_Normal",
+ VALID_RESOURCE_BUNDLE);
+ assertEquals(VALID_RESOURCE_BUNDLE, log.getResourceBundleName());
+
+ Logger mlog = new MockLogger(null, null);
+ assertNull(mlog.getResourceBundleName());
+ }
+
+ /*
+ * Test getResourceBundleName() when it it null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getResourceBundleName() when it it null.",
+ method = "getResourceBundleName",
+ args = {}
+ )
+ public void testGetResourceBundleName_Null() {
+ Logger log = Logger.getLogger("testGetResourceBundleName_Null", null);
+ assertNull(log.getResourceBundleName());
+
+ Logger mlog = new MockLogger(null, null);
+ assertNull(mlog.getResourceBundleName());
+ }
+
+
+ /*
+ * Test isLoggable(Level).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isLoggable",
+ args = {java.util.logging.Level.class}
+ )
+ public void testIsLoggable() {
+ MockLogger mlog = new MockLogger(null, null);
+ assertNull(mlog.getLevel());
+ assertNull(mlog.getParent());
+
+ assertTrue(mlog.isLoggable(Level.SEVERE));
+ assertTrue(mlog.isLoggable(Level.WARNING));
+ assertTrue(mlog.isLoggable(Level.INFO));
+ assertFalse(mlog.isLoggable(Level.CONFIG));
+ assertFalse(mlog.isLoggable(Level.FINE));
+ assertFalse(mlog.isLoggable(Level.ALL));
+ assertTrue(mlog.isLoggable(Level.OFF));
+
+ mlog.setLevel(Level.CONFIG);
+ assertTrue(mlog.isLoggable(Level.SEVERE));
+ assertTrue(mlog.isLoggable(Level.CONFIG));
+ assertFalse(mlog.isLoggable(Level.ALL));
+ assertTrue(mlog.isLoggable(Level.OFF));
+
+ mlog.setLevel(Level.ALL);
+ assertTrue(mlog.isLoggable(Level.ALL));
+ assertTrue(mlog.isLoggable(Level.SEVERE));
+ assertTrue(mlog.isLoggable(Level.OFF));
+
+ mlog.setLevel(Level.OFF);
+ assertFalse(mlog.isLoggable(Level.ALL));
+ assertFalse(mlog.isLoggable(Level.SEVERE));
+ assertFalse(mlog.isLoggable(Level.OFF));
+ }
+
+ /*
+ * Test throwing(String, String, Throwable) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "throwing",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testThrowing_Normal() {
+ Throwable t = new Throwable();
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.throwing("sourceClass", "sourceMethod", t);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "THROW");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters(), null);
+ assertSame(r.getThrown(), t);
+
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.throwing("sourceClass", "sourceMethod", t);
+
+ // FINE is a level too low, message will be lost => empty
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test throwing(String, String, Throwable) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "throwing",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testThrowing_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.throwing(null, null, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "THROW");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters(), null);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test entering(String, String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String) with normal values.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testEntering_StringString_Normal() {
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.entering("sourceClass", "sourceMethod");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "ENTRY");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters(), null);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.entering("sourceClass", "sourceMethod");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test entering(String, String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String) with null values.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testEntering_StringString_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.entering(null, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "ENTRY");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters(), null);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test entering(String, String, Object) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object) with normal values.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testEntering_StringStringObject_Normal() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.entering("sourceClass", "sourceMethod", param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "ENTRY {0}");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters()[0], param);
+ assertEquals(1, r.getParameters().length);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.entering("sourceClass", "sourceMethod", param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test entering(String, String, Object) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object) with null values.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testEntering_StringStringObject_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.entering(null, null, (Object) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "ENTRY {0}");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertEquals(r.getParameters().length, 1);
+ assertNull(r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test entering(String, String, Object[]) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object[]) with normal values.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testEntering_StringStringObjects_Normal() {
+ Object[] params = new Object[2];
+ params[0] = new Object();
+ params[1] = new Object();
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.entering("sourceClass", "sourceMethod", params);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "ENTRY {0} {1}");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters()[0], params[0]);
+ assertSame(r.getParameters()[1], params[1]);
+ assertEquals(2, r.getParameters().length);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.entering("sourceClass", "sourceMethod", params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test entering(String, String, Object[]) with null class name and method
+ * name and empty parameter array.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object[]) with null class name and method name and empty parameter array.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testEntering_StringStringObjects_NullEmpty() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.entering(null, null, new Object[0]);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "ENTRY");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertEquals(0, r.getParameters().length);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test entering(String, String, Object[]) with null values with appropriate
+ * logging level set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object[]) with null values with appropriate logging level set.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testEntering_StringStringObjects_Null() {
+ sharedLogger.setLevel(Level.FINER);
+ sharedLogger.entering(null, null, (Object[]) null);
+ // regression test for Harmony-1265
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(sharedLogger.getName(), r.getLoggerName());
+ assertEquals("ENTRY", r.getMessage());
+ assertSame(sharedLogger.getResourceBundleName(), r
+ .getResourceBundleName());
+ assertSame(sharedLogger.getResourceBundle(), r.getResourceBundle());
+ assertNull(r.getSourceClassName());
+ assertNull(r.getSourceMethodName());
+ assertSame(Level.FINER, r.getLevel());
+ assertNull(r.getParameters());
+ assertNull(r.getThrown());
+ }
+
+ /*
+ * Test entering(String, String, Object[]) with null values with
+ * inappropriate logging level set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies entering(String, String, Object[]) with null values with inappropriate logging level set.",
+ method = "entering",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testEntering_StringStringObjects_NullDisabled() {
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.entering(null, null, (Object[]) null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test exiting(String, String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies exiting(String, String) with normal values.",
+ method = "exiting",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testExiting_StringString_Normal() {
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.exiting("sourceClass", "sourceMethod");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "RETURN");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.exiting("sourceClass", "sourceMethod");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test exiting(String, String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies exiting(String, String) with null values.",
+ method = "exiting",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testExiting_StringString_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.exiting(null, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "RETURN");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters(), null);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test exiting(String, String, Object) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies exiting(String, String, Object) with normal values.",
+ method = "exiting",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testExiting_StringStringObject_Normal() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.exiting("sourceClass", "sourceMethod", param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "RETURN {0}");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.FINER);
+ assertSame(r.getParameters()[0], param);
+ assertEquals(1, r.getParameters().length);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.exiting("sourceClass", "sourceMethod", param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test exiting(String, String, Object) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies exiting(String, String, Object) with null values.",
+ method = "exiting",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testExiting_StringStringObject_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.exiting(null, null, (Object) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertEquals(r.getMessage(), "RETURN {0}");
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertEquals(r.getParameters().length, 1);
+ assertNull(r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test config(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "config",
+ args = {java.lang.String.class}
+ )
+ public void testConfig_Normal() {
+ this.sharedLogger.setLevel(Level.CONFIG);
+ this.sharedLogger.config("config msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "config msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.CONFIG);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.config("config again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test config(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies null as a parameter.",
+ method = "config",
+ args = {java.lang.String.class}
+ )
+ public void testConfig_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.CONFIG);
+ child.config(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.CONFIG);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.config(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test fine(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "fine",
+ args = {java.lang.String.class}
+ )
+ public void testFine_Normal() {
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.fine("fine msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertEquals(r.getMessage(), "fine msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.CONFIG);
+ this.sharedLogger.fine("fine again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test fine(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies fine(String) with null values.",
+ method = "fine",
+ args = {java.lang.String.class}
+ )
+ public void testFine_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINE);
+ child.fine(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.CONFIG);
+ this.sharedLogger.fine(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test finer(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies finer(String) with normal values.",
+ method = "finer",
+ args = {java.lang.String.class}
+ )
+ public void testFiner_Normal() {
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.finer("finer msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "finer msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.finer("finer again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test finer(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies finer(String) with null values.",
+ method = "finer",
+ args = {java.lang.String.class}
+ )
+ public void testFiner_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINER);
+ child.finer(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINER);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINE);
+ this.sharedLogger.finer(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test finest(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies finest(String) with normal values.",
+ method = "finest",
+ args = {java.lang.String.class}
+ )
+ public void testFinest_Normal() {
+ this.sharedLogger.setLevel(Level.FINEST);
+ this.sharedLogger.finest("finest msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "finest msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINEST);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.finest("finest again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test finest(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies finest(String) with null values.",
+ method = "finest",
+ args = {java.lang.String.class}
+ )
+ public void testFinest_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.FINEST);
+ child.finest(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINEST);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.FINER);
+ this.sharedLogger.finest(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test info(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "info",
+ args = {java.lang.String.class}
+ )
+ public void testInfo_Normal() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.info("info msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "info msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.WARNING);
+ this.sharedLogger.info("info again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test info(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "info",
+ args = {java.lang.String.class}
+ )
+ public void testInfo_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.info(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.WARNING);
+ this.sharedLogger.info(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test warning(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "warning",
+ args = {java.lang.String.class}
+ )
+ public void testWarning_Normal() {
+ this.sharedLogger.setLevel(Level.WARNING);
+ this.sharedLogger.warning("warning msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "warning msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.WARNING);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.SEVERE);
+ this.sharedLogger.warning("warning again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test warning(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "warning",
+ args = {java.lang.String.class}
+ )
+ public void testWarning_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.WARNING);
+ child.warning(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.WARNING);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.SEVERE);
+ this.sharedLogger.warning(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test severe(String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "severe",
+ args = {java.lang.String.class}
+ )
+ public void testSevere_Normal() {
+ this.sharedLogger.setLevel(Level.SEVERE);
+ this.sharedLogger.severe("severe msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "severe msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.SEVERE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.severe("severe again");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test severe(String) with null values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "severe",
+ args = {java.lang.String.class}
+ )
+ public void testSevere_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.SEVERE);
+ child.severe(null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.SEVERE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.severe(null);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(Level, String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class}
+ )
+ public void testLog_LevelString_Normal() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.log(Level.INFO, "log(Level, String) msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "log(Level, String) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.log(Level.CONFIG, "log(Level, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.log(Level.OFF, "log(Level, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(Level, String) with null message.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class}
+ )
+ public void testLog_LevelString_NullMsg() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.log(Level.INFO, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(Level, String) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class}
+ )
+ public void testLog_LevelString_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.log(null, "log(Level, String) msg");
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test log(Level, String, Object) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLog_LevelStringObject_Normal() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.log(Level.INFO, "log(Level, String, Object) msg",
+ param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "log(Level, String, Object) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertSame(param, r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.log(Level.CONFIG, "log(Level, String, Object) msg",
+ param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.log(Level.OFF, "log(Level, String, Object) msg",
+ param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(Level, String, Object) with null message and object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLog_LevelStringObject_NullMsgObj() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.log(Level.INFO, null, (Object) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertNull(r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(Level, String, Object) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLog_LevelStringObject_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.log(null, "log(Level, String, Object) msg",
+ new Object());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test log(Level, String, Object[]) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
+ )
+
+ public void testLog_LevelStringObjects_Normal() {
+ Object[] params = new Object[2];
+ params[0] = new Object();
+ params[1] = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.log(Level.INFO, "log(Level, String, Object[]) msg",
+ params);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "log(Level, String, Object[]) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(2, r.getParameters().length);
+ assertSame(params[0], r.getParameters()[0]);
+ assertSame(params[1], r.getParameters()[1]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.log(Level.CONFIG, "log(Level, String, Object[]) msg",
+ params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.log(Level.OFF, "log(Level, String, Object[]) msg",
+ params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(Level, String, Object[]) with null message and object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLog_LevelStringObjects_NullMsgObj() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.log(Level.INFO, null, (Object[]) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(Level, String, Object[]) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLog_LevelStringObjects_NullLevel() {
+ try {
+ this.sharedLogger.log(null, "log(Level, String, Object[]) msg",
+ new Object[0]);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test log(Level, String, Throwable) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLog_LevelStringThrowable_Normal() {
+ Throwable t = new Throwable();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.log(Level.INFO, "log(Level, String, Throwable) msg",
+ t);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "log(Level, String, Throwable) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), t);
+
+ this.sharedLogger.log(Level.CONFIG,
+ "log(Level, String, Throwable) msg", t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger
+ .log(Level.OFF, "log(Level, String, Throwable) msg", t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(Level, String, Throwable) with null message and throwable.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLog_LevelStringThrowable_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.log(Level.INFO, null, (Throwable) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(Level, String, Throwable) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLog_LevelStringThrowable_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.log(null, "log(Level, String, Throwable) msg",
+ new Throwable());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logp(Level, String, String, String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogp_LevelStringStringString_Normal() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logp(Level.INFO, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String) msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(), "logp(Level, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logp(Level.CONFIG, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logp(Level.OFF, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logp(Level, String, String, String) with null message.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogp_LevelStringStringString_NullMsg() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.logp(Level.INFO, null, null, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logp(Level, String, String, String) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogp_LevelStringStringString_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logp(null, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String) msg");
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogp_LevelStringStringStringObject_Normal() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logp(Level.INFO, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object) msg", param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logp(Level, String, String, String, Object) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertSame(param, r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logp(Level.CONFIG, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object) msg", param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logp(Level.OFF, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object) msg", param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object) with null message and
+ * object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogp_LevelStringStringStringObject_NullMsgObj() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.logp(Level.INFO, null, null, null, (Object) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertNull(r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+
+ public void testLogp_LevelStringStringStringObject_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logp(null, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object) msg",
+ new Object());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object[]) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+
+ public void testLogp_LevelStringStringStringObjects_Normal() {
+ Object[] params = new Object[2];
+ params[0] = new Object();
+ params[1] = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logp(Level.INFO, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object[]) msg", params);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logp(Level, String, String, String, Object[]) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(2, r.getParameters().length);
+ assertSame(params[0], r.getParameters()[0]);
+ assertSame(params[1], r.getParameters()[1]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logp(Level.CONFIG, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object[]) msg", params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logp(Level.OFF, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object[]) msg", params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object[]) with null message and
+ * object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogp_LevelStringStringStringObjects_NullMsgObj() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.logp(Level.INFO, null, null, null, (Object[]) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Object[]) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogp_LevelStringStringStringObjects_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logp(null, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Object[]) msg",
+ new Object[0]);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Throwable) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogp_LevelStringStringStringThrowable_Normal() {
+ Throwable t = new Throwable();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logp(Level.INFO, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Throwable) msg", t);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logp(Level, String, String, String, Throwable) msg");
+ assertSame(r.getResourceBundleName(), this.sharedLogger
+ .getResourceBundleName());
+ assertSame(r.getResourceBundle(), this.sharedLogger.getResourceBundle());
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), t);
+
+ this.sharedLogger.logp(Level.CONFIG, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Throwable) msg", t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logp(Level.OFF, "sourceClass", "sourceMethod",
+ "logp(Level, String, String, String, Throwable) msg", t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Throwable) with null message and
+ * throwable.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogp_LevelStringStringStringThrowable_Null() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+
+ child.setLevel(Level.INFO);
+ child.logp(Level.INFO, null, null, null, (Throwable) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), child.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), parent.getResourceBundleName());
+ assertSame(r.getResourceBundle(), parent.getResourceBundle());
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logp(Level, String, String, String, Throwable) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logp",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogp_LevelStringStringStringThrowable_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logp(null, "sourceClass", "sourceMethod",
+ "log(Level, String, String, String, Throwable) msg",
+ new Throwable());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String) with normal values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogrb_LevelStringStringString_Normal() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String) msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE2);
+ assertEquals(VALID_VALUE2, r.getResourceBundle().getString(VALID_KEY));
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logrb(Level.CONFIG, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logrb(Level.OFF, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String) msg");
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String) with null message.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogrb_LevelStringStringString_NullMsg() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, null, null, null, null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String) with null level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogrb_LevelStringStringString_NullLevel() {
+ try {
+ this.sharedLogger.logrb(null, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String) msg");
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String) with invalid resource
+ * bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testLogrb_LevelStringStringString_InvalidRes() {
+ this.sharedLogger.setLevel(Level.ALL);
+ this.sharedLogger.logrb(Level.ALL, "sourceClass", "sourceMethod",
+ INVALID_RESOURCE_BUNDLE,
+ "logrb(Level, String, String, String, String) msg");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), INVALID_RESOURCE_BUNDLE);
+ assertSame(r.getResourceBundle(), null);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.ALL);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object) with normal
+ * values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogrb_LevelStringStringStringObject_Normal() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object) msg",
+ param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String, Object) msg");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE2);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertSame(param, r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logrb(Level.CONFIG, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object) msg",
+ param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logrb(Level.OFF, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object) msg",
+ param);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object) with null
+ * message and object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogrb_LevelStringStringStringObject_NullMsgObj() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, null, null, null, null,
+ (Object) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(1, r.getParameters().length);
+ assertNull(r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /**
+ * java.util.logging.Logger#logrb(Level, String, String, String, String,
+ * Object)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression test.",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void test_logrbLLevel_LString_LString_LObject_Security()
+ throws Exception {
+ // regression test for Harmony-1290
+ SecurityManager originalSecurityManager = System.getSecurityManager();
+ try {
+ System.setSecurityManager(new MockSecurityManager());
+ Logger.global.logrb(Level.OFF, null, null, "abc", "def");
+ } finally {
+ System.setSecurityManager(originalSecurityManager);
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object) with null
+ * level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogrb_LevelStringStringStringObject_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logrb(null, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object) msg",
+ new Object());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object) with invalid
+ * resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
+ )
+ public void testLogrb_LevelStringStringStringObject_InvalidRes() {
+ Object param = new Object();
+ this.sharedLogger.setLevel(Level.ALL);
+ this.sharedLogger.logrb(Level.ALL, "sourceClass", "sourceMethod",
+ INVALID_RESOURCE_BUNDLE,
+ "logrb(Level, String, String, String, String) msg", param);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), INVALID_RESOURCE_BUNDLE);
+ assertSame(r.getResourceBundle(), null);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.ALL);
+ assertEquals(1, r.getParameters().length);
+ assertSame(param, r.getParameters()[0]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object[]) with normal
+ * values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogrb_LevelStringStringStringObjects_Normal() {
+ Object[] params = new Object[2];
+ params[0] = new Object();
+ params[1] = new Object();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object[]) msg",
+ params);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String, Object[]) msg");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE2);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.INFO);
+ assertEquals(2, r.getParameters().length);
+ assertSame(params[0], r.getParameters()[0]);
+ assertSame(params[1], r.getParameters()[1]);
+ assertSame(r.getThrown(), null);
+
+ this.sharedLogger.logrb(Level.CONFIG, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object[]) msg",
+ params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logrb(Level.OFF, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object[]) msg",
+ params);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object[]) with null
+ * message and object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogrb_LevelStringStringStringObjects_NullMsgObj() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, null, null, null, null,
+ (Object[]) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object[]) with null
+ * level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogrb_LevelStringStringStringObjects_NullLevel() {
+ try {
+ this.sharedLogger.logrb(
+ null,
+ "sourceClass",
+ "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Object[]) msg",
+ new Object[0]);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Object[]) with invalid
+ * resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
+ )
+ public void testLogrb_LevelStringStringStringObjects_InvalidRes() {
+ Object[] params = new Object[2];
+ params[0] = new Object();
+ params[1] = new Object();
+ this.sharedLogger.setLevel(Level.ALL);
+ this.sharedLogger.logrb(Level.ALL, "sourceClass", "sourceMethod",
+ INVALID_RESOURCE_BUNDLE,
+ "logrb(Level, String, String, String, String) msg", params);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), INVALID_RESOURCE_BUNDLE);
+ assertSame(r.getResourceBundle(), null);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.ALL);
+ assertEquals(2, r.getParameters().length);
+ assertSame(params[0], r.getParameters()[0]);
+ assertSame(params[1], r.getParameters()[1]);
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Throwable) with normal
+ * values.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogrb_LevelStringStringStringThrowable_Normal() {
+ Throwable t = new Throwable();
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.parse("1611"), "sourceClass",
+ "sourceMethod", VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Throwable) msg",
+ t);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String, Throwable) msg");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE2);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.parse("1611"));
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), t);
+ assertNull(Level.parse("1611").getResourceBundleName());
+
+ this.sharedLogger.logrb(Level.CONFIG, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Throwable) msg",
+ t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.logrb(Level.OFF, "sourceClass", "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "logrb(Level, String, String, String, String, Throwable) msg",
+ t);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Throwable) with null
+ * message and throwable.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogrb_LevelStringTStringStringhrowable_NullMsgObj() {
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.logrb(Level.INFO, null, null, null, null,
+ (Throwable) null);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertNull(r.getMessage());
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Throwable) with null
+ * level.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogrb_LevelStringStringStringThrowable_NullLevel() {
+ // this.sharedLogger.setLevel(Level.OFF);
+ try {
+ this.sharedLogger.logrb(
+ null,
+ "sourceClass",
+ "sourceMethod",
+ VALID_RESOURCE_BUNDLE2,
+ "log(Level, String, String, String, String, Throwable) msg",
+ new Throwable());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test logrb(Level, String, String, String, String, Throwable) with invalid
+ * resource bundle.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "logrb",
+ args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
+ )
+ public void testLogrb_LevelStringStringStringThrowable_InvalidRes() {
+ Throwable t = new Throwable();
+ this.sharedLogger.setLevel(Level.ALL);
+ this.sharedLogger.logrb(Level.ALL, "sourceClass", "sourceMethod",
+ INVALID_RESOURCE_BUNDLE,
+ "logrb(Level, String, String, String, String) msg", t);
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), this.sharedLogger.getName());
+ assertEquals(r.getMessage(),
+ "logrb(Level, String, String, String, String) msg");
+ assertSame(r.getResourceBundleName(), INVALID_RESOURCE_BUNDLE);
+ assertSame(r.getResourceBundle(), null);
+ assertSame(r.getSourceClassName(), "sourceClass");
+ assertSame(r.getSourceMethodName(), "sourceMethod");
+ assertSame(r.getLevel(), Level.ALL);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), t);
+ }
+
+ /*
+ * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
+ * appropriate level, no filter, no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_LogRecord_AppropriateLevelNoFilterNoParent() {
+ LogRecord r = new LogRecord(Level.INFO,
+ "testLog_LogRecord_AppropriateLevelNoFilterNoParent");
+
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.log(r);
+
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), null);
+ assertEquals(r.getMessage(),
+ "testLog_LogRecord_AppropriateLevelNoFilterNoParent");
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(LogRecord) with null log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_LogRecord_Null() {
+ this.sharedLogger.setLevel(Level.INFO);
+ try {
+ this.sharedLogger.log(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
+ * inappropriate level, no filter, no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_LogRecord_InppropriateLevelNoFilterNoParent() {
+ LogRecord r = new LogRecord(Level.INFO,
+ "testLog_LogRecord_InppropriateLevelNoFilterNoParent");
+
+ this.sharedLogger.setLevel(Level.WARNING);
+ this.sharedLogger.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ r.setLevel(Level.OFF);
+ this.sharedLogger.setLevel(Level.OFF);
+ this.sharedLogger.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
+ * appropriate level, a filter that accepts the fed log record, no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_LogRecord_AppropriateLevelTrueFilterNoParent() {
+ LogRecord r = new LogRecord(Level.INFO,
+ "testLog_LogRecord_AppropriateLevelTrueFilterNoParent");
+
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.setFilter(new MockTrueFilter());
+ this.sharedLogger.log(r);
+
+ // pop twice, one pushed by mock handler, one by true mock filter
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ assertSame(r.getLoggerName(), null);
+ assertEquals(r.getMessage(),
+ "testLog_LogRecord_AppropriateLevelTrueFilterNoParent");
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
+ * appropriate level, a filter that rejects the fed log record, no parent.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_LogRecord_AppropriateLevelFalseFilterNoParent() {
+ LogRecord r = new LogRecord(Level.INFO,
+ "testLog_LogRecord_AppropriateLevelFalseFilterNoParent");
+
+ this.sharedLogger.setLevel(Level.INFO);
+ this.sharedLogger.setFilter(new MockFilter());
+ this.sharedLogger.log(r);
+
+ // pop only once, pushed by mock filter
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ assertSame(r.getLoggerName(), null);
+ assertEquals(r.getMessage(),
+ "testLog_LogRecord_AppropriateLevelFalseFilterNoParent");
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ }
+
+ /*
+ * Test that the parent's handler is notified for a new log record when
+ * getUseParentHandlers() is true.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_ParentInformed() {
+ Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
+ Logger parent = new MockParentLogger("parentLogger",
+ VALID_RESOURCE_BUNDLE2);
+
+ child.setParent(parent);
+ child.setLevel(Level.INFO);
+ parent.setLevel(Level.INFO);
+ parent.addHandler(new MockHandler());
+ LogRecord r = new LogRecord(Level.INFO, "testLog_ParentInformed");
+ child.log(r);
+ assertTrue(child.getUseParentHandlers());
+ // pop only once, pushed by the parent logger's handler, not by the
+ // parent itself!
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertSame(r.getLoggerName(), null);
+ assertEquals(r.getMessage(), "testLog_ParentInformed");
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.INFO);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+
+ // set the child logger to disabling level
+ child.setLevel(Level.SEVERE);
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set the parent logger to disabling level
+ child.setLevel(Level.INFO);
+ parent.setLevel(Level.SEVERE);
+ child.log(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set the child logger off
+ child.setLevel(Level.OFF);
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set the record off
+ r.setLevel(Level.OFF);
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test that the ancestor's handler is notified for a new log record when
+ * getUseParentHandlers() is true.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_AncestorInformed() {
+ Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
+ Logger parent = new MockParentLogger("parentLogger",
+ VALID_RESOURCE_BUNDLE2);
+ Logger ancestor = new MockParentLogger("ancestorLogger",
+ VALID_RESOURCE_BUNDLE3);
+
+ child.setParent(parent);
+ parent.setParent(ancestor);
+ child.setLevel(Level.INFO);
+ parent.setLevel(Level.INFO);
+ ancestor.setLevel(Level.OFF);
+ ancestor.addHandler(new MockHandler());
+ LogRecord r = new LogRecord(Level.INFO, "testLog_AncestorInformed");
+ child.log(r);
+ assertTrue(child.getUseParentHandlers());
+ assertTrue(parent.getUseParentHandlers());
+ // pop only once, pushed by the ancestor's logger's handler, not by the
+ // parent itself!
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set parent's level to a disabling one
+ parent.setLevel(Level.WARNING);
+ child.log(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set child's level to a disabling one
+ parent.setLevel(Level.INFO);
+ child.setLevel(Level.WARNING);
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ // set parent's useParentHandlers to false
+ parent.setLevel(Level.INFO);
+ child.setLevel(Level.INFO);
+ parent.setUseParentHandlers(false);
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test that the parent's handler is notified for a new log record when
+ * getUseParentHandlers() is false.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_ParentNotInformed() {
+ Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
+ Logger parent = new MockParentLogger("parentLogger",
+ VALID_RESOURCE_BUNDLE2);
+
+ child.setParent(parent);
+ child.setLevel(Level.INFO);
+ parent.setLevel(Level.INFO);
+ parent.addHandler(new MockHandler());
+ LogRecord r = new LogRecord(Level.INFO, "testLog_ParentInformed");
+ child.setUseParentHandlers(false);
+ child.log(r);
+ assertFalse(child.getUseParentHandlers());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test that a logger with null level and no parent. Defaulted to
+ * Level.INFO.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_NullLevelNoParent() {
+ LogRecord r = new LogRecord(Level.INFO, "testLog_NullLevelNoParent");
+ assertNull(this.sharedLogger.getLevel());
+ assertNull(this.sharedLogger.getParent());
+ assertTrue(this.sharedLogger.isLoggable(r.getLevel()));
+ this.sharedLogger.log(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertNull(this.sharedLogger.getLevel());
+
+ r.setLevel(Level.WARNING);
+ assertTrue(this.sharedLogger.isLoggable(r.getLevel()));
+ this.sharedLogger.log(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ r.setLevel(Level.CONFIG);
+ this.sharedLogger.log(r);
+ assertFalse(this.sharedLogger.isLoggable(r.getLevel()));
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test that a logger inherits its parent level when its level is null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_NullLevelHasParent() {
+ Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+ parent.setLevel(Level.FINER);
+
+ assertNull(child.getLevel());
+
+ LogRecord r = new LogRecord(Level.FINE, "testLog_NullLevelHasParent");
+ child.log(r);
+ assertTrue(child.isLoggable(r.getLevel()));
+ // pop only once, pushed by the child logger's handler
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ assertSame(r.getLoggerName(), null);
+ assertEquals(r.getMessage(), "testLog_NullLevelHasParent");
+ assertSame(r.getResourceBundleName(), null);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ assertNull(child.getLevel());
+
+ // set the parent logger to disabling level
+ parent.setLevel(Level.CONFIG);
+ assertFalse(child.isLoggable(r.getLevel()));
+ child.log(r);
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertNull(child.getLevel());
+
+ // test ancestor
+ Logger ancestor = new MockLogger("ancestorLogger",
+ VALID_RESOURCE_BUNDLE3);
+ parent.setParent(ancestor);
+ parent.setLevel(null);
+ parent.setUseParentHandlers(false);
+ ancestor.setLevel(Level.ALL);
+ child.log(r);
+ assertTrue(child.isLoggable(r.getLevel()));
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertNull(child.getLevel());
+ assertNull(parent.getLevel());
+ }
+
+ /*
+ * Test that a logger with null resource bundle and no parent. Defaulted to
+ * null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_NullResNoParent() {
+ Logger log = new MockLogger("Logger", null);
+ log.addHandler(new MockHandler());
+ log.setLevel(Level.FINE);
+
+ assertNull(log.getResourceBundle());
+ assertNull(log.getResourceBundleName());
+ assertNull(log.getParent());
+ log.log(Level.INFO, "testLog_NullResNoParent");
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertNull(log.getResourceBundle());
+ assertNull(log.getResourceBundleName());
+ assertNull(r.getResourceBundle());
+ assertNull(r.getResourceBundleName());
+ }
+
+ /*
+ * Test that a logger inherits its parent resource bundle when its resource
+ * bundle is null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_NullResHasParent() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+ parent.setLevel(Level.FINER);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+
+ child.log(Level.FINE, "testLog_NullResHasParent");
+ // pop only once, pushed by the child logger's handler
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ assertSame(r.getLoggerName(), "childLogger");
+ assertEquals(r.getMessage(), "testLog_NullResHasParent");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE2);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+ }
+
+ /*
+ * Test that a logger inherits its ancestor's resource bundle when its
+ * resource bundle and its parent's resource bundle are both null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_NullResHasAncestor() {
+ Logger child = new MockLogger("childLogger", null);
+ Logger parent = new MockLogger("parentLogger", null);
+ Logger ancestor = new MockLogger("ancestorLogger",
+ VALID_RESOURCE_BUNDLE3);
+ child.addHandler(new MockHandler());
+ child.setParent(parent);
+ parent.setParent(ancestor);
+ parent.setLevel(Level.FINER);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+
+ child.log(Level.FINE, "testLog_NullResHasAncestor");
+ // pop only once, pushed by the child logger's handler
+ LogRecord r = (LogRecord) CallVerificationStack.getInstance().pop();
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ assertSame(r.getLoggerName(), "childLogger");
+ assertEquals(r.getMessage(), "testLog_NullResHasAncestor");
+ assertSame(r.getResourceBundleName(), VALID_RESOURCE_BUNDLE3);
+ assertSame(r.getSourceClassName(), null);
+ assertSame(r.getSourceMethodName(), null);
+ assertSame(r.getLevel(), Level.FINE);
+ assertNull(r.getParameters());
+ assertSame(r.getThrown(), null);
+ assertNull(child.getResourceBundle());
+ assertNull(child.getResourceBundleName());
+ }
+
+ /*
+ * Test when one handler throws an exception.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "log",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLog_ExceptionalHandler() {
+ MockLogger l = new MockLogger("testLog_ExceptionalHandler", null);
+ l.addHandler(new MockExceptionalHandler());
+ l.addHandler(new MockHandler());
+ try {
+ l.severe("testLog_ExceptionalHandler");
+ fail("Should throw RuntimeException!");
+ } catch (RuntimeException e) {
+ }
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test whether privileged code is used to load resource bundles.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAnonymousLogger",
+ args = {java.lang.String.class}
+ )
+ public void testLoadResourceBundle() {
+ //
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockNoLoadingClassSecurityManager());
+ try {
+ Logger.getAnonymousLogger(VALID_RESOURCE_BUNDLE);
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+
+ /**
+ * java.util.logging.Logger#logrb(Level, String, String, String, String,
+ * Object)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getLogger",
+ args = {java.lang.String.class}
+ )
+ public void test_init_logger() throws Exception {
+ Properties p = new Properties();
+ p.put("testGetLogger_Normal_ANewLogger2.level", "ALL");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertNull(LogManager.getLogManager().getLogger(
+ "testGetLogger_Normal_ANewLogger2"));
+ SecurityManager originalSecurityManager = System.getSecurityManager();
+ try {
+ Logger logger = Logger
+ .getLogger("testGetLogger_Normal_ANewLogger2");
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ logger.setLevel(Level.ALL);
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+ try {
+ logger.setParent(Logger.getLogger(""));
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+ } finally {
+ System.setSecurityManager(originalSecurityManager);
+ }
+ }
+
+
+ /*
+ * A mock logger, used to test the protected constructors and fields.
+ */
+ public static class MockLogger extends Logger {
+
+ public MockLogger(String name, String resourceBundleName) {
+ super(name, resourceBundleName);
+ }
+ }
+
+ /*
+ * A mock logger, used to test inheritance.
+ */
+ public static class MockParentLogger extends Logger {
+
+ public MockParentLogger(String name, String resourceBundleName) {
+ super(name, resourceBundleName);
+ }
+
+ public void log(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ super.log(record);
+ }
+
+ }
+
+ /*
+ * A mock handler, used to validate the expected method is called with the
+ * expected parameters.
+ */
+ public static class MockHandler extends Handler {
+
+ public void close() {
+ // System.out.println("close!");
+ }
+
+ public void flush() {
+ // System.out.println("flushed!");
+ }
+
+ public void publish(LogRecord record) {
+ // System.out.println("publish!");
+ CallVerificationStack.getInstance().push(record);
+ }
+ }
+
+ /*
+ * A mock handler that throws an exception when publishing a log record.
+ */
+ public static class MockExceptionalHandler extends Handler {
+
+ public void close() {
+ // System.out.println("close!");
+ }
+
+ public void flush() {
+ // System.out.println("flushed!");
+ }
+
+ public void publish(LogRecord record) {
+ // System.out.println("publish!");
+ throw new RuntimeException();
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockSecurityManager extends SecurityManager {
+
+ public MockSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ /*
+ * Used to grant all permissions except getting class loader.
+ */
+ public static class MockNoLoadingClassSecurityManager extends
+ SecurityManager {
+
+ public MockNoLoadingClassSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except getting class loader
+ if (perm instanceof RuntimePermission) {
+ if ("getClassLoader".equals(perm.getName())) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+
+ /*
+ * A mock filter, always return false.
+ */
+ public static class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ return false;
+ }
+ }
+
+ /*
+ * A mock filter, always return true.
+ */
+ public static class MockTrueFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ return true;
+ }
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java
new file mode 100644
index 0000000..c9b7d50
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+
+import junit.framework.TestCase;
+
+import tests.util.CallVerificationStack;
+
+import java.util.List;
+import java.util.logging.LoggingMXBean;
+/**
+ * This testcase verifies the signature of the interface Filter.
+ *
+ */
+@TestTargetClass(LoggingMXBean.class)
+public class LoggingMXBeanTest extends TestCase {
+
+ private MockLoggingMXBean m = null;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ m = new MockLoggingMXBean();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLoggerLevel",
+ args = {java.lang.String.class}
+ )
+ public void testGetLoggerLevel() {
+ assertNull(m.getLoggerLevel(null));
+ }
+
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getLoggerNames",
+ args = {}
+ )
+ public void testGetLoggerNames() {
+ assertNull(m.getLoggerNames());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getParentLoggerName",
+ args = {java.lang.String.class}
+ )
+ public void testGetParentLoggerName() {
+ assertNull(m.getParentLoggerName(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setLoggerLevel",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetLoggerLevel() {
+ try{
+ m.setLoggerLevel(null,null);
+ }
+ catch (Exception e){
+ throw new AssertionError();
+ }
+ }
+
+ /*
+ * This inner class implements the interface Filter to verify the signature.
+ */
+ private class MockLoggingMXBean implements LoggingMXBean {
+
+ public String getLoggerLevel(String loggerName) {
+ return null;
+ }
+
+ public List<String> getLoggerNames() {
+ return null;
+ }
+
+ public String getParentLoggerName(String loggerName) {
+ return null;
+ }
+
+ public void setLoggerLevel(String loggerName, String levelName) {
+
+ }
+
+
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java
new file mode 100644
index 0000000..9507bbd
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.logging.LoggingPermission;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+@TestTargetClass(LoggingPermission.class)
+public class LoggingPermissionTest extends TestCase {
+
+ /**
+ * @tests serialization/deserialization compatibility.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "!SerializationSelf",
+ args = {}
+ )
+ public void testSerializationSelf() throws Exception {
+ SerializationTest.verifySelf(new LoggingPermission("control", ""));
+ }
+
+ /**
+ * @tests serialization/deserialization compatibility with RI.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "!SerializationGolden",
+ args = {}
+ )
+ public void testSerializationCompatibility() throws Exception {
+
+ SerializationTest.verifyGolden(this, new LoggingPermission("control",
+ ""));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "LoggingPermission",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testLoggingPermission() {
+ try {
+ new LoggingPermission(null, null);
+ fail("should throw IllegalArgumentException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ new LoggingPermission("", null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ new LoggingPermission("bad name", null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ new LoggingPermission("Control", null);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ new LoggingPermission("control",
+ "bad action");
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ new LoggingPermission("control", "");
+
+ new LoggingPermission("control", null);
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java
new file mode 100644
index 0000000..9aa344a
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java
@@ -0,0 +1,554 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StringWriter;
+import java.security.Permission;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.MemoryHandler;
+import java.util.logging.SimpleFormatter;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+/**
+ *
+ */
+@TestTargetClass(MemoryHandler.class)
+public class MemoryHandlerTest extends TestCase {
+
+ final static LogManager manager = LogManager.getLogManager();
+
+ final static Properties props = new Properties();
+
+ final static String baseClassName = MemoryHandlerTest.class.getName();
+
+ final static StringWriter writer = new StringWriter();
+
+ final static SecurityManager securityManager = new MockSecurityManager();
+
+ private final PrintStream err = System.err;
+
+ private OutputStream errSubstituteStream = null;
+
+ MemoryHandler handler;
+
+ Handler target = new MockHandler();
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ manager.reset();
+ initProps();
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ errSubstituteStream = new NullOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ }
+
+ /**
+ *
+ */
+ private void initProps() {
+ props.put("java.util.logging.MemoryHandler.level", "FINE");
+ props.put("java.util.logging.MemoryHandler.filter", baseClassName
+ + "$MockFilter");
+ props.put("java.util.logging.MemoryHandler.size", "2");
+ props.put("java.util.logging.MemoryHandler.push", "WARNING");
+ props.put("java.util.logging.MemoryHandler.target", baseClassName
+ + "$MockHandler");
+ props.put("java.util.logging.MemoryHandler.formatter", baseClassName
+ + "$MockFormatter");
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ manager.readConfiguration();
+ props.clear();
+ System.setErr(err);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "close",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "setPushLevel",
+ args = {java.util.logging.Level.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "flush",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "push",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "getPushLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "SecurityException",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ })
+ public void testGlobalSecurity() {
+ SecurityManager currentManager = System.getSecurityManager();
+ System.setSecurityManager(securityManager);
+ try {
+ try {
+ handler.close();
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ try {
+ handler.setPushLevel(Level.CONFIG);
+ fail("should throw security exception");
+ } catch (SecurityException e) {
+ }
+ handler.flush();
+ handler.push();
+ handler.getPushLevel();
+ handler.isLoggable(new LogRecord(Level.ALL, "message"));
+ handler.publish(new LogRecord(Level.ALL, "message"));
+ } finally {
+ System.setSecurityManager(currentManager);
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "close",
+ args = {}
+ )
+ public void testClose() {
+ Filter filter = handler.getFilter();
+ Formatter formatter = handler.getFormatter();
+ writer.getBuffer().setLength(0);
+ handler.close();
+ assertEquals(writer.toString(), "close");
+ assertEquals(handler.getFilter(), filter);
+ assertEquals(handler.getFormatter(), formatter);
+ assertNull(handler.getEncoding());
+ assertNotNull(handler.getErrorManager());
+ assertEquals(handler.getLevel(), Level.OFF);
+ assertEquals(handler.getPushLevel(), Level.WARNING);
+ assertFalse(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "flush",
+ args = {}
+ )
+ public void testFlush() {
+ Filter filter = handler.getFilter();
+ Formatter formatter = handler.getFormatter();
+ writer.getBuffer().setLength(0);
+ handler.flush();
+ assertEquals(writer.toString(), "flush");
+ assertEquals(handler.getFilter(), filter);
+ assertEquals(handler.getFormatter(), formatter);
+ assertNull(handler.getEncoding());
+ assertNotNull(handler.getErrorManager());
+ assertEquals(handler.getLevel(), Level.FINE);
+ assertEquals(handler.getPushLevel(), Level.WARNING);
+ assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable() {
+ try {
+ handler.isLoggable(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ LogRecord record = new LogRecord(Level.FINER, "MSG1");
+ assertFalse(handler.isLoggable(record));
+
+
+ record = new LogRecord(Level.FINE, "MSG2");
+ assertTrue(handler.isLoggable(record));
+ assertTrue(handler.isLoggable(new LogRecord(Level.INFO, "1")));
+ assertTrue(handler.isLoggable(new LogRecord(Level.WARNING, "2")));
+ assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "3")));
+
+ record = new LogRecord(Level.CONFIG, "MSG3");
+ assertTrue(handler.isLoggable(record));
+
+ record = new LogRecord(Level.CONFIG, "false");
+ assertFalse(handler.isLoggable(record));
+
+ handler.setFilter(null);
+ record = new LogRecord(Level.CONFIG, "false");
+ assertTrue(handler.isLoggable(record));
+ }
+
+ /*
+ * Class under test for void MemoryHandler()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "check errors",
+ method = "MemoryHandler",
+ args = {}
+ )
+ public void testMemoryHandler() throws IOException {
+ assertNotNull("Filter should not be null", handler.getFilter());
+ assertNotNull("Formatter should not be null", handler.getFormatter());
+ assertNull("character encoding should be null", handler.getEncoding());
+ assertNotNull("ErrorManager should not be null", handler
+ .getErrorManager());
+ assertEquals("Level should be FINE", Level.FINE, handler.getLevel());
+ assertEquals("Level should be WARNING", Level.WARNING, handler
+ .getPushLevel());
+
+ props.clear();
+ props.put("java.util.logging.MemoryHandler.target", baseClassName
+ + "$MockHandler");
+
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertNull(handler.getFilter());
+ assertTrue(handler.getFormatter() instanceof SimpleFormatter);
+ assertNull(handler.getEncoding());
+ assertNotNull(handler.getErrorManager());
+ assertEquals(handler.getLevel(), Level.ALL);
+ assertEquals(handler.getPushLevel(), Level.SEVERE);
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "MemoryHandler",
+ args = {}
+ )
+ public void testMemoryHandlerInvalidProps() throws IOException {
+ // null target
+ try {
+ props.remove("java.util.logging.MemoryHandler.target");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ fail("should throw RuntimeException: target must be set");
+ } catch (RuntimeException e) {
+ }
+
+ // invalid target
+ try {
+ props.put("java.util.logging.MemoryHandler.target", "badname");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ fail("should throw RuntimeException: target must be valid");
+ } catch (RuntimeException e) {
+ }
+
+ // invalid formatter
+ initProps();
+ props.put("java.util.logging.MemoryHandler.formatter", "badname");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertTrue(handler.getFormatter() instanceof SimpleFormatter);
+
+ // invalid level
+ initProps();
+ props.put("java.util.logging.MemoryHandler.level", "badname");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertEquals(handler.getLevel(), Level.ALL);
+
+ // invalid pushlevel
+ initProps();
+ props.put("java.util.logging.MemoryHandler.push", "badname");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertEquals(handler.getPushLevel(), Level.SEVERE);
+
+ // invalid filter
+ initProps();
+ props.put("java.util.logging.MemoryHandler.filter", "badname");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertNull(handler.getFilter());
+
+ // invalid size
+ initProps();
+ props.put("java.util.logging.MemoryHandler.size", "-1");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ initProps();
+ props.put("java.util.logging.MemoryHandler.size", "badsize");
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "MemoryHandler",
+ args = {}
+ )
+ public void testMemoryHandlerDefaultValue() throws SecurityException,
+ IOException {
+ props.clear();
+ props.put("java.util.logging.MemoryHandler.target", baseClassName
+ + "$MockHandler");
+
+ manager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ handler = new MemoryHandler();
+ assertNull(handler.getFilter());
+ assertTrue(handler.getFormatter() instanceof SimpleFormatter);
+ assertNull(handler.getEncoding());
+ assertNotNull(handler.getErrorManager());
+ assertEquals(handler.getLevel(), Level.ALL);
+ assertEquals(handler.getPushLevel(), Level.SEVERE);
+ }
+
+ /*
+ * Class under test for void MemoryHandler(Handler, int, Level)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "MemoryHandler",
+ args = {java.util.logging.Handler.class, int.class, java.util.logging.Level.class}
+ )
+ public void testMemoryHandlerHandlerintLevel() {
+ handler = new MemoryHandler(target, 2, Level.FINEST);
+ assertNotNull("Filter should not be null", handler.getFilter());
+ assertNotNull("Formatter should not be null", handler.getFormatter());
+ assertNull("character encoding should be null", handler.getEncoding());
+ assertNotNull("ErrorManager should not be null", handler
+ .getErrorManager());
+ assertEquals("Level should be FINE", Level.FINE, handler.getLevel());
+ assertEquals("Level should be FINEST", Level.FINEST, handler
+ .getPushLevel());
+
+ try {
+ new MemoryHandler(null, 2, Level.FINEST);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ new MemoryHandler(target, 2, null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ new MemoryHandler(target, 0, Level.FINEST);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ new MemoryHandler(target, -1, Level.FINEST);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getPushLevel",
+ args = {}
+ )
+ public void testGetPushLevel() {
+ try {
+ handler.setPushLevel(null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ handler.setPushLevel(Level.parse("123"));
+ assertEquals(handler.getPushLevel(), Level.parse("123"));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setPushLevel",
+ args = {java.util.logging.Level.class}
+ )
+ public void testSetPushLevel() {
+ // change push level don't trigger push action
+ writer.getBuffer().setLength(0);
+ LogRecord lr = new LogRecord(Level.CONFIG, "lr");
+ assertTrue(handler.isLoggable(lr));
+ handler.publish(lr);
+ assertEquals(writer.toString(), "");
+ writer.getBuffer().setLength(0);
+ handler.setPushLevel(Level.FINE);
+ assertEquals(writer.toString(), "");
+ handler.publish(lr);
+ assertEquals(writer.toString(), lr.getMessage() + lr.getMessage());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "push",
+ args = {}
+ )
+ public void testPushPublic() {
+ writer.getBuffer().setLength(0);
+ // loggable but don't trig push
+ handler.publish(new LogRecord(Level.CONFIG, "MSG1"));
+ assertEquals("", writer.toString());
+ // trig push
+ handler.publish(new LogRecord(Level.SEVERE, "MSG2"));
+ assertEquals(writer.toString(), "MSG1MSG2");
+ writer.getBuffer().setLength(0);
+
+ // regression test for Harmony-1292
+ handler.publish(new LogRecord(Level.WARNING, "MSG"));
+ assertEquals("MSG",writer.toString());
+
+ writer.getBuffer().setLength(0);
+ // push nothing
+ handler.push();
+ assertEquals("", writer.toString());
+ // loggable but not push
+ handler.publish(new LogRecord(Level.CONFIG, "MSG3"));
+ assertEquals("", writer.toString());
+ // not loggable
+ handler.publish(new LogRecord(Level.FINEST, "MSG4"));
+ assertEquals("", writer.toString());
+ // loggable but not push
+ handler.publish(new LogRecord(Level.CONFIG, "MSG5"));
+ assertEquals("", writer.toString());
+ // not loggable
+ handler.publish(new LogRecord(Level.FINER, "MSG6"));
+ assertEquals("", writer.toString());
+ // not loggable
+ handler.publish(new LogRecord(Level.FINER, "false"));
+ assertEquals("", writer.toString());
+ // loggable but not push
+ handler.publish(new LogRecord(Level.CONFIG, "MSG8"));
+ assertEquals("", writer.toString());
+ // push all
+ handler.push();
+ assertEquals(writer.toString(), "MSG5MSG8");
+ writer.getBuffer().setLength(0);
+ handler.push();
+ assertEquals("", writer.toString());
+ }
+
+ /*
+ * mock classes
+ */
+ public static class MockFilter implements Filter {
+ public boolean isLoggable(LogRecord record) {
+ return !record.getMessage().equals("false");
+ }
+ }
+
+ public static class MockHandler extends Handler {
+ public void close() {
+ writer.write("close");
+ }
+
+ public void flush() {
+ writer.write("flush");
+ }
+
+ public void publish(LogRecord record) {
+ writer.write(record.getMessage());
+ }
+
+ }
+
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord r) {
+ return r.getMessage();
+ }
+ }
+
+ public static class MockSecurityManager extends SecurityManager {
+ public void checkPermission(Permission perm) {
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ return;
+ }
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java
new file mode 100644
index 0000000..74edbcb
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.logging.ErrorManager;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+
+
+@TestTargetClass(Messages.class)
+public class MessagesTest extends TestCase{
+
+
+ private Messages m = null;
+
+ public void setUp() throws Exception{
+ super.setUp();
+ m = new Messages();
+
+ }
+
+ public void tearDown() throws Exception{
+ super.tearDown();
+ }
+
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Just check signature, cannot make use of mock, method depend on luni",
+ method = "getString",
+ args = {java.lang.String.class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_String() {
+ m.getString(new String());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Juste check signature, cannot make use of mock, depend on luni",
+ method = "getString",
+ args = {java.lang.String.class, java.lang.Object.class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_StringObject() {
+ m.getString(new String(), new Object());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Juste check signature, cannot make use of mock, depend on luni",
+ method = "getString",
+ args = {java.lang.String.class, int.class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_StringInt() {
+ m.getString(new String(), 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Juste check signature, cannot make use of mock, depend on luni",
+ method = "getString",
+ args = {java.lang.String.class, char.class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_StringChar() {
+ m.getString(new String(), 'a');
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Juste check signature, cannot make use of mock, depend on luni",
+ method = "getString",
+ args = {java.lang.String.class, java.lang.Object.class, java.lang.Object.class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_StringObjectObject() {
+ m.getString(new String(), new Object(), new Object() );
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Juste check signature, cannot make use of mock, depend on luni",
+ method = "getString",
+ args = {java.lang.String.class, java.lang.Object[].class}
+ )
+ @AndroidOnly("harmony specific")
+ public void testGetString_StringObjectArray() {
+ m.getString(new String(), new Object[1]);
+ }
+
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java
new file mode 100644
index 0000000..79e37e8
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.Calendar;
+import java.util.ResourceBundle;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.MemoryHandler;
+import java.util.logging.SimpleFormatter;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+@TestTargetClass(SimpleFormatter.class)
+public class SimpleFormatterTest extends TestCase {
+
+ SimpleFormatter sf;
+
+ LogRecord lr;
+
+ private static String MSG = "test msg. pls. ignore it\nadaadasfdasfd\nadfafdadfsa";
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ sf = new SimpleFormatter();
+ lr = new LogRecord(Level.FINE, MSG);
+ }
+
+ /*
+ * test for constructor protected SimpleFormatter
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SimpleFormatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {java.util.logging.Handler.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ )
+ })
+ public void testSimpleFormatter() {
+ assertEquals("Head for this SimpleFormatter should be empty", "", sf
+ .getHead(null));
+ assertEquals("Tail for this SimpleFormatter should be empty", "", sf
+ .getTail(null));
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testFormatNull() {
+ try {
+ sf.format(null);
+ fail("should throw nullpointer exception");
+ } catch (NullPointerException e) {
+ }
+ sf.format(new LogRecord(Level.SEVERE, null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLocalizedFormat() {
+ // if bundle set, should use localized message
+ ResourceBundle rb = ResourceBundle
+ .getBundle("bundles/java/util/logging/res");
+ lr.setResourceBundle(rb);
+ lr.setMessage("msg");
+ String localeMsg = rb.getString("msg");
+ String str = sf.format(lr);
+ assertTrue(str.indexOf(localeMsg) > 0);
+
+ // if bundle not set but bundle name set, should use original message
+ lr.setResourceBundle(null);
+ lr.setResourceBundleName("bundles/java/util/logging/res");
+ lr.setMessage("msg");
+ str = sf.format(lr);
+ localeMsg = rb.getString("msg");
+ assertTrue(str.indexOf(localeMsg) < 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testFormat() {
+ String str = sf.format(lr);
+ Throwable t;
+
+ lr.setMessage(MSG + " {0,number}");
+ lr.setLoggerName("logger");
+ lr.setResourceBundleName("rb name");
+ lr.setSourceClassName("class");
+ lr.setSourceMethodName("method");
+ lr.setParameters(new Object[] { new Integer(100), new Object() });
+ lr.setThreadID(1000);
+ lr.setThrown(t = new Exception("exception") {
+ private static final long serialVersionUID = 1L;
+
+ public String getLocalizedMessage() {
+ return "locale";
+ }
+ });
+ lr.setSequenceNumber(12321312);
+ lr.setMillis(0);
+ str = sf.format(lr);
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(12321312);
+ assertTrue(str.indexOf(String.valueOf(cal.get(Calendar.YEAR))) >= 0);
+ assertTrue(str.indexOf("class") > 0);
+ assertTrue(str.indexOf("method") > 0);
+ assertTrue(str.indexOf("100") > 0);
+ assertTrue(str.indexOf(t.toString()) > 0);
+ assertTrue(str.indexOf(Level.FINE.getLocalizedName()) > 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testGetHead() {
+ assertEquals("", sf.getHead(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testGetTail() {
+ assertEquals("", sf.getTail(null));
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java
new file mode 100644
index 0000000..3e17ff6
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java
@@ -0,0 +1,1039 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.Permission;
+import java.util.Properties;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.SimpleFormatter;
+import java.util.logging.SocketHandler;
+import java.util.logging.XMLFormatter;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+import tests.util.CallVerificationStack;
+
+/**
+ * Test class java.util.logging.ConsoleHandler
+ */
+@TestTargetClass(SocketHandler.class)
+public class SocketHandlerTest extends TestCase {
+
+ private static final LogManager LOG_MANAGER = LogManager.getLogManager();
+
+ private final static String INVALID_LEVEL = "impossible_level";
+
+ private final PrintStream err = System.err;
+
+ private OutputStream errSubstituteStream = null;
+
+ private static String className = SocketHandlerTest.class.getName();
+
+ private SocketHandler h = null;
+
+ private Properties props;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ errSubstituteStream = new NullOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ //initProps
+ props = new Properties();
+ props.put("handlers", className + "$MockHandler " + className
+ + "$MockHandler");
+ props.put("java.util.logging.FileHandler.pattern", "%h/java%u.log");
+ props.put("java.util.logging.FileHandler.limit", "50000");
+ props.put("java.util.logging.FileHandler.count", "5");
+ props.put("java.util.logging.FileHandler.formatter",
+ "java.util.logging.XMLFormatter");
+ props.put(".level", "FINE");
+ props.put("java.util.logging.ConsoleHandler.level", "OFF");
+ props.put("java.util.logging.ConsoleHandler.formatter",
+ "java.util.logging.SimpleFormatter");
+ props.put("foo.handlers", "java.util.logging.ConsoleHandler");
+ props.put("foo.level", "WARNING");
+ props.put("com.xyz.foo.level", "SEVERE");
+
+
+ LOG_MANAGER.reset();
+ LOG_MANAGER.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ CallVerificationStack.getInstance().clear();
+ if (null != h) {
+ h.close();
+ h = null;
+ }
+ System.setErr(err);
+ super.tearDown();
+ }
+
+
+ /*
+ * Test the constructor with no relevant log manager properties are set.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no relevant log manager properties are set.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no relevant log manager properties are set.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_NoProperties() throws Exception {
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.level"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.filter"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.formatter"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.encoding"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.host"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.port"));
+
+ try {
+ h = new SocketHandler();
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler(null, 0);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler("", 0);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler("127.0.0.1", -1);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler("127.0.0.1", Integer.MAX_VALUE);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler("127.0.0.1", 66666);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ h = new SocketHandler("127.0.0.1", 0);
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler("127.0.0.1", 6666);
+ assertSame(h.getLevel(), Level.ALL);
+ assertTrue(h.getFormatter() instanceof XMLFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ }
+
+ /*
+ * Test the constructor with no relevant log manager properties are set
+ * except host and port.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no relevant log manager properties are set except host and port.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no relevant log manager properties are set except host and port.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_NoBasicProperties() throws Exception {
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.level"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.filter"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.formatter"));
+ assertNull(LOG_MANAGER.getProperty(
+ "java.util.logging.SocketHandler.encoding"));
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ assertSame(h.getLevel(), Level.ALL);
+ assertTrue(h.getFormatter() instanceof XMLFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+
+ try {
+ h = new SocketHandler("127.0.sdfcdsfsa%%&&^0.1", 6665);
+ fail("Should throw IOException!");
+ } catch (IOException e) {
+ }
+ }
+
+ /*
+ * Test the constructor with insufficient privilege for connection.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_InsufficientPrivilege() throws Exception {
+ SecurityManager oldMan = null;
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", "FINE");
+ p.put("java.util.logging.SocketHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.encoding", "utf-8");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockNoSocketSecurityManager());
+ try {
+ new SocketHandler();
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ System.setSecurityManager(new MockNoSocketSecurityManager());
+ try {
+ new SocketHandler("127.0.0.1", 6666);
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test the constructor with valid relevant log manager properties are set.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with valid relevant log manager properties are set.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with valid relevant log manager properties are set.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_ValidProperties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", "FINE");
+ p.put("java.util.logging.SocketHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ assertSame(h.getLevel(), Level.parse("FINE"));
+ assertTrue(h.getFormatter() instanceof MockFormatter);
+ assertTrue(h.getFilter() instanceof MockFilter);
+ assertEquals(h.getEncoding(), "iso-8859-1");
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+
+ // start the server to be ready to accept log messages
+ thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler("127.0.0.1", 6666);
+ assertSame(h.getLevel(), Level.parse("FINE"));
+ assertTrue(h.getFormatter() instanceof MockFormatter);
+ assertTrue(h.getFilter() instanceof MockFilter);
+ assertEquals(h.getEncoding(), "iso-8859-1");
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ }
+
+ /*
+ * Test the constructor with invalid relevant log manager properties are set
+ * except host and port.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with invalid relevant log manager properties are set except host and port.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with invalid relevant log manager properties are set except host and port.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_InvalidBasicProperties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", INVALID_LEVEL);
+ p.put("java.util.logging.SocketHandler.filter", className + "");
+ p.put("java.util.logging.SocketHandler.formatter", className + "");
+ p.put("java.util.logging.SocketHandler.encoding", "XXXX");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ assertSame(h.getLevel(), Level.ALL);
+ assertTrue(h.getFormatter() instanceof XMLFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.publish(new LogRecord(Level.SEVERE, "test"));
+ assertNull(h.getEncoding());
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+
+ // start the server to be ready to accept log messages
+ thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler("127.0.0.1", 6666);
+ assertSame(h.getLevel(), Level.ALL);
+ assertTrue(h.getFormatter() instanceof XMLFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.publish(new LogRecord(Level.SEVERE, "test"));
+ assertNull(h.getEncoding());
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ }
+
+ /*
+ * Test the constructor with valid relevant log manager properties are set
+ * except port.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IllegalArgumentException.",
+ method = "SocketHandler",
+ args = {}
+ )
+ public void testConstructor_InvalidPort() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", "FINE");
+ p.put("java.util.logging.SocketHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666i");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ try {
+ h = new SocketHandler();
+ fail("Should throw IllegalArgumentException!");
+ } catch (IllegalArgumentException e) {
+
+ }
+ }
+
+ /*
+ * Test the constructor with valid relevant log manager properties are set,
+ * but the port is not open.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that the constructor with valid relevant log manager properties are set, but the port is not open.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that the constructor with valid relevant log manager properties are set, but the port is not open.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_NotOpenPort() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", "FINE");
+ p.put("java.util.logging.SocketHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6665");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ try {
+ h = new SocketHandler();
+ fail("Should throw IOException!");
+ } catch (IOException e) {
+
+ }
+
+ try {
+ h = new SocketHandler("127.0.0.1", 6665);
+ fail("Should throw IOException!");
+ } catch (IOException e) {
+
+ }
+ }
+
+ /*
+ * Test the constructor with valid relevant log manager properties are set
+ * except port.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IOException.",
+ method = "SocketHandler",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies IOException.",
+ method = "SocketHandler",
+ args = {java.lang.String.class, int.class}
+ )
+ })
+ public void testConstructor_InvalidHost() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.level", "FINE");
+ p.put("java.util.logging.SocketHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.encoding", "iso-8859-1");
+ p.put("java.util.logging.SocketHandler.host", " 34345 #$#%$%$");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ try {
+ h = new SocketHandler();
+ fail("Should throw IOException!");
+ } catch (IOException e) {
+
+ }
+
+ try {
+ h = new SocketHandler(" 34345 #$#%$%$", 6666);
+ fail("Should throw IOException!");
+ } catch (IOException e) {
+
+ }
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and a record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_NormalClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ h.publish(new LogRecord(Level.SEVERE,
+ "testClose_SufficientPrivilege_NormalClose msg"));
+ h.close();
+ assertEquals("MockFormatter_Head"
+ + "testClose_SufficientPrivilege_NormalClose msg"
+ + "MockFormatter_Tail", thread.getReadString());
+ h.close();
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and no record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and no record has been written to the output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_DirectClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+
+ h.close();
+ assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
+ .getReadString());
+ }
+
+ /*
+ * Test close() when having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having insufficient privilege.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_InsufficientPrivilege() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ h.close();
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ } finally {
+ System.setSecurityManager(oldMan);
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ }
+ }
+
+ /*
+ * Test publish(), use no filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use no filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NoFilter() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ h.close();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+ + "testPublish_NoFilter" + "MockFormatter_Tail", thread
+ .getReadString());
+ }
+
+ /*
+ * Test publish(), use a filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use a filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_WithFilter() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+ h.setFilter(new MockFilter());
+
+ System.setErr(new PrintStream(new ByteArrayOutputStream()));
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ h.close();
+ assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
+ .getReadString());
+ }
+
+ /*
+ * Test publish(), null log record, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), null log record, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_Null() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+ try {
+ h.publish(null);
+ } finally {
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ }
+ }
+
+ /*
+ * Test publish(), a log record with empty msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish() method, a log record with empty msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_EmptyMsg() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+ LogRecord r = new LogRecord(Level.INFO, "");
+ h.publish(r);
+ h.close();
+ assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
+ .getReadString());
+ }
+
+ /*
+ * Test publish(), a log record with null msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), a log record with null msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NullMsg() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+ h = new SocketHandler();
+ h.setLevel(Level.INFO);
+ LogRecord r = new LogRecord(Level.INFO, null);
+ h.publish(r);
+ h.close();
+ assertEquals("MockFormatter_Head" + "MockFormatter_Tail", thread
+ .getReadString());
+ }
+
+ /*
+ * Test publish(), after close.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish() method after close.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_AfterClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.SocketHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.SocketHandler.host", "127.0.0.1");
+ p.put("java.util.logging.SocketHandler.port", "6666");
+ LOG_MANAGER.readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ // start the server to be ready to accept log messages
+ ServerThread thread = new ServerThread();
+ thread.start();
+ Thread.sleep(2000);
+ h = new SocketHandler();
+ h.setLevel(Level.FINE);
+
+ assertSame(h.getLevel(), Level.FINE);
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFormatter");
+ assertTrue(h.isLoggable(r));
+ h.close();
+ // ensure the thread exits and the port becomes available again
+ thread.getReadString();
+ // assertFalse(h.isLoggable(r));
+ h.publish(r);
+ h.flush();
+ // assertEquals("MockFormatter_Head",
+ // this.errSubstituteStream.toString());
+ }
+
+ /*
+ * A mock filter, always return false.
+ */
+ public static class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ // System.out.println("filter called...");
+ return false;
+ }
+ }
+
+ /*
+ * A mock formatter.
+ */
+ public static class MockFormatter extends Formatter {
+ public String format(LogRecord r) {
+ // System.out.println("formatter called...");
+ return super.formatMessage(r);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
+ */
+ public String getHead(Handler h) {
+ return "MockFormatter_Head";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
+ */
+ public String getTail(Handler h) {
+ return "MockFormatter_Tail";
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockSecurityManager extends SecurityManager {
+
+ public MockSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockNoSocketSecurityManager extends SecurityManager {
+
+ public MockNoSocketSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ }
+
+ public void checkConnect(String host, int port) {
+ throw new SecurityException();
+ }
+ }
+
+ /*
+ * A mock stream handler, expose setOutputStream.
+ */
+ public static class MockSocketHandler extends SocketHandler {
+ public MockSocketHandler() throws Exception {
+ super();
+ }
+
+ public void setOutputStream(OutputStream out) {
+ super.setOutputStream(out);
+ }
+
+ public boolean isLoggable(LogRecord r) {
+ CallVerificationStack.getInstance().push(r);
+ return super.isLoggable(r);
+ }
+ }
+
+ /*
+ * A server thread that accepts an incoming connection request and reads any
+ * incoming data into an byte array.
+ */
+ public static class ServerThread extends Thread {
+
+ private volatile StringBuffer sb = new StringBuffer();
+
+ private volatile boolean finished = false;
+
+ public boolean finished() {
+ return this.finished;
+ }
+
+ public String getReadString() throws Exception {
+ int i = 0;
+ while (!this.finished) {
+ sleep(100);
+ if (++i > 100) {
+ // connect to port 6666 to stop the listening.
+ try {
+ Socket s = new Socket("127.0.0.1", 6666);
+ OutputStream os = s.getOutputStream();
+ os.write(1);
+ os.close();
+ s.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+ return this.sb.toString();
+ }
+
+ public void run() {
+ ServerSocket ss = null;
+ Socket s = null;
+ InputStreamReader reader = null;
+ try {
+ char[] buffer = new char[32];
+ ss = new ServerSocket(6666);
+ s = ss.accept();
+ reader = new InputStreamReader(s.getInputStream());
+ while (true) {
+ int length = reader.read(buffer);
+ if (-1 == length) {
+ break;
+ }
+ this.sb.append(buffer, 0, length);
+ }
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ } finally {
+ try {
+ if (null != reader) {
+ reader.close();
+ s.close();
+ ss.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ }
+ this.finished = true;
+ }
+ }
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java
new file mode 100644
index 0000000..72270e5
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java
@@ -0,0 +1,1324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.logging.Filter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.LoggingPermission;
+import java.util.logging.SimpleFormatter;
+import java.util.logging.SocketHandler;
+import java.util.logging.StreamHandler;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+import tests.util.CallVerificationStack;
+
+/**
+ * Test the class StreamHandler.
+ */
+@TestTargetClass(StreamHandler.class)
+public class StreamHandlerTest extends TestCase {
+
+ private final static String INVALID_LEVEL = "impossible_level";
+
+ private final PrintStream err = System.err;
+
+ private OutputStream errSubstituteStream = null;
+
+ private static String className = StreamHandlerTest.class.getName();
+
+ private static CharsetEncoder encoder;
+
+ static {
+ encoder = Charset.forName("iso-8859-1").newEncoder();
+ encoder.onMalformedInput(CodingErrorAction.REPLACE);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ }
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ errSubstituteStream = new NullOutputStream();
+ System.setErr(new PrintStream(errSubstituteStream));
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ LogManager.getLogManager().reset();
+ CallVerificationStack.getInstance().clear();
+ System.setErr(err);
+ super.tearDown();
+ }
+
+ /*
+ * Test the constructor with no parameter, and no relevant log manager
+ * properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no parameter, and no relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {}
+ )
+ public void testConstructor_NoParameter_NoProperties() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+
+ StreamHandler h = new StreamHandler();
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with insufficient privilege.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_NoParameter_InsufficientPrivilege() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ // set a normal value
+ try {
+ StreamHandler h = new StreamHandler();
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test the constructor with no parameter, and valid relevant log manager
+ * properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no parameter, and valid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {}
+ )
+ public void testConstructor_NoParameter_ValidProperties() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", "FINE");
+ p.put("java.util.logging.StreamHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.StreamHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals("FINE", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ StreamHandler h = new StreamHandler();
+ assertSame(h.getLevel(), Level.parse("FINE"));
+ assertTrue(h.getFormatter() instanceof MockFormatter);
+ assertTrue(h.getFilter() instanceof MockFilter);
+ assertEquals("iso-8859-1", h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with no parameter, and invalid relevant log manager
+ * properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with no parameter, and invalid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {}
+ )
+ public void testConstructor_NoParameter_InvalidProperties()
+ throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
+ p.put("java.util.logging.StreamHandler.filter", className + "");
+ p.put("java.util.logging.StreamHandler.formatter", className + "");
+ p.put("java.util.logging.StreamHandler.encoding", "XXXX");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("XXXX", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ StreamHandler h = new StreamHandler();
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof SimpleFormatter);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ h.publish(new LogRecord(Level.SEVERE, "test"));
+ assertTrue(CallVerificationStack.getInstance().empty());
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with normal parameter values, and no relevant log
+ * manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with normal parameter values, and no relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameters_NoProperties() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new MockFormatter2());
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof MockFormatter2);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with insufficient privilege.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameter_InsufficientPrivilege() {
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.filter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.formatter"));
+ assertNull(LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ // set a normal value
+ try {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new MockFormatter2());
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof MockFormatter2);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test the constructor with normal parameter values, and valid relevant log
+ * manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with normal parameter values, and valid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameters_ValidProperties()
+ throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", "FINE");
+ p.put("java.util.logging.StreamHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.StreamHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals("FINE", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new MockFormatter2());
+ assertSame(h.getLevel(), Level.parse("FINE"));
+ assertTrue(h.getFormatter() instanceof MockFormatter2);
+ assertTrue(h.getFilter() instanceof MockFilter);
+ assertEquals("iso-8859-1", h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with normal parameter, and invalid relevant log
+ * manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with normal parameter, and invalid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameters_InvalidProperties()
+ throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
+ p.put("java.util.logging.StreamHandler.filter", className + "");
+ p.put("java.util.logging.StreamHandler.formatter", className + "");
+ p.put("java.util.logging.StreamHandler.encoding", "XXXX");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("XXXX", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new MockFormatter2());
+ assertSame(Level.INFO, h.getLevel());
+ assertTrue(h.getFormatter() instanceof MockFormatter2);
+ assertNull(h.getFilter());
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test the constructor with null formatter, and invalid relevant log manager
+ * properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with null formatter, and invalid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameters_ValidPropertiesNullStream()
+ throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", "FINE");
+ p.put("java.util.logging.StreamHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.StreamHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals("FINE", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ try {
+ new StreamHandler(new ByteArrayOutputStream(), null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test the constructor with null output stream, and invalid relevant log
+ * manager properties are set.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies the constructor with null output stream, and invalid relevant log manager properties are set.",
+ method = "StreamHandler",
+ args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
+ )
+ public void testConstructor_HasParameters_ValidPropertiesNullFormatter()
+ throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", "FINE");
+ p.put("java.util.logging.StreamHandler.filter", className
+ + "$MockFilter");
+ p.put("java.util.logging.StreamHandler.formatter", className
+ + "$MockFormatter");
+ p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ assertEquals("FINE", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.level"));
+ assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+ "java.util.logging.StreamHandler.encoding"));
+ try {
+ new StreamHandler(null, new MockFormatter2());
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and a record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_NormalClose() {
+ ByteArrayOutputStream aos = new MockOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.publish(new LogRecord(Level.SEVERE,
+ "testClose_SufficientPrivilege_NormalClose msg"));
+ h.close();
+ assertEquals("close", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertEquals("flush", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ CallVerificationStack.getInstance().clear();
+ assertTrue(aos.toString().endsWith("MockFormatter_Tail"));
+ h.close();
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and an output stream that
+ * always throws exceptions.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() when having sufficient privilege, and an output stream that always throws exceptions.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_Exception() {
+ ByteArrayOutputStream aos = new MockExceptionOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.publish(new LogRecord(Level.SEVERE,
+ "testClose_SufficientPrivilege_Exception msg"));
+ h.flush();
+ h.close();
+ }
+
+ /*
+ * Test close() when having sufficient privilege, and no record has been
+ * written to the output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() method when having sufficient privilege, and no record has been written to the output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_SufficientPrivilege_DirectClose() {
+ ByteArrayOutputStream aos = new MockOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.close();
+ assertEquals("close", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ assertNull(CallVerificationStack.getInstance().pop());
+ assertEquals("flush", CallVerificationStack.getInstance()
+ .getCurrentSourceMethod());
+ CallVerificationStack.getInstance().clear();
+ assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString());
+ }
+
+ /*
+ * Test close() when having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_InsufficientPrivilege() {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new MockFormatter());
+
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ h.close();
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * Test close() when having no output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies close() method when having no output stream.",
+ method = "close",
+ args = {}
+ )
+ public void testClose_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ h.close();
+ }
+
+ /*
+ * Test flush().
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies flush() method.",
+ method = "flush",
+ args = {}
+ )
+ public void testFlush_Normal() {
+ ByteArrayOutputStream aos = new MockOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.flush();
+ assertEquals("flush", CallVerificationStack.getInstance().getCurrentSourceMethod());
+ assertNull(CallVerificationStack.getInstance().pop());
+ CallVerificationStack.getInstance().clear();
+ }
+
+ /*
+ * Test flush() when having no output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies flush() when having no output stream.",
+ method = "flush",
+ args = {}
+ )
+ public void testFlush_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ h.flush();
+ }
+
+ /*
+ * Test isLoggable(), use no filter, having no output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies isLoggable(), use no filter, having no output stream.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ LogRecord r = new LogRecord(Level.INFO, null);
+ assertFalse(h.isLoggable(r));
+
+ h.setLevel(Level.WARNING);
+ assertFalse(h.isLoggable(r));
+
+ h.setLevel(Level.CONFIG);
+ assertFalse(h.isLoggable(r));
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ assertFalse(h.isLoggable(r));
+ }
+
+ /*
+ * Test isLoggable(), use no filter, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies isLoggable(), use no filter, having output stream.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_NoFilter() {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new SimpleFormatter());
+ LogRecord r = new LogRecord(Level.INFO, null);
+ assertTrue(h.isLoggable(r));
+
+ h.setLevel(Level.WARNING);
+ assertFalse(h.isLoggable(r));
+
+ h.setLevel(Level.CONFIG);
+ assertTrue(h.isLoggable(r));
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ assertFalse(h.isLoggable(r));
+ }
+
+ /*
+ * Test isLoggable(), use a filter, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies isLoggable(), use a filter, having output stream.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_WithFilter() {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new SimpleFormatter());
+ LogRecord r = new LogRecord(Level.INFO, null);
+ h.setFilter(new MockFilter());
+ assertFalse(h.isLoggable(r));
+ assertSame(r, CallVerificationStack.getInstance().pop());
+
+ h.setLevel(Level.CONFIG);
+ assertFalse(h.isLoggable(r));
+ assertSame(r, CallVerificationStack.getInstance().pop());
+
+ h.setLevel(Level.WARNING);
+ assertFalse(h.isLoggable(r)); //level to high, data will not reach the filter
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test isLoggable(), null log record, having output stream. Handler should
+ * call ErrorManager to handle exceptional case
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies isLoggable(), null log record, having output stream. Handler should call ErrorManager to handle exceptional case.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_Null() {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new SimpleFormatter());
+ assertFalse(h.isLoggable(null));
+ }
+
+ /*
+ * Test isLoggable(), null log record, without output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies isLoggable(), null log record, without output stream.",
+ method = "isLoggable",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testIsLoggable_Null_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ assertFalse(h.isLoggable(null));
+ }
+
+ /*
+ * Test publish(), use no filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use no filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoOutputStream");
+ h.publish(r);
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ }
+
+ /*
+ * Test publish(), use no filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use no filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NoFilter() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
+ .toString());
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
+ .toString());
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+ + "testPublish_NoFilter", aos.toString());
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+ + "testPublish_NoFilter", aos.toString());
+ }
+
+ /*
+ * Test publish(), use a filter, having output stream, normal log record.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), use a filter, having output stream, normal log record.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_WithFilter() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.setFilter(new MockFilter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+ h.setLevel(Level.INFO);
+ h.publish(r);
+ h.flush();
+ assertEquals("", aos.toString());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+
+ h.setLevel(Level.WARNING);
+ h.publish(r);
+ h.flush();
+ assertEquals("", aos.toString());
+ assertTrue(CallVerificationStack.getInstance().empty());
+
+ h.setLevel(Level.CONFIG);
+ h.publish(r);
+ h.flush();
+ assertEquals("", aos.toString());
+ assertSame(r, CallVerificationStack.getInstance().pop());
+
+ r.setLevel(Level.OFF);
+ h.setLevel(Level.OFF);
+ h.publish(r);
+ h.flush();
+ assertEquals("", aos.toString());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test publish(), null log record, handler should call ErrorManager to
+ * handle exceptional case
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), null log record, handler should call ErrorManager to handle exceptional case.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_Null() {
+ StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+ new SimpleFormatter());
+ h.publish(null);
+ }
+
+ /*
+ * Test publish(), null log record, without output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), null log record, without output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_Null_NoOutputStream() {
+ StreamHandler h = new StreamHandler();
+ h.publish(null);
+ // regression test for Harmony-1279
+ MockFilter filter = new MockFilter();
+ h.setLevel(Level.FINER);
+ h.setFilter(filter);
+ LogRecord record = new LogRecord(Level.FINE, "abc");
+ h.publish(record);
+ // verify that filter.isLoggable is not called, because there's no
+ // associated output stream.
+ assertTrue(CallVerificationStack.getInstance().empty());
+ }
+
+ /*
+ * Test publish(), a log record with empty msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), a log record with empty msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_EmptyMsg() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ LogRecord r = new LogRecord(Level.INFO, "");
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head", aos.toString());
+ }
+
+ /*
+ * Test publish(), a log record with null msg, having output stream
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), a log record with null msg, having output stream.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_NullMsg() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ LogRecord r = new LogRecord(Level.INFO, null);
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_Head", aos.toString());
+ }
+
+ /*
+ * Test publish(), after close.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies publish(), after close.",
+ method = "publish",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testPublish_AfterClose() throws Exception {
+ Properties p = new Properties();
+ p.put("java.util.logging.StreamHandler.level", "FINE");
+ LogManager.getLogManager().readConfiguration(
+ EnvironmentHelper.PropertiesToInputStream(p));
+
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ assertSame(h.getLevel(), Level.FINE);
+ LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFormatter");
+ assertTrue(h.isLoggable(r));
+ h.close();
+ assertFalse(h.isLoggable(r));
+ h.publish(r);
+ h.flush();
+ assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString());
+ }
+
+ /*
+ * Test setEncoding() method with supported encoding.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setEncoding() method with supported encoding.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_Normal() throws Exception {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.setEncoding("iso-8859-1");
+ assertEquals("iso-8859-1", h.getEncoding());
+ LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+ h.publish(r);
+ h.flush();
+
+ byte[] bytes = encoder.encode(
+ CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+ .array();
+ assertTrue(Arrays.equals(bytes, aos.toByteArray()));
+ }
+
+ /*
+ * Test setEncoding() method with supported encoding, after a log record
+ * has been written.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setEncoding() method with supported encoding, after a log record has been written.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_AfterPublish() throws Exception {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ h.setEncoding("iso-8859-1");
+ assertEquals("iso-8859-1", h.getEncoding());
+ LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+ h.publish(r);
+ h.flush();
+ assertTrue(Arrays.equals(aos.toByteArray(), encoder.encode(
+ CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+ .array()));
+
+ h.setEncoding("iso8859-1");
+ assertEquals("iso8859-1", h.getEncoding());
+ r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+ h.publish(r);
+ h.flush();
+ assertFalse(Arrays.equals(aos.toByteArray(), encoder.encode(
+ CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"
+ + "testSetEncoding_Normal2")).array()));
+ byte[] b0 = aos.toByteArray();
+ byte[] b1 = encoder.encode(
+ CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+ .array();
+ byte[] b2 = encoder.encode(CharBuffer.wrap("\u6881\u884D\u8F69"))
+ .array();
+ byte[] b3 = new byte[b1.length + b2.length];
+ System.arraycopy(b1, 0, b3, 0, b1.length);
+ System.arraycopy(b2, 0, b3, b1.length, b2.length);
+ assertTrue(Arrays.equals(b0, b3));
+ }
+
+ /*
+ * Test setEncoding() methods with null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setEncoding() methods with null.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_Null() throws Exception {
+ StreamHandler h = new StreamHandler();
+ h.setEncoding(null);
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test setEncoding() methods with unsupported encoding.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setEncoding() methods with unsupported encoding.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_Unsupported() {
+ StreamHandler h = new StreamHandler();
+ try {
+ h.setEncoding("impossible");
+ fail("Should throw UnsupportedEncodingException!");
+ } catch (UnsupportedEncodingException e) {
+ // expected
+ }
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test setEncoding() with insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setEncoding() method with insufficient privilege.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_InsufficientPrivilege() throws Exception {
+ StreamHandler h = new StreamHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+ // set a normal value
+ try {
+ h.setEncoding("iso-8859-1");
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ assertNull(h.getEncoding());
+ System.setSecurityManager(new MockSecurityManager());
+ // set an invalid value
+ try {
+
+ h.setEncoding("impossible");
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ assertNull(h.getEncoding());
+ }
+
+ /*
+ * Test setEncoding() methods will flush a stream before setting.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that setEncoding() method will flush a stream before setting.",
+ method = "setEncoding",
+ args = {java.lang.String.class}
+ )
+ public void testSetEncoding_FlushBeforeSetting() throws Exception {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ StreamHandler h = new StreamHandler(aos, new MockFormatter());
+ LogRecord r = new LogRecord(Level.INFO, "abcd");
+ h.publish(r);
+ assertFalse(aos.toString().indexOf("abcd") > 0);
+ h.setEncoding("iso-8859-1");
+ assertTrue(aos.toString().indexOf("abcd") > 0);
+ }
+
+ /*
+ * Test setOutputStream() with null.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setOutputStream() method with null.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testSetOutputStream_null() {
+ MockStreamHandler h = new MockStreamHandler(
+ new ByteArrayOutputStream(), new SimpleFormatter());
+ try {
+ h.setOutputStream(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /*
+ * Test setOutputStream() under normal condition.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setOutputStream() method under normal condition.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testSetOutputStream_Normal() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+ h.publish(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
+ .toString());
+
+ ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+ h.setOutputStream(aos2);
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ + "MockFormatter_Tail", aos.toString());
+ r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+ h.publish(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
+ .toString());
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ + "MockFormatter_Tail", aos.toString());
+ }
+
+ /*
+ * Test setOutputStream() after close.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setOutputStream() method after close.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testSetOutputStream_AfterClose() {
+ ByteArrayOutputStream aos = new ByteArrayOutputStream();
+ MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
+
+ LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+ h.publish(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
+ .toString());
+ h.close();
+
+ ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+ h.setOutputStream(aos2);
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ + "MockFormatter_Tail", aos.toString());
+ r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+ h.publish(r);
+ assertSame(r, CallVerificationStack.getInstance().pop());
+ assertTrue(CallVerificationStack.getInstance().empty());
+ h.flush();
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
+ .toString());
+ assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+ + "MockFormatter_Tail", aos.toString());
+ }
+
+ /*
+ * Test setOutputStream() when having insufficient privilege.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies setOutputStream() method when having insufficient privilege.",
+ method = "setOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testSetOutputStream_InsufficientPrivilege() {
+ MockStreamHandler h = new MockStreamHandler();
+ SecurityManager oldMan = System.getSecurityManager();
+ System.setSecurityManager(new MockSecurityManager());
+
+ try {
+ h.setOutputStream(new ByteArrayOutputStream());
+ fail("Should throw SecurityException!");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+
+ h = new MockStreamHandler();
+ System.setSecurityManager(new MockSecurityManager());
+ try {
+ h.setOutputStream(null);
+ fail("Should throw NullPointerException!");
+ } catch (NullPointerException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldMan);
+ }
+ }
+
+ /*
+ * A mock stream handler, expose setOutputStream.
+ */
+ public static class MockStreamHandler extends StreamHandler {
+ public MockStreamHandler() {
+ super();
+ }
+
+ public MockStreamHandler(OutputStream out, Formatter formatter) {
+ super(out, formatter);
+ }
+
+ public void setOutputStream(OutputStream out) {
+ super.setOutputStream(out);
+ }
+
+ public boolean isLoggable(LogRecord r) {
+ CallVerificationStack.getInstance().push(r);
+ return super.isLoggable(r);
+ }
+ }
+
+ /*
+ * A mock filter, always return false.
+ */
+ public static class MockFilter implements Filter {
+
+ public boolean isLoggable(LogRecord record) {
+ CallVerificationStack.getInstance().push(record);
+ return false;
+ }
+ }
+
+ /*
+ * A mock formatter.
+ */
+ public static class MockFormatter extends java.util.logging.Formatter {
+ public String format(LogRecord r) {
+ // System.out.println("formatter called...");
+ return super.formatMessage(r);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
+ */
+ public String getHead(Handler h) {
+ return "MockFormatter_Head";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
+ */
+ public String getTail(Handler h) {
+ return "MockFormatter_Tail";
+ }
+ }
+
+ /*
+ * Another mock formatter.
+ */
+ public static class MockFormatter2 extends java.util.logging.Formatter {
+ public String format(LogRecord r) {
+ // System.out.println("formatter2 called...");
+ return r.getMessage();
+ }
+ }
+
+ /*
+ * A mock output stream.
+ */
+ public static class MockOutputStream extends ByteArrayOutputStream {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#close()
+ */
+ public void close() throws IOException {
+ CallVerificationStack.getInstance().push(null);
+ super.close();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#flush()
+ */
+ public void flush() throws IOException {
+ CallVerificationStack.getInstance().push(null);
+ super.flush();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int oneByte) {
+ super.write(oneByte);
+ }
+ }
+
+ /*
+ * A mock output stream that always throw exception.
+ */
+ public static class MockExceptionOutputStream extends ByteArrayOutputStream {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#close()
+ */
+ public void close() throws IOException {
+ throw new IOException();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#flush()
+ */
+ public void flush() throws IOException {
+ throw new IOException();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public synchronized void write(byte[] buffer, int offset, int count) {
+ throw new NullPointerException();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(int)
+ */
+ public synchronized void write(int oneByte) {
+ throw new NullPointerException();
+ }
+ }
+
+ /*
+ * Used to grant all permissions except logging control.
+ */
+ public static class MockSecurityManager extends SecurityManager {
+
+ public MockSecurityManager() {
+ }
+
+ public void checkPermission(Permission perm) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // grant all permissions except logging control
+ if (perm instanceof LoggingPermission) {
+ throw new SecurityException();
+ }
+ }
+ }
+
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
new file mode 100644
index 0000000..917a898
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ResourceBundle;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.XMLFormatter;
+
+@TestTargetClass(XMLFormatter.class)
+public class XMLFormatterTest extends TestCase {
+
+ XMLFormatter formatter = null;
+
+ MockHandler handler = null;
+
+ LogRecord lr = null;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ formatter = new XMLFormatter();
+ handler = new MockHandler();
+ lr = new LogRecord(Level.SEVERE, "pattern");
+ }
+
+ /*
+ * test for constructor public XMLFormatter()
+ *
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "XMLFormatter",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {java.util.logging.Handler.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ )
+ })
+ public void testXMLFormatter() {
+ String result = formatter.getHead(handler);
+ int headPos = result
+ .indexOf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+ int dtdPos = result.indexOf("<!DOCTYPE log SYSTEM \"logger.dtd\">");
+ int rootPos = result.indexOf("<log>");
+ assertTrue("head string position should be more or equal zero",
+ headPos >= 0);
+ assertTrue("dtd string position should be more head string position",
+ dtdPos > headPos);
+ assertTrue("root string position should be more dtd string position",
+ rootPos > dtdPos);
+
+ assertTrue("Tail string position should be more zero", formatter
+ .getTail(handler).indexOf("/log>") > 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testLocalFormat() {
+ // if set resource bundle, output will use localized message,
+ // but put the original message into the key element
+ // further more, if message pattern has no effect
+ ResourceBundle rb = ResourceBundle
+ .getBundle("bundles/java/util/logging/res");
+ lr.setResourceBundle(rb);
+ lr.setMessage("pattern");
+ String result = formatter.format(lr);
+ assertTrue(result.indexOf("<message>" + rb.getString("pattern")
+ + "</message>") > 0);
+ assertTrue(result.indexOf("<key>pattern</key>") > 0);
+
+ lr.setMessage("msg");
+ result = formatter.format(lr);
+ assertTrue(result.indexOf("<message>" + rb.getString("msg")
+ + "</message>") > 0);
+ assertTrue(result.indexOf("<key>msg</key>") > 0);
+
+ lr.setMessage("pattern {0, number}");
+ result = formatter.format(lr);
+ assertTrue(result.indexOf("<message>pattern {0, number}</message>") > 0);
+ assertTrue(result.indexOf("<key>") < 0);
+
+ // if message has no relevant localized message, use the original
+ lr.setMessage("bad key");
+ result = formatter.format(lr);
+ assertTrue(result.indexOf("<message>bad key</message>") > 0);
+ assertTrue(result.indexOf("<key>") < 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testFullFormat() {
+ lr.setSourceClassName("source class");
+ lr.setSourceMethodName("source method");
+ lr.setLoggerName("logger name");
+ lr.setMillis(0);
+ lr.setThrown(new Throwable("message"));
+ lr.setParameters(new Object[] { "100", "200" });
+ lr.setSequenceNumber(1);
+ ResourceBundle rb = ResourceBundle
+ .getBundle("bundles/java/util/logging/res");
+ lr.setResourceBundle(rb);
+ lr.setResourceBundleName("rbname");
+ String output = formatter.format(lr);
+ // System.out.println(output);
+ assertTrue(output.indexOf("<record>") >= 0);
+ assertTrue(output.indexOf("<date>") >= 0);
+ assertTrue(output.indexOf("<millis>0</millis>") >= 0);
+ assertTrue(output.indexOf("<sequence>") >= 0);
+ assertTrue(output.indexOf("<level>SEVERE</level>") >= 0);
+ assertTrue(output.indexOf("<thread>") >= 0);
+ assertTrue(output.indexOf("<message>" + rb.getString("pattern")
+ + "</message>") >= 0);
+ assertTrue(output.indexOf("<logger>logger name</logger>") > 0);
+ assertTrue(output.indexOf("<class>source class</class>") > 0);
+ assertTrue(output.indexOf("<method>source method</method>") > 0);
+ assertTrue(output.indexOf("<catalog>rbname</catalog>") > 0);
+ assertTrue(output.indexOf("<param>100</param>") > 0);
+ assertTrue(output.indexOf("<param>200</param>") > 0);
+ assertTrue(output.indexOf("<exception>") > 0);
+ assertTrue(output.indexOf("<key>pattern</key>") > 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ )
+ public void testFormat() {
+ String output = formatter.format(lr);
+ // System.out.println(output);
+ assertTrue(output.indexOf("<record>") >= 0);
+ assertTrue(output.indexOf("<date>") >= 0);
+ assertTrue(output.indexOf("<millis>") >= 0);
+ assertTrue(output.indexOf("<sequence>") >= 0);
+ assertTrue(output.indexOf("<level>SEVERE</level>") >= 0);
+ assertTrue(output.indexOf("<thread>") >= 0);
+ assertTrue(output.indexOf("<message>pattern</message>") >= 0);
+ assertTrue(output.indexOf("<logger>") < 0);
+ assertTrue(output.indexOf("<class>") < 0);
+ assertTrue(output.indexOf("<method>") < 0);
+ assertTrue(output.indexOf("<catalog>") < 0);
+ assertTrue(output.indexOf("<param>") < 0);
+ assertTrue(output.indexOf("<exception>") < 0);
+ assertTrue(output.indexOf("<key>") < 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getHead",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testGetHead() throws SecurityException,
+ UnsupportedEncodingException {
+ String result = formatter.getHead(handler);
+ assertNull(handler.getEncoding());
+ // TODO: where do we get the default encoding from?
+ // assertTrue(result.indexOf(defaultEncoding)>0);
+
+ handler.setEncoding("ISO-8859-1");
+ String head = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>";
+ String dtd = "<!DOCTYPE log SYSTEM \"logger.dtd\">";
+ String rootELement = "<log>";
+ result = formatter.getHead(handler);
+ int headPos = result.indexOf(head);
+ int dtdPos = result.indexOf(dtd);
+ int rootPos = result.indexOf(rootELement);
+ assertTrue(headPos >= 0);
+ assertTrue(dtdPos > headPos);
+ assertTrue(rootPos > dtdPos);
+
+ handler.setEncoding(null);
+ result = formatter.getHead(handler);
+ assertNull(handler.getEncoding());
+
+ // make sure no NPE is thrown
+ formatter.getHead(null);
+
+ }
+
+ /*
+ * test for method public String getTail(Handler h)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ )
+ public void testGetTail() {
+ assertEquals(
+ "Tail string with null handler should be equal expected value",
+ "</log>", formatter.getTail(null).trim());
+ assertEquals("Tail string should be equal expected value", "</log>",
+ formatter.getTail(handler).trim());
+ handler.publish(lr);
+ assertEquals(
+ "Tail string after publish() should be equal expected value",
+ "</log>", formatter.getTail(handler).trim());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "format",
+ args = {java.util.logging.LogRecord.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getTail",
+ args = {java.util.logging.Handler.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "XMLFormatter",
+ args = {}
+ )
+ })
+ @AndroidOnly("This test fails on RI. Output doesn't contain " +
+ "<message/>.")
+ public void testInvalidParameter() {
+ formatter.getTail(null);
+ try {
+ formatter.format(null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+
+ formatter = new XMLFormatter();
+ lr = new LogRecord(Level.SEVERE, null);
+ String output = formatter.format(lr);
+ assertTrue(output.indexOf("<message/>") != -1);
+ }
+
+ public static class MockHandler extends Handler {
+ public void close() {
+ }
+
+ public void flush() {
+ }
+
+ public void publish(LogRecord record) {
+ }
+
+ }
+}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/util/EnvironmentHelper.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/util/EnvironmentHelper.java
new file mode 100644
index 0000000..0dafe68
--- /dev/null
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/util/EnvironmentHelper.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.harmony.logging.tests.java.util.logging.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Helper to prepare testing environment, for example, configuration files.
+ */
+public class EnvironmentHelper {
+
+ /**
+ * Can't be instantiated.
+ */
+ private EnvironmentHelper() {
+ }
+
+ public static InputStream PropertiesToInputStream(Properties p) {
+ ByteArrayOutputStream bos = null;
+ try {
+ bos = new ByteArrayOutputStream();
+ p.store(bos, "");
+ return new ByteArrayInputStream(bos.toByteArray());
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ bos.close();
+ } catch (Exception ex) {
+ }
+ }
+ }
+
+}
diff --git a/logging/src/test/java/tests/logging/AllTests.java b/logging/src/test/java/tests/logging/AllTests.java
new file mode 100644
index 0000000..c6032df
--- /dev/null
+++ b/logging/src/test/java/tests/logging/AllTests.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that includes all tests for the Logging project.
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Logging test suites");
+ // $JUnit-BEGIN$
+ suite.addTest(org.apache.harmony.logging.tests.java.util.logging.AllTests.suite());
+ // $JUnit-END$
+ return suite;
+ }
+} \ No newline at end of file
diff --git a/logging/src/test/resources/bundles/java/util/logging/res.properties b/logging/src/test/resources/bundles/java/util/logging/res.properties
new file mode 100644
index 0000000..db455b0
--- /dev/null
+++ b/logging/src/test/resources/bundles/java/util/logging/res.properties
@@ -0,0 +1,12 @@
+level1=en_US_level1
+SEVERE=US_SEVERE
+WARNING=US_WARNING
+CONFIG=US_CONFIG
+FINE=US_FINE
+FINER=US_FINER
+FINEST=US_FINEST
+ALL=US_ALL
+OFF=US_OFF
+msg=US_MSG
+pattern=US_pattern {0, number}
+pattern{0,number}=US \ No newline at end of file
diff --git a/logging/src/test/resources/bundles/java/util/logging/res2.properties b/logging/src/test/resources/bundles/java/util/logging/res2.properties
new file mode 100644
index 0000000..66f02eb
--- /dev/null
+++ b/logging/src/test/resources/bundles/java/util/logging/res2.properties
@@ -0,0 +1,13 @@
+level1=level1
+SEVERE=SEVERE2
+WARNING=WARNING2
+CONFIG=CONFIG2
+FINE=FINE2
+FINER=FINER2
+FINEST=FINEST2
+ALL=ALL2
+OFF=OFF2
+msg=MSG2
+pattern=pattern {0, number}2
+pattern{0,number}=NOLOCALE2
+LOGGERTEST=Test_NoLocale2 \ No newline at end of file
diff --git a/logging/src/test/resources/bundles/java/util/logging/res3.properties b/logging/src/test/resources/bundles/java/util/logging/res3.properties
new file mode 100644
index 0000000..f7b4b29
--- /dev/null
+++ b/logging/src/test/resources/bundles/java/util/logging/res3.properties
@@ -0,0 +1,13 @@
+level1=level13
+SEVERE=SEVERE3
+WARNING=WARNING3
+CONFIG=CONFIG3
+FINE=FINE3
+FINER=FINER3
+FINEST=FINEST3
+ALL=ALL3
+OFF=OFF3
+msg=MSG3
+pattern=pattern {0, number}3
+pattern{0,number}=NOLOCALE3
+LOGGERTEST=Test_NoLocale3 \ No newline at end of file
diff --git a/logging/src/test/resources/bundles/java/util/logging/res_en_US.properties b/logging/src/test/resources/bundles/java/util/logging/res_en_US.properties
new file mode 100644
index 0000000..db455b0
--- /dev/null
+++ b/logging/src/test/resources/bundles/java/util/logging/res_en_US.properties
@@ -0,0 +1,12 @@
+level1=en_US_level1
+SEVERE=US_SEVERE
+WARNING=US_WARNING
+CONFIG=US_CONFIG
+FINE=US_FINE
+FINER=US_FINER
+FINEST=US_FINEST
+ALL=US_ALL
+OFF=US_OFF
+msg=US_MSG
+pattern=US_pattern {0, number}
+pattern{0,number}=US \ No newline at end of file
diff --git a/logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties b/logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties
new file mode 100644
index 0000000..e96803d
--- /dev/null
+++ b/logging/src/test/resources/bundles/java/util/logging/res_zh_CN.properties
@@ -0,0 +1,13 @@
+level1=zh_CN_level1
+SEVERE=zh_CN_SEVERE
+WARNING=zh_CN_WARNING
+CONFIG=ZH_CN_CONFIG
+FINE=ZH_CN_FINE
+FINER=ZH_CN_FINER
+FINEST=ZH_CN_FINEST
+ALL=ZH_CN_ALL
+OFF=ZH_CN_OFF
+msg=ZH_CN_MSG
+pattern=ZH_CN_pattern {0, number}
+pattern{0,number}=ZH_CN
+LOGGERTEST=Test_ZH_CN \ No newline at end of file
diff --git a/logging/src/test/resources/config/java/util/logging/logging.config b/logging/src/test/resources/config/java/util/logging/logging.config
new file mode 100644
index 0000000..f4c5146
--- /dev/null
+++ b/logging/src/test/resources/config/java/util/logging/logging.config
@@ -0,0 +1,3 @@
+handlers=org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$MockHandler java.util.logging.ConsoleHandler
+.level=ALL
+org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$MockHandler.level=OFF \ No newline at end of file
diff --git a/logging/src/test/resources/config/java/util/logging/logging.properties b/logging/src/test/resources/config/java/util/logging/logging.properties
new file mode 100644
index 0000000..f4c5146
--- /dev/null
+++ b/logging/src/test/resources/config/java/util/logging/logging.properties
@@ -0,0 +1,3 @@
+handlers=org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$MockHandler java.util.logging.ConsoleHandler
+.level=ALL
+org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$MockHandler.level=OFF \ No newline at end of file
diff --git a/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LevelTest.golden.ser b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LevelTest.golden.ser
new file mode 100644
index 0000000..721a368
--- /dev/null
+++ b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LevelTest.golden.ser
Binary files differ
diff --git a/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.golden.ser b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.golden.ser
new file mode 100644
index 0000000..955c6fb
--- /dev/null
+++ b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.golden.ser
Binary files differ
diff --git a/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.golden.ser b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.golden.ser
new file mode 100644
index 0000000..f4cdced
--- /dev/null
+++ b/logging/src/test/resources/serialization/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.golden.ser
Binary files differ