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