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.string.StringHelper;
35 import com.helger.commons.string.ToStringGenerator;
36 import com.helger.schematron.CSchematron;
37 import com.helger.schematron.CSchematronXML;
38 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 @NotThreadSafe
54 public class PSDiagnostic implements IPSClonableElement <PSDiagnostic>, IPSOptionalElement, IPSHasID, IPSHasForeignElements, IPSHasMixedContent, IPSHasRichGroup
55 {
56 private String m_sID;
57 private PSRichGroup m_aRich;
58 private final List <Object> m_aContent = new ArrayList <Object> ();
59 private Map <String, String> m_aForeignAttrs;
60 private List <IMicroElement> m_aForeignElements;
61
62 public PSDiagnostic ()
63 {}
64
65 public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
66 {
67 for (final Object aContent : m_aContent)
68 if (aContent instanceof IPSElement)
69 if (!((IPSElement) aContent).isValid (aErrorHandler))
70 return false;
71 if (StringHelper.hasNoText (m_sID))
72 {
73 aErrorHandler.error (this, "<diagnostic> has no 'id'");
74 return false;
75 }
76 return true;
77 }
78
79 public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
80 {
81 for (final Object aContent : m_aContent)
82 if (aContent instanceof IPSElement)
83 ((IPSElement) aContent).validateCompletely (aErrorHandler);
84 if (StringHelper.hasNoText (m_sID))
85 aErrorHandler.error (this, "<diagnostic> has no 'id'");
86 }
87
88 public boolean isMinimal ()
89 {
90 return false;
91 }
92
93 public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
94 {
95 ValueEnforcer.notNull (aForeignElement, "ForeignElement");
96 if (aForeignElement.hasParent ())
97 throw new IllegalArgumentException ("ForeignElement already has a parent!");
98 if (m_aForeignElements == null)
99 m_aForeignElements = new ArrayList <IMicroElement> ();
100 m_aForeignElements.add (aForeignElement);
101 }
102
103 public void addForeignElements (@Nonnull final List <IMicroElement> aForeignElements)
104 {
105 ValueEnforcer.notNull (aForeignElements, "ForeignElements");
106 for (final IMicroElement aForeignElement : aForeignElements)
107 addForeignElement (aForeignElement);
108 }
109
110 public boolean hasForeignElements ()
111 {
112 return m_aForeignElements != null && !m_aForeignElements.isEmpty ();
113 }
114
115 @Nonnull
116 @ReturnsMutableCopy
117 public List <IMicroElement> getAllForeignElements ()
118 {
119 return CollectionHelper.newList (m_aForeignElements);
120 }
121
122 public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
123 {
124 ValueEnforcer.notNull (sAttrName, "AttrName");
125 ValueEnforcer.notNull (sAttrValue, "AttrValue");
126 if (m_aForeignAttrs == null)
127 m_aForeignAttrs = new LinkedHashMap <String, String> ();
128 m_aForeignAttrs.put (sAttrName, sAttrValue);
129 }
130
131 public void addForeignAttributes (@Nonnull final Map <String, String> aForeignAttrs)
132 {
133 ValueEnforcer.notNull (aForeignAttrs, "ForeignAttrs");
134 for (final Map.Entry <String, String> aEntry : aForeignAttrs.entrySet ())
135 addForeignAttribute (aEntry.getKey (), aEntry.getValue ());
136 }
137
138 public boolean hasForeignAttributes ()
139 {
140 return m_aForeignAttrs != null && !m_aForeignAttrs.isEmpty ();
141 }
142
143 @Nonnull
144 @ReturnsMutableCopy
145 public Map <String, String> getAllForeignAttributes ()
146 {
147 return CollectionHelper.newOrderedMap (m_aForeignAttrs);
148 }
149
150 public void setID (@Nullable final String sID)
151 {
152 m_sID = sID;
153 }
154
155 public boolean hasID ()
156 {
157 return m_sID != null;
158 }
159
160 @Nullable
161 public String getID ()
162 {
163 return m_sID;
164 }
165
166 public void setRich (@Nullable final PSRichGroup aRich)
167 {
168 m_aRich = aRich;
169 }
170
171 public boolean hasRich ()
172 {
173 return m_aRich != null;
174 }
175
176 @Nullable
177 public PSRichGroup getRich ()
178 {
179 return m_aRich;
180 }
181
182 @Nullable
183 public PSRichGroup getRichClone ()
184 {
185 return m_aRich == null ? null : m_aRich.getClone ();
186 }
187
188 public void addText (@Nonnull @Nonempty final String sText)
189 {
190 ValueEnforcer.notEmpty (sText, "Text");
191 m_aContent.add (sText);
192 }
193
194 public boolean hasAnyText ()
195 {
196 for (final Object aElement : m_aContent)
197 if (aElement instanceof String)
198 return true;
199 return false;
200 }
201
202 @Nonnull
203 @ReturnsMutableCopy
204 public List <String> getAllTexts ()
205 {
206 final List <String> ret = new ArrayList <String> ();
207 for (final Object aElement : m_aContent)
208 if (aElement instanceof String)
209 ret.add ((String) aElement);
210 return ret;
211 }
212
213 public void addValueOf (@Nonnull final PSValueOf aValueOf)
214 {
215 ValueEnforcer.notNull (aValueOf, "ValueOf");
216 m_aContent.add (aValueOf);
217 }
218
219 @Nonnull
220 @ReturnsMutableCopy
221 public List <PSValueOf> getAllValueOfs ()
222 {
223 final List <PSValueOf> ret = new ArrayList <PSValueOf> ();
224 for (final Object aElement : m_aContent)
225 if (aElement instanceof PSValueOf)
226 ret.add ((PSValueOf) aElement);
227 return ret;
228 }
229
230 public void addEmph (@Nonnull final PSEmph aEmph)
231 {
232 ValueEnforcer.notNull (aEmph, "Emph");
233 m_aContent.add (aEmph);
234 }
235
236 @Nonnull
237 @ReturnsMutableCopy
238 public List <PSEmph> getAllEmphs ()
239 {
240 final List <PSEmph> ret = new ArrayList <PSEmph> ();
241 for (final Object aElement : m_aContent)
242 if (aElement instanceof PSEmph)
243 ret.add ((PSEmph) aElement);
244 return ret;
245 }
246
247 public void addDir (@Nonnull final PSDir aDir)
248 {
249 ValueEnforcer.notNull (aDir, "Dir");
250 m_aContent.add (aDir);
251 }
252
253 @Nonnull
254 @ReturnsMutableCopy
255 public List <PSDir> getAllDirs ()
256 {
257 final List <PSDir> ret = new ArrayList <PSDir> ();
258 for (final Object aElement : m_aContent)
259 if (aElement instanceof PSDir)
260 ret.add ((PSDir) aElement);
261 return ret;
262 }
263
264 public void addSpan (@Nonnull final PSSpan aSpan)
265 {
266 ValueEnforcer.notNull (aSpan, "Span");
267 m_aContent.add (aSpan);
268 }
269
270 @Nonnull
271 @ReturnsMutableCopy
272 public List <PSSpan> getAllSpans ()
273 {
274 final List <PSSpan> ret = new ArrayList <PSSpan> ();
275 for (final Object aElement : m_aContent)
276 if (aElement instanceof PSSpan)
277 ret.add ((PSSpan) aElement);
278 return ret;
279 }
280
281
282
283
284
285 @Nonnull
286 @ReturnsMutableCopy
287 public List <Object> getAllContentElements ()
288 {
289 return CollectionHelper.newList (m_aContent);
290 }
291
292 @Nonnull
293 public IMicroElement getAsMicroElement ()
294 {
295 final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_DIAGNOSTIC);
296 ret.setAttribute (CSchematronXML.ATTR_ID, m_sID);
297 if (m_aRich != null)
298 m_aRich.fillMicroElement (ret);
299 if (m_aForeignElements != null)
300 for (final IMicroElement aForeignElement : m_aForeignElements)
301 ret.appendChild (aForeignElement.getClone ());
302 for (final Object aContent : m_aContent)
303 if (aContent instanceof String)
304 ret.appendText ((String) aContent);
305 else
306 ret.appendChild (((IPSElement) aContent).getAsMicroElement ());
307 if (m_aForeignAttrs != null)
308 for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
309 ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
310 return ret;
311 }
312
313 @Nonnull
314 public PSDiagnostic getClone ()
315 {
316 final PSDiagnostic ret = new PSDiagnostic ();
317 ret.setID (m_sID);
318 ret.setRich (getRichClone ());
319 for (final Object aContent : m_aContent)
320 {
321 if (aContent instanceof String)
322 ret.addText ((String) aContent);
323 else
324 if (aContent instanceof PSValueOf)
325 ret.addValueOf (((PSValueOf) aContent).getClone ());
326 else
327 if (aContent instanceof PSEmph)
328 ret.addEmph (((PSEmph) aContent).getClone ());
329 else
330 if (aContent instanceof PSDir)
331 ret.addDir (((PSDir) aContent).getClone ());
332 else
333 if (aContent instanceof PSSpan)
334 ret.addSpan (((PSSpan) aContent).getClone ());
335 }
336 if (hasForeignElements ())
337 ret.addForeignElements (m_aForeignElements);
338 if (hasForeignAttributes ())
339 ret.addForeignAttributes (m_aForeignAttrs);
340 return ret;
341 }
342
343 @Override
344 public String toString ()
345 {
346 return new ToStringGenerator (this).appendIfNotNull ("id", m_sID)
347 .appendIfNotNull ("rich", m_aRich)
348 .appendIfNotEmpty ("content", m_aContent)
349 .appendIfNotEmpty ("foreignAttrs", m_aForeignAttrs)
350 .appendIfNotEmpty ("foreignElements", m_aForeignElements)
351 .toString ();
352 }
353 }