View Javadoc
1   /**
2    * Copyright (C) 2014-2015 Philip Helger (www.helger.com)
3    * philip[at]helger[dot]com
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *         http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * A single Schematron p-element.<br>
42   * A paragraph of natural language text containing maintainer and user
43   * information about the parent element. The schema can nominate paragraphs that
44   * should be rendered in a distinct way, keyed with the class attribute.<br>
45   * An implementation is not required to make use of this element.
46   *
47   * @author Philip Helger
48   */
49  @NotThreadSafe
50  public class PSP implements IPSElement, IPSOptionalElement, IPSHasForeignElements, IPSHasMixedContent, IPSHasID
51  {
52    private String m_sID;
53    private String m_sClass;
54    private String m_sIcon;
55    private final List <Object> m_aContent = new ArrayList <Object> ();
56    private Map <String, String> m_aForeignAttrs;
57    private List <IMicroElement> m_aForeignElements;
58  
59    public PSP ()
60    {}
61  
62    public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
63    {
64      for (final Object aContent : m_aContent)
65        if (aContent instanceof IPSElement)
66          if (!((IPSElement) aContent).isValid (aErrorHandler))
67            return false;
68      return true;
69    }
70  
71    public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
72    {
73      for (final Object aContent : m_aContent)
74        if (aContent instanceof IPSElement)
75          ((IPSElement) aContent).validateCompletely (aErrorHandler);
76    }
77  
78    public boolean isMinimal ()
79    {
80      return false;
81    }
82  
83    public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
84    {
85      ValueEnforcer.notNull (aForeignElement, "ForeignElement");
86      if (aForeignElement.hasParent ())
87        throw new IllegalArgumentException ("ForeignElement already has a parent!");
88      if (m_aForeignElements == null)
89        m_aForeignElements = new ArrayList <IMicroElement> ();
90      m_aForeignElements.add (aForeignElement);
91    }
92  
93    public void addForeignElements (@Nonnull final List <IMicroElement> aForeignElements)
94    {
95      ValueEnforcer.notNull (aForeignElements, "ForeignElements");
96      for (final IMicroElement aForeignElement : aForeignElements)
97        addForeignElement (aForeignElement);
98    }
99  
100   public boolean hasForeignElements ()
101   {
102     return m_aForeignElements != null && !m_aForeignElements.isEmpty ();
103   }
104 
105   @Nonnull
106   @ReturnsMutableCopy
107   public List <IMicroElement> getAllForeignElements ()
108   {
109     return CollectionHelper.newList (m_aForeignElements);
110   }
111 
112   public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
113   {
114     ValueEnforcer.notNull (sAttrName, "AttrName");
115     ValueEnforcer.notNull (sAttrValue, "AttrValue");
116     if (m_aForeignAttrs == null)
117       m_aForeignAttrs = new LinkedHashMap <String, String> ();
118     m_aForeignAttrs.put (sAttrName, sAttrValue);
119   }
120 
121   public void addForeignAttributes (@Nonnull final Map <String, String> aForeignAttrs)
122   {
123     ValueEnforcer.notNull (aForeignAttrs, "ForeignAttrs");
124     for (final Map.Entry <String, String> aEntry : aForeignAttrs.entrySet ())
125       addForeignAttribute (aEntry.getKey (), aEntry.getValue ());
126   }
127 
128   public boolean hasForeignAttributes ()
129   {
130     return m_aForeignAttrs != null && !m_aForeignAttrs.isEmpty ();
131   }
132 
133   @Nonnull
134   @ReturnsMutableCopy
135   public Map <String, String> getAllForeignAttributes ()
136   {
137     return CollectionHelper.newOrderedMap (m_aForeignAttrs);
138   }
139 
140   public void setID (@Nullable final String sID)
141   {
142     m_sID = sID;
143   }
144 
145   public boolean hasID ()
146   {
147     return m_sID != null;
148   }
149 
150   @Nullable
151   public String getID ()
152   {
153     return m_sID;
154   }
155 
156   public void setClazz (@Nullable final String sClass)
157   {
158     m_sClass = sClass;
159   }
160 
161   @Nullable
162   public String getClazz ()
163   {
164     return m_sClass;
165   }
166 
167   public void setIcon (@Nullable final String sIcon)
168   {
169     m_sIcon = sIcon;
170   }
171 
172   @Nullable
173   public String getIcon ()
174   {
175     return m_sIcon;
176   }
177 
178   public void addText (@Nonnull @Nonempty final String sText)
179   {
180     ValueEnforcer.notEmpty (sText, "Text");
181     m_aContent.add (sText);
182   }
183 
184   public boolean hasAnyText ()
185   {
186     for (final Object aElement : m_aContent)
187       if (aElement instanceof String)
188         return true;
189     return false;
190   }
191 
192   @Nonnull
193   @ReturnsMutableCopy
194   public List <String> getAllTexts ()
195   {
196     final List <String> ret = new ArrayList <String> ();
197     for (final Object aElement : m_aContent)
198       if (aElement instanceof String)
199         ret.add ((String) aElement);
200     return ret;
201   }
202 
203   @Nullable
204   public String getText ()
205   {
206     return StringHelper.getImploded ("", m_aContent);
207   }
208 
209   public void addDir (@Nonnull final PSDir aDir)
210   {
211     ValueEnforcer.notNull (aDir, "Dir");
212     m_aContent.add (aDir);
213   }
214 
215   @Nonnull
216   @ReturnsMutableCopy
217   public List <PSDir> getAllDirs ()
218   {
219     final List <PSDir> ret = new ArrayList <PSDir> ();
220     for (final Object aElement : m_aContent)
221       if (aElement instanceof PSDir)
222         ret.add ((PSDir) aElement);
223     return ret;
224   }
225 
226   public void addEmph (@Nonnull final PSEmph aEmph)
227   {
228     if (aEmph == null)
229       throw new NullPointerException ("Emph");
230     m_aContent.add (aEmph);
231   }
232 
233   @Nonnull
234   @ReturnsMutableCopy
235   public List <PSEmph> getAllEmphs ()
236   {
237     final List <PSEmph> ret = new ArrayList <PSEmph> ();
238     for (final Object aElement : m_aContent)
239       if (aElement instanceof PSEmph)
240         ret.add ((PSEmph) aElement);
241     return ret;
242   }
243 
244   public void addSpan (@Nonnull final PSSpan aSpan)
245   {
246     ValueEnforcer.notNull (aSpan, "Span");
247     m_aContent.add (aSpan);
248   }
249 
250   @Nonnull
251   @ReturnsMutableCopy
252   public List <PSSpan> getAllSpans ()
253   {
254     final List <PSSpan> ret = new ArrayList <PSSpan> ();
255     for (final Object aElement : m_aContent)
256       if (aElement instanceof PSSpan)
257         ret.add ((PSSpan) aElement);
258     return ret;
259   }
260 
261   /**
262    * @return A list of {@link String}, {@link PSDir}, {@link PSEmph} and
263    *         {@link PSSpan} elements.
264    */
265   @Nonnull
266   @ReturnsMutableCopy
267   public List <Object> getAllContentElements ()
268   {
269     return CollectionHelper.newList (m_aContent);
270   }
271 
272   @Nonnull
273   public IMicroElement getAsMicroElement ()
274   {
275     final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_P);
276     ret.setAttribute (CSchematronXML.ATTR_ID, m_sID);
277     ret.setAttribute (CSchematronXML.ATTR_CLASS, m_sClass);
278     ret.setAttribute (CSchematronXML.ATTR_ICON, m_sIcon);
279     if (m_aForeignElements != null)
280       for (final IMicroElement aForeignElement : m_aForeignElements)
281         ret.appendChild (aForeignElement.getClone ());
282     for (final Object aContent : m_aContent)
283       if (aContent instanceof String)
284         ret.appendText ((String) aContent);
285       else
286         ret.appendChild (((IPSElement) aContent).getAsMicroElement ());
287     if (m_aForeignAttrs != null)
288       for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
289         ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
290     return ret;
291   }
292 
293   @Override
294   public String toString ()
295   {
296     return new ToStringGenerator (this).appendIfNotNull ("id", m_sID)
297                                        .appendIfNotNull ("class", m_sClass)
298                                        .appendIfNotNull ("icon", m_sIcon)
299                                        .appendIfNotEmpty ("content", m_aContent)
300                                        .appendIfNotEmpty ("foreignAttrs", m_aForeignAttrs)
301                                        .appendIfNotEmpty ("foreignElements", m_aForeignElements)
302                                        .toString ();
303   }
304 }