001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.status; 015 016import java.util.ArrayList; 017import java.util.Iterator; 018import java.util.List; 019 020abstract public class StatusBase implements Status { 021 022 static private final List<Status> EMPTY_LIST = new ArrayList<Status>(0); 023 024 int level; 025 final String message; 026 final Object origin; 027 List<Status> childrenList; 028 Throwable throwable; 029 long date; 030 031 StatusBase(int level, String msg, Object origin) { 032 this(level, msg, origin, null); 033 } 034 035 StatusBase(int level, String msg, Object origin, Throwable t) { 036 this.level = level; 037 this.message = msg; 038 this.origin = origin; 039 this.throwable = t; 040 this.date = System.currentTimeMillis(); 041 } 042 043 public synchronized void add(Status child) { 044 if (child == null) { 045 throw new NullPointerException("Null values are not valid Status."); 046 } 047 if (childrenList == null) { 048 childrenList = new ArrayList<Status>(); 049 } 050 childrenList.add(child); 051 } 052 053 public synchronized boolean hasChildren() { 054 return ((childrenList != null) && (childrenList.size() > 0)); 055 } 056 057 public synchronized Iterator<Status> iterator() { 058 if (childrenList != null) { 059 return childrenList.iterator(); 060 } else { 061 return EMPTY_LIST.iterator(); 062 } 063 } 064 065 public synchronized boolean remove(Status statusToRemove) { 066 if (childrenList == null) { 067 return false; 068 } 069 // TODO also search in childrens' children 070 return childrenList.remove(statusToRemove); 071 } 072 073 public int getLevel() { 074 return level; 075 } 076 077 // status messages are not supposed to contain cycles. 078 // cyclic status arrangements are like to cause deadlocks 079 // when this method is called from different thread on 080 // different status objects lying on the same cycle 081 public synchronized int getEffectiveLevel() { 082 int result = level; 083 int effLevel; 084 085 Iterator<Status> it = iterator(); 086 Status s; 087 while (it.hasNext()) { 088 s = (Status) it.next(); 089 effLevel = s.getEffectiveLevel(); 090 if (effLevel > result) { 091 result = effLevel; 092 } 093 } 094 return result; 095 } 096 097 public String getMessage() { 098 return message; 099 } 100 101 public Object getOrigin() { 102 return origin; 103 } 104 105 public Throwable getThrowable() { 106 return throwable; 107 } 108 109 public Long getDate() { 110 return date; 111 } 112 113 @Override 114 public String toString() { 115 StringBuilder buf = new StringBuilder(); 116 switch (getEffectiveLevel()) { 117 case INFO: 118 buf.append("INFO"); 119 break; 120 case WARN: 121 buf.append("WARN"); 122 break; 123 case ERROR: 124 buf.append("ERROR"); 125 break; 126 } 127 if (origin != null) { 128 buf.append(" in "); 129 buf.append(origin); 130 buf.append(" -"); 131 } 132 133 buf.append(" "); 134 buf.append(message); 135 136 if (throwable != null) { 137 buf.append(" "); 138 buf.append(throwable); 139 } 140 141 return buf.toString(); 142 } 143 144 @Override 145 public int hashCode() { 146 final int prime = 31; 147 int result = 1; 148 result = prime * result + level; 149 result = prime * result + ((message == null) ? 0 : message.hashCode()); 150 return result; 151 } 152 153 @Override 154 public boolean equals(Object obj) { 155 if (this == obj) 156 return true; 157 if (obj == null) 158 return false; 159 if (getClass() != obj.getClass()) 160 return false; 161 final StatusBase other = (StatusBase) obj; 162 if (level != other.level) 163 return false; 164 if (message == null) { 165 if (other.message != null) 166 return false; 167 } else if (!message.equals(other.message)) 168 return false; 169 return true; 170 } 171 172}