001 /* 002 // $Id: //open/mondrian/src/main/mondrian/recorder/AbstractRecorder.java#8 $ 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-2008 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/src/main/mondrian/recorder/AbstractRecorder.java#8 $ 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 enum MsgType { 058 INFO, 059 WARN, 060 ERROR 061 } 062 063 public static final int DEFAULT_MSG_LIMIT = 10; 064 065 private final int errorMsgLimit; 066 private final List<String> contexts; 067 private int errorMsgCount; 068 private int warningMsgCount; 069 private int infoMsgCount; 070 private String contextMsgCache; 071 private long startTime; 072 073 protected AbstractRecorder() { 074 this(DEFAULT_MSG_LIMIT); 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 public boolean hasWarnings() { 106 return (warningMsgCount > 0); 107 } 108 public boolean hasErrors() { 109 return (errorMsgCount > 0); 110 } 111 public int getInfoCount() { 112 return infoMsgCount; 113 } 114 public int getWarningCount() { 115 return warningMsgCount; 116 } 117 public int getErrorCount() { 118 return errorMsgCount; 119 } 120 121 public String getContext() { 122 // heavy weight 123 if (contextMsgCache == null) { 124 final StringBuilder buf = new StringBuilder(); 125 int k = 0; 126 for (String name : contexts) { 127 if (k++ > 0) { 128 buf.append(':'); 129 } 130 buf.append(name); 131 } 132 contextMsgCache = buf.toString(); 133 } 134 return contextMsgCache; 135 } 136 137 public void pushContextName(final String name) { 138 // light weight 139 contexts.add(name); 140 contextMsgCache = null; 141 } 142 143 public void popContextName() { 144 // light weight 145 contexts.remove(contexts.size() - 1); 146 contextMsgCache = null; 147 } 148 149 public void throwRTException() throws RecorderException { 150 if (hasErrors()) { 151 final String errorMsg = 152 MondrianResource.instance().ForceMessageRecorderError.str( 153 getContext(), 154 errorMsgCount); 155 throw new RecorderException(errorMsg); 156 } 157 } 158 159 public void reportError(final Exception ex) 160 throws RecorderException { 161 reportError(ex, null); 162 } 163 164 public void reportError(final Exception ex, final Object info) 165 throws RecorderException { 166 reportError(ex.toString(), info); 167 } 168 169 public void reportError(final String msg) 170 throws RecorderException { 171 reportError(msg, null); 172 } 173 public void reportError(final String msg, final Object info) 174 throws RecorderException { 175 errorMsgCount++; 176 recordMessage(msg, info, MsgType.ERROR); 177 178 if (errorMsgCount >= errorMsgLimit) { 179 final String errorMsg = 180 MondrianResource.instance().TooManyMessageRecorderErrors.str( 181 getContext(), 182 errorMsgCount); 183 throw new RecorderException(errorMsg); 184 } 185 } 186 187 public void reportWarning(final String msg) { 188 reportWarning(msg, null); 189 } 190 public void reportWarning(final String msg, final Object info) { 191 warningMsgCount++; 192 recordMessage(msg, info, MsgType.WARN); 193 } 194 195 public void reportInfo(final String msg) { 196 reportInfo(msg, null); 197 } 198 public void reportInfo(final String msg, final Object info) { 199 infoMsgCount++; 200 recordMessage(msg, info, MsgType.INFO); 201 } 202 203 /** 204 * Handles a message. 205 * Classes implementing this abstract class must provide an implemention 206 * of this method; it receives all warning/error messages. 207 * 208 * @param msg the error or warning message. 209 * @param info the information Object which might be null. 210 * @param msgType one of the message type enum values 211 */ 212 protected abstract void recordMessage( 213 String msg, 214 Object info, 215 MsgType msgType); 216 } 217 218 // End AbstractRecorder.java