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 java.util.Collections; 019import java.util.EnumSet; 020import java.util.Iterator; 021import java.util.List; 022import org.modeshape.common.collection.Problem.Status; 023import org.modeshape.common.function.Consumer; 024import org.modeshape.common.i18n.I18n; 025import org.modeshape.common.logging.Logger; 026import org.modeshape.common.logging.Logger.Level; 027 028/** 029 * A list of problems for some execution context. The problems will be {@link #iterator() returned} in the order in which they 030 * were encountered (although this cannot be guaranteed in contexts involving multiple threads or processes). 031 */ 032public abstract class AbstractProblems implements Problems { 033 private static final long serialVersionUID = 1L; 034 035 protected static final List<Problem> EMPTY_PROBLEMS = Collections.emptyList(); 036 037 @Override 038 public void addError( I18n message, 039 Object... params ) { 040 addProblem(new Problem(Problem.Status.ERROR, Problem.DEFAULT_CODE, message, params, null, null, null)); 041 } 042 043 @Override 044 public void addError( Throwable throwable, 045 I18n message, 046 Object... params ) { 047 addProblem(new Problem(Problem.Status.ERROR, Problem.DEFAULT_CODE, message, params, null, null, throwable)); 048 } 049 050 @Override 051 public void addError( String resource, 052 String location, 053 I18n message, 054 Object... params ) { 055 addProblem(new Problem(Problem.Status.ERROR, Problem.DEFAULT_CODE, message, params, resource, location, null)); 056 } 057 058 @Override 059 public void addError( Throwable throwable, 060 String resource, 061 String location, 062 I18n message, 063 Object... params ) { 064 addProblem(new Problem(Problem.Status.ERROR, Problem.DEFAULT_CODE, message, params, resource, location, throwable)); 065 } 066 067 @Override 068 public void addError( int code, 069 I18n message, 070 Object... params ) { 071 addProblem(new Problem(Problem.Status.ERROR, code, message, params, null, null, null)); 072 } 073 074 @Override 075 public void addError( Throwable throwable, 076 int code, 077 I18n message, 078 Object... params ) { 079 addProblem(new Problem(Problem.Status.ERROR, code, message, params, null, null, throwable)); 080 } 081 082 @Override 083 public void addError( int code, 084 String resource, 085 String location, 086 I18n message, 087 Object... params ) { 088 addProblem(new Problem(Problem.Status.ERROR, code, message, params, resource, location, null)); 089 } 090 091 @Override 092 public void addError( Throwable throwable, 093 int code, 094 String resource, 095 String location, 096 I18n message, 097 Object... params ) { 098 addProblem(new Problem(Problem.Status.ERROR, code, message, params, resource, location, throwable)); 099 } 100 101 @Override 102 public void addWarning( I18n message, 103 Object... params ) { 104 addProblem(new Problem(Problem.Status.WARNING, Problem.DEFAULT_CODE, message, params, null, null, null)); 105 } 106 107 @Override 108 public void addWarning( Throwable throwable, 109 I18n message, 110 Object... params ) { 111 addProblem(new Problem(Problem.Status.WARNING, Problem.DEFAULT_CODE, message, params, null, null, throwable)); 112 } 113 114 @Override 115 public void addWarning( String resource, 116 String location, 117 I18n message, 118 Object... params ) { 119 addProblem(new Problem(Problem.Status.WARNING, Problem.DEFAULT_CODE, message, params, resource, location, null)); 120 } 121 122 @Override 123 public void addWarning( Throwable throwable, 124 String resource, 125 String location, 126 I18n message, 127 Object... params ) { 128 addProblem(new Problem(Problem.Status.WARNING, Problem.DEFAULT_CODE, message, params, resource, location, throwable)); 129 } 130 131 @Override 132 public void addWarning( int code, 133 I18n message, 134 Object... params ) { 135 addProblem(new Problem(Problem.Status.WARNING, code, message, params, null, null, null)); 136 } 137 138 @Override 139 public void addWarning( Throwable throwable, 140 int code, 141 I18n message, 142 Object... params ) { 143 addProblem(new Problem(Problem.Status.WARNING, code, message, params, null, null, throwable)); 144 } 145 146 @Override 147 public void addWarning( int code, 148 String resource, 149 String location, 150 I18n message, 151 Object... params ) { 152 addProblem(new Problem(Problem.Status.WARNING, code, message, params, resource, location, null)); 153 } 154 155 @Override 156 public void addWarning( Throwable throwable, 157 int code, 158 String resource, 159 String location, 160 I18n message, 161 Object... params ) { 162 addProblem(new Problem(Problem.Status.WARNING, code, message, params, resource, location, throwable)); 163 } 164 165 @Override 166 public void addInfo( I18n message, 167 Object... params ) { 168 addProblem(new Problem(Problem.Status.INFO, Problem.DEFAULT_CODE, message, params, null, null, null)); 169 } 170 171 @Override 172 public void addInfo( Throwable throwable, 173 I18n message, 174 Object... params ) { 175 addProblem(new Problem(Problem.Status.INFO, Problem.DEFAULT_CODE, message, params, null, null, throwable)); 176 } 177 178 @Override 179 public void addInfo( String resource, 180 String location, 181 I18n message, 182 Object... params ) { 183 addProblem(new Problem(Problem.Status.INFO, Problem.DEFAULT_CODE, message, params, resource, location, null)); 184 } 185 186 @Override 187 public void addInfo( Throwable throwable, 188 String resource, 189 String location, 190 I18n message, 191 Object... params ) { 192 addProblem(new Problem(Problem.Status.INFO, Problem.DEFAULT_CODE, message, params, resource, location, throwable)); 193 } 194 195 @Override 196 public void addInfo( int code, 197 I18n message, 198 Object... params ) { 199 addProblem(new Problem(Problem.Status.INFO, code, message, params, null, null, null)); 200 } 201 202 @Override 203 public void addInfo( Throwable throwable, 204 int code, 205 I18n message, 206 Object... params ) { 207 addProblem(new Problem(Problem.Status.INFO, code, message, params, null, null, throwable)); 208 } 209 210 @Override 211 public void addInfo( int code, 212 String resource, 213 String location, 214 I18n message, 215 Object... params ) { 216 addProblem(new Problem(Problem.Status.INFO, code, message, params, resource, location, null)); 217 } 218 219 @Override 220 public void addInfo( Throwable throwable, 221 int code, 222 String resource, 223 String location, 224 I18n message, 225 Object... params ) { 226 addProblem(new Problem(Problem.Status.INFO, code, message, params, resource, location, throwable)); 227 } 228 229 @Override 230 public boolean hasProblems() { 231 return getProblems().size() > 0; 232 } 233 234 @Override 235 public boolean hasErrors() { 236 for (Problem problem : this.getProblems()) { 237 if (problem.getStatus() == Problem.Status.ERROR) return true; 238 } 239 return false; 240 } 241 242 @Override 243 public boolean hasWarnings() { 244 for (Problem problem : this.getProblems()) { 245 if (problem.getStatus() == Problem.Status.WARNING) return true; 246 } 247 return false; 248 } 249 250 @Override 251 public boolean hasInfo() { 252 for (Problem problem : this.getProblems()) { 253 if (problem.getStatus() == Problem.Status.INFO) return true; 254 } 255 return false; 256 } 257 258 @Override 259 public boolean isEmpty() { 260 return getProblems().isEmpty(); 261 } 262 263 @Override 264 public int errorCount() { 265 int count = 0; 266 for (Problem problem : getProblems()) { 267 if (problem.getStatus() == Problem.Status.ERROR) ++count; 268 } 269 return count; 270 } 271 272 @Override 273 public int problemCount() { 274 return getProblems().size(); 275 } 276 277 @Override 278 public int warningCount() { 279 int count = 0; 280 for (Problem problem : getProblems()) { 281 if (problem.getStatus() == Problem.Status.WARNING) ++count; 282 } 283 return count; 284 } 285 286 @Override 287 public int infoCount() { 288 int count = 0; 289 for (Problem problem : getProblems()) { 290 if (problem.getStatus() == Problem.Status.INFO) ++count; 291 } 292 return count; 293 } 294 295 @Override 296 public int size() { 297 return getProblems().size(); 298 } 299 300 @Override 301 public Iterator<Problem> iterator() { 302 return getProblems().iterator(); 303 } 304 305 protected abstract void addProblem( Problem problem ); 306 307 protected abstract List<Problem> getProblems(); 308 309 @Override 310 public void writeTo( Logger logger ) { 311 if (hasProblems()) { 312 for (Problem problem : this) { 313 Level level = logLevelFor(problem.getStatus()); 314 logger.log(level, problem.getMessage(), problem.getParameters()); 315 } 316 } 317 } 318 319 @Override 320 public void writeTo( Logger logger, 321 Status firstStatus, 322 Status... additionalStatuses ) { 323 EnumSet<Status> stats = EnumSet.of(firstStatus, additionalStatuses); 324 if (hasProblems()) { 325 for (Problem problem : this) { 326 Status status = problem.getStatus(); 327 if (!stats.contains(status)) continue; 328 Level level = logLevelFor(status); 329 logger.log(level, problem.getMessage(), problem.getParameters()); 330 } 331 } 332 } 333 334 protected final Level logLevelFor( Status status ) { 335 switch (status) { 336 case ERROR: 337 return Level.ERROR; 338 case WARNING: 339 return Level.WARNING; 340 case INFO: 341 return Level.INFO; 342 } 343 assert false : "Should not happen"; 344 return Level.INFO; 345 } 346 347 @Override 348 public void apply( Consumer<Problem> consumer ) { 349 if (consumer != null) { 350 for (Problem problem : getProblems()) { 351 if (problem != null) consumer.accept(problem); 352 } 353 } 354 } 355 356 @Override 357 public void apply( Status status, 358 Consumer<Problem> consumer ) { 359 if (status != null && consumer != null) { 360 for (Problem problem : getProblems()) { 361 if (problem != null && problem.getStatus() == status) consumer.accept(problem); 362 } 363 } 364 } 365 366 @Override 367 public void apply( EnumSet<Status> statuses, 368 Consumer<Problem> consumer ) { 369 if (statuses != null && consumer != null) { 370 for (Problem problem : getProblems()) { 371 if (problem != null && statuses.contains(problem.getStatus())) consumer.accept(problem); 372 } 373 } 374 } 375 376 @Override 377 public String toString() { 378 final StringBuilder sb = new StringBuilder(); 379 final Consumer<Problem> consumer = new Consumer<Problem>() { 380 private boolean first = true; 381 382 @Override 383 public void accept( Problem problem ) { 384 if (first) first = false; 385 else sb.append("\n"); 386 sb.append(problem); 387 } 388 }; 389 // Do these in this order, not all at once ... 390 apply(Status.ERROR, consumer); 391 apply(Status.WARNING, consumer); 392 apply(Status.INFO, consumer); 393 return sb.toString(); 394 } 395}