/* * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/** * Utility which provides an abstract "logger" like RMI internal API * which can be directed to use one of two types of logging * infrastructure: the java.util.logging API or the * java.rmi.server.LogStream API. The default behavior is to use the * java.util.logging API. The LogStream API may be used instead by * setting the system property sun.rmi.log.useOld to true. * * For backwards compatibility, supports the RMI system logging * properties which pre-1.4 comprised the only way to configure RMI * logging. If the java.util.logging API is used and RMI system log * properties are set, the system properties override initial RMI * logger values as appropriate. If the java.util.logging API is * turned off, pre-1.4 logging behavior is used. * * @author Laird Dornin * @since 1.4
*/
@SuppressWarnings("deprecation") publicabstractclass Log {
/** Logger re-definition of old RMI log values */ publicstaticfinal Level BRIEF = Level.FINE; publicstaticfinal Level VERBOSE = Level.FINER;
/* set factory to select the logging facility to use */
logFactory = (useOld ? (LogFactory) new LogStreamLogFactory() :
(LogFactory) new LoggerLogFactory());
}
/** "logger like" API to be used by RMI implementation */ publicabstractboolean isLoggable(Level level); publicabstractvoid log(Level level, String message); publicabstractvoid log(Level level, String message, Throwable thrown);
/** get and set the RMI server call output stream */ publicabstractvoid setOutputStream(OutputStream stream); publicabstract PrintStream getPrintStream();
/** * Access log for a tri-state system property. * * Need to first convert override value to a log level, taking * care to interpret a range of values between BRIEF, VERBOSE and * SILENT. * * An override {@literal <} 0 is interpreted to mean that the logging * configuration should not be overridden. The level passed to the * factories createLog method will be null in this case. * * Note that if oldLogName is null and old logging is on, the * returned LogStreamLog will ignore the override parameter - the * log will never log messages. This permits new logs that only * write to Loggers to do nothing when old logging is active. * * Do not call getLog multiple times on the same logger name. * Since this is an internal API, no checks are made to ensure * that multiple logs do not exist for the same logger.
*/ publicstatic Log getLog(String loggerName, String oldLogName, int override)
{
Level level;
/** * Access logs associated with boolean properties * * Do not call getLog multiple times on the same logger name. * Since this is an internal API, no checks are made to ensure * that multiple logs do not exist for the same logger.
*/ publicstatic Log getLog(String loggerName, String oldLogName, boolean override)
{
Level level = (override ? VERBOSE : null); return logFactory.createLog(loggerName, oldLogName, level);
}
/** * Factory to create Log objects which deliver log messages to the * java.util.logging API.
*/ privatestaticclass LoggerLogFactory implements LogFactory {
LoggerLogFactory() {}
/* * Accessor to obtain an arbitrary RMI logger with name * loggerName. If the level of the logger is greater than the * level for the system property with name, the logger level * will be set to the value of system property.
*/ public Log createLog(final String loggerName, String oldLogName, final Level level)
{
Logger logger = Logger.getLogger(loggerName); returnnew LoggerLog(logger, level);
}
}
/** * Class specialized to log messages to the java.util.logging API
*/ privatestaticclass LoggerLog extends Log {
/* alternate console handler for RMI loggers */
@SuppressWarnings("removal") privatestaticfinal Handler alternateConsole =
java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Handler>() { public Handler run() {
InternalStreamHandler alternate = new InternalStreamHandler(System.err);
alternate.setLevel(Level.ALL); return alternate;
}
});
/** handler to which messages are copied */ private InternalStreamHandler copyHandler = null;
/* logger to which log messages are written */ privatefinal Logger logger;
/* used as return value of RemoteServer.getLog */ private LoggerPrintStream loggerSandwich;
/** creates a Log which will delegate to the given logger */
@SuppressWarnings("removal") private LoggerLog(final Logger logger, final Level level) { this.logger = logger;
if (level != null){
java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Void>() { publicVoid run() { if (!logger.isLoggable(level)) {
logger.setLevel(level);
}
logger.addHandler(alternateConsole); returnnull;
}
}
);
}
}
/** * Set the output stream associated with the RMI server call * logger. * * Calling code needs LoggingPermission "control".
*/ publicsynchronizedvoid setOutputStream(OutputStream out) { if (out != null) { if (!logger.isLoggable(VERBOSE)) {
logger.setLevel(VERBOSE);
}
copyHandler = new InternalStreamHandler(out);
copyHandler.setLevel(Log.VERBOSE);
logger.addHandler(copyHandler);
} else { /* ensure that messages are not logged */ if (copyHandler != null) {
logger.removeHandler(copyHandler);
}
copyHandler = null;
}
}
publicsynchronized PrintStream getPrintStream() { if (loggerSandwich == null) {
loggerSandwich = new LoggerPrintStream(logger);
} return loggerSandwich;
}
}
/** * Subclass of StreamHandler for redirecting log output. flush * must be called in the publish and close methods.
*/ privatestaticclass InternalStreamHandler extends StreamHandler {
InternalStreamHandler(OutputStream out) { super(out, new SimpleFormatter());
}
/** * PrintStream which forwards log messages to the logger. Class * is needed to maintain backwards compatibility with * RemoteServer.{set|get}Log().
*/ privatestaticclass LoggerPrintStream extends PrintStream {
/** logger where output of this log is sent */ privatefinal Logger logger;
/** record the last character written to this stream */ privateint last = -1;
/** stream used for buffering lines */ privatefinal ByteArrayOutputStream bufOut;
publicvoid write(int b) { if ((last == '\r') && (b == '\n')) {
last = -1; return;
} elseif ((b == '\n') || (b == '\r')) { try { /* write the converted bytes of the log message */
String message = Thread.currentThread().getName() + ": " +
bufOut.toString();
logger.logp(Level.INFO, "LogStream", "print", message);
} finally {
bufOut.reset();
}
} else { super.write(b);
}
last = b;
}
publicvoid write(byte b[], int off, int len) { if (len < 0) { thrownew ArrayIndexOutOfBoundsException(len);
} for (int i = 0; i < len; i++) {
write(b[off + i]);
}
}
public String toString() { return"RMI";
}
}
/** * Factory to create Log objects which deliver log messages to the * java.rmi.server.LogStream API
*/ privatestaticclass LogStreamLogFactory implements LogFactory {
LogStreamLogFactory() {}
/* create a new LogStreamLog for the specified log */ public Log createLog(String loggerName, String oldLogName,
Level level)
{
LogStream stream = null; if (oldLogName != null) {
stream = LogStream.log(oldLogName);
} returnnew LogStreamLog(stream, level);
}
}
/** * Class specialized to log messages to the * java.rmi.server.LogStream API
*/ privatestaticclass LogStreamLog extends Log { /** Log stream to which log messages are written */ privatefinal LogStream stream;
/** the level of the log as set by associated property */ privateint levelValue = Level.OFF.intValue();
private LogStreamLog(LogStream stream, Level level) { if ((stream != null) && (level != null)) { /* if the stream or level is null, don't log any * messages
*/
levelValue = level.intValue();
} this.stream = stream;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.