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.binding.xpath;
18  
19  import java.util.Map;
20  import java.util.TreeMap;
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.Nonempty;
28  import com.helger.commons.annotation.ReturnsMutableCopy;
29  import com.helger.commons.compare.ComparatorStringLongestFirst;
30  import com.helger.commons.state.EChange;
31  import com.helger.commons.string.StringHelper;
32  import com.helger.commons.string.ToStringGenerator;
33  
34  /**
35   * This class manages all variables present in Schematron <let> elements.
36   *
37   * @author Philip Helger
38   */
39  @NotThreadSafe
40  public class PSXPathVariables implements IPSXPathVariables
41  {
42    @Nonnull
43    @ReturnsMutableCopy
44    private static Map <String, String> _createMap ()
45    {
46      return new TreeMap <String, String> (new ComparatorStringLongestFirst ());
47    }
48  
49    private final Map <String, String> m_aMap;
50  
51    public PSXPathVariables ()
52    {
53      m_aMap = _createMap ();
54    }
55  
56    public PSXPathVariables (@Nonnull final IPSXPathVariables aOther)
57    {
58      m_aMap = aOther.getAll ();
59    }
60  
61    /**
62     * Add a new variable.
63     *
64     * @param aEntry
65     *        The entry to be added - key is the variable name and value is the
66     *        variable value. May not be <code>null</code>.
67     * @return {@link EChange#UNCHANGED} if a variable with the same name is
68     *         already present. Never <code>null</code>.
69     */
70    @Nonnull
71    public EChange add (@Nonnull final Map.Entry <String, String> aEntry)
72    {
73      return add (aEntry.getKey (), aEntry.getValue ());
74    }
75  
76    /**
77     * Add a new variable.
78     *
79     * @param sName
80     *        The name of the variable. May neither be <code>null</code> nor
81     *        empty.
82     * @param sValue
83     *        The value of the variable. May neither be <code>null</code> nor
84     *        empty.
85     * @return {@link EChange#UNCHANGED} if a variable with the same name is
86     *         already present. Never <code>null</code>.
87     */
88    @Nonnull
89    public EChange add (@Nonnull @Nonempty final String sName, @Nonnull @Nonempty final String sValue)
90    {
91      ValueEnforcer.notEmpty (sName, "Name");
92      ValueEnforcer.notEmpty (sValue, "Value");
93  
94      // Prepend the "$" prefix to the variable name
95      final String sRealName = PSXPathQueryBinding.PARAM_VARIABLE_PREFIX + sName;
96      if (m_aMap.containsKey (sRealName))
97        return EChange.UNCHANGED;
98  
99      // Apply all existing variables to this variable value!
100     final String sRealValue = getAppliedReplacement (sValue);
101     m_aMap.put (sRealName, sRealValue);
102     return EChange.CHANGED;
103   }
104 
105   /**
106    * Perform the text replacement of all variables in the specified text.
107    *
108    * @param sText
109    *        The source text. May be <code>null</code>.
110    * @return The text with all values replaced. May be <code>null</code> if the
111    *         source text is <code>null</code>.
112    */
113   @Nullable
114   public String getAppliedReplacement (@Nullable final String sText)
115   {
116     return PSXPathQueryBinding.getWithParamTextsReplacedStatic (sText, m_aMap);
117   }
118 
119   /**
120    * Remove the variable with the specified name
121    *
122    * @param sVarName
123    *        The name of the variable to be removed. May be <code>null</code>.
124    * @return {@link EChange#CHANGED} if the variable was removed successfully.
125    *         Never <code>null</code>.
126    */
127   @Nonnull
128   public EChange remove (@Nullable final String sVarName)
129   {
130     if (StringHelper.hasText (sVarName))
131       if (m_aMap.remove (PSXPathQueryBinding.PARAM_VARIABLE_PREFIX + sVarName) == null)
132         return EChange.CHANGED;
133     return EChange.UNCHANGED;
134   }
135 
136   /**
137    * Remove all variables with the specified names
138    *
139    * @param aVars
140    *        A list of variable names to be removed. May be <code>null</code>.
141    * @return {@link EChange#CHANGED} if at least one variable was removed
142    *         successfully. Never <code>null</code>.
143    */
144   @Nonnull
145   public EChange removeAll (@Nullable final Iterable <String> aVars)
146   {
147     EChange eChange = EChange.UNCHANGED;
148     if (aVars != null)
149       for (final String sName : aVars)
150         eChange = eChange.or (remove (sName));
151     return eChange;
152   }
153 
154   @Nonnull
155   @ReturnsMutableCopy
156   public Map <String, String> getAll ()
157   {
158     final Map <String, String> ret = _createMap ();
159     ret.putAll (m_aMap);
160     return ret;
161   }
162 
163   public boolean contains (@Nullable final String sName)
164   {
165     if (StringHelper.hasNoText (sName))
166       return false;
167     return m_aMap.containsKey (sName);
168   }
169 
170   @Nullable
171   public String get (@Nullable final String sName)
172   {
173     if (StringHelper.hasNoText (sName))
174       return null;
175     return m_aMap.get (sName);
176   }
177 
178   @Nonnull
179   @ReturnsMutableCopy
180   public PSXPathVariables getClone ()
181   {
182     return new PSXPathVariables (this);
183   }
184 
185   @Override
186   public String toString ()
187   {
188     return new ToStringGenerator (this).append ("map", m_aMap).toString ();
189   }
190 }