View Javadoc
1   /**
2    * Copyright (C) 2014-2018 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.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.impl.CommonsArrayList;
30  import com.helger.commons.collection.impl.CommonsLinkedHashMap;
31  import com.helger.commons.collection.impl.ICommonsList;
32  import com.helger.commons.collection.impl.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   * A single Schematron p-element.<br>
43   * A paragraph of natural language text containing maintainer and user
44   * information about the parent element. The schema can nominate paragraphs that
45   * should be rendered in a distinct way, keyed with the class attribute.<br>
46   * An implementation is not required to make use of this element.
47   *
48   * @author Philip Helger
49   */
50  @NotThreadSafe
51  public class PSP implements IPSElement, IPSOptionalElement, IPSHasForeignElements, IPSHasMixedContent, IPSHasID
52  {
53    private String m_sID;
54    private String m_sClass;
55    private String m_sIcon;
56    private final ICommonsList <Object> m_aContent = new CommonsArrayList <> ();
57    private ICommonsOrderedMap <String, String> m_aForeignAttrs;
58    private ICommonsList <IMicroElement> m_aForeignElements;
59  
60    public PSP ()
61    {}
62  
63    public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
64    {
65      for (final Object aContent : m_aContent)
66        if (aContent instanceof IPSElement)
67          if (!((IPSElement) aContent).isValid (aErrorHandler))
68            return false;
69      return true;
70    }
71  
72    public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
73    {
74      for (final Object aContent : m_aContent)
75        if (aContent instanceof IPSElement)
76          ((IPSElement) aContent).validateCompletely (aErrorHandler);
77    }
78  
79    public boolean isMinimal ()
80    {
81      return false;
82    }
83  
84    public void addForeignElement (@Nonnull final IMicroElement aForeignElement)
85    {
86      ValueEnforcer.notNull (aForeignElement, "ForeignElement");
87      if (aForeignElement.hasParent ())
88        throw new IllegalArgumentException ("ForeignElement already has a parent!");
89      if (m_aForeignElements == null)
90        m_aForeignElements = new CommonsArrayList <> ();
91      m_aForeignElements.add (aForeignElement);
92    }
93  
94    public boolean hasForeignElements ()
95    {
96      return m_aForeignElements != null && m_aForeignElements.isNotEmpty ();
97    }
98  
99    @Nonnull
100   @ReturnsMutableCopy
101   public ICommonsList <IMicroElement> getAllForeignElements ()
102   {
103     return new CommonsArrayList <> (m_aForeignElements);
104   }
105 
106   public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
107   {
108     ValueEnforcer.notNull (sAttrName, "AttrName");
109     ValueEnforcer.notNull (sAttrValue, "AttrValue");
110     if (m_aForeignAttrs == null)
111       m_aForeignAttrs = new CommonsLinkedHashMap <> ();
112     m_aForeignAttrs.put (sAttrName, sAttrValue);
113   }
114 
115   public boolean hasForeignAttributes ()
116   {
117     return m_aForeignAttrs != null && m_aForeignAttrs.isNotEmpty ();
118   }
119 
120   @Nonnull
121   @ReturnsMutableCopy
122   public ICommonsOrderedMap <String, String> getAllForeignAttributes ()
123   {
124     return new CommonsLinkedHashMap <> (m_aForeignAttrs);
125   }
126 
127   public void setID (@Nullable final String sID)
128   {
129     m_sID = sID;
130   }
131 
132   @Nullable
133   public String getID ()
134   {
135     return m_sID;
136   }
137 
138   public void setClazz (@Nullable final String sClass)
139   {
140     m_sClass = sClass;
141   }
142 
143   @Nullable
144   public String getClazz ()
145   {
146     return m_sClass;
147   }
148 
149   public void setIcon (@Nullable final String sIcon)
150   {
151     m_sIcon = sIcon;
152   }
153 
154   @Nullable
155   public String getIcon ()
156   {
157     return m_sIcon;
158   }
159 
160   public void addText (@Nonnull @Nonempty final String sText)
161   {
162     ValueEnforcer.notEmpty (sText, "Text");
163     m_aContent.add (sText);
164   }
165 
166   public boolean hasAnyText ()
167   {
168     return m_aContent.containsAny (e -> e instanceof String);
169   }
170 
171   @Nonnull
172   @ReturnsMutableCopy
173   public ICommonsList <String> getAllTexts ()
174   {
175     return m_aContent.getAllInstanceOf (String.class);
176   }
177 
178   @Nullable
179   public String getText ()
180   {
181     return StringHelper.getImploded (m_aContent);
182   }
183 
184   public void addDir (@Nonnull final PSDir aDir)
185   {
186     ValueEnforcer.notNull (aDir, "Dir");
187     m_aContent.add (aDir);
188   }
189 
190   @Nonnull
191   @ReturnsMutableCopy
192   public ICommonsList <PSDir> getAllDirs ()
193   {
194     return m_aContent.getAllInstanceOf (PSDir.class);
195   }
196 
197   public void addEmph (@Nonnull final PSEmph aEmph)
198   {
199     ValueEnforcer.notNull (aEmph, "Emph");
200     m_aContent.add (aEmph);
201   }
202 
203   @Nonnull
204   @ReturnsMutableCopy
205   public ICommonsList <PSEmph> getAllEmphs ()
206   {
207     return m_aContent.getAllInstanceOf (PSEmph.class);
208   }
209 
210   public void addSpan (@Nonnull final PSSpan aSpan)
211   {
212     ValueEnforcer.notNull (aSpan, "Span");
213     m_aContent.add (aSpan);
214   }
215 
216   @Nonnull
217   @ReturnsMutableCopy
218   public ICommonsList <PSSpan> getAllSpans ()
219   {
220     return m_aContent.getAllInstanceOf (PSSpan.class);
221   }
222 
223   /**
224    * @return A list of {@link String}, {@link PSDir}, {@link PSEmph} and
225    *         {@link PSSpan} elements.
226    */
227   @Nonnull
228   @ReturnsMutableCopy
229   public ICommonsList <Object> getAllContentElements ()
230   {
231     return m_aContent.getClone ();
232   }
233 
234   @Nonnull
235   public IMicroElement getAsMicroElement ()
236   {
237     final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_P);
238     ret.setAttribute (CSchematronXML.ATTR_ID, m_sID);
239     ret.setAttribute (CSchematronXML.ATTR_CLASS, m_sClass);
240     ret.setAttribute (CSchematronXML.ATTR_ICON, m_sIcon);
241     if (m_aForeignElements != null)
242       for (final IMicroElement aForeignElement : m_aForeignElements)
243         ret.appendChild (aForeignElement.getClone ());
244     for (final Object aContent : m_aContent)
245       if (aContent instanceof String)
246         ret.appendText ((String) aContent);
247       else
248         ret.appendChild (((IPSElement) aContent).getAsMicroElement ());
249     if (m_aForeignAttrs != null)
250       for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
251         ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
252     return ret;
253   }
254 
255   @Override
256   public String toString ()
257   {
258     return new ToStringGenerator (this).appendIfNotNull ("id", m_sID)
259                                        .appendIfNotNull ("class", m_sClass)
260                                        .appendIfNotNull ("icon", m_sIcon)
261                                        .appendIf ("content", m_aContent, CollectionHelper::isNotEmpty)
262                                        .appendIf ("foreignAttrs", m_aForeignAttrs, CollectionHelper::isNotEmpty)
263                                        .appendIf ("foreignElements", m_aForeignElements, CollectionHelper::isNotEmpty)
264                                        .getToString ();
265   }
266 }