Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

IdConverter.cxx

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/xmlUtil/src/id/IdConverter.cxx,v 1.6 2002/04/05 18:26:44 jrb Exp $
00002 
00003 #include "xmlUtil/id/IdConversion.h"
00004 #include "xmlUtil/id/IdConverter.h"
00005 #include "xmlUtil/id/IdDictMan.h"
00006 #include "xmlUtil/id/IdDict.h"
00007 #include <dom/DOM_Element.hpp>
00008 #include "xml/Dom.h"
00009 #include <algorithm>
00010 #include "xmlUtil/id/IdConverterLessThan.h"
00011 
00012 namespace xmlUtil {
00013 
00014   IdDictMan * IdConverter::dictMan = 0;
00015 
00016   IdConverter::IdConverter(DOM_Element elt) : m_consistent(UNKNOWN),
00017   m_sorted(NO) {
00018     if (!dictMan) dictMan = IdDictMan::getPointer();
00019 
00020     // An idConverter element may optionally have as first child
00021     // a constants element, but we're assuming that the XML document
00022     // has already had constants evaluation and substitution done
00023     // on it, if necessary.
00024     // Assume that any constant evaluations and substitutions have
00025     // already been dealt with 
00026     DOM_Element child = xml::Dom::getFirstChildElement(elt);
00027 
00028     if ( (child.getTagName()).equals(DOMString("constants")) ) { // move on
00029       child = xml::Dom::getSiblingElement(child);
00030     }
00031     while ( (child.getTagName()).equals(DOMString("idDict")) ) {
00032       IdDict* dict = new IdDict(child);
00033       dictMan->registerDict(dict);
00034       child = xml::Dom::getSiblingElement(child);
00035     }
00036 
00037     // Now that all id dictionaries we need should have been defined,
00038     // handle attributes
00039     std::string dictName = xml::Dom::getAttribute(elt, "fromDict");
00040     if (dictName.size() > 0 ) {  // then it's not just an empty string
00041       inputDictName = new std::string(dictName);
00042       inputDict = dictMan->findDict(dictName);
00043     }
00044     dictName = xml::Dom::getAttribute(elt, "toDict");
00045     if (dictName.size() > 0 ) {
00046       outputDictName = new std::string(dictName);
00047       outputDict = dictMan->findDict(dictName);
00048     }
00049 
00050     // All remaining elements should be idConv
00051     while (child != DOM_Element() ) {
00052       IdConversion *conv = new IdConversion(child);
00053       m_convCol.push_back(conv);
00054       child = xml::Dom::getSiblingElement(child);
00055     }
00056 
00057     // check for consistency before unleashing this object
00058     isConsistent();
00059   }
00060 
00061   IdConverter::~IdConverter() {
00062     m_convCol.clear();
00063   }
00064 
00065   // Sort by path length
00066   void IdConverter::sortConvs() {
00067     if (m_sorted != YES) {
00068       ConversionIt start = m_convCol.begin(), last = m_convCol.end();
00069       IdConverterLessThan weakOrder;
00070       std::sort(start, last, weakOrder);  // sort them
00071       m_sorted = YES;
00072     }
00073   }
00074 
00075   bool IdConverter::isConsistent() {
00076     if (m_consistent == UNKNOWN) {
00077       sortConvs();
00078       // Check whether a path is a subsequence of some other path,
00079       // unfortunately an o(n**2) procedure
00080       unsigned int ix, jx;
00081       for (ix = 0; ix < (m_convCol.size() - 1); ix++ ) {
00082         for (jx = ix + 1; jx < (m_convCol.size()); jx++) {
00083           // Since conversions are ordered by size, only need
00084           // to check whether ix-th path is subpath of jx-th,
00085           // not the reverse
00086           if (m_convCol[ix]->subpathOf(*(m_convCol[jx]))) {
00087             m_consistent = NO;
00088             return m_consistent;
00089           }
00090         }
00091       }
00092       m_consistent = YES;
00093     }
00094     return m_consistent;
00095   }
00096 
00097   NamedId *IdConverter::convert(const NamedId *in) const {
00098     unsigned int ix;
00099 
00100     if (m_consistent == NO) return 0;
00101 
00102     // Based on path, find appropriate conversion, if any
00103     for (ix = 0; ix < m_convCol.size(); ix++) {
00104       if ((m_convCol[ix])->inDomain(*in)) {  // convert
00105         return (m_convCol[ix]->convert(*in));
00106       }
00107     }
00108     //       else return copy of input  
00109     return new NamedId(*in);
00110   }
00111 
00112 
00113   Identifier *IdConverter::convert(const Identifier *inIdent) const {
00114     if (!inputDict) return 0;  // can't get names without dictionary
00115 
00116     if (m_consistent == NO) return 0;
00117 
00118     NamedId *inNamed = inputDict->getNamedId(*inIdent);
00119     if (inNamed == 0) return 0;
00120 
00121     NamedId *outNamed = convert(inNamed);
00122     
00123     Identifier *converted = outNamed->stripNames();
00124     delete inNamed;
00125     delete outNamed;
00126     return converted;
00127   }
00128 
00129   std::ostream& IdConverter::displayConversions(std::ostream& s) {
00130     Conversions::const_iterator it = m_convCol.begin();
00131 
00132     while (it != m_convCol.end() ) {
00133       s << (**it) << std::endl;
00134       ++it;
00135     }
00136     return s;
00137   }
00138 }
00139 

Generated on Wed Oct 16 14:02:47 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001