001 /*
002 // $Id: //open/mondrian-release/3.0/src/main/mondrian/recorder/AbstractRecorder.java#2 $
003 // This software is subject to the terms of the Common Public License
004 // Agreement, available at the following URL:
005 // http://www.opensource.org/licenses/cpl.html.
006 // Copyright (C) 2005-2006 Julian Hyde and others
007 // All Rights Reserved.
008 // You must accept the terms of that agreement to use this software.
009 */
010
011 package mondrian.recorder;
012
013 import mondrian.resource.MondrianResource;
014
015 import java.util.*;
016
017 /**
018 * Abstract implemention of the {@link MessageRecorder} interface.
019 *
020 * @author Richard M. Emberson
021 * @version $Id: //open/mondrian-release/3.0/src/main/mondrian/recorder/AbstractRecorder.java#2 $
022 */
023 public abstract class AbstractRecorder implements MessageRecorder {
024
025 /**
026 * Helper method to format a message and write to logger.
027 */
028 public static void logMessage(
029 final String context,
030 final String msg,
031 final MsgType msgType,
032 final org.apache.log4j.Logger logger) {
033 StringBuilder buf = new StringBuilder(64);
034 buf.append(context);
035 buf.append(": ");
036 buf.append(msg);
037
038 switch (msgType) {
039 case INFO:
040 logger.info(buf.toString());
041 break;
042 case WARN:
043 logger.warn(buf.toString());
044 break;
045 case ERROR:
046 logger.error(buf.toString());
047 break;
048 default:
049 logger.warn(
050 "Unknown message type enum \"" +
051 msgType +
052 "\" for message: " +
053 buf.toString()
054 );
055 }
056 }
057
058 enum MsgType {
059 INFO,
060 WARN,
061 ERROR
062 }
063
064 public static final int DEFAULT_MSG_LIMIT = 10;
065
066 private final int errorMsgLimit;
067 private final List<String> contexts;
068 private int errorMsgCount;
069 private int warningMsgCount;
070 private int infoMsgCount;
071 private String contextMsgCache;
072 private long startTime;
073
074 protected AbstractRecorder() {
075 this(DEFAULT_MSG_LIMIT);
076 }
077 protected AbstractRecorder(final int errorMsgLimit) {
078 this.errorMsgLimit = errorMsgLimit;
079 this.contexts = new ArrayList<String>();
080 this.startTime = System.currentTimeMillis();
081 }
082
083 /**
084 * Resets this MessageRecorder.
085 */
086 public void clear() {
087 errorMsgCount = 0;
088 warningMsgCount = 0;
089 infoMsgCount = 0;
090 contextMsgCache = null;
091 contexts.clear();
092 this.startTime = System.currentTimeMillis();
093 }
094
095 public long getStartTimeMillis() {
096 return this.startTime;
097 }
098
099 public long getRunTimeMillis() {
100 return (System.currentTimeMillis() - this.startTime);
101 }
102
103 public boolean hasInformation() {
104 return (infoMsgCount > 0);
105 }
106 public boolean hasWarnings() {
107 return (warningMsgCount > 0);
108 }
109 public boolean hasErrors() {
110 return (errorMsgCount > 0);
111 }
112 public int getInfoCount() {
113 return infoMsgCount;
114 }
115 public int getWarningCount() {
116 return warningMsgCount;
117 }
118 public int getErrorCount() {
119 return errorMsgCount;
120 }
121
122 public String getContext() {
123 // heavy weight
124 if (contextMsgCache == null) {
125 final StringBuilder buf = new StringBuilder();
126 int k = 0;
127 for (String name : contexts) {
128 if (k++ > 0) {
129 buf.append(':');
130 }
131 buf.append(name);
132 }
133 contextMsgCache = buf.toString();
134 }
135 return contextMsgCache;
136 }
137
138 public void pushContextName(final String name) {
139 // light weight
140 contexts.add(name);
141 contextMsgCache = null;
142 }
143
144 public void popContextName() {
145 // light weight
146 contexts.remove(contexts.size()-1);
147 contextMsgCache = null;
148 }
149
150 public void throwRTException() throws RecorderException {
151 if (hasErrors()) {
152 final String errorMsg =
153 MondrianResource.instance().ForceMessageRecorderError.str(
154 getContext(),
155 errorMsgCount);
156 throw new RecorderException(errorMsg);
157 }
158 }
159
160 public void reportError(final Exception ex)
161 throws RecorderException {
162 reportError(ex, null);
163 }
164
165 public void reportError(final Exception ex, final Object info)
166 throws RecorderException {
167 reportError(ex.toString(), info);
168 }
169
170 public void reportError(final String msg)
171 throws RecorderException {
172 reportError(msg, null);
173 }
174 public void reportError(final String msg, final Object info)
175 throws RecorderException {
176 errorMsgCount++;
177 recordMessage(msg, info, MsgType.ERROR);
178
179 if (errorMsgCount >= errorMsgLimit) {
180 final String errorMsg =
181 MondrianResource.instance().TooManyMessageRecorderErrors.str(
182 getContext(),
183 errorMsgCount);
184 throw new RecorderException(errorMsg);
185 }
186 }
187
188 public void reportWarning(final String msg) {
189 reportWarning(msg, null);
190 }
191 public void reportWarning(final String msg, final Object info) {
192 warningMsgCount++;
193 recordMessage(msg, info, MsgType.WARN);
194 }
195
196 public void reportInfo(final String msg) {
197 reportInfo(msg, null);
198 }
199 public void reportInfo(final String msg, final Object info) {
200 infoMsgCount++;
201 recordMessage(msg, info, MsgType.INFO);
202 }
203
204 /**
205 * Handles a message.
206 * Classes implementing this abstract class must provide an implemention
207 * of this method; it receives all warning/error messages.
208 *
209 * @param msg the error or warning message.
210 * @param info the information Object which might be null.
211 * @param msgType one of the message type enum values
212 */
213 protected abstract void recordMessage(
214 String msg,
215 Object info,
216 MsgType msgType);
217 }
218
219 // End AbstractRecorder.java