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 }