View Javadoc
1   /**
2    * Copyright (C) 2014-2016 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.ReturnsMutableCopy;
27  import com.helger.commons.collection.CollectionHelper;
28  import com.helger.commons.collection.ext.CommonsLinkedHashMap;
29  import com.helger.commons.collection.ext.ICommonsOrderedMap;
30  import com.helger.commons.string.StringHelper;
31  import com.helger.commons.string.ToStringGenerator;
32  import com.helger.schematron.CSchematron;
33  import com.helger.schematron.CSchematronXML;
34  import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
35  import com.helger.xml.microdom.IMicroElement;
36  import com.helger.xml.microdom.MicroElement;
37  
38  /**
39   * A single Schematron value-of-element.<br>
40   * Finds or calculates values from the instance document to allow clearer
41   * assertions and diagnostics. The required select attribute is an expression
42   * evaluated in the current context that returns a string.<br>
43   * Variable references in the select attribute are resolved in the scope of the
44   * current schema, phase, pattern and rule.<br>
45   * An implementation which does not report natural-language assertions is not
46   * required to make use of this element.
47   *
48   * @author Philip Helger
49   */
50  @NotThreadSafe
51  public class PSValueOf implements IPSClonableElement <PSValueOf>, IPSHasForeignAttributes
52  {
53    private String m_sSelect;
54    private ICommonsOrderedMap <String, String> m_aForeignAttrs;
55  
56    public PSValueOf ()
57    {}
58  
59    public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
60    {
61      if (StringHelper.hasNoText (m_sSelect))
62      {
63        aErrorHandler.error (this, "<value-of> has no 'select'");
64        return false;
65      }
66      return true;
67    }
68  
69    public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
70    {
71      if (StringHelper.hasNoText (m_sSelect))
72        aErrorHandler.error (this, "<value-of> has no 'select'");
73    }
74  
75    public boolean isMinimal ()
76    {
77      return true;
78    }
79  
80    public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
81    {
82      ValueEnforcer.notNull (sAttrName, "AttrName");
83      ValueEnforcer.notNull (sAttrValue, "AttrValue");
84      if (m_aForeignAttrs == null)
85        m_aForeignAttrs = new CommonsLinkedHashMap <> ();
86      m_aForeignAttrs.put (sAttrName, sAttrValue);
87    }
88  
89    public boolean hasForeignAttributes ()
90    {
91      return m_aForeignAttrs != null && m_aForeignAttrs.isNotEmpty ();
92    }
93  
94    @Nonnull
95    @ReturnsMutableCopy
96    public ICommonsOrderedMap <String, String> getAllForeignAttributes ()
97    {
98      return new CommonsLinkedHashMap <> (m_aForeignAttrs);
99    }
100 
101   /**
102    * Set the expression to retrieve the value of
103    *
104    * @param sSelect
105    *        The select expression string. May be <code>null</code>.
106    */
107   public void setSelect (@Nullable final String sSelect)
108   {
109     m_sSelect = sSelect;
110   }
111 
112   /**
113    * @return The select expression string. May be <code>null</code>.
114    */
115   @Nullable
116   public String getSelect ()
117   {
118     return m_sSelect;
119   }
120 
121   @Nonnull
122   public IMicroElement getAsMicroElement ()
123   {
124     final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_VALUE_OF);
125     ret.setAttribute (CSchematronXML.ATTR_SELECT, m_sSelect);
126     if (m_aForeignAttrs != null)
127       for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
128         ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
129     return ret;
130   }
131 
132   @Nonnull
133   public PSValueOf getClone ()
134   {
135     final PSValueOf ret = new PSValueOf ();
136     ret.setSelect (m_sSelect);
137     if (hasForeignAttributes ())
138       ret.addForeignAttributes (m_aForeignAttrs);
139     return ret;
140   }
141 
142   @Override
143   public String toString ()
144   {
145     return new ToStringGenerator (this).appendIfNotNull ("select", m_sSelect)
146                                        .appendIf ("foreignAttrs", m_aForeignAttrs, CollectionHelper::isNotEmpty)
147                                        .toString ();
148   }
149 }