00001
00002 #include <dom/DOM_Element.hpp>
00003 #include <dom/DOMString.hpp>
00004 #include "xml/Dom.h"
00005 #include "xmlUtil/id/DictNode.h"
00006 #include "xmlUtil/id/DictFieldMan.h"
00007 #include <assert.h>
00008
00009 namespace xmlUtil {
00010 std::ostream* DictNode::m_err = &(std::cout);
00011 DictNode::DictNode(DOM_Element elt, DictNode *parent,
00012 DictFieldMan *fieldMan) :
00013 m_children(0), m_parent(parent), m_parConstraints(0),
00014 m_myConstraints(0) {
00015
00016
00017
00018 assert( (elt.getTagName().equals("dictNode")) ||
00019 (elt.getTagName().equals("dictRoot")) ) ;
00020
00021
00022 std::string fName =
00023 std::string(xml::Dom::transToChar(elt.getAttribute("fieldName")));
00024
00025 m_field = fieldMan->find(fName.c_str());
00026 assert(m_field != 0);
00027
00028
00029
00030 DOM_Element child = xml::Dom::getFirstChildElement(elt);
00031
00032 if (child == DOM_Element()) return;
00033
00034 if ((child.getTagName()).equals("pValues")) {
00035 DOM_Element gChild = xml::Dom::getFirstChildElement(child);
00036 m_parConstraints = new DictConstraints(gChild);
00037
00038
00039 DictConstraints* fromParent = 0;
00040 if (parent->m_myConstraints) fromParent = (parent->m_myConstraints);
00041 else {
00042 fromParent = parent->m_field->getConstraints();
00043 }
00044 if (fromParent) {
00045 bool allowed = (fromParent->allowed(m_parConstraints));
00046 if (!allowed) {
00047 assert(allowed);
00048 }
00049 }
00050 child = xml::Dom::getSiblingElement(child);
00051 if (child == DOM_Element()) return;
00052 }
00053
00054
00055 if (!(child.getTagName().equals("dictNode")) ) {
00056 m_myConstraints = new DictConstraints(child);
00057
00058
00059
00060 DictConstraints* fCon = m_field->getConstraints();
00061 if (fCon != 0) {
00062 assert(fCon->allowed(m_myConstraints));
00063 }
00064 child = xml::Dom::getSiblingElement(child);
00065 }
00066
00067
00068
00069 while (child != DOM_Element()) {
00070 DictNode *nextChild = new DictNode(child, this, fieldMan);
00071
00072 m_children.push_back(nextChild);
00073 child = xml::Dom::getSiblingElement(child);
00074 }
00075
00076 if (!consistentChildren()) {
00077 std::cout << "Inconsistent children, fieldname " <<
00078 m_field->getName();
00079
00080 }
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 bool DictNode::consistentChildren() {
00093 if (m_children.size() < 2) return true;
00094
00095
00096
00097 ConstNodeIterator it = m_children.begin();
00098 bool childMode = ((*it)->m_parConstraints != 0);
00099 ++it;
00100 for (; it < m_children.end(); ++it) {
00101 if (((*it)->m_parConstraints != 0) != childMode) {
00102 (*m_err) << "Mixed parent-constraint mode among children "
00103 << std::endl;
00104 (*m_err) << "Current node has field name " << this->m_field->getName()
00105 << std::endl;
00106 return false;
00107 }
00108 }
00109 if (!childMode) {
00110 return valuesDisjoint(m_children.begin(), m_children.end());
00111 }
00112
00113
00114 POrder parOrder;
00115 std::sort(m_children.begin(), m_children.end(), parOrder);
00116
00117
00118 for (it = m_children.begin(); (it + 1) != m_children.end(); ++it) {
00119 DictConstraints *par1 = (*it)->m_parConstraints;
00120 DictConstraints *par2 = (*(it + 1))->m_parConstraints;
00121
00122 if ( (!par1->equals(*par2)) &&
00123 (!par1->disjoint(*par2)) ) {
00124 (*m_err) << "Non-disjoint parent constraints among children"
00125 << std::endl;
00126 (*m_err) << "Current node has field name " << this->m_field->getName()
00127 << std::endl;
00128 return false;
00129 }
00130 }
00131
00132
00133
00134 it = m_children.begin();
00135 while (it != m_children.end() ) {
00136 ConstNodeIterator follow = it + 1;
00137 unsigned ourMin = (*it)->m_parConstraints->getMin();
00138
00139
00140
00141 if (follow == m_children.end()) return true;
00142 while (follow != m_children.end()) {
00143 DictConstraints *par2 = (*follow)->m_parConstraints;
00144
00145 if (par2->getMin() != ourMin) {
00146 --follow;
00147 break;
00148 }
00149 ++follow;
00150
00151 }
00152
00153 bool ok = valuesDisjoint(it, follow);
00154 if (!ok) {
00155 (*m_err) <<
00156 "Non-disjoint values for children with same parent constraints"
00157 << std::endl;
00158 (*m_err) << "Current node has field name " << this->m_field->getName()
00159 << std::endl;
00160 return false;
00161 }
00162
00163
00164 it = ++follow;
00165 }
00166 return true;
00167 }
00168
00169 bool DictNode::consistentParent() {
00170 if (!m_parConstraints) return true;
00171
00172 if (DictConstraints *parConstraints = m_parent->m_myConstraints) {
00173 bool ok = parConstraints->allowed(*m_parConstraints);
00174 if (!ok) {
00175 (*m_err) <<
00176 "Parent value constraints and local parent constraints inconsistent"
00177 << std::endl;
00178 (*m_err) << "Current node has field name " << this->m_field->getName()
00179 << std::endl;
00180
00181 return ok;
00182 }
00183 }
00184 else if (DictConstraints *parConstraints =
00185 m_parent->m_field->getConstraints()) {
00186 bool ok = parConstraints->allowed(*m_parConstraints);
00187 if (!ok) {
00188 (*m_err) <<
00189 "Global value constraints on parent, local parent constraints clash"
00190 << std::endl;
00191 (*m_err) << "Current node has field name " << this->m_field->getName()
00192 << std::endl;
00193 }
00194 return ok;
00195 }
00196 return true;
00197 }
00198
00199 bool DictNode::consistentValues() {
00200 if (!m_myConstraints) return true;
00201
00202 DictConstraints *fieldConstraints = m_field->getConstraints();
00203
00204 if (!fieldConstraints) return true;
00205
00206 bool ok= fieldConstraints->allowed(*m_myConstraints);
00207 if (!ok) {
00208 (*m_err) << "local value constraints and global field constraints clash"
00209 << std::endl;
00210 (*m_err) << "Current node has field name " << this->m_field->getName()
00211 << std::endl;
00212 }
00213 return ok;
00214 }
00215
00216 bool DictNode::valuesDisjoint(ConstNodeIterator start,
00217 ConstNodeIterator last) {
00218 if (*start == *last) return true;
00219
00220 ConstNodeIterator pCurrentNode = start;
00221 std::set<unsigned> values;
00222
00223 if (!(*start)->m_myConstraints) {
00224
00225 DictConstraints* fieldCon = (*start)->m_myConstraints =
00226 new DictConstraints(*((*start)->m_field->getConstraints()));
00227 assert(fieldCon != 0);
00228 }
00229
00230 (*start)->m_myConstraints->insertValues(values);
00231
00232 while (pCurrentNode != last) {
00233
00234 ++pCurrentNode;
00235
00236
00237 std::set<unsigned> curValues;
00238
00239 if (!(*pCurrentNode)->m_myConstraints) {
00240
00241 DictConstraints* fieldCon = (*pCurrentNode)->m_myConstraints =
00242 new DictConstraints(*((*pCurrentNode)->m_field->getConstraints()));
00243 assert(fieldCon != 0);
00244 }
00245
00246 (*pCurrentNode)->m_myConstraints->insertValues(curValues);
00247
00248
00249 std::vector<unsigned> intersect;
00250 std::set_intersection(values.begin(), values.end(), curValues.begin(),
00251 curValues.end(), intersect.begin());
00252 if (intersect.size() > 0) return false;
00253
00254
00255 (*pCurrentNode)->m_myConstraints->insertValues(values);
00256
00257 }
00258 return true;
00259
00260 }
00261
00262 bool DictNode::allowed(const unsigned value) const {
00263 if (!m_myConstraints) {
00264 return m_field->allowed(value);
00265 }
00266 else {
00267 return m_myConstraints->allowed(value);
00268 }
00269 }
00270
00271 bool DictNode::allowedChild(std::string childField, unsigned childValue,
00272 unsigned myValue) const {
00273 if (!allowed(myValue)) return false;
00274
00275 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00276 ++it) {
00277 if ( ((*it)->getField()).getName() == childField) {
00278 return allowedChild(*it, childValue, myValue);
00279 }
00280 }
00281
00282 return false;
00283 }
00284
00285 bool DictNode::allowedChild(unsigned childValue,
00286 unsigned myValue) const {
00287
00288 if (!allowed(myValue)) return false;
00289 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00290 ++it) {
00291 if (allowedChild(*it, childValue, myValue)) return true;
00292 }
00293 return false;
00294 }
00295
00296 bool DictNode::allowedChild(const DictNode* const child, unsigned childValue,
00297 unsigned myValue) const {
00298 if (child->m_parConstraints) {
00299 if (!(child->m_parConstraints)->allowed(myValue)) return false;
00300 }
00301 return child->allowed(childValue);
00302 }
00303
00304 bool DictNode::allowIdentifier(Identifier::const_iterator idIt,
00305 Identifier::const_iterator end,
00306 NamedId *named) {
00307 if (!allowed(*idIt)) return false;
00308 if (named != 0) named->addField(m_field->getName(), *idIt);
00309 Identifier::const_iterator tmp = idIt;
00310 ++tmp;
00311 if (tmp == end) return true;
00312
00313
00314 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00315 it++) {
00316 DictNode *child = *it;
00317 if ( (child->m_parConstraints == 0) ||
00318 (child->m_parConstraints->allowed(*idIt)) ) {
00319 if (child->allowIdentifier(++idIt, end, named)) return true;
00320 }
00321 }
00322
00323 if (named != 0) named->popField();
00324 return false;
00325 }
00326
00327 bool DictNode::allowIdentifier(const Identifier& id, NamedId* named) {
00328 Identifier::const_iterator idIt = id.begin();
00329 return allowIdentifier(idIt, id.end(), named);
00330 }
00331
00332 bool DictNode::allowNamedId(const NamedId& nId) {
00333 NamedId::FieldIt nIdIt = nId.m_fields->begin();
00334 return allowNamedId(nIdIt, nId.m_fields->end());
00335 }
00336
00337 bool DictNode::allowNamedId(NamedId::FieldIt nIdIt,
00338 NamedId::FieldIt end) {
00339
00340
00341
00342 if (nIdIt == end) return true;
00343 if (!(*nIdIt)) return false;
00344
00345 if ( ((*nIdIt)->name).compare(m_field->getName()) ) return false;
00346 if (!allowed((*nIdIt)->value) ) return false;
00347
00348 NamedId::FieldIt tmp = nIdIt;
00349 ++tmp;
00350 if (tmp == end) return true;
00351
00352
00353 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00354 it++) {
00355 DictNode *child = *it;
00356 if ( (child->m_parConstraints == 0) ||
00357 (child->m_parConstraints->allowed((*nIdIt)->value) ) ) {
00358 if (child->allowNamedId(++nIdIt, end) ) return true;
00359 }
00360 }
00361 return false;
00362 }
00363
00364 bool DictNode::allowNameSeq(const NameSeq& seq) const {
00365 NameSeq::const_iterator seqIt = seq.begin();
00366 return allowNameSeq(seqIt, seq.end());
00367 }
00368
00369 bool DictNode::allowNameSeq(NameSeq::const_iterator seqIt,
00370 NameSeq::const_iterator end) const {
00371 if (seqIt == end) return true;
00372 if ( (*seqIt)->compare(m_field->getName()) ) return false;
00373
00374 NameSeq::const_iterator tmp = seqIt;
00375 ++tmp;
00376 if (tmp == end) return true;
00377
00378
00379 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00380 it++) {
00381 DictNode *child = *it;
00382 if (child->allowNameSeq(++seqIt, end) ) return true;
00383 }
00384 return false;
00385
00386
00387 }
00388
00389
00390 bool DictNode::addChild(DictNode* child) {
00391 if ((m_myConstraints != 0) & (child->m_parConstraints != 0)) {
00392 if (!(m_myConstraints->allowed(child->m_parConstraints))) return false;
00393 }
00394 m_children.push_back(child);
00395 return true;
00396 }
00397
00398
00399
00400
00401
00402 bool DictNode::accept(DictVisitor* vis) {
00403
00404
00405 for (ConstNodeIterator it = m_children.begin(); it != m_children.end();
00406 it++) {
00407 bool keepGoing = (*it)->accept(vis);
00408 if (!keepGoing) return false;
00409 }
00410
00411 return vis->visitNode(this);
00412 }
00413
00414 DictNode::DictNode(const DictNode& toCopy) : DictObject(toCopy) {
00415 deepCopy(toCopy);
00416 }
00417
00418 DictNode& DictNode::operator=(const DictNode& d) {
00419 throw No_Assignment();
00420 }
00421
00422 void DictNode::deepCopy(const DictNode& d) {
00423
00424
00425
00426 m_parent = 0;
00427 m_parConstraints = 0;
00428 if (d.m_field) {
00429 m_field = new DictField(*(d.m_field));
00430 }
00431 else m_field = 0;
00432
00433 if (d.m_myConstraints) {
00434 m_myConstraints = new DictConstraints(*(d.m_myConstraints));
00435 }
00436 else m_myConstraints = 0;
00437
00438
00439 for (ConstNodeIterator it = d.m_children.begin();
00440 it != d.m_children.end(); ++it) {
00441 DictNode *newChild = new DictNode(**it);
00442 DictConstraints *oldParConstraints = (*it)->m_parConstraints;
00443
00444 newChild->m_parConstraints = (oldParConstraints) ?
00445 new DictConstraints(*oldParConstraints) : 0;
00446
00447
00448
00449 addChild(newChild);
00450 }
00451 }
00452
00453 DictNode::~DictNode() {
00454 if (m_parConstraints != 0) {
00455 delete m_parConstraints;
00456 m_parConstraints = 0;
00457 }
00458 if (m_myConstraints != 0) {
00459 delete m_myConstraints;
00460 m_myConstraints = 0;
00461 }
00462 for (NodeIterator it = m_children.begin();
00463 it != m_children.end(); ++it) {
00464 delete *it;
00465 }
00466 }
00467 }
00468
00469