API documentation
SequenceTree.cpp
Go to the documentation of this file.
00001 00005 /* 00006 * JEMRIS Copyright (C) 2007-2010 Tony Stöcker, Kaveh Vahedipour 00007 * Forschungszentrum Jülich, Germany 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #include "SequenceTree.h" 00025 #include "Module.h" 00026 #include "World.h" 00027 #include "Parameters.h" 00028 #include "ConcatSequence.h" 00029 #include "AtomicSequence.h" 00030 #include "Pulse.h" 00031 #include "XMLIO.h" 00032 00033 SequenceTree* SequenceTree::m_instance = 0; 00034 00035 /***********************************************************/ 00036 SequenceTree::SequenceTree() { 00037 00038 m_dom_doc = 0; 00039 m_parameters = 0; 00040 m_root_seq = 0; 00041 m_state = false; 00042 m_depth = 0; 00043 m_mpf = new ModulePrototypeFactory(); 00044 m_xio = new XMLIO(); 00045 00046 } 00047 00048 /***********************************************************/ 00049 SequenceTree::~SequenceTree() { 00050 00051 SequenceTree::m_instance = 0; 00052 00053 delete m_xio; 00054 00055 XMLPlatformUtils::Terminate(); 00056 00057 // Delete all Modules, except the Parameters singleton 00058 map<DOMNode*,Module*>::iterator iter; 00059 for (iter = m_Modules.begin(); iter != m_Modules.end(); iter++ ) 00060 if (m_parameters != iter->second) 00061 delete iter->second; 00062 00063 // Delete the factory (deletes the Parameters singleton!) 00064 delete m_mpf; 00065 00066 } 00067 00068 /***********************************************************/ 00069 SequenceTree* SequenceTree::instance() { 00070 00071 if(m_instance == 0) 00072 m_instance = new SequenceTree(); 00073 00074 return m_instance; 00075 00076 } 00077 00078 /***********************************************************/ 00079 void SequenceTree::Initialize(string seqFile) { 00080 00081 //initialize 00082 m_state = false; 00083 m_dom_doc = m_xio->Parse(seqFile); 00084 00085 DOMNode* topnode; 00086 00087 if (!(topnode = m_dom_doc->getFirstChild())) 00088 return; 00089 00090 m_state = ( StrX(topnode->getNodeName()).std_str() == "Parameters"); 00091 00092 } 00093 00094 /***********************************************************/ 00095 DOMNode* SequenceTree::GetParentNode (DOMNode* node) { 00096 00097 return node->getParentNode(); 00098 00099 } 00100 00101 /***********************************************************/ 00102 DOMNodeList* SequenceTree::GetChildNodes (DOMNode* node) { 00103 00104 return node->getChildNodes(); 00105 00106 } 00107 00108 /***********************************************************/ 00109 DOMNamedNodeMap* SequenceTree::GetAttributes (DOMNode* node) { 00110 return node->getAttributes(); 00111 } 00112 00113 /***********************************************************/ 00114 Module* SequenceTree::GetModule (DOMNode* node) { 00115 00116 map<DOMNode*,Module*>::iterator iter = m_Modules.find(node); 00117 00118 if( iter != m_Modules.end() ) 00119 return ( iter->second ); 00120 00121 return NULL; 00122 00123 } 00124 00125 /***********************************************************/ 00126 unsigned int SequenceTree::AddModule (string name) { 00127 00128 unsigned int id = 0; 00129 return id; 00130 00131 } 00132 00133 /***********************************************************/ 00134 unsigned int SequenceTree::Populate () { 00135 00136 DOMNode* topnode; 00137 if (!(topnode = m_dom_doc->getFirstChild())) return EMPTY_DOCUMENT; 00138 00139 //Prepare the parameters first! (if any specified in XML) 00140 DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("Parameters").XMLchar() ); 00141 if (dnl->getLength() > 0) { 00142 00143 m_parameters = Parameters::instance(); 00144 SequenceTree::CreateModule(this,dnl->item(0)); 00145 m_parameters->Prepare(PREP_INIT); 00146 m_parameters->Prepare(PREP_VERBOSE); 00147 00148 if (dnl->getLength() > 1) 00149 cout << "Warning: multiple tags 'Parameters' in XML." << endl; 00150 00151 } 00152 00153 //populate 00154 m_depth = 0; 00155 RunTree(topnode, this, &SequenceTree::CreateModule); 00156 m_depth--; 00157 //find top node of the sequence tree 00158 ConcatSequence* m_root_seq = GetRootConcatSequence(); 00159 00160 //run Prepare() twice to solve all module cross-dependencies (silent) 00161 m_root_seq->Prepare(PREP_INIT); 00162 m_root_seq->Prepare(PREP_INIT); 00163 m_root_seq->Prepare(PREP_INIT); 00164 00165 //prep. static atom, if exists 00166 World* pW = World::instance(); 00167 if (pW->pStaticAtom != NULL) 00168 { 00169 double d = m_root_seq->GetDuration(); 00170 vector<Module*> children = pW->pStaticAtom->GetChildren(); 00171 pW->pStaticAtom->Prepare(PREP_INIT); 00172 pW->pStaticAtom->Prepare(PREP_INIT); 00173 for (unsigned int j=0; j<children.size() ; ++j) 00174 ((Pulse*) children[j])->SetDuration(d); 00175 //cout << children.size() << " " << pW->pStaticAtom->GetDuration() << " XX\n"; 00176 } 00177 00178 //check name consistency 00179 map<DOMNode*,Module*>::iterator iter1; 00180 map<DOMNode*,Module*>::iterator iter2; 00181 00182 for (iter1 = m_Modules.begin(); iter1!=m_Modules.end(); iter1++ ) 00183 for (iter2 = iter1,iter2++; iter2!=m_Modules.end(); iter2++ ) 00184 if ( (iter1->second)->GetName() == (iter2->second)->GetName() ) 00185 cout << "SequenceTree::Populate warning: 2 modules with equal names exist: '" 00186 << (iter1->second)->GetName() << "'. Class types: (" 00187 << (iter1->second)->GetClassType() << "," << (iter2->second)->GetClassType() << ")" << endl; 00188 00189 //verbose Prepare call : errors have to be reported 00190 m_root_seq->Prepare(PREP_VERBOSE); 00191 00192 return OK; 00193 00194 } 00195 00196 /***********************************************************/ 00197 int SequenceTree::RunTree (DOMNode* node, void* ptr, unsigned int (*fun) (void*, DOMNode*) ,int depth ) { 00198 00199 DOMNode* child; 00200 00201 if (node) { 00202 00203 if (node->getNodeType() == DOMNode::ELEMENT_NODE) { 00204 00205 string s = StrX(node->getNodeName()).std_str() ; 00206 00207 if ( s != "Parameters" ) { 00208 unsigned int code = fun(ptr,node); 00209 if (code>0) return depth; 00210 } 00211 00212 depth++; 00213 m_depth = (depth>m_depth?depth:m_depth); 00214 00215 for (child = node->getFirstChild(); child != 0; child=child->getNextSibling()) 00216 { 00217 RunTree(child,ptr,fun,depth); 00218 if (s == "Parameters" && StrX(child->getNodeName()).std_str() == "AtomicSequence" ) 00219 { 00220 DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("AtomicSequence").XMLchar() ); 00221 AtomicSequence* A = ((AtomicSequence*) m_Modules.find(dnl->item(dnl->getLength()-1))->second); 00222 World* pW = World::instance(); 00223 pW->pStaticAtom = A; 00224 } 00225 } 00226 } 00227 } 00228 00229 return depth; 00230 00231 } 00232 00233 /***********************************************************/ 00234 unsigned int SequenceTree::CreateModule(void* ptr,DOMNode* node){ 00235 00236 SequenceTree* ST = (SequenceTree*) ptr; 00237 Module* module = ST->m_mpf->CloneModule(node); 00238 00239 if (!module) 00240 return 1; 00241 00242 ST->m_Modules.insert(pair<DOMNode*, Module*> (node, module)); 00243 module->Initialize(node); 00244 00245 return OK; 00246 00247 } 00248 00249 /***********************************************************/ 00250 Module* SequenceTree::GetParent (DOMNode* node) { 00251 00252 DOMNode* parent = node->getParentNode(); 00253 00254 if (!parent) 00255 return NULL; 00256 00257 return m_Modules.find(parent)->second; 00258 00259 } 00260 00261 /***********************************************************/ 00262 vector<Module*> SequenceTree::GetChildren (DOMNode* node) { 00263 00264 vector<Module*> children; 00265 00266 DOMNodeList* dnl = node->getChildNodes(); 00267 00268 for (unsigned int i = 0; i < dnl->getLength(); i++) { 00269 if (dnl->item(i)->getNodeType() == DOMNode::ELEMENT_NODE) 00270 children.push_back( m_Modules.find(dnl->item(i))->second ); 00271 } 00272 00273 return children; 00274 00275 } 00276 00277 00278 /***********************************************************/ 00279 Module* SequenceTree::GetChild (DOMNode* node, unsigned int position) { 00280 00281 vector<Module*> children = GetChildren(node); 00282 return children.at(position); 00283 00284 } 00285 00286 00287 /***********************************************************/ 00288 ConcatSequence* SequenceTree::GetRootConcatSequence() { 00289 00290 DOMNodeList* dnl = m_dom_doc->getElementsByTagName( StrX("ConcatSequence").XMLchar() ); 00291 return ((ConcatSequence*) m_Modules.find(dnl->item(0))->second); 00292 00293 } 00294 00295 /***********************************************************/ 00296 Module* SequenceTree::GetModuleByAttributeValue (string name, string value) { 00297 00298 map<DOMNode*, Module*>::iterator itmod; 00299 00300 for( itmod = m_Modules.begin(); itmod != m_Modules.end(); itmod++ ) 00301 if ( value == StrX(((DOMElement*) itmod->first )->getAttribute (StrX(name).XMLchar())).std_str() ) 00302 return itmod->second; 00303 00304 return NULL; 00305 00306 } 00307 00308 /***********************************************************/ 00309 void SequenceTree::SerializeModules(string xml_file){ 00310 00311 DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(StrX("Core").XMLchar() ); 00312 00313 if (impl==NULL) return; 00314 00315 DOMDocument* docbackup = m_dom_doc; 00316 DOMDocument* doc = impl->createDocument( 0, StrX("JEMRIS_MODULES").XMLchar(), 0); 00317 m_dom_doc = doc; 00318 DOMNode* topnode = doc->getFirstChild(); 00319 00320 DOMElement* concats = doc->createElement ( StrX("CONCATS").XMLchar() ); 00321 DOMElement* atoms = doc->createElement ( StrX("ATOMS" ).XMLchar() ); 00322 DOMElement* pulses = doc->createElement ( StrX("PULSES" ).XMLchar() ); 00323 00324 topnode->appendChild(concats); 00325 topnode->appendChild(atoms); 00326 topnode->appendChild(pulses); 00327 00328 map<string, Module*>* ModList = m_mpf->GetModuleList(); 00329 map<string, Module*>::iterator itmod; 00330 00331 for(itmod = ModList->begin(); itmod != ModList->end(); itmod++) { 00332 00333 string module_name = itmod->first; 00334 DOMElement* node = doc->createElement ( StrX(module_name).XMLchar() ); 00335 Module* module = m_mpf->CloneModule(node); 00336 00337 module->Initialize(node); 00338 module->Prepare(PREP_INIT); 00339 00340 //if any automatically added children, remove them 00341 for (int i=0;i<module->GetNumberOfChildren(); i++) 00342 node->removeChild(module->GetChild(i)->GetNode()); 00343 00344 module->AddAllDOMattributes(); 00345 00346 if (module->GetType() == MOD_CONCAT) concats->appendChild(node); 00347 if (module->GetType() == MOD_ATOM ) atoms->appendChild(node); 00348 if (module->GetType() == MOD_PULSE ) pulses->appendChild(node); 00349 if (module->GetType() == MOD_VOID ) topnode->appendChild(node); 00350 00351 cout << module->GetClassType() << endl; 00352 } 00353 00354 XMLIO xio; 00355 xio.Write(impl, doc->getDocumentElement(), xml_file); 00356 00357 m_dom_doc = docbackup; 00358 00359 }
