1 /*
2 * Copyright (c) 2011-2014, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include "SelectionCriterionRule.h"
31 #include "SelectionCriterion.h"
32 #include "XmlDomainSerializingContext.h"
33 #include "XmlDomainImportContext.h"
34 #include "SelectionCriteriaDefinition.h"
35 #include "SelectionCriterionTypeInterface.h"
36 #include "RuleParser.h"
37 #include <assert.h>
38
39 #define base CRule
40
41 using std::string;
42
43 const CSelectionCriterionRule::SMatchingRuleDescription CSelectionCriterionRule::_astMatchesWhen[CSelectionCriterionRule::ENbMatchesWhen] = {
44 { "Is", true },
45 { "IsNot", true },
46 { "Includes", false },
47 { "Excludes", false }
48 };
49
CSelectionCriterionRule()50 CSelectionCriterionRule::CSelectionCriterionRule() : _pSelectionCriterion(NULL), _eMatchesWhen(CSelectionCriterionRule::EIs), _iMatchValue(0)
51 {
52 }
53
54 // Class kind
getKind() const55 string CSelectionCriterionRule::getKind() const
56 {
57 return "SelectionCriterionRule";
58 }
59
60 // Content dumping
logValue(string & strValue,CErrorContext & errorContext) const61 void CSelectionCriterionRule::logValue(string& strValue, CErrorContext& errorContext) const
62 {
63 (void)errorContext;
64
65 // Dump rule
66 dump(strValue);
67 }
68
69 // Parse
parse(CRuleParser & ruleParser,string & strError)70 bool CSelectionCriterionRule::parse(CRuleParser& ruleParser, string& strError)
71 {
72 // Criterion
73 _pSelectionCriterion = ruleParser.getSelectionCriteriaDefinition()->getSelectionCriterion(ruleParser.getType());
74
75 // Check existence
76 if (!_pSelectionCriterion) {
77
78 strError = "Couldn't find selection criterion " + ruleParser.getType();
79
80 return false;
81 }
82
83 // Verb
84 string strMatchesWhen;
85
86 if (!ruleParser.next(strMatchesWhen, strError)) {
87
88 return false;
89 }
90 // Value
91 string strValue;
92
93 if (!ruleParser.next(strValue, strError)) {
94
95 return false;
96 }
97
98 // Matches when
99 if (!setMatchesWhen(strMatchesWhen, strError)) {
100
101 strError = "Verb error: " + strError;
102
103 return false;
104 }
105
106 // Value
107 if (!_pSelectionCriterion->getCriterionType()->getNumericalValue(strValue, _iMatchValue)) {
108
109 strError = "Value error: \"" + strValue + "\" is not part of criterion \"" +
110 _pSelectionCriterion->getCriterionName() + "\"";
111
112 return false;
113 }
114
115 return true;
116 }
117
118 // Dump
dump(string & strResult) const119 void CSelectionCriterionRule::dump(string& strResult) const
120 {
121 // Criterion
122 strResult += _pSelectionCriterion->getName();
123 strResult += " ";
124 // Verb
125 strResult += _astMatchesWhen[_eMatchesWhen].pcMatchesWhen;
126 strResult += " ";
127 // Value
128 string strValue;
129 _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue);
130 strResult += strValue;
131 }
132
133 // Rule check
matches() const134 bool CSelectionCriterionRule::matches() const
135 {
136 assert(_pSelectionCriterion);
137
138 switch(_eMatchesWhen) {
139 case EIs:
140 return _pSelectionCriterion->is(_iMatchValue);
141 case EIsNot:
142 return _pSelectionCriterion->isNot(_iMatchValue);
143 case EIncludes:
144 return _pSelectionCriterion->includes(_iMatchValue);
145 case EExcludes:
146 return _pSelectionCriterion->excludes(_iMatchValue);
147 default:
148 assert(0);
149 return false;
150 }
151 }
152
153 // From IXmlSink
fromXml(const CXmlElement & xmlElement,CXmlSerializingContext & serializingContext)154 bool CSelectionCriterionRule::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
155 {
156 // Retrieve actual context
157 CXmlDomainImportContext& xmlDomainImportContext = static_cast<CXmlDomainImportContext&>(serializingContext);
158
159 // Get selection criterion
160 string strSelectionCriterion = xmlElement.getAttributeString("SelectionCriterion");
161
162 _pSelectionCriterion = xmlDomainImportContext.getSelectionCriteriaDefinition()->getSelectionCriterion(strSelectionCriterion);
163
164 // Check existence
165 if (!_pSelectionCriterion) {
166
167 xmlDomainImportContext.setError("Couldn't find selection criterion " + strSelectionCriterion + " in " + getKind() + " " + xmlElement.getPath());
168
169 return false;
170 }
171
172 // Get MatchesWhen
173 string strMatchesWhen = xmlElement.getAttributeString("MatchesWhen");
174 string strError;
175
176 if (!setMatchesWhen(strMatchesWhen, strError)) {
177
178 xmlDomainImportContext.setError("Wrong MatchesWhen attribute " + strMatchesWhen + " in " + getKind() + " " + xmlElement.getPath() + ": " + strError);
179
180 return false;
181 }
182
183 // Get Value
184 string strValue = xmlElement.getAttributeString("Value");
185
186 if (!_pSelectionCriterion->getCriterionType()->getNumericalValue(strValue, _iMatchValue)) {
187
188 xmlDomainImportContext.setError("Wrong Value attribute value " + strValue + " in " + getKind() + " " + xmlElement.getPath());
189
190 return false;
191 }
192
193 // Done
194 return true;
195 }
196
197 // From IXmlSource
toXml(CXmlElement & xmlElement,CXmlSerializingContext & serializingContext) const198 void CSelectionCriterionRule::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
199 {
200 (void)serializingContext;
201
202 assert(_pSelectionCriterion);
203
204 // Set selection criterion
205 xmlElement.setAttributeString("SelectionCriterion", _pSelectionCriterion->getName());
206
207 // Set MatchesWhen
208 xmlElement.setAttributeString("MatchesWhen", _astMatchesWhen[_eMatchesWhen].pcMatchesWhen);
209
210 // Set Value
211 string strValue;
212
213 _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue);
214
215 xmlElement.setAttributeString("Value", strValue);
216 }
217
218 // XML MatchesWhen attribute parsing
setMatchesWhen(const string & strMatchesWhen,string & strError)219 bool CSelectionCriterionRule::setMatchesWhen(const string& strMatchesWhen, string& strError)
220 {
221 uint32_t uiMatchesWhen;
222
223 for (uiMatchesWhen = 0; uiMatchesWhen < ENbMatchesWhen; uiMatchesWhen++) {
224
225 const SMatchingRuleDescription* pstMatchingRuleDescription = &_astMatchesWhen[uiMatchesWhen];
226
227 if (strMatchesWhen == pstMatchingRuleDescription->pcMatchesWhen) {
228
229 // Found it!
230
231 // Get Type
232 const ISelectionCriterionTypeInterface* pSelectionCriterionType = _pSelectionCriterion->getCriterionType();
233
234 // Check compatibility if relevant
235 if (!pSelectionCriterionType->isTypeInclusive() && !pstMatchingRuleDescription->bExclusiveTypeCompatible) {
236
237 strError = "Value incompatible with exclusive kind of type";
238
239 return false;
240 }
241
242 // Store
243 _eMatchesWhen = (MatchesWhen)uiMatchesWhen;
244
245 return true;
246 }
247 }
248
249 strError = "Value not found";
250
251 return false;
252 }
253