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 org.apache.logging.log4j.util.StringBuilderFormattable;
020
021import java.io.IOException;
022import java.io.ObjectInputStream;
023import java.io.ObjectOutputStream;
024
025/**
026 * The simplest possible implementation of Message. It just returns the String given as the constructor argument.
027 */
028public class SimpleMessage implements Message, StringBuilderFormattable, CharSequence {
029    private static final long serialVersionUID = -8398002534962715992L;
030
031    private String message;
032    private transient CharSequence charSequence;
033
034    /**
035     * Basic constructor.
036     */
037    public SimpleMessage() {
038        this(null);
039    }
040
041    /**
042     * Constructor that includes the message.
043     * @param message The String message.
044     */
045    public SimpleMessage(final String message) {
046        this.message = message;
047        this.charSequence = message;
048    }
049
050    /**
051     * Constructor that includes the message.
052     * @param charSequence The CharSequence message.
053     */
054    public SimpleMessage(final CharSequence charSequence) {
055        // this.message = String.valueOf(charSequence); // postponed until getFormattedMessage
056        this.charSequence = charSequence;
057    }
058
059    /**
060     * Returns the message.
061     * @return the message.
062     */
063    @Override
064    public String getFormattedMessage() {
065        return message = message == null ? String.valueOf(charSequence) : message ;
066    }
067
068    @Override
069    public void formatTo(final StringBuilder buffer) {
070        buffer.append(message != null ? message : charSequence);
071    }
072
073    /**
074     * Returns the message.
075     * @return the message.
076     */
077    @Override
078    public String getFormat() {
079        return message;
080    }
081
082    /**
083     * Returns null since there are no parameters.
084     * @return null.
085     */
086    @Override
087    public Object[] getParameters() {
088        return null;
089    }
090
091    @Override
092    public boolean equals(final Object o) {
093        if (this == o) {
094            return true;
095        }
096        if (o == null || getClass() != o.getClass()) {
097            return false;
098        }
099
100        final SimpleMessage that = (SimpleMessage) o;
101
102        return !(charSequence != null ? !charSequence.equals(that.charSequence) : that.charSequence != null);
103    }
104
105    @Override
106    public int hashCode() {
107        return charSequence != null ? charSequence.hashCode() : 0;
108    }
109
110    @Override
111    public String toString() {
112        return getFormattedMessage();
113    }
114
115    /**
116     * Always returns null.
117     *
118     * @return null
119     */
120    @Override
121    public Throwable getThrowable() {
122        return null;
123    }
124
125
126    // CharSequence impl
127
128    @Override
129    public int length() {
130        return charSequence == null ? 0 : charSequence.length();
131    }
132
133    @Override
134    public char charAt(final int index) {
135        return charSequence.charAt(index);
136    }
137
138    @Override
139    public CharSequence subSequence(final int start, final int end) {
140        return charSequence.subSequence(start, end);
141    }
142
143
144    private void writeObject(final ObjectOutputStream out) throws IOException {
145        getFormattedMessage(); // initialize the message:String field
146        out.defaultWriteObject();
147    }
148
149    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
150        in.defaultReadObject();
151        charSequence = message;
152    }
153}