You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/05/09 23:52:20 UTC
[2/2] incubator-geode git commit: Move Geode ParameterizedMessage
optimizations to com.gemstone.gemfire.internal.logging.log4j.message package
Move Geode ParameterizedMessage optimizations to com.gemstone.gemfire.internal.logging.log4j.message package
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/93c797eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/93c797eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/93c797eb
Branch: refs/heads/feature/GEODE-951
Commit: 93c797eb7cebac1e5a29263ad72691b94db6f726
Parents: c4643ee
Author: Kirk Lund <kl...@apache.org>
Authored: Mon May 9 16:51:25 2016 -0700
Committer: Kirk Lund <kl...@apache.org>
Committed: Mon May 9 16:51:25 2016 -0700
----------------------------------------------------------------------
.../gemfire/internal/logging/LogService.java | 2 +-
.../internal/logging/log4j/LogWriterLogger.java | 2 +-
.../message/GemFireParameterizedMessage.java | 556 +++++++++++++++++++
.../GemFireParameterizedMessageFactory.java | 56 ++
.../message/GemFireParameterizedMessage.java | 556 -------------------
.../GemFireParameterizedMessageFactory.java | 56 --
6 files changed, 614 insertions(+), 614 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
index 5572d11..3aa7734 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/LogService.java
@@ -35,7 +35,7 @@ import com.gemstone.gemfire.internal.logging.log4j.ConfigLocator;
import com.gemstone.gemfire.internal.logging.log4j.Configurator;
import com.gemstone.gemfire.internal.logging.log4j.FastLogger;
import com.gemstone.gemfire.internal.logging.log4j.LogWriterLogger;
-import com.gemstone.org.apache.logging.log4j.message.GemFireParameterizedMessageFactory;
+import com.gemstone.gemfire.internal.logging.log4j.message.GemFireParameterizedMessageFactory;
/**
* Centralizes log configuration and initialization.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/LogWriterLogger.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/LogWriterLogger.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/LogWriterLogger.java
index f1e314a..dc36f95 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/LogWriterLogger.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/LogWriterLogger.java
@@ -32,7 +32,7 @@ import com.gemstone.gemfire.i18n.StringId;
import com.gemstone.gemfire.internal.logging.GemFireHandler;
import com.gemstone.gemfire.internal.logging.InternalLogWriter;
import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.org.apache.logging.log4j.message.GemFireParameterizedMessageFactory;
+import com.gemstone.gemfire.internal.logging.log4j.message.GemFireParameterizedMessageFactory;
/**
* Implements GemFireLogger with custom levels while also bridging LogWriter
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessage.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessage.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessage.java
new file mode 100755
index 0000000..641645b
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessage.java
@@ -0,0 +1,556 @@
+/*
+ * 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 com.gemstone.gemfire.internal.logging.log4j.message;
+
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.logging.log4j.message.Message;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.cache.EntriesSet;
+
+/**
+ * Handles messages that consist of a format string containing '{}' to represent each replaceable token, and
+ * the parameters.
+ * <p/>
+ * This class was originally written for <a href="http://lilithapp.com/">Lilith</a> by Joern Huxhorn where it is
+ * licensed under the LGPL. It has been relicensed here with his permission providing that this attribution remain.
+ * <p/>
+ * Copied into Geode from org.apache.logging.log4j.message.ParameterizedMessage (http://logging.apache.org/log4j/2.x/license.html)
+ * <p/>
+ * Geode changes include changing class name and package. Additional changes are commented with "// GEODE: note"
+ */
+public class GemFireParameterizedMessage implements Message {
+
+ /**
+ * Prefix for recursion.
+ */
+ public static final String RECURSION_PREFIX = "[...";
+ /**
+ * Suffix for recursion.
+ */
+ public static final String RECURSION_SUFFIX = "...]";
+
+ /**
+ * Prefix for errors.
+ */
+ public static final String ERROR_PREFIX = "[!!!";
+ /**
+ * Separator for errors.
+ */
+ public static final String ERROR_SEPARATOR = "=>";
+ /**
+ * Separator for error messages.
+ */
+ public static final String ERROR_MSG_SEPARATOR = ":";
+ /**
+ * Suffix for errors.
+ */
+ public static final String ERROR_SUFFIX = "!!!]";
+
+ private static final long serialVersionUID = -665975803997290697L;
+
+ private static final int HASHVAL = 31;
+
+ private static final char DELIM_START = '{';
+ private static final char DELIM_STOP = '}';
+ private static final char ESCAPE_CHAR = '\\';
+
+ private final String messagePattern;
+ private final String[] stringArgs;
+ private transient Object[] argArray;
+ private transient String formattedMessage;
+ private transient Throwable throwable;
+
+ /**
+ * Creates a parameterized message.
+ * @param messagePattern The message "format" string. This will be a String containing "{}" placeholders
+ * where parameters should be substituted.
+ * @param stringArgs The arguments for substitution.
+ * @param throwable A Throwable.
+ */
+ public GemFireParameterizedMessage(final String messagePattern, final String[] stringArgs, final Throwable throwable) {
+ this.messagePattern = messagePattern;
+ this.stringArgs = stringArgs;
+ this.throwable = throwable;
+ }
+
+ /**
+ * Creates a parameterized message.
+ * @param messagePattern The message "format" string. This will be a String containing "{}" placeholders
+ * where parameters should be substituted.
+ * @param objectArgs The arguments for substitution.
+ * @param throwable A Throwable.
+ */
+ public GemFireParameterizedMessage(final String messagePattern, final Object[] objectArgs, final Throwable throwable) {
+ this.messagePattern = messagePattern;
+ this.throwable = throwable;
+ this.stringArgs = parseArguments(objectArgs);
+ }
+
+ /**
+ * Constructs a ParameterizedMessage which contains the arguments converted to String as well as an optional
+ * Throwable.
+ *
+ * <p>If the last argument is a Throwable and is NOT used up by a placeholder in the message pattern it is returned
+ * in {@link #getThrowable()} and won't be contained in the created String[].
+ * If it is used up {@link #getThrowable()} will return null even if the last argument was a Throwable!</p>
+ *
+ * @param messagePattern the message pattern that to be checked for placeholders.
+ * @param arguments the argument array to be converted.
+ */
+ public GemFireParameterizedMessage(final String messagePattern, final Object[] arguments) {
+ this.messagePattern = messagePattern;
+ this.stringArgs = parseArguments(arguments);
+ }
+
+ /**
+ * Constructor with a pattern and a single parameter.
+ * @param messagePattern The message pattern.
+ * @param arg The parameter.
+ */
+ public GemFireParameterizedMessage(final String messagePattern, final Object arg) {
+ this(messagePattern, new Object[]{arg});
+ }
+
+ /**
+ * Constructor with a pattern and two parameters.
+ * @param messagePattern The message pattern.
+ * @param arg1 The first parameter.
+ * @param arg2 The second parameter.
+ */
+ public GemFireParameterizedMessage(final String messagePattern, final Object arg1, final Object arg2) {
+ this(messagePattern, new Object[]{arg1, arg2});
+ }
+
+ private String[] parseArguments(final Object[] arguments) {
+ if (arguments == null) {
+ return null;
+ }
+ final int argsCount = countArgumentPlaceholders(messagePattern);
+ int resultArgCount = arguments.length;
+ if (argsCount < arguments.length && throwable == null && arguments[arguments.length - 1] instanceof Throwable) {
+ throwable = (Throwable) arguments[arguments.length - 1];
+ resultArgCount--;
+ }
+ argArray = new Object[resultArgCount];
+ System.arraycopy(arguments, 0, argArray, 0, resultArgCount);
+
+ String[] strArgs;
+ if (argsCount == 1 && throwable == null && arguments.length > 1) {
+ // special case
+ strArgs = new String[1];
+ strArgs[0] = deepToString(arguments);
+ } else {
+ strArgs = new String[resultArgCount];
+ for (int i = 0; i < strArgs.length; i++) {
+ strArgs[i] = deepToString(arguments[i]);
+ }
+ }
+ return strArgs;
+ }
+
+ /**
+ * Returns the formatted message.
+ * @return the formatted message.
+ */
+ @Override
+ public String getFormattedMessage() {
+ if (formattedMessage == null) {
+ formattedMessage = formatMessage(messagePattern, stringArgs);
+ }
+ return formattedMessage;
+ }
+
+ /**
+ * Returns the message pattern.
+ * @return the message pattern.
+ */
+ @Override
+ public String getFormat() {
+ return messagePattern;
+ }
+
+ /**
+ * Returns the message parameters.
+ * @return the message parameters.
+ */
+ @Override
+ public Object[] getParameters() {
+ if (argArray != null) {
+ return argArray;
+ }
+ return stringArgs;
+ }
+
+ /**
+ * Returns the Throwable that was given as the last argument, if any.
+ * It will not survive serialization. The Throwable exists as part of the message
+ * primarily so that it can be extracted from the end of the list of parameters
+ * and then be added to the LogEvent. As such, the Throwable in the event should
+ * not be used once the LogEvent has been constructed.
+ *
+ * @return the Throwable, if any.
+ */
+ @Override
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ protected String formatMessage(final String msgPattern, final String[] sArgs) {
+ return format(msgPattern, sArgs);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final GemFireParameterizedMessage that = (GemFireParameterizedMessage) o;
+
+ if (messagePattern != null ? !messagePattern.equals(that.messagePattern) : that.messagePattern != null) {
+ return false;
+ }
+ if (!Arrays.equals(stringArgs, that.stringArgs)) {
+ return false;
+ }
+ //if (throwable != null ? !throwable.equals(that.throwable) : that.throwable != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = messagePattern != null ? messagePattern.hashCode() : 0;
+ result = HASHVAL * result + (stringArgs != null ? Arrays.hashCode(stringArgs) : 0);
+ return result;
+ }
+
+ /**
+ * Replace placeholders in the given messagePattern with arguments.
+ *
+ * @param messagePattern the message pattern containing placeholders.
+ * @param arguments the arguments to be used to replace placeholders.
+ * @return the formatted message.
+ */
+ public static String format(final String messagePattern, final Object[] arguments) {
+ if (messagePattern == null || arguments == null || arguments.length == 0) {
+ return messagePattern;
+ }
+
+ final StringBuilder result = new StringBuilder();
+ int escapeCounter = 0;
+ int currentArgument = 0;
+ for (int i = 0; i < messagePattern.length(); i++) {
+ final char curChar = messagePattern.charAt(i);
+ if (curChar == ESCAPE_CHAR) {
+ escapeCounter++;
+ } else {
+ if (curChar == DELIM_START && i < messagePattern.length() - 1
+ && messagePattern.charAt(i + 1) == DELIM_STOP) {
+ // write escaped escape chars
+ final int escapedEscapes = escapeCounter / 2;
+ for (int j = 0; j < escapedEscapes; j++) {
+ result.append(ESCAPE_CHAR);
+ }
+
+ if (escapeCounter % 2 == 1) {
+ // i.e. escaped
+ // write escaped escape chars
+ result.append(DELIM_START);
+ result.append(DELIM_STOP);
+ } else {
+ // unescaped
+ if (currentArgument < arguments.length) {
+ result.append(arguments[currentArgument]);
+ } else {
+ result.append(DELIM_START).append(DELIM_STOP);
+ }
+ currentArgument++;
+ }
+ i++;
+ escapeCounter = 0;
+ continue;
+ }
+ // any other char beside ESCAPE or DELIM_START/STOP-combo
+ // write unescaped escape chars
+ if (escapeCounter > 0) {
+ for (int j = 0; j < escapeCounter; j++) {
+ result.append(ESCAPE_CHAR);
+ }
+ escapeCounter = 0;
+ }
+ result.append(curChar);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Counts the number of unescaped placeholders in the given messagePattern.
+ *
+ * @param messagePattern the message pattern to be analyzed.
+ * @return the number of unescaped placeholders.
+ */
+ public static int countArgumentPlaceholders(final String messagePattern) {
+ if (messagePattern == null) {
+ return 0;
+ }
+
+ final int delim = messagePattern.indexOf(DELIM_START);
+
+ if (delim == -1) {
+ // special case, no placeholders at all.
+ return 0;
+ }
+ int result = 0;
+ boolean isEscaped = false;
+ for (int i = 0; i < messagePattern.length(); i++) {
+ final char curChar = messagePattern.charAt(i);
+ if (curChar == ESCAPE_CHAR) {
+ isEscaped = !isEscaped;
+ } else if (curChar == DELIM_START) {
+ if (!isEscaped && i < messagePattern.length() - 1 && messagePattern.charAt(i + 1) == DELIM_STOP) {
+ result++;
+ i++;
+ }
+ isEscaped = false;
+ } else {
+ isEscaped = false;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This method performs a deep toString of the given Object.
+ * Primitive arrays are converted using their respective Arrays.toString methods while
+ * special handling is implemented for "container types", i.e. Object[], Map and Collection because those could
+ * contain themselves.
+ * <p>
+ * It should be noted that neither AbstractMap.toString() nor AbstractCollection.toString() implement such a
+ * behavior. They only check if the container is directly contained in itself, but not if a contained container
+ * contains the original one. Because of that, Arrays.toString(Object[]) isn't safe either.
+ * Confusing? Just read the last paragraph again and check the respective toString() implementation.
+ * </p>
+ * <p>
+ * This means, in effect, that logging would produce a usable output even if an ordinary System.out.println(o)
+ * would produce a relatively hard-to-debug StackOverflowError.
+ * </p>
+ * @param o The object.
+ * @return The String representation.
+ */
+ public static String deepToString(final Object o) {
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof String) {
+ return (String) o;
+ }
+ final StringBuilder str = new StringBuilder();
+ final Set<String> dejaVu = new HashSet<String>(); // that's actually a neat name ;)
+ recursiveDeepToString(o, str, dejaVu);
+ return str.toString();
+ }
+
+ /**
+ * This method performs a deep toString of the given Object.
+ * Primitive arrays are converted using their respective Arrays.toString methods while
+ * special handling is implemented for "container types", i.e. Object[], Map and Collection because those could
+ * contain themselves.
+ * <p>
+ * dejaVu is used in case of those container types to prevent an endless recursion.
+ * </p>
+ * <p>
+ * It should be noted that neither AbstractMap.toString() nor AbstractCollection.toString() implement such a
+ * behavior.
+ * They only check if the container is directly contained in itself, but not if a contained container contains the
+ * original one. Because of that, Arrays.toString(Object[]) isn't safe either.
+ * Confusing? Just read the last paragraph again and check the respective toString() implementation.
+ * </p>
+ * <p>
+ * This means, in effect, that logging would produce a usable output even if an ordinary System.out.println(o)
+ * would produce a relatively hard-to-debug StackOverflowError.
+ * </p>
+ *
+ * @param o the Object to convert into a String
+ * @param str the StringBuilder that o will be appended to
+ * @param dejaVu a list of container identities that were already used.
+ */
+ private static void recursiveDeepToString(final Object o, final StringBuilder str, final Set<String> dejaVu) {
+ if (o == null) {
+ str.append("null");
+ return;
+ }
+ if (o instanceof String) {
+ str.append(o);
+ return;
+ }
+
+ final Class<?> oClass = o.getClass();
+ if (oClass.isArray()) {
+ if (oClass == byte[].class) {
+ str.append(Arrays.toString((byte[]) o));
+ } else if (oClass == short[].class) {
+ str.append(Arrays.toString((short[]) o));
+ } else if (oClass == int[].class) {
+ str.append(Arrays.toString((int[]) o));
+ } else if (oClass == long[].class) {
+ str.append(Arrays.toString((long[]) o));
+ } else if (oClass == float[].class) {
+ str.append(Arrays.toString((float[]) o));
+ } else if (oClass == double[].class) {
+ str.append(Arrays.toString((double[]) o));
+ } else if (oClass == boolean[].class) {
+ str.append(Arrays.toString((boolean[]) o));
+ } else if (oClass == char[].class) {
+ str.append(Arrays.toString((char[]) o));
+ } else {
+ // special handling of container Object[]
+ final String id = identityToString(o);
+ if (dejaVu.contains(id)) {
+ str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
+ } else {
+ dejaVu.add(id);
+ final Object[] oArray = (Object[]) o;
+ str.append('[');
+ boolean first = true;
+ for (final Object current : oArray) {
+ if (first) {
+ first = false;
+ } else {
+ str.append(", ");
+ }
+ recursiveDeepToString(current, str, new HashSet<String>(dejaVu));
+ }
+ str.append(']');
+ }
+ //str.append(Arrays.deepToString((Object[]) o));
+ }
+ } else if (o instanceof Map && !(o instanceof Region)) { // GEODE: do NOT use Map handling if instanceof Geode Region
+ // special handling of container Map
+ final String id = identityToString(o);
+ if (dejaVu.contains(id)) {
+ str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
+ } else {
+ dejaVu.add(id);
+ final Map<?, ?> oMap = (Map<?, ?>) o;
+ str.append('{');
+ boolean isFirst = true;
+ for (final Object o1 : oMap.entrySet()) {
+ final Map.Entry<?, ?> current = (Map.Entry<?, ?>) o1;
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ str.append(", ");
+ }
+ final Object key = current.getKey();
+ final Object value = current.getValue();
+ recursiveDeepToString(key, str, new HashSet<String>(dejaVu));
+ str.append('=');
+ recursiveDeepToString(value, str, new HashSet<String>(dejaVu));
+ }
+ str.append('}');
+ }
+ } else if (o instanceof Collection && !(o instanceof EntriesSet)) { // GEODE: do NOT use Colleciton handling if instanceof Geode EntriesSet
+ // special handling of container Collection
+ final String id = identityToString(o);
+ if (dejaVu.contains(id)) {
+ str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
+ } else {
+ dejaVu.add(id);
+ final Collection<?> oCol = (Collection<?>) o;
+ str.append('[');
+ boolean isFirst = true;
+ for (final Object anOCol : oCol) {
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ str.append(", ");
+ }
+ recursiveDeepToString(anOCol, str, new HashSet<String>(dejaVu));
+ }
+ str.append(']');
+ }
+ } else if (o instanceof Date) {
+ final Date date = (Date) o;
+ final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ // I'll leave it like this for the moment... this could probably be optimized using ThreadLocal...
+ str.append(format.format(date));
+ } else {
+ // it's just some other Object, we can only use toString().
+ try {
+ str.append(o.toString());
+ } catch (final Throwable t) {
+ str.append(ERROR_PREFIX);
+ str.append(identityToString(o));
+ str.append(ERROR_SEPARATOR);
+ final String msg = t.getMessage();
+ final String className = t.getClass().getName();
+ str.append(className);
+ if (!className.equals(msg)) {
+ str.append(ERROR_MSG_SEPARATOR);
+ str.append(msg);
+ }
+ str.append(ERROR_SUFFIX);
+ }
+ }
+ }
+
+ /**
+ * This method returns the same as if Object.toString() would not have been
+ * overridden in obj.
+ * <p>
+ * Note that this isn't 100% secure as collisions can always happen with hash codes.
+ * </p>
+ * <p>
+ * Copied from Object.hashCode():
+ * </p>
+ * <blockquote>
+ * As much as is reasonably practical, the hashCode method defined by
+ * class {@code Object} does return distinct integers for distinct
+ * objects. (This is typically implemented by converting the internal
+ * address of the object into an integer, but this implementation
+ * technique is not required by the Java™ programming language.)
+ * </blockquote>
+ *
+ * @param obj the Object that is to be converted into an identity string.
+ * @return the identity string as also defined in Object.toString()
+ */
+ public static String identityToString(final Object obj) {
+ if (obj == null) {
+ return null;
+ }
+ return obj.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(obj));
+ }
+
+ @Override
+ public String toString() {
+ return "GemFireParameterizedMessage[messagePattern=" + messagePattern + ", stringArgs=" +
+ Arrays.toString(stringArgs) + ", throwable=" + throwable + ']'; // GEODE: adjust toString to GemFireParameterizedMessage
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessageFactory.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessageFactory.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessageFactory.java
new file mode 100755
index 0000000..3756da7
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/logging/log4j/message/GemFireParameterizedMessageFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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 com.gemstone.gemfire.internal.logging.log4j.message;
+
+import org.apache.logging.log4j.message.AbstractMessageFactory;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.message.ParameterizedMessage;
+
+/**
+ * Enables use of <code>{}</code> parameter markers in message strings.
+ * <p/>
+ * Creates {@link ParameterizedMessage} instances for {@link #newMessage(String, Object...)}.
+ * <p/>
+ * This class is immutable.
+ * <p/>
+ * Copied into Geode from org.apache.logging.log4j.message.ParameterizedMessageFactory (http://logging.apache.org/log4j/2.x/license.html)
+ * <p/>
+ * Geode changes include changing class name and package. Additional changes are commented with "// GEODE: note"
+ */
+public final class GemFireParameterizedMessageFactory extends AbstractMessageFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Instance of StringFormatterMessageFactory.
+ */
+ public static final GemFireParameterizedMessageFactory INSTANCE = new GemFireParameterizedMessageFactory();
+
+ /**
+ * Creates {@link ParameterizedMessage} instances.
+ * @param message The message pattern.
+ * @param params The message parameters.
+ * @return The Message.
+ *
+ * @see MessageFactory#newMessage(String, Object...)
+ */
+ @Override
+ public Message newMessage(final String message, final Object... params) {
+ return new GemFireParameterizedMessage(message, params); // GEODE: change to construct GemFireParameterizedMessage
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessage.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessage.java b/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessage.java
deleted file mode 100755
index f124016..0000000
--- a/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessage.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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 com.gemstone.org.apache.logging.log4j.message;
-
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.logging.log4j.message.Message;
-
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.internal.cache.EntriesSet;
-
-/**
- * Handles messages that consist of a format string containing '{}' to represent each replaceable token, and
- * the parameters.
- * <p/>
- * This class was originally written for <a href="http://lilithapp.com/">Lilith</a> by Joern Huxhorn where it is
- * licensed under the LGPL. It has been relicensed here with his permission providing that this attribution remain.
- * <p/>
- * Copied into Geode from org.apache.logging.log4j.message.ParameterizedMessage (http://logging.apache.org/log4j/2.x/license.html)
- * <p/>
- * Geode changes include changing class name and package. Additional changes are commented with "// GEODE: note"
- */
-public class GemFireParameterizedMessage implements Message {
-
- /**
- * Prefix for recursion.
- */
- public static final String RECURSION_PREFIX = "[...";
- /**
- * Suffix for recursion.
- */
- public static final String RECURSION_SUFFIX = "...]";
-
- /**
- * Prefix for errors.
- */
- public static final String ERROR_PREFIX = "[!!!";
- /**
- * Separator for errors.
- */
- public static final String ERROR_SEPARATOR = "=>";
- /**
- * Separator for error messages.
- */
- public static final String ERROR_MSG_SEPARATOR = ":";
- /**
- * Suffix for errors.
- */
- public static final String ERROR_SUFFIX = "!!!]";
-
- private static final long serialVersionUID = -665975803997290697L;
-
- private static final int HASHVAL = 31;
-
- private static final char DELIM_START = '{';
- private static final char DELIM_STOP = '}';
- private static final char ESCAPE_CHAR = '\\';
-
- private final String messagePattern;
- private final String[] stringArgs;
- private transient Object[] argArray;
- private transient String formattedMessage;
- private transient Throwable throwable;
-
- /**
- * Creates a parameterized message.
- * @param messagePattern The message "format" string. This will be a String containing "{}" placeholders
- * where parameters should be substituted.
- * @param stringArgs The arguments for substitution.
- * @param throwable A Throwable.
- */
- public GemFireParameterizedMessage(final String messagePattern, final String[] stringArgs, final Throwable throwable) {
- this.messagePattern = messagePattern;
- this.stringArgs = stringArgs;
- this.throwable = throwable;
- }
-
- /**
- * Creates a parameterized message.
- * @param messagePattern The message "format" string. This will be a String containing "{}" placeholders
- * where parameters should be substituted.
- * @param objectArgs The arguments for substitution.
- * @param throwable A Throwable.
- */
- public GemFireParameterizedMessage(final String messagePattern, final Object[] objectArgs, final Throwable throwable) {
- this.messagePattern = messagePattern;
- this.throwable = throwable;
- this.stringArgs = parseArguments(objectArgs);
- }
-
- /**
- * Constructs a ParameterizedMessage which contains the arguments converted to String as well as an optional
- * Throwable.
- *
- * <p>If the last argument is a Throwable and is NOT used up by a placeholder in the message pattern it is returned
- * in {@link #getThrowable()} and won't be contained in the created String[].
- * If it is used up {@link #getThrowable()} will return null even if the last argument was a Throwable!</p>
- *
- * @param messagePattern the message pattern that to be checked for placeholders.
- * @param arguments the argument array to be converted.
- */
- public GemFireParameterizedMessage(final String messagePattern, final Object[] arguments) {
- this.messagePattern = messagePattern;
- this.stringArgs = parseArguments(arguments);
- }
-
- /**
- * Constructor with a pattern and a single parameter.
- * @param messagePattern The message pattern.
- * @param arg The parameter.
- */
- public GemFireParameterizedMessage(final String messagePattern, final Object arg) {
- this(messagePattern, new Object[]{arg});
- }
-
- /**
- * Constructor with a pattern and two parameters.
- * @param messagePattern The message pattern.
- * @param arg1 The first parameter.
- * @param arg2 The second parameter.
- */
- public GemFireParameterizedMessage(final String messagePattern, final Object arg1, final Object arg2) {
- this(messagePattern, new Object[]{arg1, arg2});
- }
-
- private String[] parseArguments(final Object[] arguments) {
- if (arguments == null) {
- return null;
- }
- final int argsCount = countArgumentPlaceholders(messagePattern);
- int resultArgCount = arguments.length;
- if (argsCount < arguments.length && throwable == null && arguments[arguments.length - 1] instanceof Throwable) {
- throwable = (Throwable) arguments[arguments.length - 1];
- resultArgCount--;
- }
- argArray = new Object[resultArgCount];
- System.arraycopy(arguments, 0, argArray, 0, resultArgCount);
-
- String[] strArgs;
- if (argsCount == 1 && throwable == null && arguments.length > 1) {
- // special case
- strArgs = new String[1];
- strArgs[0] = deepToString(arguments);
- } else {
- strArgs = new String[resultArgCount];
- for (int i = 0; i < strArgs.length; i++) {
- strArgs[i] = deepToString(arguments[i]);
- }
- }
- return strArgs;
- }
-
- /**
- * Returns the formatted message.
- * @return the formatted message.
- */
- @Override
- public String getFormattedMessage() {
- if (formattedMessage == null) {
- formattedMessage = formatMessage(messagePattern, stringArgs);
- }
- return formattedMessage;
- }
-
- /**
- * Returns the message pattern.
- * @return the message pattern.
- */
- @Override
- public String getFormat() {
- return messagePattern;
- }
-
- /**
- * Returns the message parameters.
- * @return the message parameters.
- */
- @Override
- public Object[] getParameters() {
- if (argArray != null) {
- return argArray;
- }
- return stringArgs;
- }
-
- /**
- * Returns the Throwable that was given as the last argument, if any.
- * It will not survive serialization. The Throwable exists as part of the message
- * primarily so that it can be extracted from the end of the list of parameters
- * and then be added to the LogEvent. As such, the Throwable in the event should
- * not be used once the LogEvent has been constructed.
- *
- * @return the Throwable, if any.
- */
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- protected String formatMessage(final String msgPattern, final String[] sArgs) {
- return format(msgPattern, sArgs);
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- final GemFireParameterizedMessage that = (GemFireParameterizedMessage) o;
-
- if (messagePattern != null ? !messagePattern.equals(that.messagePattern) : that.messagePattern != null) {
- return false;
- }
- if (!Arrays.equals(stringArgs, that.stringArgs)) {
- return false;
- }
- //if (throwable != null ? !throwable.equals(that.throwable) : that.throwable != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = messagePattern != null ? messagePattern.hashCode() : 0;
- result = HASHVAL * result + (stringArgs != null ? Arrays.hashCode(stringArgs) : 0);
- return result;
- }
-
- /**
- * Replace placeholders in the given messagePattern with arguments.
- *
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- * @return the formatted message.
- */
- public static String format(final String messagePattern, final Object[] arguments) {
- if (messagePattern == null || arguments == null || arguments.length == 0) {
- return messagePattern;
- }
-
- final StringBuilder result = new StringBuilder();
- int escapeCounter = 0;
- int currentArgument = 0;
- for (int i = 0; i < messagePattern.length(); i++) {
- final char curChar = messagePattern.charAt(i);
- if (curChar == ESCAPE_CHAR) {
- escapeCounter++;
- } else {
- if (curChar == DELIM_START && i < messagePattern.length() - 1
- && messagePattern.charAt(i + 1) == DELIM_STOP) {
- // write escaped escape chars
- final int escapedEscapes = escapeCounter / 2;
- for (int j = 0; j < escapedEscapes; j++) {
- result.append(ESCAPE_CHAR);
- }
-
- if (escapeCounter % 2 == 1) {
- // i.e. escaped
- // write escaped escape chars
- result.append(DELIM_START);
- result.append(DELIM_STOP);
- } else {
- // unescaped
- if (currentArgument < arguments.length) {
- result.append(arguments[currentArgument]);
- } else {
- result.append(DELIM_START).append(DELIM_STOP);
- }
- currentArgument++;
- }
- i++;
- escapeCounter = 0;
- continue;
- }
- // any other char beside ESCAPE or DELIM_START/STOP-combo
- // write unescaped escape chars
- if (escapeCounter > 0) {
- for (int j = 0; j < escapeCounter; j++) {
- result.append(ESCAPE_CHAR);
- }
- escapeCounter = 0;
- }
- result.append(curChar);
- }
- }
- return result.toString();
- }
-
- /**
- * Counts the number of unescaped placeholders in the given messagePattern.
- *
- * @param messagePattern the message pattern to be analyzed.
- * @return the number of unescaped placeholders.
- */
- public static int countArgumentPlaceholders(final String messagePattern) {
- if (messagePattern == null) {
- return 0;
- }
-
- final int delim = messagePattern.indexOf(DELIM_START);
-
- if (delim == -1) {
- // special case, no placeholders at all.
- return 0;
- }
- int result = 0;
- boolean isEscaped = false;
- for (int i = 0; i < messagePattern.length(); i++) {
- final char curChar = messagePattern.charAt(i);
- if (curChar == ESCAPE_CHAR) {
- isEscaped = !isEscaped;
- } else if (curChar == DELIM_START) {
- if (!isEscaped && i < messagePattern.length() - 1 && messagePattern.charAt(i + 1) == DELIM_STOP) {
- result++;
- i++;
- }
- isEscaped = false;
- } else {
- isEscaped = false;
- }
- }
- return result;
- }
-
- /**
- * This method performs a deep toString of the given Object.
- * Primitive arrays are converted using their respective Arrays.toString methods while
- * special handling is implemented for "container types", i.e. Object[], Map and Collection because those could
- * contain themselves.
- * <p>
- * It should be noted that neither AbstractMap.toString() nor AbstractCollection.toString() implement such a
- * behavior. They only check if the container is directly contained in itself, but not if a contained container
- * contains the original one. Because of that, Arrays.toString(Object[]) isn't safe either.
- * Confusing? Just read the last paragraph again and check the respective toString() implementation.
- * </p>
- * <p>
- * This means, in effect, that logging would produce a usable output even if an ordinary System.out.println(o)
- * would produce a relatively hard-to-debug StackOverflowError.
- * </p>
- * @param o The object.
- * @return The String representation.
- */
- public static String deepToString(final Object o) {
- if (o == null) {
- return null;
- }
- if (o instanceof String) {
- return (String) o;
- }
- final StringBuilder str = new StringBuilder();
- final Set<String> dejaVu = new HashSet<String>(); // that's actually a neat name ;)
- recursiveDeepToString(o, str, dejaVu);
- return str.toString();
- }
-
- /**
- * This method performs a deep toString of the given Object.
- * Primitive arrays are converted using their respective Arrays.toString methods while
- * special handling is implemented for "container types", i.e. Object[], Map and Collection because those could
- * contain themselves.
- * <p>
- * dejaVu is used in case of those container types to prevent an endless recursion.
- * </p>
- * <p>
- * It should be noted that neither AbstractMap.toString() nor AbstractCollection.toString() implement such a
- * behavior.
- * They only check if the container is directly contained in itself, but not if a contained container contains the
- * original one. Because of that, Arrays.toString(Object[]) isn't safe either.
- * Confusing? Just read the last paragraph again and check the respective toString() implementation.
- * </p>
- * <p>
- * This means, in effect, that logging would produce a usable output even if an ordinary System.out.println(o)
- * would produce a relatively hard-to-debug StackOverflowError.
- * </p>
- *
- * @param o the Object to convert into a String
- * @param str the StringBuilder that o will be appended to
- * @param dejaVu a list of container identities that were already used.
- */
- private static void recursiveDeepToString(final Object o, final StringBuilder str, final Set<String> dejaVu) {
- if (o == null) {
- str.append("null");
- return;
- }
- if (o instanceof String) {
- str.append(o);
- return;
- }
-
- final Class<?> oClass = o.getClass();
- if (oClass.isArray()) {
- if (oClass == byte[].class) {
- str.append(Arrays.toString((byte[]) o));
- } else if (oClass == short[].class) {
- str.append(Arrays.toString((short[]) o));
- } else if (oClass == int[].class) {
- str.append(Arrays.toString((int[]) o));
- } else if (oClass == long[].class) {
- str.append(Arrays.toString((long[]) o));
- } else if (oClass == float[].class) {
- str.append(Arrays.toString((float[]) o));
- } else if (oClass == double[].class) {
- str.append(Arrays.toString((double[]) o));
- } else if (oClass == boolean[].class) {
- str.append(Arrays.toString((boolean[]) o));
- } else if (oClass == char[].class) {
- str.append(Arrays.toString((char[]) o));
- } else {
- // special handling of container Object[]
- final String id = identityToString(o);
- if (dejaVu.contains(id)) {
- str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
- } else {
- dejaVu.add(id);
- final Object[] oArray = (Object[]) o;
- str.append('[');
- boolean first = true;
- for (final Object current : oArray) {
- if (first) {
- first = false;
- } else {
- str.append(", ");
- }
- recursiveDeepToString(current, str, new HashSet<String>(dejaVu));
- }
- str.append(']');
- }
- //str.append(Arrays.deepToString((Object[]) o));
- }
- } else if (o instanceof Map && !(o instanceof Region)) { // GEODE: do NOT use Map handling if instanceof Geode Region
- // special handling of container Map
- final String id = identityToString(o);
- if (dejaVu.contains(id)) {
- str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
- } else {
- dejaVu.add(id);
- final Map<?, ?> oMap = (Map<?, ?>) o;
- str.append('{');
- boolean isFirst = true;
- for (final Object o1 : oMap.entrySet()) {
- final Map.Entry<?, ?> current = (Map.Entry<?, ?>) o1;
- if (isFirst) {
- isFirst = false;
- } else {
- str.append(", ");
- }
- final Object key = current.getKey();
- final Object value = current.getValue();
- recursiveDeepToString(key, str, new HashSet<String>(dejaVu));
- str.append('=');
- recursiveDeepToString(value, str, new HashSet<String>(dejaVu));
- }
- str.append('}');
- }
- } else if (o instanceof Collection && !(o instanceof EntriesSet)) { // GEODE: do NOT use Colleciton handling if instanceof Geode EntriesSet
- // special handling of container Collection
- final String id = identityToString(o);
- if (dejaVu.contains(id)) {
- str.append(RECURSION_PREFIX).append(id).append(RECURSION_SUFFIX);
- } else {
- dejaVu.add(id);
- final Collection<?> oCol = (Collection<?>) o;
- str.append('[');
- boolean isFirst = true;
- for (final Object anOCol : oCol) {
- if (isFirst) {
- isFirst = false;
- } else {
- str.append(", ");
- }
- recursiveDeepToString(anOCol, str, new HashSet<String>(dejaVu));
- }
- str.append(']');
- }
- } else if (o instanceof Date) {
- final Date date = (Date) o;
- final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
- // I'll leave it like this for the moment... this could probably be optimized using ThreadLocal...
- str.append(format.format(date));
- } else {
- // it's just some other Object, we can only use toString().
- try {
- str.append(o.toString());
- } catch (final Throwable t) {
- str.append(ERROR_PREFIX);
- str.append(identityToString(o));
- str.append(ERROR_SEPARATOR);
- final String msg = t.getMessage();
- final String className = t.getClass().getName();
- str.append(className);
- if (!className.equals(msg)) {
- str.append(ERROR_MSG_SEPARATOR);
- str.append(msg);
- }
- str.append(ERROR_SUFFIX);
- }
- }
- }
-
- /**
- * This method returns the same as if Object.toString() would not have been
- * overridden in obj.
- * <p>
- * Note that this isn't 100% secure as collisions can always happen with hash codes.
- * </p>
- * <p>
- * Copied from Object.hashCode():
- * </p>
- * <blockquote>
- * As much as is reasonably practical, the hashCode method defined by
- * class {@code Object} does return distinct integers for distinct
- * objects. (This is typically implemented by converting the internal
- * address of the object into an integer, but this implementation
- * technique is not required by the Java™ programming language.)
- * </blockquote>
- *
- * @param obj the Object that is to be converted into an identity string.
- * @return the identity string as also defined in Object.toString()
- */
- public static String identityToString(final Object obj) {
- if (obj == null) {
- return null;
- }
- return obj.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(obj));
- }
-
- @Override
- public String toString() {
- return "GemFireParameterizedMessage[messagePattern=" + messagePattern + ", stringArgs=" +
- Arrays.toString(stringArgs) + ", throwable=" + throwable + ']'; // GEODE: adjust toString to GemFireParameterizedMessage
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/93c797eb/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessageFactory.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessageFactory.java b/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessageFactory.java
deleted file mode 100755
index a888f19..0000000
--- a/geode-core/src/main/java/com/gemstone/org/apache/logging/log4j/message/GemFireParameterizedMessageFactory.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 com.gemstone.org.apache.logging.log4j.message;
-
-import org.apache.logging.log4j.message.AbstractMessageFactory;
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ParameterizedMessage;
-
-/**
- * Enables use of <code>{}</code> parameter markers in message strings.
- * <p/>
- * Creates {@link ParameterizedMessage} instances for {@link #newMessage(String, Object...)}.
- * <p/>
- * This class is immutable.
- * <p/>
- * Copied into Geode from org.apache.logging.log4j.message.ParameterizedMessageFactory (http://logging.apache.org/log4j/2.x/license.html)
- * <p/>
- * Geode changes include changing class name and package. Additional changes are commented with "// GEODE: note"
- */
-public final class GemFireParameterizedMessageFactory extends AbstractMessageFactory {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Instance of StringFormatterMessageFactory.
- */
- public static final GemFireParameterizedMessageFactory INSTANCE = new GemFireParameterizedMessageFactory();
-
- /**
- * Creates {@link ParameterizedMessage} instances.
- * @param message The message pattern.
- * @param params The message parameters.
- * @return The Message.
- *
- * @see MessageFactory#newMessage(String, Object...)
- */
- @Override
- public Message newMessage(final String message, final Object... params) {
- return new GemFireParameterizedMessage(message, params); // GEODE: change to construct GemFireParameterizedMessage
- }
-}