1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.helger.schematron.pure.model;
18
19 import java.util.ArrayList;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.annotation.Nonnull;
25 import javax.annotation.Nullable;
26 import javax.annotation.concurrent.NotThreadSafe;
27
28 import com.helger.commons.ValueEnforcer;
29 import com.helger.commons.annotation.Nonempty;
30 import com.helger.commons.annotation.ReturnsMutableCopy;
31 import com.helger.commons.collection.CollectionHelper;
32 import com.helger.commons.microdom.IMicroElement;
33 import com.helger.commons.microdom.MicroElement;
34 import com.helger.commons.regex.RegExHelper;
35 import com.helger.commons.string.StringHelper;
36 import com.helger.commons.string.ToStringGenerator;
37 import com.helger.schematron.CSchematron;
38 import com.helger.schematron.CSchematronXML;
39 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 @NotThreadSafe
61 public class PSAssertReport implements IPSElement, IPSHasFlag, IPSHasForeignElements, IPSHasMixedContent, IPSHasID, IPSHasRichGroup, IPSHasLinkableGroup
62 {
63 private final boolean m_bIsAssert;
64 private String m_sTest;
65 private String m_sFlag;
66 private String m_sID;
67 private List <String> m_aDiagnostics;
68 private PSRichGroup m_aRich;
69 private PSLinkableGroup m_aLinkable;
70 private final List <Object> m_aContent = new ArrayList <Object> ();
71 private Map <String, String> m_aForeignAttrs;
72 private List <IMicroElement> m_aForeignElements;
73
74 public PSAssertReport (final boolean bIsAssert)
75 {
76 m_bIsAssert = bIsAssert;
77 }
78
79 public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
80 {
81 for (final Object aContent : m_aContent)
82 if (aContent instanceof IPSElement)
83 if (!((IPSElement) aContent).isValid (aErrorHandler))
84 return false;
85 if (StringHelper.hasNoText (m_sTest))
86 {
87 aErrorHandler.error (this, (m_bIsAssert ? "<assert>" : "<report>") + " has no 'test'");
88 return false;
89 }
90 return true;
91 }
92
93 public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
94 {
95 for (final Object aContent : m_aContent)
96 if (aContent instanceof IPSElement)
97 ((IPSElement) aContent).validateCompletely (aErrorHandler);
98 if (StringHelper.hasNoText (m_sTest))
99 aErrorHandler.error (this, (m_bIsAssert ? "<assert>" : "<report>") + " has no 'test'");
100 }
101
102 public boolean isMinimal ()
103 {
104 if (!m_bIsAssert)
105 return false;
106 for (final Object aContent : m_aContent)
107 if (aContent instanceof IPSElement)
108 if (!((IPSElement) aContent).isMinimal ())
109 return false;
110 return true;
111 }
112
113 public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
114 {
115 ValueEnforcer.notNull (aForeignElement, "ForeignElement");
116 if (aForeignElement.hasParent ())
117 throw new IllegalArgumentException ("ForeignElement already has a parent!");
118 if (m_aForeignElements == null)
119 m_aForeignElements = new ArrayList <IMicroElement> ();
120 m_aForeignElements.add (aForeignElement);
121 }
122
123 public void addForeignElements (@Nonnull final List <IMicroElement> aForeignElements)
124 {
125 ValueEnforcer.notNull (aForeignElements, "ForeignElements");
126 for (final IMicroElement aForeignElement : aForeignElements)
127 addForeignElement (aForeignElement);
128 }
129
130 public boolean hasForeignElements ()
131 {
132 return m_aForeignElements != null && !m_aForeignElements.isEmpty ();
133 }
134
135 @Nonnull
136 @ReturnsMutableCopy
137 public List <IMicroElement> getAllForeignElements ()
138 {
139 return CollectionHelper.newList (m_aForeignElements);
140 }
141
142 public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
143 {
144 ValueEnforcer.notNull (sAttrName, "AttrName");
145 ValueEnforcer.notNull (sAttrValue, "AttrValue");
146 if (m_aForeignAttrs == null)
147 m_aForeignAttrs = new LinkedHashMap <String, String> ();
148 m_aForeignAttrs.put (sAttrName, sAttrValue);
149 }
150
151 public void addForeignAttributes (@Nonnull final Map <String, String> aForeignAttrs)
152 {
153 ValueEnforcer.notNull (aForeignAttrs, "ForeignAttrs");
154 for (final Map.Entry <String, String> aEntry : aForeignAttrs.entrySet ())
155 addForeignAttribute (aEntry.getKey (), aEntry.getValue ());
156 }
157
158 public boolean hasForeignAttributes ()
159 {
160 return m_aForeignAttrs != null && !m_aForeignAttrs.isEmpty ();
161 }
162
163 @Nonnull
164 @ReturnsMutableCopy
165 public Map <String, String> getAllForeignAttributes ()
166 {
167 return CollectionHelper.newOrderedMap (m_aForeignAttrs);
168 }
169
170 public boolean isAssert ()
171 {
172 return m_bIsAssert;
173 }
174
175 public boolean isReport ()
176 {
177 return !m_bIsAssert;
178 }
179
180 public void setTest (@Nullable final String sTest)
181 {
182 m_sTest = sTest;
183 }
184
185 @Nullable
186 public String getTest ()
187 {
188 return m_sTest;
189 }
190
191 public void setFlag (@Nullable final String sFlag)
192 {
193 m_sFlag = sFlag;
194 }
195
196 @Nullable
197 public String getFlag ()
198 {
199 return m_sFlag;
200 }
201
202 public void setID (@Nullable final String sID)
203 {
204 m_sID = sID;
205 }
206
207 public boolean hasID ()
208 {
209 return m_sID != null;
210 }
211
212 @Nullable
213 public String getID ()
214 {
215 return m_sID;
216 }
217
218
219
220
221
222
223
224
225 public void setDiagnostics (@Nullable final String sDiagnostics)
226 {
227 if (StringHelper.hasText (sDiagnostics))
228 setDiagnostics (RegExHelper.getSplitToList (sDiagnostics.trim (), "\\s+"));
229 else
230 m_aDiagnostics = null;
231 }
232
233
234
235
236
237
238
239
240 public void setDiagnostics (@Nullable final List <String> aDiagnostics)
241 {
242 m_aDiagnostics = aDiagnostics;
243 }
244
245
246
247
248 @Nonnull
249 @ReturnsMutableCopy
250 public List <String> getAllDiagnostics ()
251 {
252 return CollectionHelper.newList (m_aDiagnostics);
253 }
254
255 public void setRich (@Nullable final PSRichGroup aRich)
256 {
257 m_aRich = aRich;
258 }
259
260 public boolean hasRich ()
261 {
262 return m_aRich != null;
263 }
264
265 @Nullable
266 public PSRichGroup getRich ()
267 {
268 return m_aRich;
269 }
270
271 @Nullable
272 public PSRichGroup getRichClone ()
273 {
274 return m_aRich == null ? null : m_aRich.getClone ();
275 }
276
277 public void setLinkable (@Nullable final PSLinkableGroup aLinkable)
278 {
279 m_aLinkable = aLinkable;
280 }
281
282 public boolean hasLinkable ()
283 {
284 return m_aLinkable != null;
285 }
286
287 @Nullable
288 public PSLinkableGroup getLinkable ()
289 {
290 return m_aLinkable;
291 }
292
293 @Nullable
294 public PSLinkableGroup getLinkableClone ()
295 {
296 return m_aLinkable == null ? null : m_aLinkable.getClone ();
297 }
298
299 public void addText (@Nonnull @Nonempty final String sText)
300 {
301 ValueEnforcer.notEmpty (sText, "Text");
302 m_aContent.add (sText);
303 }
304
305 public boolean hasAnyText ()
306 {
307 for (final Object aElement : m_aContent)
308 if (aElement instanceof String)
309 return true;
310 return false;
311 }
312
313 @Nonnull
314 @ReturnsMutableCopy
315 public List <String> getAllTexts ()
316 {
317 final List <String> ret = new ArrayList <String> ();
318 for (final Object aElement : m_aContent)
319 if (aElement instanceof String)
320 ret.add ((String) aElement);
321 return ret;
322 }
323
324 public void addName (@Nonnull final PSName aName)
325 {
326 ValueEnforcer.notNull (aName, "Name");
327 m_aContent.add (aName);
328 }
329
330 @Nonnull
331 @ReturnsMutableCopy
332 public List <PSName> getAllNames ()
333 {
334 final List <PSName> ret = new ArrayList <PSName> ();
335 for (final Object aElement : m_aContent)
336 if (aElement instanceof PSName)
337 ret.add ((PSName) aElement);
338 return ret;
339 }
340
341 public void addValueOf (@Nonnull final PSValueOf aValueOf)
342 {
343 ValueEnforcer.notNull (aValueOf, "ValueOf");
344 m_aContent.add (aValueOf);
345 }
346
347 @Nonnull
348 @ReturnsMutableCopy
349 public List <PSValueOf> getAllValueOfs ()
350 {
351 final List <PSValueOf> ret = new ArrayList <PSValueOf> ();
352 for (final Object aElement : m_aContent)
353 if (aElement instanceof PSValueOf)
354 ret.add ((PSValueOf) aElement);
355 return ret;
356 }
357
358 public void addEmph (@Nonnull final PSEmph aEmph)
359 {
360 ValueEnforcer.notNull (aEmph, "Emph");
361 m_aContent.add (aEmph);
362 }
363
364 @Nonnull
365 @ReturnsMutableCopy
366 public List <PSEmph> getAllEmphs ()
367 {
368 final List <PSEmph> ret = new ArrayList <PSEmph> ();
369 for (final Object aElement : m_aContent)
370 if (aElement instanceof PSEmph)
371 ret.add ((PSEmph) aElement);
372 return ret;
373 }
374
375 public void addDir (@Nonnull final PSDir aDir)
376 {
377 ValueEnforcer.notNull (aDir, "Dir");
378 m_aContent.add (aDir);
379 }
380
381 @Nonnull
382 @ReturnsMutableCopy
383 public List <PSDir> getAllDirs ()
384 {
385 final List <PSDir> ret = new ArrayList <PSDir> ();
386 for (final Object aElement : m_aContent)
387 if (aElement instanceof PSDir)
388 ret.add ((PSDir) aElement);
389 return ret;
390 }
391
392 public void addSpan (@Nonnull final PSSpan aSpan)
393 {
394 ValueEnforcer.notNull (aSpan, "Span");
395 m_aContent.add (aSpan);
396 }
397
398 @Nonnull
399 @ReturnsMutableCopy
400 public List <PSSpan> getAllSpans ()
401 {
402 final List <PSSpan> ret = new ArrayList <PSSpan> ();
403 for (final Object aElement : m_aContent)
404 if (aElement instanceof PSSpan)
405 ret.add ((PSSpan) aElement);
406 return ret;
407 }
408
409
410
411
412
413 @Nonnull
414 @ReturnsMutableCopy
415 public List <Object> getAllContentElements ()
416 {
417 return CollectionHelper.newList (m_aContent);
418 }
419
420 @Nonnull
421 public IMicroElement getAsMicroElement ()
422 {
423 final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON,
424 m_bIsAssert ? CSchematronXML.ELEMENT_ASSERT
425 : CSchematronXML.ELEMENT_REPORT);
426 ret.setAttribute (CSchematronXML.ATTR_ID, m_sID);
427 ret.setAttribute (CSchematronXML.ATTR_FLAG, m_sFlag);
428 ret.setAttribute (CSchematronXML.ATTR_TEST, m_sTest);
429 if (CollectionHelper.isNotEmpty (m_aDiagnostics))
430 ret.setAttribute (CSchematronXML.ATTR_DIAGNOSTICS, StringHelper.getImploded (' ', m_aDiagnostics));
431 if (m_aRich != null)
432 m_aRich.fillMicroElement (ret);
433 if (m_aLinkable != null)
434 m_aLinkable.fillMicroElement (ret);
435 if (m_aForeignElements != null)
436 for (final IMicroElement aForeignElement : m_aForeignElements)
437 ret.appendChild (aForeignElement.getClone ());
438 for (final Object aContent : m_aContent)
439 if (aContent instanceof String)
440 ret.appendText ((String) aContent);
441 else
442 ret.appendChild (((IPSElement) aContent).getAsMicroElement ());
443 if (m_aForeignAttrs != null)
444 for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
445 ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
446 return ret;
447 }
448
449 @Override
450 public String toString ()
451 {
452 return new ToStringGenerator (this).append ("isAssert", m_bIsAssert)
453 .appendIfNotNull ("test", m_sTest)
454 .appendIfNotNull ("flag", m_sFlag)
455 .appendIfNotNull ("id", m_sID)
456 .appendIfNotNull ("diagnostics", m_aDiagnostics)
457 .appendIfNotNull ("rich", m_aRich)
458 .appendIfNotNull ("linkable", m_aLinkable)
459 .appendIfNotEmpty ("content", m_aContent)
460 .appendIfNotEmpty ("foreignAttrs", m_aForeignAttrs)
461 .appendIfNotEmpty ("foreignElements", m_aForeignElements)
462 .toString ();
463 }
464 }