001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.collection; 017 018import org.modeshape.common.annotation.Immutable; 019import org.modeshape.common.i18n.I18n; 020import org.modeshape.common.logging.Logger; 021import org.modeshape.common.util.CheckArg; 022import org.modeshape.common.util.HashCode; 023 024/** 025 * An immutable representation of a problem, with a status, code, internationalized and parameterized message, values for the 026 * parameters, information about the resource and location, and an optional exception. The use of internationalized messages 027 * allows for automatic localization of the messages (and substitution of the parameter values) via the 028 * {@link #getMessageString()} method. 029 */ 030@Immutable 031public class Problem { 032 033 public static final int DEFAULT_CODE = 0; 034 035 public enum Status { 036 ERROR, 037 WARNING, 038 INFO; 039 040 public Logger.Level getLogLevel() { 041 switch (this) { 042 case ERROR: 043 return Logger.Level.ERROR; 044 case WARNING: 045 return Logger.Level.WARNING; 046 case INFO: 047 default: 048 return Logger.Level.INFO; 049 } 050 } 051 } 052 053 private final Status status; 054 private final I18n message; 055 private final Object[] parameters; 056 private final Throwable throwable; 057 private final int code; 058 private final String resource; 059 private final String location; 060 061 public Problem( Status status, 062 int code, 063 I18n message, 064 Object[] params, 065 String resource, 066 String location, 067 Throwable throwable ) { 068 CheckArg.isNotNull(status, "status"); 069 CheckArg.isNotNull(message, "message"); 070 this.status = status; 071 this.code = code; 072 this.message = message; 073 this.parameters = params; 074 this.resource = resource != null ? resource.trim() : null; 075 this.location = location != null ? location.trim() : null; 076 this.throwable = throwable; 077 } 078 079 public int getCode() { 080 return this.code; 081 } 082 083 public String getLocation() { 084 return this.location; 085 } 086 087 /** 088 * Get the message written in the current locale. 089 * 090 * @return the message 091 */ 092 public String getMessageString() { 093 return this.message.text(this.parameters); 094 } 095 096 public I18n getMessage() { 097 return this.message; 098 } 099 100 public Object[] getParameters() { 101 return this.parameters; 102 } 103 104 public String getResource() { 105 return this.resource; 106 } 107 108 public Status getStatus() { 109 return this.status; 110 } 111 112 public Throwable getThrowable() { 113 return this.throwable; 114 } 115 116 @Override 117 public int hashCode() { 118 return HashCode.compute(status, code, message, resource, location); 119 } 120 121 @Override 122 public boolean equals( Object obj ) { 123 if (obj == this) return true; 124 if (obj instanceof Problem) { 125 Problem that = (Problem)obj; 126 if (this.getStatus() != that.getStatus()) return false; 127 if (this.getCode() != that.getCode()) return false; 128 if (!this.getMessage().equals(that.getMessage())) return false; 129 if (!this.getParameters().equals(that.getParameters())) return false; 130 131 String thisResource = this.getResource(); 132 String thatResource = that.getResource(); 133 if (thisResource != thatResource) { 134 if (thisResource == null || !thisResource.equals(thatResource)) return false; 135 } 136 137 String thisLocation = this.getLocation(); 138 String thatLocation = that.getLocation(); 139 if (thisLocation != thatLocation) { 140 if (thisLocation == null || !thisLocation.equals(thatLocation)) return false; 141 } 142 143 Throwable thisThrowable = this.getThrowable(); 144 Throwable thatThrowable = that.getThrowable(); 145 if (thisThrowable != thatThrowable) { 146 if (thisThrowable == null || !thisThrowable.equals(thatThrowable)) return false; 147 } 148 return true; 149 } 150 return false; 151 } 152 153 @Override 154 public String toString() { 155 StringBuilder sb = new StringBuilder(); 156 sb.append(this.getStatus()).append(": "); 157 if (this.getCode() != DEFAULT_CODE) { 158 sb.append("(").append(this.getCode()).append(") "); 159 } 160 sb.append(this.getMessageString()); 161 if (this.getResource() != null) { 162 sb.append(" Resource=\"").append(this.getResource()).append("\""); 163 } 164 if (this.getLocation() != null) { 165 sb.append(" At \"").append(this.getLocation()).append("\""); 166 } 167 if (this.getThrowable() != null) { 168 sb.append(" (threw ").append(this.getThrowable().getLocalizedMessage()).append(")"); 169 } 170 return sb.toString(); 171 } 172 173}