#include <DictNode.h>
Inheritance diagram for xmlUtil::DictNode::

Public Methods | |
| DictNode (DOM_Element elt, DictNode *parent, DictFieldMan *fieldMan) | |
| Construct a node from its XML representation (probably recursively construct children as well). More... | |
| ~DictNode () | |
| const DictField & | getField () const |
| const DictConstraints & | getValueConstraints () const |
| const DictConstraints & | getParentConstraints () const |
| bool | accept (DictVisitor *vis) |
| bool | consistentChildren () |
| Check that collection of children define appropriately disjoint collections of Identifiers. In the process may do some sorting of child nodes, so these functions are not const. More... | |
| bool | consistentParent () |
| Verify that parent constraints, if any, are consistent with other restrictions on values parent node may take on. More... | |
| bool | consistentValues () |
| Verify that constraints (if any) on node's own value are consistent with constraints on field. More... | |
| bool | allowed (const unsigned value) const |
| bool | allowedChild (std::string childField, unsigned childValue, unsigned myValue) const |
| Are the given child field name, child field value, and value this node compatible with defn of node and children? More... | |
| bool | allowedChild (unsigned childValue, unsigned myValue) const |
| Are the given child field value, and value this node compatible with defn of node and children? More... | |
| bool | allowIdentifier (const Identifier &id, NamedId *named=0) |
| Given an identifier, see if it is "allowed" by this node and a sequence of its descendents. If there is a non-null NamedId argument, build up the associated NamedId. More... | |
| bool | allowNamedId (const NamedId &nId) |
| return true iff there is a path starting with current node which could produce the NamedId nId. More... | |
| bool | allowNameSeq (const NameSeq &seq) const |
| return true iff there is a path starting with current node such that node field names match those in seq. More... | |
Private Types | |
| typedef std::vector< DictNode *> | Nodes |
| typedef std::vector< DictNode *>::iterator | NodeIterator |
| typedef std::vector< DictNode *>::const_iterator | ConstNodeIterator |
Private Methods | |
| const Nodes & | getChildren () const |
| bool | allowedChild (const DictNode *const thisChild, unsigned childValue, unsigned myValue) const |
| Is the particular child node compatible with the given childValue and value for this? More... | |
| bool | allowIdentifier (Identifier::const_iterator idIt, Identifier::const_iterator end, NamedId *named=0) |
| Called by version without iterators. More... | |
| bool | allowNamedId (NamedId::FieldIt nIdIt, NamedId::FieldIt end) |
| Called by version with simple NamedId rather than iterators. More... | |
| bool | allowNameSeq (NameSeq::const_iterator seqIt, NameSeq::const_iterator end) const |
| called by version with simple NameSeq arg rather than iterators. More... | |
| bool | addChild (DictNode *child) |
| bool | valuesDisjoint (ConstNodeIterator start, ConstNodeIterator last) |
| Check that for nodes in the interval demarcated by [first, last] value constraints give pairwise-disjoint sets. More... | |
| DictNode (const DictNode &toCopy) | |
| Copy constructor copies all children, grandchildren, etc. More... | |
| DictNode & | operator= (const DictNode &) |
| void | deepCopy (const DictNode &toCopy) |
| DictNode () | |
| don't allow uninitialized node. More... | |
Static Private Methods | |
| void | setOstream (std::ostream *out) |
| The following may be called by IdDict during, e.g., validation. More... | |
Private Attributes | |
| Nodes | m_children |
| collection of child nodes. More... | |
| const DictField * | m_field |
| id field for this node. More... | |
| const DictNode * | m_parent |
| parent dictnode. More... | |
| DictConstraints * | m_parConstraints |
| Constraints on values of parent. More... | |
| DictConstraints * | m_myConstraints |
| Constraints on values for this node. More... | |
Static Private Attributes | |
| std::ostream * | m_err = &(std::cout) |
Friends | |
| class | IdDict |
| class | IdConverter |
| struct | POrder |
|
|
Definition at line 96 of file DictNode.h. Referenced by accept(), allowedChild(), allowIdentifier(), allowNamedId(), allowNameSeq(), consistentChildren(), deepCopy(), setOstream(), and valuesDisjoint(). |
|
|
Definition at line 95 of file DictNode.h. Referenced by ~DictNode(). |
|
|
Definition at line 94 of file DictNode.h. Referenced by getChildren(). |
|
||||||||||||||||
|
Construct a node from its XML representation (probably recursively construct children as well).
Definition at line 11 of file DictNode.cxx. References allowed(), consistentChildren(), DictNode(), m_children, m_field, m_myConstraints, and m_parConstraints. Referenced by allowIdentifier(), allowNamedId(), allowNameSeq(), deepCopy(), DictNode(), and setOstream().
00012 : 00013 m_children(0), m_parent(parent), m_parConstraints(0), 00014 m_myConstraints(0) { 00015 // check element type is OK. Shouldn't be a problem if 00016 // the xml file validates. Note sense of assert is: 00017 // abort program if assertion is *false* 00018 assert( (elt.getTagName().equals("dictNode")) || 00019 (elt.getTagName().equals("dictRoot")) ) ; 00020 00021 // Field name stuff: 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 // Do something if it doesn't exist?? Shouldn't be terribly 00028 // necessary by ID/IDREF mechanism 00029 00030 DOM_Element child = xml::Dom::getFirstChildElement(elt); 00031 // Could be a leaf with no children 00032 if (child == DOM_Element()) return; 00033 00034 if ((child.getTagName()).equals("pValues")) { // parent constraints 00035 DOM_Element gChild = xml::Dom::getFirstChildElement(child); 00036 m_parConstraints = new DictConstraints(gChild); 00037 00038 // check for compatibility 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; // new Dec. 4 00052 } 00053 00054 // Next up we might have our own constraint 00055 if (!(child.getTagName().equals("dictNode")) ) { 00056 m_myConstraints = new DictConstraints(child); 00057 00058 // Check it's consistent with constraints on our own field, 00059 // if any 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 // All that's left are child nodes, if any 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 // Finally, how about checking for consistency among children? 00076 if (!consistentChildren()) { 00077 std::cout << "Inconsistent children, fieldname " << 00078 m_field->getName(); 00079 // make a fuss 00080 } 00081 } |
|
|
Definition at line 453 of file DictNode.cxx. References m_children, m_myConstraints, m_parConstraints, and NodeIterator.
00453 {
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 }
|
|
|
Copy constructor copies all children, grandchildren, etc.
Definition at line 414 of file DictNode.cxx. References deepCopy().
00414 : DictObject(toCopy) {
00415 deepCopy(toCopy);
00416 }
|
|
|
don't allow uninitialized node.
Definition at line 159 of file DictNode.h. Referenced by deepCopy(), and DictNode().
00159 {};
|
|
|
Reimplemented from xmlUtil::DictObject. Definition at line 402 of file DictNode.cxx. References ConstNodeIterator, and m_children.
00402 {
00403 // Call back visitor for child nodes, then self
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 }
|
|
|
Definition at line 390 of file DictNode.cxx. References m_children, and m_myConstraints. Referenced by deepCopy().
00390 {
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 }
|
|
|
Definition at line 262 of file DictNode.cxx. References m_field, and m_myConstraints. Referenced by allowedChild(), allowIdentifier(), allowNamedId(), and DictNode().
00262 {
00263 if (!m_myConstraints) {
00264 return m_field->allowed(value);
00265 }
00266 else {
00267 return m_myConstraints->allowed(value);
00268 }
00269 }
|
|
||||||||||||||||
|
Is the particular child node compatible with the given childValue and value for this? Assume we've already checked that this node may take on myValue; still need to check that for the child indicated myValue is allowed. Definition at line 296 of file DictNode.cxx.
00297 {
00298 if (child->m_parConstraints) {
00299 if (!(child->m_parConstraints)->allowed(myValue)) return false;
00300 }
00301 return child->allowed(childValue);
00302 }
|
|
||||||||||||
|
Are the given child field value, and value this node compatible with defn of node and children?
Definition at line 285 of file DictNode.cxx. References allowed(), allowedChild(), ConstNodeIterator, and m_children.
00286 {
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 }
|
|
||||||||||||||||
|
Are the given child field name, child field value, and value this node compatible with defn of node and children?
Definition at line 271 of file DictNode.cxx. References allowed(), ConstNodeIterator, and m_children. Referenced by allowedChild().
00272 {
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 // Never found child with correct field name
00282 return false;
00283 }
|
|
||||||||||||||||
|
Called by version without iterators.
Definition at line 304 of file DictNode.cxx. References allowed(), ConstNodeIterator, DictNode(), m_children, and m_field.
00306 {
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 //look for children allowing our value for parent node
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 // Didn't work out so remove ourselves
00323 if (named != 0) named->popField();
00324 return false;
00325 }
|
|
||||||||||||
|
Given an identifier, see if it is "allowed" by this node and a sequence of its descendents. If there is a non-null NamedId argument, build up the associated NamedId.
Definition at line 327 of file DictNode.cxx.
00327 {
00328 Identifier::const_iterator idIt = id.begin();
00329 return allowIdentifier(idIt, id.end(), named);
00330 }
|
|
||||||||||||
|
Called by version with simple NamedId rather than iterators.
Definition at line 337 of file DictNode.cxx. References allowed(), ConstNodeIterator, DictNode(), m_children, and m_field.
00338 {
00339 // Check information for first field matches
00340
00341 // These aren't supposed to happen
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; //done
00351
00352 // Now search children for match of remaining fields
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 }
|
|
|
return true iff there is a path starting with current node which could produce the NamedId nId.
Definition at line 332 of file DictNode.cxx.
00332 {
00333 NamedId::FieldIt nIdIt = nId.m_fields->begin();
00334 return allowNamedId(nIdIt, nId.m_fields->end());
00335 }
|
|
||||||||||||
|
called by version with simple NameSeq arg rather than iterators.
Definition at line 369 of file DictNode.cxx. References ConstNodeIterator, DictNode(), m_children, and m_field.
00370 {
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; // done
00377
00378 // Now search children for match of remaining fields
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 /* TO DO */
00387 }
|
|
|
return true iff there is a path starting with current node such that node field names match those in seq.
Definition at line 364 of file DictNode.cxx. References xmlUtil::NameSeq.
00364 {
00365 NameSeq::const_iterator seqIt = seq.begin();
00366 return allowNameSeq(seqIt, seq.end());
00367 }
|
|
|
Check that collection of children define appropriately disjoint collections of Identifiers. In the process may do some sorting of child nodes, so these functions are not const.
Definition at line 92 of file DictNode.cxx. References ConstNodeIterator, m_children, m_field, POrder, and valuesDisjoint(). Referenced by DictNode().
00092 {
00093 if (m_children.size() < 2) return true; // most common case
00094
00095 // Either all children must have parent-value constraints or
00096 // none can.
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) { // no parent constraints
00110 return valuesDisjoint(m_children.begin(), m_children.end());
00111 }
00112
00113 // Otherwise sort nodes by minValue of parent constraint
00114 POrder parOrder;
00115 std::sort(m_children.begin(), m_children.end(), parOrder);
00116
00117 // Check that parent constraints are disjoint or identical
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 // Finally need to check that child values are disjoint
00133 // within subcollection of nodes with same parent constraints
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 // If we're ever starting a new collection to check at the
00140 // last child, we're done
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 // If we got here, it's time to check out a collection of children
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 // Otherwise see if there is another bunch left
00164 it = ++follow;
00165 }
00166 return true;
00167 }
|
|
|
Verify that parent constraints, if any, are consistent with other restrictions on values parent node may take on.
Definition at line 169 of file DictNode.cxx. References m_field, m_parConstraints, and m_parent.
00169 {
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 }
|
|
|
Verify that constraints (if any) on node's own value are consistent with constraints on field.
Definition at line 199 of file DictNode.cxx. References m_field, and m_myConstraints.
00199 {
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 }
|
|
|
Definition at line 422 of file DictNode.cxx. References addChild(), ConstNodeIterator, DictNode(), m_field, m_myConstraints, m_parConstraints, and m_parent. Referenced by DictNode().
00422 {
00423 // Don't copy parent. Nodes created with copy constructor
00424 // are parentless. Use addChild after creation.
00425 // Also have to get parent constraints some other way
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 // Now for child nodes
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 // Need some exception handling here. addChild returns
00447 // true or false, depending on whether child actually was
00448 // added or not.
00449 addChild(newChild);
00450 }
00451 }
|
|
|
Definition at line 106 of file DictNode.h. References m_children, and Nodes.
00106 {return m_children;}
|
|
|
Definition at line 31 of file DictNode.h. References m_field.
00031 {return *m_field;};
|
|
|
Definition at line 39 of file DictNode.h. References m_parConstraints, and xmlUtil::NameSeq.
00039 {
00040 return *m_parConstraints;};
|
|
|
Definition at line 37 of file DictNode.h. References m_myConstraints.
00037 {
00038 return *m_myConstraints;};
|
|
|
Definition at line 418 of file DictNode.cxx.
00418 {
00419 throw No_Assignment();
00420 }
|
|
|
The following may be called by IdDict during, e.g., validation.
Definition at line 109 of file DictNode.h. References ConstNodeIterator, DictNode(), and m_err.
00109 {m_err = out;}
|
|
||||||||||||
|
Check that for nodes in the interval demarcated by [first, last] value constraints give pairwise-disjoint sets.
Definition at line 216 of file DictNode.cxx. References ConstNodeIterator. Referenced by consistentChildren().
00217 {
00218 if (*start == *last) return true;
00219
00220 ConstNodeIterator pCurrentNode = start;
00221 std::set<unsigned> values;
00222
00223 if (!(*start)->m_myConstraints) { // There had better be some
00224 //associated with the field name; copy them
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 // Make a new set containing values for current node
00237 std::set<unsigned> curValues;
00238
00239 if (!(*pCurrentNode)->m_myConstraints) { // There had better be some
00240 //associated with the field name; copy them
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 // See if it intersects accumulated values from previous nodes
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 // If not, continue to accumulate
00255 (*pCurrentNode)->m_myConstraints->insertValues(values);
00256
00257 }
00258 return true;
00259
00260 }
|
|
|
Definition at line 89 of file DictNode.h. |
|
|
Definition at line 88 of file DictNode.h. |
|
|
Definition at line 90 of file DictNode.h. Referenced by consistentChildren(). |
|
|
collection of child nodes.
Definition at line 161 of file DictNode.h. Referenced by accept(), addChild(), allowedChild(), allowIdentifier(), allowNamedId(), allowNameSeq(), consistentChildren(), DictNode(), getChildren(), and ~DictNode(). |
|
|
Definition at line 10 of file DictNode.cxx. Referenced by setOstream(). |
|
|
id field for this node.
Definition at line 162 of file DictNode.h. Referenced by allowed(), allowIdentifier(), allowNamedId(), allowNameSeq(), consistentChildren(), consistentParent(), consistentValues(), deepCopy(), DictNode(), and getField(). |
|
|
Constraints on values for this node.
Definition at line 165 of file DictNode.h. Referenced by addChild(), allowed(), consistentValues(), deepCopy(), DictNode(), getValueConstraints(), and ~DictNode(). |
|
|
Constraints on values of parent.
Definition at line 164 of file DictNode.h. Referenced by consistentParent(), deepCopy(), DictNode(), getParentConstraints(), and ~DictNode(). |
|
|
parent dictnode.
Definition at line 163 of file DictNode.h. Referenced by consistentParent(), and deepCopy(). |
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001