/** * Copyright 2008-2009 Dan Pritchett * * 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 org.addsimplicity.anicetus.entity; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; /** * GlobalInfo serves as the base object for all telemetry artifacts. Telemetry * artifacts are maps that have type safe helper methods for setting and * accessing properties. The map interface is preserved however to allow * applications to add any arbitrary information to the telemetry object without * having to extend it. * * This class will always set the entity identifier to a random UUID and the * timestamp to the current time in milliseconds. * * @author Dan Pritchett (driveawedge@yahoo.com) * */ public abstract class GlobalInfo implements Map<String, Object> { private final Map<String, Object> m_delegateMap = new HashMap<String, Object>(); /** * Construct a telemetry artifact without a parent. */ protected GlobalInfo() { init(); } /** * Construct a telemetry object as a child of the specified parent. If the * parent implements TelemetryContainer, this object will be added as a child. * Note that any object can serve as a parent from a closure perspective, * which means that in the telemetry stream this object will refer to the * parent object by GUID, regardless of whether the parent can contain this * object in the Java structure. * * @param parent * The parent of this object. */ protected GlobalInfo(GlobalInfo parent) { init(); setParentId(parent.getEntityId()); if (parent instanceof TelemetryContainer) { ((TelemetryContainer) parent).addChild(this); } } /** * Clear all entries in the map. * * @see java.util.Map#clear() */ public void clear() { m_delegateMap.clear(); } /** * * @see java.util.Map#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { return m_delegateMap.containsKey(key); } /** * * @see java.util.Map#containsValue(java.lang.Object) */ public boolean containsValue(Object value) { return m_delegateMap.containsValue(value); } /** * * @see java.util.Map#entrySet() */ public Set<Entry<String, Object>> entrySet() { return m_delegateMap.entrySet(); } /** * Equality is defined as entityId equivalence. * * @return true for two objects with the same entityId property. */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (this.getClass() != o.getClass()) { return false; } GlobalInfo other = (GlobalInfo) o; return get(GlobalInfoFields.EntityId.name()).equals(other.get(GlobalInfoFields.EntityId.name())); } /** * * @see java.util.Map#get(java.lang.Object) */ public Object get(Object key) { return m_delegateMap.get(key); } /** * Return the entity identifier for this artifact. Entity identifiers are * typically generated using the random UUID method. * * @return the entity identifier. * @see java.util.UUID#randomUUID() */ public UUID getEntityId() { return (UUID) get(GlobalInfoFields.EntityId.name()); } /** * Return the execution context. The execution context is typically defined as * the process and thread where this artifact was created. * * @return the execution context. */ public String getExecutionContext() { return (String) get(GlobalInfoFields.ExecutionContext.name()); } /** * Return the message associated with the artifact. Artifacts support an * optional message string that may be set by the application. * * @return the message. */ public String getMessage() { return (String) get(GlobalInfoFields.Message.name()); } /** * Return the entity id of the parent of this artifact. * * @return the parent entity identifier or null if this artifact has no * parent. */ public UUID getParentId() { return (UUID) get(GlobalInfoFields.ParentId.name()); } /** * Return the node where this artifact was created. This is typically a host * name or IP address. * * @return the reporting node. */ public String getReportingNode() { return (String) get(GlobalInfoFields.ReportingNode.name()); } /** * Return the time stamp when this artifact was created. This is the number of * milliseconds since January 1, 1970 00:00:00 GMT. * * @return the creation time stamp. */ public long getTimeStamp() { return (Long) get(GlobalInfoFields.TimeStamp.name()); } /** * The hash code is implemented as the entity identifier hash code. * * @see java.util.UUID#hashCode() */ @Override public int hashCode() { return ((UUID) get(GlobalInfoFields.EntityId.name())).hashCode(); } /** * @see java.util.Map#isEmpty() */ public boolean isEmpty() { return m_delegateMap.isEmpty(); } /** * @see java.util.Map#keySet() */ public Set<String> keySet() { return m_delegateMap.keySet(); } /** * @see java.util.Map#put(java.lang.Object, java.lang.Object) */ public Object put(String key, Object value) { return m_delegateMap.put(key, value); } /** * @see java.util.Map#putAll(java.util.Map) */ public void putAll(Map<? extends String, ? extends Object> t) { m_delegateMap.putAll(t); } /** * @see java.util.Map#remove(java.lang.Object) */ public Object remove(Object key) { return m_delegateMap.remove(key); } /** * Set the entity identifier for this artifact. This value is automatically * set when new artifacts are created. This method is primarily used for * deserializing existing streams. * * @param id * The GUID to be used as the entity identifer. */ public void setEntityId(UUID id) { put(GlobalInfoFields.EntityId.name(), id); } /** * Set the message to the formatted exception. The exception is converted to a * string, including the stack trace and set as the message. * * @param exception * The exception to format. * @see java.lang.Throwable#printStackTrace() */ public void setExceptionAsMessage(Throwable exception) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); exception.printStackTrace(pw); pw.close(); sw.flush(); setMessage(sw.toString()); } /** * Set the execution context for this artifact. This is typically the process * identifer and optionally the thread identifier. * * @param context * The execution context. */ public void setExecutionContext(String context) { put(GlobalInfoFields.ExecutionContext.name(), context); } /** * Set a message on this artifact. Messages are application defined text * related to the artifact. * * @param message * The message. */ public void setMessage(String message) { put(GlobalInfoFields.Message.name(), message); } /** * Set the GUID of the parent of this artifact. * * @param parent * The parent entity identifier. */ public void setParentId(UUID parent) { put(GlobalInfoFields.ParentId.name(), parent); } /** * Set the reporting node where this artifact is created. This is typically * the host name or IP address. * * @param node * The reporting node identifier. */ public void setReportingNode(String node) { put(GlobalInfoFields.ReportingNode.name(), node); } /** * Set the time stamp when this artifact was created. The time stamp is set * automatically when an artifact is created. This method is primarily for * deserializing previously created artifacts. Time stamps are expressed as * the number of milliseconds since January 1, 1970 00:00:00 GMT. * * @param timeStamp * The time stamp when the artifact was created. * @see java.lang.System#currentTimeMillis() */ public void setTimeStamp(long timeStamp) { put(GlobalInfoFields.TimeStamp.name(), timeStamp); } /** * @see java.util.Map#size() */ public int size() { return m_delegateMap.size(); } /** * @see java.util.Map#values() */ public Collection<Object> values() { return m_delegateMap.values(); } private void init() { put(GlobalInfoFields.EntityId.name(), UUID.randomUUID()); put(GlobalInfoFields.TimeStamp.name(), System.currentTimeMillis()); } }