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 44 CSelectionCriterionRule::_astMatchesWhen[CSelectionCriterionRule::ENbMatchesWhen] = { 45 {"Is", true}, {"IsNot", true}, {"Includes", false}, {"Excludes", false}}; 46 47 // Class kind 48 string CSelectionCriterionRule::getKind() const 49 { 50 return "SelectionCriterionRule"; 51 } 52 53 // Content dumping 54 string CSelectionCriterionRule::logValue(utility::ErrorContext & /*cxt*/) const 55 { 56 // Dump rule 57 return dump(); 58 } 59 60 // Parse 61 bool CSelectionCriterionRule::parse(CRuleParser &ruleParser, string &strError) 62 { 63 // Criterion 64 _pSelectionCriterion = 65 ruleParser.getSelectionCriteriaDefinition()->getSelectionCriterion(ruleParser.getType()); 66 67 // Check existence 68 if (!_pSelectionCriterion) { 69 70 strError = "Couldn't find selection criterion " + ruleParser.getType(); 71 72 return false; 73 } 74 75 // Verb 76 string strMatchesWhen; 77 78 if (!ruleParser.next(strMatchesWhen, strError)) { 79 80 return false; 81 } 82 // Value 83 string strValue; 84 85 if (!ruleParser.next(strValue, strError)) { 86 87 return false; 88 } 89 90 // Matches when 91 if (!setMatchesWhen(strMatchesWhen, strError)) { 92 93 strError = "Verb error: " + strError; 94 95 return false; 96 } 97 98 // Value 99 if (!_pSelectionCriterion->getCriterionType()->getNumericalValue(strValue, _iMatchValue)) { 100 101 strError = "Value error: \"" + strValue + "\" is not part of criterion \"" + 102 _pSelectionCriterion->getCriterionName() + "\""; 103 104 return false; 105 } 106 107 return true; 108 } 109 110 // Dump 111 string CSelectionCriterionRule::dump() const 112 { 113 // Value 114 string value; 115 _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, value); 116 117 // "<Name> <Verb> <Value>" 118 return string(_pSelectionCriterion->getName()) + " " + 119 _astMatchesWhen[_eMatchesWhen].pcMatchesWhen + " " + value; 120 } 121 122 // Rule check 123 bool CSelectionCriterionRule::matches() const 124 { 125 assert(_pSelectionCriterion); 126 127 switch (_eMatchesWhen) { 128 case EIs: 129 return _pSelectionCriterion->is(_iMatchValue); 130 case EIsNot: 131 return _pSelectionCriterion->isNot(_iMatchValue); 132 case EIncludes: 133 return _pSelectionCriterion->includes(_iMatchValue); 134 case EExcludes: 135 return _pSelectionCriterion->excludes(_iMatchValue); 136 default: 137 assert(0); 138 return false; 139 } 140 } 141 142 // From IXmlSink 143 bool CSelectionCriterionRule::fromXml(const CXmlElement &xmlElement, 144 CXmlSerializingContext &serializingContext) 145 { 146 // Retrieve actual context 147 CXmlDomainImportContext &xmlDomainImportContext = 148 static_cast<CXmlDomainImportContext &>(serializingContext); 149 150 // Get selection criterion 151 string strSelectionCriterion; 152 xmlElement.getAttribute("SelectionCriterion", strSelectionCriterion); 153 154 _pSelectionCriterion = 155 xmlDomainImportContext.getSelectionCriteriaDefinition()->getSelectionCriterion( 156 strSelectionCriterion); 157 158 // Check existence 159 if (!_pSelectionCriterion) { 160 161 xmlDomainImportContext.setError("Couldn't find selection criterion " + 162 strSelectionCriterion + " in " + getKind() + " " + 163 xmlElement.getPath()); 164 165 return false; 166 } 167 168 // Get MatchesWhen 169 string strMatchesWhen; 170 xmlElement.getAttribute("MatchesWhen", strMatchesWhen); 171 string strError; 172 173 if (!setMatchesWhen(strMatchesWhen, strError)) { 174 175 xmlDomainImportContext.setError("Wrong MatchesWhen attribute " + strMatchesWhen + " in " + 176 getKind() + " " + xmlElement.getPath() + ": " + strError); 177 178 return false; 179 } 180 181 // Get Value 182 string strValue; 183 xmlElement.getAttribute("Value", strValue); 184 185 if (!_pSelectionCriterion->getCriterionType()->getNumericalValue(strValue, _iMatchValue)) { 186 187 xmlDomainImportContext.setError("Wrong Value attribute value " + strValue + " in " + 188 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 & /*ctx*/) const 199 { 200 assert(_pSelectionCriterion); 201 202 // Set selection criterion 203 xmlElement.setAttribute("SelectionCriterion", _pSelectionCriterion->getName()); 204 205 // Set MatchesWhen 206 xmlElement.setAttribute("MatchesWhen", _astMatchesWhen[_eMatchesWhen].pcMatchesWhen); 207 208 // Set Value 209 string strValue; 210 211 _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue); 212 213 xmlElement.setAttribute("Value", strValue); 214 } 215 216 // XML MatchesWhen attribute parsing 217 bool CSelectionCriterionRule::setMatchesWhen(const string &strMatchesWhen, string &strError) 218 { 219 for (size_t matchesWhen = 0; matchesWhen < ENbMatchesWhen; matchesWhen++) { 220 221 const SMatchingRuleDescription *pstMatchingRuleDescription = &_astMatchesWhen[matchesWhen]; 222 223 if (strMatchesWhen == pstMatchingRuleDescription->pcMatchesWhen) { 224 225 // Found it! 226 227 // Get Type 228 const ISelectionCriterionTypeInterface *pSelectionCriterionType = 229 _pSelectionCriterion->getCriterionType(); 230 231 // Check compatibility if relevant 232 if (!pSelectionCriterionType->isTypeInclusive() && 233 !pstMatchingRuleDescription->bExclusiveTypeCompatible) { 234 235 strError = "Value incompatible with exclusive kind of type"; 236 237 return false; 238 } 239 240 // Store 241 _eMatchesWhen = (MatchesWhen)matchesWhen; 242 243 return true; 244 } 245 } 246 247 strError = "Value not found"; 248 249 return false; 250 } 251