/*
* Copyright 2010 Fred Sauer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.allen_sauer.gwt.log.shared;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.allen_sauer.gwt.log.client.Log;
import com.allen_sauer.gwt.log.client.LogMessageFormatter;
import com.allen_sauer.gwt.log.client.LogUtil;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
/**
* Wrapper class to capture a single log message and optional stack trace, used primarily for
* transfer between client and server.
*/
@SuppressWarnings("serial")
public class LogRecord implements Serializable, IsSerializable {
static final LogMessageFormatter FORMATTER = (LogMessageFormatter) (GWT.isClient() ? GWT.create(
LogMessageFormatter.class) : null);
private static int gloablRecordSequence;
private transient Throwable bookmarkThrowable;
private String category;
private transient String formattedMessage;
private int level;
private HashMap<String, String> map;
private String message;
private int recordSequence;
private transient Throwable throwable;
private WrappedClientThrowable wrappedBookmarkThrowable;
private WrappedClientThrowable wrappedClientThrowable;
// For GWT serialization
@SuppressWarnings("unused")
private LogRecord() {
}
/**
* Constructor.
*
* @param category The category in which this message should be logged
* @param level the level at which this message should be logged
* @param message the message to be logged
* @param throwable the stack trace associated with this message or null
*/
public LogRecord(String category, int level, String message, Throwable throwable) {
this.category = category;
this.throwable = throwable;
recordSequence = ++gloablRecordSequence;
this.level = level;
this.message = message;
wrappedClientThrowable = WrappedClientThrowable.getInstanceOrNull(throwable);
// If no throwable provided, bookmark the current stack here
if (throwable == null) {
bookmarkThrowable = new Throwable();
wrappedBookmarkThrowable = WrappedClientThrowable.getInstanceOrNull(bookmarkThrowable);
}
}
public String getCategory() {
return category;
}
/**
* Retrieve a formatted message for this log record.
*
* @return the formatted message
*/
public String getFormattedMessage() {
assert GWT.isClient() : "Method should only be called in Client Code";
if (formattedMessage != null) {
// avoid recomputing message for each logger
return formattedMessage;
}
Throwable callerThrowable = UnwrappedClientThrowable.getInstanceOrNull(
wrappedClientThrowable != null ? wrappedClientThrowable : wrappedBookmarkThrowable);
formattedMessage = level == Log.LOG_LEVEL_OFF ? message : FORMATTER.format(
LogUtil.levelToString(level), getCategory(), message, callerThrowable);
return formattedMessage;
}
private HashMap<String, String> getHashMap() {
if (map == null) {
map = new HashMap<String, String>();
map.put("logSequence", "" + getRecordSequence());
}
return map;
}
/**
* Retrieve the log level for this log record.
*
* @return the log level
*/
public int getLevel() {
return level;
}
/**
* Retrieve the Set of key/value pairs for this log record, used for logging arbitrary data.
*
* @return the Set of key/value pairs
*/
public Set<Entry<String, String>> getMapEntrySet() {
return getHashMap().entrySet();
}
/**
* Retrieve this raw log record.
*
* @return the raw log message
*/
public String getMessage() {
return message;
}
/**
* Get the wrapped client throwable, suitable for serialization with RPC serialization code
* penalty.
*
* @return the wrapped client throwable
*/
public WrappedClientThrowable getModifiableWrappedClientThrowable() {
return wrappedClientThrowable;
}
/**
* Retrieve the global client-side or server-side sequence number for this log record.
*
* @return the global client-side or server-side sequence number
*/
public int getRecordSequence() {
return recordSequence;
}
/**
* Retrieves either the original (server side) throwable or a reconstituted client-side throwable.
*
* @return the original or reconstituted throwable
*/
public Throwable getThrowable() {
return throwable != null ? throwable : UnwrappedClientThrowable.getInstanceOrNull(
wrappedClientThrowable);
}
/**
* Set a key/value pair associated with this log record.
*
* @param key the unique key under which to store the supplied value
* @param value the value to be stored under the provided key
*/
public void set(String key, String value) {
getHashMap().put(key, value);
}
}