001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.message;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.util.Arrays;
023
024/**
025 * Handles messages that contain an Object[].
026 * <p>
027 * Created for use with the CSV layout. For example:
028 * </p>
029 * <p>
030 * {@code logger.debug(new ObjectArrayMessage(1, 2, "Bob"));}
031 * </p>
032 * 
033 * @since 2.4
034 */
035public final class ObjectArrayMessage implements Message {
036
037    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
038
039    private static final long serialVersionUID = -5903272448334166185L;
040
041    private transient Object[] array;
042    private transient String arrayString;
043
044    /**
045     * Creates the ObjectMessage.
046     * 
047     * @param obj
048     *            The Object to format.
049     */
050    public ObjectArrayMessage(final Object... obj) {
051        this.array = obj == null ? EMPTY_OBJECT_ARRAY : obj;
052    }
053
054    private boolean equalObjectsOrStrings(final Object[] left, final Object[] right) {
055        return Arrays.equals(left, right) || Arrays.toString(left).equals(Arrays.toString(right));
056    }
057
058    @Override
059    public boolean equals(final Object o) {
060        if (this == o) {
061            return true;
062        }
063        if (o == null || getClass() != o.getClass()) {
064            return false;
065        }
066
067        final ObjectArrayMessage that = (ObjectArrayMessage) o;
068        return array == null ? that.array == null : equalObjectsOrStrings(array, that.array);
069    }
070
071    /**
072     * Returns the object formatted using its toString method.
073     * 
074     * @return the String representation of the object.
075     */
076    @Override
077    public String getFormat() {
078        return getFormattedMessage();
079    }
080
081    /**
082     * Returns the formatted object message.
083     * 
084     * @return the formatted object message.
085     */
086    @Override
087    public String getFormattedMessage() {
088        // LOG4J2-763: cache formatted string in case obj changes later
089        if (arrayString == null) {
090            arrayString = Arrays.toString(array);
091        }
092        return arrayString;
093    }
094
095    /**
096     * Returns the object as if it were a parameter.
097     * 
098     * @return The object.
099     */
100    @Override
101    public Object[] getParameters() {
102        return array;
103    }
104
105    /**
106     * Returns null.
107     *
108     * @return null.
109     */
110    @Override
111    public Throwable getThrowable() {
112        return null;
113    }
114
115    @Override
116    public int hashCode() {
117        return Arrays.hashCode(array);
118    }
119
120    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
121        in.defaultReadObject();
122        array = (Object[]) in.readObject();
123    }
124
125    @Override
126    public String toString() {
127        return getFormattedMessage();
128    }
129
130    private void writeObject(final ObjectOutputStream out) throws IOException {
131        out.defaultWriteObject();
132        out.writeObject(array);
133    }
134}