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.Map;
20
21 import javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23 import javax.annotation.concurrent.NotThreadSafe;
24
25 import com.helger.commons.ValueEnforcer;
26 import com.helger.commons.annotation.Nonempty;
27 import com.helger.commons.annotation.ReturnsMutableCopy;
28 import com.helger.commons.collection.CollectionHelper;
29 import com.helger.commons.collection.ext.CommonsArrayList;
30 import com.helger.commons.collection.ext.CommonsLinkedHashMap;
31 import com.helger.commons.collection.ext.ICommonsList;
32 import com.helger.commons.collection.ext.ICommonsOrderedMap;
33 import com.helger.commons.string.StringHelper;
34 import com.helger.commons.string.ToStringGenerator;
35 import com.helger.schematron.CSchematron;
36 import com.helger.schematron.CSchematronXML;
37 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
38 import com.helger.xml.microdom.IMicroElement;
39 import com.helger.xml.microdom.MicroElement;
40
41
42
43
44
45
46
47
48
49 @NotThreadSafe
50 public class PSSpan implements IPSClonableElement <PSSpan>, IPSOptionalElement, IPSHasForeignElements, IPSHasTexts
51 {
52 private String m_sClass;
53 private final ICommonsList <String> m_aContent = new CommonsArrayList <> ();
54 private ICommonsOrderedMap <String, String> m_aForeignAttrs;
55 private ICommonsList <IMicroElement> m_aForeignElements;
56
57 public PSSpan ()
58 {}
59
60 public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
61 {
62 if (StringHelper.hasNoText (m_sClass))
63 {
64 aErrorHandler.error (this, "<span> has no 'class'");
65 return false;
66 }
67 if (m_aContent.isEmpty ())
68 {
69 aErrorHandler.error (this, "<span> has no content");
70 return false;
71 }
72 return true;
73 }
74
75 public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
76 {
77 if (StringHelper.hasNoText (m_sClass))
78 aErrorHandler.error (this, "<span> has no 'class'");
79 if (m_aContent.isEmpty ())
80 aErrorHandler.error (this, "<span> has no content");
81 }
82
83 public boolean isMinimal ()
84 {
85 return true;
86 }
87
88 public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
89 {
90 ValueEnforcer.notNull (aForeignElement, "ForeignElement");
91 if (aForeignElement.hasParent ())
92 throw new IllegalArgumentException ("ForeignElement already has a parent!");
93 if (m_aForeignElements == null)
94 m_aForeignElements = new CommonsArrayList <> ();
95 m_aForeignElements.add (aForeignElement);
96 }
97
98 public boolean hasForeignElements ()
99 {
100 return m_aForeignElements != null && m_aForeignElements.isNotEmpty ();
101 }
102
103 @Nonnull
104 @ReturnsMutableCopy
105 public ICommonsList <IMicroElement> getAllForeignElements ()
106 {
107 return new CommonsArrayList <> (m_aForeignElements);
108 }
109
110 public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
111 {
112 ValueEnforcer.notNull (sAttrName, "AttrName");
113 ValueEnforcer.notNull (sAttrValue, "AttrValue");
114 if (m_aForeignAttrs == null)
115 m_aForeignAttrs = new CommonsLinkedHashMap <> ();
116 m_aForeignAttrs.put (sAttrName, sAttrValue);
117 }
118
119 public boolean hasForeignAttributes ()
120 {
121 return m_aForeignAttrs != null && m_aForeignAttrs.isNotEmpty ();
122 }
123
124 @Nonnull
125 @ReturnsMutableCopy
126 public ICommonsOrderedMap <String, String> getAllForeignAttributes ()
127 {
128 return new CommonsLinkedHashMap <> (m_aForeignAttrs);
129 }
130
131 public void setClazz (@Nullable final String sClass)
132 {
133 m_sClass = sClass;
134 }
135
136 @Nullable
137 public String getClazz ()
138 {
139 return m_sClass;
140 }
141
142 public void addText (@Nonnull @Nonempty final String sText)
143 {
144 ValueEnforcer.notEmpty (sText, "Text");
145 m_aContent.add (sText);
146 }
147
148 public boolean hasAnyText ()
149 {
150 return m_aContent.isNotEmpty ();
151 }
152
153 @Nonnull
154 @ReturnsMutableCopy
155 public ICommonsList <String> getAllTexts ()
156 {
157 return m_aContent.getClone ();
158 }
159
160 @Nullable
161 public String getAsText ()
162 {
163 return StringHelper.getImploded (m_aContent);
164 }
165
166 @Nonnull
167 public IMicroElement getAsMicroElement ()
168 {
169 final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_SPAN);
170 ret.setAttribute (CSchematronXML.ATTR_CLASS, m_sClass);
171 if (m_aForeignElements != null)
172 for (final IMicroElement aForeignElement : m_aForeignElements)
173 ret.appendChild (aForeignElement.getClone ());
174 for (final String sContent : m_aContent)
175 ret.appendText (sContent);
176 if (m_aForeignAttrs != null)
177 for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
178 ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
179 return ret;
180 }
181
182 @Nonnull
183 public PSSpan getClone ()
184 {
185 final PSSpan ret = new PSSpan ();
186 ret.setClazz (m_sClass);
187 for (final String sContent : m_aContent)
188 ret.addText (sContent);
189 if (hasForeignElements ())
190 ret.addForeignElements (m_aForeignElements);
191 if (hasForeignAttributes ())
192 ret.addForeignAttributes (m_aForeignAttrs);
193 return ret;
194 }
195
196 @Override
197 public String toString ()
198 {
199 return new ToStringGenerator (this).appendIfNotNull ("class", m_sClass)
200 .appendIf ("content", m_aContent, CollectionHelper::isNotEmpty)
201 .appendIf ("foreignAttrs", m_aForeignAttrs, CollectionHelper::isNotEmpty)
202 .appendIf ("foreignElements", m_aForeignElements, CollectionHelper::isNotEmpty)
203 .toString ();
204 }
205 }