1 /* 2 * Copyright (C) 2005 Christian Schulte <cs@schulte.it> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * o Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * o Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 19 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $JOMC: ModelValidationReport.java 5269 2016-08-11 23:38:09Z schulte $ 29 * 30 */ 31 package org.jomc.modlet; 32 33 import java.io.Serializable; 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import java.util.List; 37 import java.util.concurrent.CopyOnWriteArrayList; 38 import java.util.logging.Level; 39 import javax.xml.bind.JAXBElement; 40 41 /** 42 * {@code Model} validation report. 43 * 44 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 45 * @version $JOMC: ModelValidationReport.java 5269 2016-08-11 23:38:09Z schulte $ 46 */ 47 public class ModelValidationReport implements Serializable 48 { 49 50 /** 51 * Report detail. 52 */ 53 public static class Detail implements Serializable 54 { 55 56 /** 57 * Serial version UID for backwards compatibility with 1.0.x object streams. 58 */ 59 private static final long serialVersionUID = -2466230076806042116L; 60 61 /** 62 * The detail identifier. 63 * 64 * @serial 65 */ 66 private final String identifier; 67 68 /** 69 * The detail level. 70 * 71 * @serial 72 */ 73 private final Level level; 74 75 /** 76 * The detail message. 77 * 78 * @serial 79 */ 80 private final String message; 81 82 /** 83 * The JAXB element this detail is associated with. 84 * 85 * @serial 86 */ 87 private final JAXBElement<?> element; 88 89 /** 90 * Creates a new {@code Detail} taking an identifier, a level, a message and an element. 91 * 92 * @param identifier The detail identifier. 93 * @param level The detail level. 94 * @param message The detail message. 95 * @param element The detail element. 96 */ 97 public Detail( final String identifier, final Level level, final String message, final JAXBElement<?> element ) 98 { 99 this.identifier = identifier; 100 this.level = level; 101 this.message = message; 102 this.element = element; 103 } 104 105 /** 106 * Gets the identifier of this detail. 107 * 108 * @return The identifier of this detail or {@code null}. 109 */ 110 public String getIdentifier() 111 { 112 return this.identifier; 113 } 114 115 /** 116 * Gets the level of this detail. 117 * 118 * @return The level of this detail or {@code null}. 119 */ 120 public Level getLevel() 121 { 122 return this.level; 123 } 124 125 /** 126 * Gets the message of this detail. 127 * 128 * @return The message of this detail or {@code null}. 129 */ 130 public String getMessage() 131 { 132 return this.message; 133 } 134 135 /** 136 * Gets the JAXB element of this detail. 137 * 138 * @return The JAXB element of this detail or {@code null}. 139 */ 140 public JAXBElement<?> getElement() 141 { 142 return this.element; 143 } 144 145 /** 146 * Creates and returns a string representation of the object. 147 * 148 * @return A string representation of the object. 149 */ 150 private String toStringInternal() 151 { 152 return new StringBuilder( 200 ).append( '{' ). 153 append( "identifier=" ).append( this.getIdentifier() ). 154 append( ", level=" ).append( this.getLevel().getLocalizedName() ). 155 append( ", message=" ).append( this.getMessage() ). 156 append( ", element=" ).append( this.getElement() ).append( '}' ).toString(); 157 158 } 159 160 /** 161 * Creates and returns a string representation of the object. 162 * 163 * @return A string representation of the object. 164 */ 165 @Override 166 public String toString() 167 { 168 return super.toString() + this.toStringInternal(); 169 } 170 171 } 172 173 /** 174 * Serial version UID for backwards compatibility with 1.0.x object streams. 175 */ 176 private static final long serialVersionUID = 6688024709865043122L; 177 178 /** 179 * Details of the instance. 180 * 181 * @serial 182 */ 183 private final List<Detail> details = new CopyOnWriteArrayList<Detail>(); 184 185 /** 186 * Creates a new {@code ModelValidationReport} instance. 187 */ 188 public ModelValidationReport() 189 { 190 super(); 191 } 192 193 /** 194 * Gets all details of the instance. 195 * <p> 196 * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make 197 * to the returned list will be present inside the object. This is why there is no {@code set} method for the 198 * details property. 199 * </p> 200 * 201 * @return All details of the instance. 202 */ 203 public List<Detail> getDetails() 204 { 205 return this.details; 206 } 207 208 /** 209 * Gets all details of the instance matching a given identifier. 210 * 211 * @param identifier The identifier of the details to return or {@code null}. 212 * 213 * @return An unmodifiable list containing all details of the instance matching {@code identifier}. 214 */ 215 public List<Detail> getDetails( final String identifier ) 216 { 217 final List<Detail> list = new ArrayList<Detail>( this.getDetails().size() ); 218 219 for ( final Detail detail : this.getDetails() ) 220 { 221 if ( identifier == null && detail.getIdentifier() == null ) 222 { 223 list.add( detail ); 224 } 225 if ( identifier != null && identifier.equals( detail.getIdentifier() ) ) 226 { 227 list.add( detail ); 228 } 229 } 230 231 return Collections.unmodifiableList( list ); 232 } 233 234 /** 235 * Gets a flag indicating model validity. 236 * 237 * @return {@code true}, if all details are set to a level lower or equal to {@code WARNING}; {@code false}, if at 238 * least one detail is set to a level higher than {@code WARNING}. 239 * 240 * @see #getDetails() 241 */ 242 public boolean isModelValid() 243 { 244 for ( final Detail detail : this.getDetails() ) 245 { 246 if ( detail.getLevel() != null && detail.getLevel().intValue() > Level.WARNING.intValue() ) 247 { 248 return false; 249 } 250 } 251 252 return true; 253 } 254 255 }