View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.message;
18  
19  import org.apache.logging.log4j.Logger;
20  import org.apache.logging.log4j.status.StatusLogger;
21  
22  import java.io.IOException;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.text.MessageFormat;
26  import java.util.Arrays;
27  import java.util.IllegalFormatException;
28  
29  /**
30   * Handles messages that consist of a format string conforming to java.text.MessageFormat.
31   */
32  public class MessageFormatMessage implements Message {
33  
34      private static final Logger LOGGER = StatusLogger.getLogger();
35  
36      private static final long serialVersionUID = -665975803997290697L;
37  
38      private static final int HASHVAL = 31;
39  
40      private String messagePattern;
41      private transient Object[] argArray;
42      private String[] stringArgs;
43      private transient String formattedMessage;
44  
45      public MessageFormatMessage(final String messagePattern, final Object... arguments) {
46          this.messagePattern = messagePattern;
47          this.argArray = arguments;
48      }
49  
50      /**
51       * Returns the formatted message.
52       * @return the formatted message.
53       */
54      public String getFormattedMessage() {
55          if (formattedMessage == null) {
56              formattedMessage = formatMessage(messagePattern, argArray);
57          }
58          return formattedMessage;
59      }
60  
61      /**
62       * Returns the message pattern.
63       * @return the message pattern.
64       */
65      public String getFormat() {
66          return messagePattern;
67      }
68  
69      /**
70       * Returns the message parameters.
71       * @return the message parameters.
72       */
73      public Object[] getParameters() {
74          if (argArray != null) {
75              return argArray;
76          }
77          return stringArgs;
78      }
79  
80      protected String formatMessage(final String msgPattern, final Object... args) {
81          try {
82              return MessageFormat.format(msgPattern, args);
83          } catch (final IllegalFormatException ife) {
84              LOGGER.error("Unable to format msg: " + msgPattern, ife);
85              return msgPattern;
86          }
87      }
88  
89      @Override
90      public boolean equals(final Object o) {
91          if (this == o) {
92              return true;
93          }
94          if (o == null || getClass() != o.getClass()) {
95              return false;
96          }
97  
98          final MessageFormatMessage that = (MessageFormatMessage) o;
99  
100         if (messagePattern != null ? !messagePattern.equals(that.messagePattern) : that.messagePattern != null) {
101             return false;
102         }
103         if (!Arrays.equals(stringArgs, that.stringArgs)) {
104             return false;
105         }
106 
107         return true;
108     }
109 
110     @Override
111     public int hashCode() {
112         int result = messagePattern != null ? messagePattern.hashCode() : 0;
113         result = HASHVAL * result + (stringArgs != null ? Arrays.hashCode(stringArgs) : 0);
114         return result;
115     }
116 
117 
118     @Override
119     public String toString() {
120         return "StringFormatMessage[messagePattern=" + messagePattern + ", args=" +
121             Arrays.toString(argArray) +  "]";
122     }
123 
124     private void writeObject(final ObjectOutputStream out) throws IOException {
125         out.defaultWriteObject();
126         getFormattedMessage();
127         out.writeUTF(formattedMessage);
128         out.writeUTF(messagePattern);
129         out.writeInt(argArray.length);
130         stringArgs = new String[argArray.length];
131         int i = 0;
132         for (final Object obj : argArray) {
133             stringArgs[i] = obj.toString();
134             ++i;
135         }
136     }
137 
138     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
139         in.defaultReadObject();
140         formattedMessage = in.readUTF();
141         messagePattern = in.readUTF();
142         final int length = in.readInt();
143         stringArgs = new String[length];
144         for (int i = 0; i < length; ++i) {
145             stringArgs[i] = in.readUTF();
146         }
147     }
148 
149     /**
150      * Always returns null.
151      *
152      * @return null
153      */
154     public Throwable getThrowable() {
155         return null;
156     }
157 }