();
+
+ /**
+ * A common instance of NullLogger, as it does nothing
+ * we only need the one
+ */
+ private static final XBLogger _nullLogger = new NullLogger();
+ /**
+ * The name of the class to use. Initialised the
+ * first time we need it
+ */
+ static String _loggerClassName = null;
+
+ /**
+ * Construct a XBLogFactory.
+ */
+ private XBLogFactory() {}
+
+ /**
+ * Get a logger, based on a class name
+ *
+ * @param theclass the class whose name defines the log
+ *
+ * @return a XBLogger for the specified class
+ */
+ public static XBLogger getLogger(final Class> theclass) {
+ return getLogger(theclass.getName());
+ }
+
+ /**
+ * Get a logger, based on a String
+ *
+ * @param cat the String that defines the log
+ *
+ * @return a XBLogger for the specified class
+ */
+ public static XBLogger getLogger(final String cat) {
+ // If we haven't found out what logger to use yet,
+ // then do so now
+ // Don't look it up until we're first asked, so
+ // that our users can set the system property
+ // between class loading and first use
+ if(_loggerClassName == null) {
+ try {
+ _loggerClassName = System.getProperty("org.apache.xmlbeans.impl.store.XBLogger");
+ } catch(Exception e) {
+ // ignore any exception here
+ }
+
+ // Use the default logger if none specified,
+ // or none could be fetched
+ if(_loggerClassName == null) {
+ _loggerClassName = _nullLogger.getClass().getName();
+ }
+ }
+
+ // Short circuit for the null logger, which
+ // ignores all categories
+ if(_loggerClassName.equals(_nullLogger.getClass().getName())) {
+ return _nullLogger;
+ }
+
+
+ // Fetch the right logger for them, creating
+ // it if that's required
+ XBLogger logger = _loggers.get(cat);
+ if (logger == null) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class extends XBLogger> loggerClass =
+ (Class extends XBLogger>) Class.forName(_loggerClassName);
+ logger = loggerClass.newInstance();
+ logger.initialize(cat);
+ } catch(Exception e) {
+ // Give up and use the null logger
+ logger = _nullLogger;
+ _loggerClassName = _nullLogger.getClass().getName();
+ }
+
+ // Save for next time
+ _loggers.put(cat, logger);
+ }
+ return logger;
+ }
+}
Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogger.java
===================================================================
--- /dev/null
+++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogger.java
@@ -0,0 +1,112 @@
+/* Copyright 2017, 2018 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.common;
+
+/**
+ * A logger interface that strives to make it as easy as possible for
+ * developers to write log calls, while simultaneously making those
+ * calls as cheap as possible by performing lazy evaluation of the log
+ * message.
+ */
+public abstract class XBLogger {
+
+ public static final int DEBUG = 1;
+ public static final int INFO = 3;
+ public static final int WARN = 5;
+ public static final int ERROR = 7;
+ public static final int FATAL = 9;
+
+ /** Short strings for numeric log level. Use level as array index. */
+ protected static final String LEVEL_STRINGS_SHORT[] = {"?", "D", "?", "I", "?", "W", "?", "E", "?", "F", "?"};
+ /** Long strings for numeric log level. Use level as array index. */
+ protected static final String LEVEL_STRINGS[] = {"?0?", "DEBUG", "?2?", "INFO", "?4?", "WARN", "?6?", "ERROR", "?8?", "FATAL", "?10+?"};
+
+
+ /**
+ * package scope so it cannot be instantiated outside of the util
+ * package. You need a XBLogger? Go to the XBLogFactory for one
+ */
+ XBLogger() {
+ // no fields to initialize
+ }
+
+ abstract public void initialize(String cat);
+
+ /**
+ * Log a message
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param obj1 The object to log. This is converted to a string.
+ */
+ abstract protected void _log(int level, Object obj1);
+
+ /**
+ * Log a message
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param obj1 The object to log. This is converted to a string.
+ * @param exception An exception to be logged
+ */
+ abstract protected void _log(int level, Object obj1, final Throwable exception);
+
+
+ /**
+ * Check if a logger is enabled to log at the specified level
+ * This allows code to avoid building strings or evaluating functions in
+ * the arguments to log.
+ *
+ * An example:
+ *
+ * if (logger.check(XBLogger.INFO)) {
+ * logger.log(XBLogger.INFO, "Avoid concatenating " + " strings and evaluating " + functions());
+ * }
+ *
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ */
+ abstract public boolean check(int level);
+
+ /**
+ * Log a message. Lazily appends Object parameters together.
+ * If the last parameter is a {@link Throwable} it is logged specially.
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param objs the objects to place in the message
+ */
+ public void log(int level, Object... objs) {
+ if (!check(level)) return;
+ StringBuilder sb = new StringBuilder(32);
+ Throwable lastEx = null;
+ for (int i=0; i
+ */
+public class NullLogger extends XBLogger {
+ @Override
+ public void initialize(final String cat) {
+ // do nothing
+ }
+
+ /**
+ * Log a message
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param obj1 The object to log.
+ */
+
+ @Override
+ protected void _log(final int level, final Object obj1) {
+ // do nothing
+ }
+
+ /**
+ * Log a message
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param obj1 The object to log. This is converted to a string.
+ * @param exception An exception to be logged
+ */
+ @Override
+ protected void _log(int level, Object obj1, final Throwable exception) {
+ // do nothing
+ }
+
+ /**
+ * Log a message. Lazily appends Object parameters together.
+ * If the last parameter is a {@link Throwable} it is logged specially.
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ * @param objs the objects to place in the message
+ */
+ @Override
+ public void log(int level, Object... objs) {
+ // do nothing
+ }
+
+
+ /**
+ * Check if a logger is enabled to log at the specified level
+ *
+ * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+ */
+ @Override
+ public boolean check(final int level) {
+ return false;
+ }
+}