NIREP

ResourceDescriptionList.cxx

Go to the documentation of this file.
00001 /***************************************************************************************
00002 *   Programmer: Gary E. Christensen
00003 *   Date: 6/24/2010
00004 *   Name: ResourceDescriptionList
00005 *   Purpose: This class keeps a list of the data files available to be loaded into memory.
00006 *      This class lists the data descriptions of images, object maps, landmark files, and 
00007 *      contour files.  It does not list information about transformations. 
00008 *      This class creates a map of DataDescription objects by parsing a data resource file.
00009 *   Required XML Tags:
00010 *       database - main tag of resource description list, must contian an id.
00011 *   resource - one tag for each resource in database, each resource can contain
00012 *                 multiple data descriptions, i.e., files
00013 *   Optional XML Tags:
00014 *      database_attributes - contains non-required user defined XML tags and values
00015 ******************************************************************************************/
00016 #include "ResourceDescriptionList.h"
00017 #include "BasicDescription.h"
00018 #include "NIREPDefinitions.h"
00019 #include <wx/log.h>
00020 
00021 #include <iostream>
00022 #include <fstream>
00023 
00026 void ResourceDescriptionList::Clear(){
00027         m_filename.clear();
00028   m_namespace.clear();
00029 
00030   ClearNameSpaceDescrips();
00031   ClearCSDescrips();
00032         ClearAlgorithmDescrips();
00033   ClearDataDescrips();
00034   ClearTransformDescrips();  
00035   ClearRDLs();
00036   ClearLabelDescrips();
00037 }
00038 
00043 //JAH changed so that we now use a FILE pointer as the main
00044 //function
00045 bool ResourceDescriptionList::Save(const std::string & filename){
00046   FILE *tempFile = fopen(filename.c_str(),"w");
00047   bool returnValue = Save(tempFile);
00048   fclose(tempFile);
00049 
00050   return returnValue;
00051 }
00052 
00053 
00058 //JAH added
00059 bool ResourceDescriptionList::Save(FILE * file){
00060         TiXmlDocument doc;  
00061 
00062         // Add XML declaration to resource description list
00063         TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  
00064   if (decl){
00065           doc.LinkEndChild( decl ); 
00066   } else {
00067     wxString msg(wxT("Error: Failed to allocate memory for Tiny XML declaration tag."));
00068     msg += wxT("\nFile: ");
00069     //msg.Append(file->_tmpfname);
00070     wxLogError(msg);  // Show a dialog box with error message
00071 
00072     return false; // Failed to allocate memory
00073   }
00074 
00075         // Add the database tag to resource description list
00076         TiXmlElement * root = new TiXmlElement("ResourceDescriptionList"); 
00077   if (root){
00078           root->SetAttribute("namespace", m_namespace.c_str());
00079           doc.LinkEndChild( root );  
00080   } else {
00081     wxString msg(wxT("Error: Failed to allocate memory for Tiny XML ResourceDescriptionList tag."));
00082     msg += wxT("\nFile: ");
00083     //msg.Append(file->_tmpfname);
00084     wxLogError(msg);  // Show a dialog box with error message
00085 
00086     return false; // Failed to allocate memory
00087   }
00088 
00089   // Cycle through included filenames. The filenames are the keys to the m_RDL map.
00090   RDLList::iterator RDL_iter;
00091   for (RDL_iter=m_RDL.begin(); RDL_iter != m_RDL.end(); RDL_iter++) {
00092     const std::string & key= RDL_iter->first;
00093 
00094     TiXmlElement * includeRDL = new TiXmlElement( "includeRDL" );
00095     if (includeRDL != NULL){
00096       includeRDL->LinkEndChild( new TiXmlText(key.c_str()));
00097       root->LinkEndChild( includeRDL );
00098     }else{
00099       wxString msg(wxT("Error: Failed to allocate memory for Tiny XML includeRDL tag."));
00100       msg += wxT("\nFile: ");
00101       //msg.Append(file->_tmpfname);
00102       wxLogError(msg);  // Show a dialog box with error message
00103 
00104       return false; // Failed to allocate memory
00105     }
00106   }
00107 
00108   // Add namespace description to resource description list DOM
00109   if (!m_namespace_descrip.empty()){
00110     BasicList::iterator ns_iter;
00111     for (ns_iter=m_namespace_descrip.begin(); ns_iter != m_namespace_descrip.end(); ns_iter++) {
00112       BasicDescription * value= ns_iter->second;
00113       root->LinkEndChild(value->CreateDOM("namespace_description"));
00114     }
00115   }
00116 
00117   // Add algorithm description to resource description list DOM
00118   if (!m_algorithm_descrip.empty()){
00119     BasicList::iterator a_iter;
00120     for (a_iter=m_algorithm_descrip.begin(); a_iter != m_algorithm_descrip.end(); a_iter++) {
00121       BasicDescription * value= a_iter->second;
00122       root->LinkEndChild(value->CreateDOM("algorithm_description"));
00123     }
00124   }
00125 
00126   // Add label descriptions to resource description list DOM
00127   if (!m_label_descrip.empty()){
00128     std::string buf;
00129     BasicList::iterator label_iter;
00130     for (label_iter=m_label_descrip.begin(); label_iter != m_label_descrip.end(); label_iter++) {
00131       BasicDescription * value= label_iter->second;
00132       root->LinkEndChild(value->CreateDOM("label_description"));
00133     }
00134   }
00135 
00136   // Add coordinate system description to resource description list DOM
00137   if (!m_cs_descrip.empty()){
00138     std::string buf;
00139     BasicList::iterator cs_iter;
00140     for (cs_iter=m_cs_descrip.begin(); cs_iter != m_cs_descrip.end(); cs_iter++) {
00141       BasicDescription * value= cs_iter->second;
00142       TiXmlElement * cs_description = value->CreateDOM("cs_description");
00143 
00144       // If there was no namespace in description, set the namespace to the
00145       // file default namespace.
00146       buf.clear();
00147       int readOkay = cs_description->QueryStringAttribute("ns", &buf);
00148       if (!readOkay || buf.empty()){
00149         cs_description->SetAttribute("ns", m_namespace.c_str());
00150       }
00151       root->LinkEndChild(cs_description);
00152     }
00153   }
00154 
00155         // Add data description to resource description list DOM
00156   if (!m_data_descrip.empty()){
00157     ResourceList::iterator dd_iter;
00158     for (dd_iter=m_data_descrip.begin(); dd_iter != m_data_descrip.end(); dd_iter++) {
00159       ResourceDescription * value= dd_iter->second;
00160       root->LinkEndChild(value->CreateDOM("data_description"));
00161     }
00162   }
00163 
00164   // Add resources to resource description list
00165   if (!m_transform_descrip.empty()){
00166     ResourceList::iterator td_iter;
00167     for (td_iter=m_transform_descrip.begin(); td_iter != m_transform_descrip.end(); td_iter++) {
00168       ResourceDescription * value= td_iter->second;
00169       root->LinkEndChild(value->CreateDOM("transform_description"));
00170     }
00171   }
00172 
00173         bool saveOkay = doc.SaveFile(file);
00174 
00175   if (saveOkay){
00176           return true;
00177   } else {
00178     wxString msg(doc.ErrorDesc(), wxConvUTF8);  // Get the error message from the tiny xml document
00179     msg += wxT("\nFile: ");
00180     //msg.Append(file->_tmpfname);
00181     wxLogError(msg);  // Show a dialog box with error message
00182 
00183     return false; // Failed to save file
00184   }
00185 }
00186 
00190 bool ResourceDescriptionList::Load(const std::string & filename){
00191         // Open fileName, parse file, and construct spatial data resource list
00192         TiXmlDocument doc(filename.c_str());
00193         bool loadOkay = doc.LoadFile();
00194 
00195   if ( !loadOkay ) {
00196     wxString msg(doc.ErrorDesc(), wxConvUTF8);  // Get the error message from the tiny xml document
00197     msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00198     wxLogError(msg);  // Show a dialog box with error message
00199 
00200     return false;
00201   }
00202    
00203 
00204         // Set the filename of this object to filename if successfully able to load and parse it.
00205         this->SetFilename(filename);
00206 
00207         TiXmlHandle hDoc(&doc);
00208         TiXmlElement* pElem;
00209         TiXmlHandle hRoot(NULL);
00210 
00211         pElem=hDoc.FirstChildElement().Element();
00212         // should always have a valid root but handle gracefully if it does
00213         if (!pElem){
00214     wxString msg(wxT("Error: no root tag"));
00215     msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00216     wxLogError(msg);  // Show a dialog box with error message
00217 
00218                 return false;
00219         }
00220 
00221   //Root should be ResourceDescriptionList and have a namespace
00222   if (pElem->ValueStr().compare("ResourceDescriptionList") == 0){
00223     if (pElem->QueryStringAttribute("namespace", &m_namespace)==TIXML_NO_ATTRIBUTE){
00224       wxString msg(wxT("Error: Missing default namespace (i.e., na=\"\") in ResourceDescriptionList tag."));
00225       msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00226       wxLogError(msg);  // Show a dialog box with error message
00227 
00228       return false; // error: namespace missing
00229     }
00230   }else{
00231     wxString msg(wxT("Error: Missing ResourceDescriptionList tag."));
00232     msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00233     wxLogError(msg);  // Show a dialog box with error message
00234 
00235     return false; // error: no ResourceDescriptionList tag in document
00236   }
00237 
00238         // save this for later
00239         hRoot=TiXmlHandle(pElem);
00240 
00241   // Get directory of current RDL file
00242   wxFileName dir(wxString(m_filename.c_str(), wxConvUTF8));
00243   wxString defaultDirectory = dir.GetPath();
00244 
00245         //Go to first attribute child of description and set attributes
00246         //Use hRoot to ensure that pElem is set to NULL if database_attributes is missing
00247         pElem=hRoot.FirstChildElement().Element();
00248         for( pElem; pElem; pElem=pElem->NextSiblingElement()) {
00249                 const std::string pKey = std::string(pElem->Value());
00250                 
00251 
00252     if (pKey.compare("namespace_description") == 0){
00253       BasicDescription * bdescrip = new BasicDescription(pElem);
00254       if(bdescrip){
00255         // Use namespace as key for adding namespace description
00256         AddNameSpaceDescrip(bdescrip->GetID(), bdescrip); 
00257       } else {
00258         wxString msg(wxT("Error: Failed to allocate memory for namespace description."));
00259         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00260         wxLogError(msg);  // Show a dialog box with error message
00261 
00262         return false; // Failed to allocate memory
00263       }
00264     }
00265 
00266     if (pKey.compare("cs_description") == 0){
00267       BasicDescription * bdescrip = new BasicDescription(pElem,m_namespace);
00268       if(bdescrip){
00269         // Use coordinate system namespace & id as key for adding coordinate system description
00270         AddCSDescrip(bdescrip->CreateNSID(), bdescrip);
00271       } else {
00272         wxString msg(wxT("Error: Failed to allocate memory for coordinate system description."));
00273         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00274         wxLogError(msg);  // Show a dialog box with error message
00275 
00276         return false; // Failed to allocate memory
00277       }
00278     }
00279     
00280     if (pKey.compare("algorithm_description") == 0){
00281       BasicDescription * bdescrip = new BasicDescription(pElem);
00282       if(bdescrip){
00283         // Use algorithm id as key for adding aglorithm description
00284         AddAlgorithmDescrip(bdescrip->GetID(), bdescrip);
00285       } else {
00286         wxString msg(wxT("Error: Failed to allocate memory for algorithm description."));
00287         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00288         wxLogError(msg);  // Show a dialog box with error message
00289 
00290         return false; // Failed to allocate memory
00291       }
00292     }
00293    
00294     if (pKey.compare("label_description") == 0){
00295       BasicDescription * bdescrip = new BasicDescription(pElem);
00296       if(bdescrip){
00297         // Use label id as key for adding label description
00298         AddLabelDescrip(bdescrip->GetID(), bdescrip);
00299       } else {
00300         wxString msg(wxT("Error: Failed to allocate memory for label description."));
00301         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00302         wxLogError(msg);  // Show a dialog box with error message
00303 
00304         return false; // Failed to allocate memory
00305       }
00306     }
00307 
00308     if (pKey.compare("data_description") == 0){
00309       ResourceDescription * rdescrip = new ResourceDescription(pElem,m_namespace);
00310       if(rdescrip){
00311         // Use dmid as key to add data description
00312         if (rdescrip->GetDMID().empty()){
00313           std::string dmid = rdescrip->CreateLabelDMID();
00314           if (dmid.empty()){
00315             wxString msg(wxT("Error: Failed to create data manager id."));
00316             msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00317             wxLogError(msg);  // Show a dialog box with error message
00318 
00319             return false; // Failed to create dmid
00320           }
00321           rdescrip->SetDMID( dmid );
00322         }
00323         // Set default directory for data description
00324         rdescrip->SetDirectory( std::string(defaultDirectory.mb_str()) );
00325         AddDataDescrip(rdescrip->GetDMID(), rdescrip);
00326       } else {
00327         wxString msg(wxT("Error: Failed to allocate memory for data description."));
00328         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00329         wxLogError(msg);  // Show a dialog box with error message
00330 
00331         return false; // Failed to allocate memory
00332       }
00333     }
00334 
00335     if (pKey.compare("transform_description") == 0){
00336       ResourceDescription * rdescrip = new ResourceDescription(pElem,m_namespace);
00337       if(rdescrip){
00338         // Use dmid as key to add transformation description
00339         if (rdescrip->GetDMID().empty()){
00340           std::string dmid = rdescrip->CreateTransformDMID();
00341           if (dmid.empty()){
00342             wxString msg(wxT("Error: Failed to create transform data manager id."));
00343             msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00344             wxLogError(msg);  // Show a dialog box with error message
00345 
00346             return false; // Failed to create dmid
00347           }
00348           rdescrip->SetDMID( dmid );
00349         }
00350         // Set default directory for transform description
00351         rdescrip->SetDirectory( std::string(defaultDirectory.mb_str()) );
00352         AddTransformDescrip(rdescrip->GetDMID(), rdescrip);
00353       } else {
00354         wxString msg(wxT("Error: Failed to allocate memory for transform description."));
00355         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00356         wxLogError(msg);  // Show a dialog box with error message
00357 
00358         return false; // Failed to allocate memory
00359       }
00360     }
00361 
00362     if (pKey.compare("includeRDL") == 0){
00363       const wxString fn = wxString(pElem->GetText(), wxConvUTF8);
00364       wxFileName fName(fn);
00365       
00366       // Set directory to defaultDirectory if fname is short form.
00367       // Assume fname is relative to directory containing filename.
00368       // Use current working directory if defaultDirectory is an empty string.     
00369       fName.Normalize(wxPATH_NORM_LONG|wxPATH_NORM_DOTS|wxPATH_NORM_TILDE|wxPATH_NORM_ABSOLUTE,defaultDirectory);
00370       std::string fullFileName = std::string(fName.GetFullPath().mb_str());
00371 
00372       ResourceDescriptionList * rdl = new ResourceDescriptionList(fullFileName,this);
00373       if (rdl){
00374         // Use filename of RDL as key to add RDL.  Add RDL to root RDL list
00375         // RDL is passed from parent to parent until added to root RDL list
00376         AddRDL(fullFileName, rdl); 
00377       } else {
00378         wxString msg(wxT("Error: Failed to allocate memory for included resource description list."));
00379         msg += wxT("\nFile: ") + wxString(filename.c_str(), wxConvUTF8);
00380         wxLogError(msg);  // Show a dialog box with error message
00381 
00382         return false; // Failed to allocate memory
00383       }
00384     }
00385 
00386         }
00387 
00388         return true;
00389 }
00390 
00397 bool ResourceDescriptionList::LoadFromDisplayDescription(const std::string & displayDescriptionFilename){
00398   wxString temp_str; // Used to remove spaces from left and right of a string
00399   std::string compare_string; // used to compare lower case string to display description tag
00400 
00401   std::ifstream dd_file(displayDescriptionFilename.c_str());
00402 
00403   if (dd_file.is_open()){
00404 
00405     // loop through the file one line at a time to find begin resource descirption list
00406     std::string line;
00407     bool found_begin = false;
00408     while (!dd_file.eof()  && (!found_begin)){  
00409       getline(dd_file,line);
00410       found_begin = CaseInsensitiveFind(line,"Begin ResourcedescriptionList");
00411     }
00412 
00413     // Report Error if did not find Begin ResourceDescriptionList
00414     if (dd_file.eof()){
00415       wxString msg(wxT("Error: "));
00416       msg += wxString(displayDescriptionFilename.c_str(), wxConvUTF8);
00417       msg += wxT(" does not contain Begin ResourceDescriptionList statement.");
00418       wxLogError(msg);
00419 
00420       dd_file.close();
00421       return false;
00422     }
00423 
00424 
00425     getline(dd_file,line);
00426     bool found_end = CaseInsensitiveFind(line,"End ResourceDescriptionList");
00427 
00428     while (!dd_file.eof()  && (!found_end)){    
00429 
00430       if(!line.empty()){
00431         // Get directory of Display Description file
00432         wxFileName dir(wxString(displayDescriptionFilename.c_str(), wxConvUTF8));
00433         wxString defaultDirectory = dir.GetPath();
00434 
00435         wxString fn = wxString(line.c_str(), wxConvUTF8);
00436         fn.Trim(false); // remove spaces from left side of filename
00437         fn.Trim(true);
00438         wxFileName fName(fn);
00439 
00440         // Set directory to defaultDirectory if fname is a short form of a filename.
00441         // Assume that fname is relative to directory containing Display Description file.
00442         // Use current working directory if defaultDirectory is an empty string.     
00443         fName.Normalize(wxPATH_NORM_LONG|wxPATH_NORM_DOTS|wxPATH_NORM_TILDE|wxPATH_NORM_ABSOLUTE,defaultDirectory);
00444         std::string rdl_filename = std::string(fName.GetFullPath().mb_str());
00445 
00446         if (!rdl_filename.empty()){
00447           if (GetFilename().empty()){
00448             this->Load(rdl_filename);
00449           } else {
00450             this->AddRDL(rdl_filename,new ResourceDescriptionList(rdl_filename));
00451           }
00452         }
00453       }
00454 
00455       getline(dd_file,line);
00456       found_end = CaseInsensitiveFind(line,"End ResourceDescriptionList");
00457     }
00458 
00459     // Check if we did not find End ResourceDescriptionList filename
00460     if (dd_file.eof()){
00461       wxString msg(wxT("Error: "));
00462       msg += wxString(displayDescriptionFilename.c_str(), wxConvUTF8);
00463       msg += wxT(" does not contain End ResourceDescriptionList");
00464       wxLogError(msg);
00465 
00466       dd_file.close();
00467       return false;
00468     }
00469 
00470     dd_file.close();
00471     return true;
00472 
00473   }else{
00474     wxString msg(wxT("Error: "));
00475     msg += wxT("Failed to open ");
00476     msg += wxString(displayDescriptionFilename.c_str(), wxConvUTF8);
00477     wxLogError(msg);
00478 
00479     return false;
00480   }
00481 }
00482 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines