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 @NotThreadSafe
49 public class PSSpan implements IPSClonableElement <PSSpan>, IPSOptionalElement, IPSHasForeignElements, IPSHasTexts
50 {
51 private String m_sClass;
52 private final List <String> m_aContent = new ArrayList <String> ();
53 private Map <String, String> m_aForeignAttrs;
54 private List <IMicroElement> m_aForeignElements;
55
56 public PSSpan ()
57 {}
58
59 public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
60 {
61 if (StringHelper.hasNoText (m_sClass))
62 {
63 aErrorHandler.error (this, "<span> has no 'class'");
64 return false;
65 }
66 if (m_aContent.isEmpty ())
67 {
68 aErrorHandler.error (this, "<span> has no content");
69 return false;
70 }
71 return true;
72 }
73
74 public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
75 {
76 if (StringHelper.hasNoText (m_sClass))
77 aErrorHandler.error (this, "<span> has no 'class'");
78 if (m_aContent.isEmpty ())
79 aErrorHandler.error (this, "<span> has no content");
80 }
81
82 public boolean isMinimal ()
83 {
84 return true;
85 }
86
87 public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
88 {
89 ValueEnforcer.notNull (aForeignElement, "ForeignElement");
90 if (aForeignElement.hasParent ())
91 throw new IllegalArgumentException ("ForeignElement already has a parent!");
92 if (m_aForeignElements == null)
93 m_aForeignElements = new ArrayList <IMicroElement> ();
94 m_aForeignElements.add (aForeignElement);
95 }
96
97 public void addForeignElements (@Nonnull final List <IMicroElement> aForeignElements)
98 {
99 ValueEnforcer.notNull (aForeignElements, "ForeignElements");
100 for (final IMicroElement aForeignElement : aForeignElements)
101 addForeignElement (aForeignElement);
102 }
103
104 public boolean hasForeignElements ()
105 {
106 return m_aForeignElements != null && !m_aForeignElements.isEmpty ();
107 }
108
109 @Nonnull
110 @ReturnsMutableCopy
111 public List <IMicroElement> getAllForeignElements ()
112 {
113 return CollectionHelper.newList (m_aForeignElements);
114 }
115
116 public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
117 {
118 ValueEnforcer.notNull (sAttrName, "AttrName");
119 ValueEnforcer.notNull (sAttrValue, "AttrValue");
120 if (m_aForeignAttrs == null)
121 m_aForeignAttrs = new LinkedHashMap <String, String> ();
122 m_aForeignAttrs.put (sAttrName, sAttrValue);
123 }
124
125 public void addForeignAttributes (@Nonnull final Map <String, String> aForeignAttrs)
126 {
127 ValueEnforcer.notNull (aForeignAttrs, "ForeignAttrs");
128 for (final Map.Entry <String, String> aEntry : aForeignAttrs.entrySet ())
129 addForeignAttribute (aEntry.getKey (), aEntry.getValue ());
130 }
131
132 public boolean hasForeignAttributes ()
133 {
134 return m_aForeignAttrs != null && !m_aForeignAttrs.isEmpty ();
135 }
136
137 @Nonnull
138 @ReturnsMutableCopy
139 public Map <String, String> getAllForeignAttributes ()
140 {
141 return CollectionHelper.newOrderedMap (m_aForeignAttrs);
142 }
143
144 public void setClazz (@Nullable final String sClass)
145 {
146 m_sClass = sClass;
147 }
148
149 @Nullable
150 public String getClazz ()
151 {
152 return m_sClass;
153 }
154
155 public void addText (@Nonnull @Nonempty final String sText)
156 {
157 ValueEnforcer.notEmpty (sText, "Text");
158 m_aContent.add (sText);
159 }
160
161 public boolean hasAnyText ()
162 {
163 return !m_aContent.isEmpty ();
164 }
165
166 @Nonnull
167 @ReturnsMutableCopy
168 public List <String> getAllTexts ()
169 {
170 return CollectionHelper.newList (m_aContent);
171 }
172
173 @Nullable
174 public String getAsText ()
175 {
176 return StringHelper.getImploded (m_aContent);
177 }
178
179 @Nonnull
180 public IMicroElement getAsMicroElement ()
181 {
182 final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_SPAN);
183 ret.setAttribute (CSchematronXML.ATTR_CLASS, m_sClass);
184 if (m_aForeignElements != null)
185 for (final IMicroElement aForeignElement : m_aForeignElements)
186 ret.appendChild (aForeignElement.getClone ());
187 for (final String sContent : m_aContent)
188 ret.appendText (sContent);
189 if (m_aForeignAttrs != null)
190 for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
191 ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
192 return ret;
193 }
194
195 @Nonnull
196 public PSSpan getClone ()
197 {
198 final PSSpan ret = new PSSpan ();
199 ret.setClazz (m_sClass);
200 for (final String sContent : m_aContent)
201 ret.addText (sContent);
202 if (hasForeignElements ())
203 ret.addForeignElements (m_aForeignElements);
204 if (hasForeignAttributes ())
205 ret.addForeignAttributes (m_aForeignAttrs);
206 return ret;
207 }
208
209 @Override
210 public String toString ()
211 {
212 return new ToStringGenerator (this).appendIfNotNull ("class", m_sClass)
213 .appendIfNotEmpty ("content", m_aContent)
214 .appendIfNotEmpty ("foreignAttrs", m_aForeignAttrs)
215 .appendIfNotEmpty ("foreignElements", m_aForeignElements)
216 .toString ();
217 }
218 }