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 50 CSelectionCriterionRule::CSelectionCriterionRule() : _pSelectionCriterion(NULL), _eMatchesWhen(CSelectionCriterionRule::EIs), _iMatchValue(0) 51 { 52 } 53 54 // Class kind 55 string CSelectionCriterionRule::getKind() const 56 { 57 return "SelectionCriterionRule"; 58 } 59 60 // Content dumping 61 void CSelectionCriterionRule::logValue(string& strValue, CErrorContext& errorContext) const 62 { 63 (void)errorContext; 64 65 // Dump rule 66 dump(strValue); 67 } 68 69 // Parse 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 119 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 134 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 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 198 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 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