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.LinkedHashMap;
20  import java.util.Map;
21  
22  import javax.annotation.Nonnull;
23  import javax.annotation.Nullable;
24  import javax.annotation.concurrent.NotThreadSafe;
25  
26  import com.helger.commons.ValueEnforcer;
27  import com.helger.commons.annotation.ReturnsMutableCopy;
28  import com.helger.commons.collection.CollectionHelper;
29  import com.helger.commons.microdom.IMicroElement;
30  import com.helger.commons.microdom.MicroElement;
31  import com.helger.commons.string.StringHelper;
32  import com.helger.commons.string.ToStringGenerator;
33  import com.helger.schematron.CSchematron;
34  import com.helger.schematron.CSchematronXML;
35  import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
36  
37  /**
38   * A single Schematron ns-element.<br>
39   * Specification of a namespace prefix and URI. The required prefix attribute is
40   * an XML name with no colon character. The required uri attribute is a
41   * namespace URI.<br>
42   * NOTE: Because the characters allowed as names may change in versions of XML
43   * subsequent to W3C XML 1.0, the ISO/IEC 19757-2 (RELAX NG Compact Syntax)
44   * schema for Schematron does not constrain the prefix to particular characters.<br>
45   * In an ISO Schematron schema, namespace prefixes in context expressions,
46   * assertion tests and other query expressions should use the namespace bindings
47   * provided by this element. Namespace prefixes should not use the namespace
48   * bindings in scope for element and attribute names.
49   *
50   * @author Philip Helger
51   */
52  @NotThreadSafe
53  public class PSNS implements IPSClonableElement <PSNS>, IPSHasForeignAttributes
54  {
55    private String m_sUri;
56    private String m_sPrefix;
57    private Map <String, String> m_aForeignAttrs;
58  
59    public PSNS ()
60    {}
61  
62    public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
63    {
64      if (StringHelper.hasNoText (m_sUri))
65      {
66        aErrorHandler.error (this, "<ns> has no 'uri'");
67        return false;
68      }
69      if (StringHelper.hasNoText (m_sPrefix))
70      {
71        aErrorHandler.error (this, "<ns> has no 'prefix'");
72        return false;
73      }
74      return true;
75    }
76  
77    public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
78    {
79      if (StringHelper.hasNoText (m_sUri))
80        aErrorHandler.error (this, "<ns> has no 'uri'");
81      if (StringHelper.hasNoText (m_sPrefix))
82        aErrorHandler.error (this, "<ns> has no 'prefix'");
83    }
84  
85    public boolean isMinimal ()
86    {
87      return true;
88    }
89  
90    public void addForeignAttribute (@Nonnull final String sAttrName, @Nonnull final String sAttrValue)
91    {
92      ValueEnforcer.notNull (sAttrName, "AttrName");
93      ValueEnforcer.notNull (sAttrValue, "AttrValue");
94      if (m_aForeignAttrs == null)
95        m_aForeignAttrs = new LinkedHashMap <String, String> ();
96      m_aForeignAttrs.put (sAttrName, sAttrValue);
97    }
98  
99    public void addForeignAttributes (@Nonnull final Map <String, String> aForeignAttrs)
100   {
101     ValueEnforcer.notNull (aForeignAttrs, "ForeignAttrs");
102     for (final Map.Entry <String, String> aEntry : aForeignAttrs.entrySet ())
103       addForeignAttribute (aEntry.getKey (), aEntry.getValue ());
104   }
105 
106   public boolean hasForeignAttributes ()
107   {
108     return m_aForeignAttrs != null && !m_aForeignAttrs.isEmpty ();
109   }
110 
111   @Nonnull
112   @ReturnsMutableCopy
113   public Map <String, String> getAllForeignAttributes ()
114   {
115     return CollectionHelper.newOrderedMap (m_aForeignAttrs);
116   }
117 
118   /**
119    * @param sUri
120    *        The namespace URI.
121    */
122   public void setUri (@Nullable final String sUri)
123   {
124     m_sUri = sUri;
125   }
126 
127   /**
128    * @return The namespace URI. May be <code>null</code>.
129    */
130   @Nullable
131   public String getUri ()
132   {
133     return m_sUri;
134   }
135 
136   /**
137    * @param sPrefix
138    *        The namespace prefix to use.
139    */
140   public void setPrefix (@Nullable final String sPrefix)
141   {
142     m_sPrefix = sPrefix;
143   }
144 
145   /**
146    * @return The namespace prefix. May be <code>null</code>.
147    */
148   @Nullable
149   public String getPrefix ()
150   {
151     return m_sPrefix;
152   }
153 
154   @Nonnull
155   public IMicroElement getAsMicroElement ()
156   {
157     final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_NS);
158     ret.setAttribute (CSchematronXML.ATTR_PREFIX, m_sPrefix);
159     ret.setAttribute (CSchematronXML.ATTR_URI, m_sUri);
160     if (m_aForeignAttrs != null)
161       for (final Map.Entry <String, String> aEntry : m_aForeignAttrs.entrySet ())
162         ret.setAttribute (aEntry.getKey (), aEntry.getValue ());
163     return ret;
164   }
165 
166   @Nonnull
167   public PSNS getClone ()
168   {
169     final PSNS ret = new PSNS ();
170     ret.setUri (m_sUri);
171     ret.setPrefix (m_sPrefix);
172     if (hasForeignAttributes ())
173       ret.addForeignAttributes (m_aForeignAttrs);
174     return ret;
175   }
176 
177   @Override
178   public String toString ()
179   {
180     return new ToStringGenerator (this).appendIfNotNull ("uri", m_sUri)
181                                        .appendIfNotNull ("prefix", m_sPrefix)
182                                        .appendIfNotEmpty ("foreignAttrs", m_aForeignAttrs)
183                                        .toString ();
184   }
185 }