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 javax.annotation.Nonnull;
20 import javax.annotation.Nullable;
21 import javax.annotation.concurrent.NotThreadSafe;
22
23 import com.helger.commons.string.StringHelper;
24 import com.helger.commons.string.ToStringGenerator;
25 import com.helger.schematron.CSchematron;
26 import com.helger.schematron.CSchematronXML;
27 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
28 import com.helger.xml.microdom.IMicroElement;
29 import com.helger.xml.microdom.MicroElement;
30
31 /**
32 * A single Schematron let-element.<br>
33 * If the let element is the child of a rule element, the variable is calculated
34 * and scoped to the current rule and context. Otherwise, the variable is
35 * calculated with the context of the instance document root.<br>
36 * The required name attribute is the name of the variable. The required value
37 * attribute is an expression evaluated in the current context.<br>
38 * It is an error to reference a variable that has not been defined in the
39 * current schema, phase, pattern, or rule, if the query language binding allows
40 * this to be determined reliably. It is an error for a variable to be multiply
41 * defined in the current schema, phase, pattern and rule.<br>
42 * The variable is substituted into assertion tests and other expressions in the
43 * same rule before the test or expression is evaluated. The query language
44 * binding specifies which lexical conventions are used to detect references to
45 * variables.<br>
46 * An implementation may provide a facility to override the values of top-level
47 * variables specified by let elements under the schema element. For example, an
48 * implementation may allow top-level variables to be supplied on the command
49 * line. The values provided are strings or data objects, not expressions.
50 *
51 * @author Philip Helger
52 */
53 @NotThreadSafe
54 public class PSLet implements IPSClonableElement <PSLet>
55 {
56 private String m_sName;
57 private String m_sValue;
58
59 public PSLet ()
60 {}
61
62 public boolean isValid (@Nonnull final IPSErrorHandler aErrorHandler)
63 {
64 if (StringHelper.hasNoText (m_sName))
65 {
66 aErrorHandler.error (this, "<let> has no 'name'");
67 return false;
68 }
69 if (StringHelper.hasNoText (m_sValue))
70 {
71 aErrorHandler.error (this, "<let> has no 'value'");
72 return false;
73 }
74 return true;
75 }
76
77 public void validateCompletely (@Nonnull final IPSErrorHandler aErrorHandler)
78 {
79 if (StringHelper.hasNoText (m_sName))
80 aErrorHandler.error (this, "<let> has no 'name'");
81 if (StringHelper.hasNoText (m_sValue))
82 aErrorHandler.error (this, "<let> has no 'value'");
83 }
84
85 public boolean isMinimal ()
86 {
87 return true;
88 }
89
90 /**
91 * @param sName
92 * The name of the variable. May be <code>null</code>.
93 */
94 public void setName (@Nullable final String sName)
95 {
96 m_sName = sName;
97 }
98
99 /**
100 * @return The name of the variable. May be <code>null</code>.
101 */
102 @Nullable
103 public String getName ()
104 {
105 return m_sName;
106 }
107
108 /**
109 * @param sValue
110 * The value of the variable. May be <code>null</code>.
111 */
112 public void setValue (@Nullable final String sValue)
113 {
114 m_sValue = sValue;
115 }
116
117 /**
118 * @return The value of the variable. May be <code>null</code>.
119 */
120 @Nullable
121 public String getValue ()
122 {
123 return m_sValue;
124 }
125
126 @Nonnull
127 public IMicroElement getAsMicroElement ()
128 {
129 final IMicroElement ret = new MicroElement (CSchematron.NAMESPACE_SCHEMATRON, CSchematronXML.ELEMENT_LET);
130 ret.setAttribute (CSchematronXML.ATTR_NAME, m_sName);
131 ret.setAttribute (CSchematronXML.ATTR_VALUE, m_sValue);
132 return ret;
133 }
134
135 @Nonnull
136 public PSLet getClone ()
137 {
138 final PSLet/pure/model/PSLet.html#PSLet">PSLet ret = new PSLet ();
139 ret.setName (m_sName);
140 ret.setValue (m_sValue);
141 return ret;
142 }
143
144 @Override
145 public String toString ()
146 {
147 return new ToStringGenerator (this).appendIfNotNull ("name", m_sName)
148 .appendIfNotNull ("value", m_sValue)
149 .getToString ();
150 }
151 }