freIDPath.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freIDPath.cxx,v $
00007   Language:  C++
00008 
00009 
00010   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00011   Institute for Medical Biometry and Informatics, University of Heidelberg,
00012   Germany). All rights reserved.
00013   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00014   for details.
00015 
00016      This software is distributed WITHOUT ANY WARRANTY; without even 
00017      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00018      PURPOSE.  See the above copyright notices for more information.
00019 
00020 =========================================================================*/
00021 #include "freIDPath.h"
00022 #include "freExceptions.h"
00023 #include "freConvert.h"
00024 
00025 namespace FREE
00026 {
00027 
00028 bool
00029 IDPath::
00030 IsParameterSelection() const
00031 {
00032   PathElementTypeVector::const_iterator pos;
00033 
00034   for (pos = m_ElementTypes.begin(); pos!=m_ElementTypes.end(); pos++)
00035   {
00036     if (*pos == IDPath::PTParameter) return true;
00037   }
00038 
00039   return false;
00040 };
00041 
00042 bool
00043 IDPath::
00044 IsMediaSelection() const
00045 {
00046   PathElementTypeVector::const_iterator pos;
00047 
00048   for (pos = m_ElementTypes.begin(); pos!=m_ElementTypes.end(); pos++)
00049   {
00050     if (*pos == IDPath::PTMedia) return true;
00051   }
00052 
00053   return false;
00054 };
00055 
00056 bool
00057 IDPath::
00058 IsComponentSelection() const
00059 {
00060   return !(IsMediaSelection() || IsParameterSelection());
00061 };
00062 
00063 unsigned int
00064 IDPath::
00065 Size() const
00066 {
00067   return m_ElementTypes.size();
00068 };
00069 
00070 unsigned int
00071 IDPath::
00072 AddComponent(const PathElementType& elementType, const std::string& sTag)
00073 {
00074   m_ElementTypes.push_back(elementType);
00075   m_ElementTags.push_back(sTag);
00076   return m_ElementTypes.size()-1;
00077 };
00078 
00079 IDPath::PathElementType
00080 IDPath::
00081 GetComponent(const unsigned int& index, std::string& sTag) const
00082 {
00083   if ((index<0) || (index>=Size()))
00084   {
00085     sTag = "";
00086     return IDPath::PTNULL;
00087   }
00088 
00089   sTag = m_ElementTags[index];
00090   return m_ElementTypes[index];
00091 };
00092 
00093 
00094 IDPath::PathElementType
00095 IDPath::
00096 GetFirstComponent(std::string& sTag) const
00097 {
00098   return GetComponent(0,sTag);
00099 };
00100 
00101 
00102 IDPath
00103 IDPath::
00104 GetSubIDPath() const
00105 {
00106   IDPath newPath = AssembleIDPath(1,Size()-1);
00107   return newPath;
00108 };
00109 
00110 IDPath
00111 IDPath::
00112 GetParentIDPath() const
00113 {
00114   IDPath newPath = AssembleIDPath(0,Size()-2);
00115   newPath.SetAbsolute(this->IsAbsolute());
00116   return newPath;
00117 };
00118 
00119 IDPath
00120 IDPath::
00121 GetParentComponentIDPath() const
00122 {
00123         IDPath newPath = GetParentIDPath();
00124         while (!newPath.IsEmpty())
00125         {
00126                 if (newPath.IsComponentSelection()) break;
00127                 newPath = newPath.GetParentIDPath();
00128         }
00129         return newPath;
00130 };
00131 
00132 
00133 IDPath
00134 IDPath::
00135 GetParameterIDPath() const
00136 {
00137   IDPath newPath;
00138 
00139   PathElementTypeVector::const_iterator pos;
00140   int iParaPos = 0;
00141 
00142   for (pos = m_ElementTypes.begin(); pos!=m_ElementTypes.end(); pos++, iParaPos++)
00143   {
00144     if (*pos == IDPath::PTParameter) break;
00145   }
00146 
00147   if (iParaPos<Size())
00148   {
00149     newPath = AssembleIDPath(iParaPos,Size()-1);
00150   }
00151   
00152   return newPath;
00153 };
00154 
00155 std::string
00156 IDPath::
00157 GetParameterName() const
00158 {
00159   PathElementTypeVector::const_iterator pos;
00160   STLStringVector::const_iterator posTag = m_ElementTags.begin();
00161 
00162   for (pos = m_ElementTypes.begin(); pos!=m_ElementTypes.end(); pos++, posTag++)
00163   {
00164     if (*pos == IDPath::PTParameter) return *posTag;
00165   }
00166   return "";
00167 };
00168 
00169 std::string
00170 IDPath::
00171 GetMediaID() const
00172 {
00173   PathElementTypeVector::const_iterator pos;
00174   STLStringVector::const_iterator posTag = m_ElementTags.begin();
00175 
00176   for (pos = m_ElementTypes.begin(); pos!=m_ElementTypes.end(); pos++, posTag++)
00177   {
00178                 if (*pos == IDPath::PTMedia) return *posTag;
00179   }
00180   return "";
00181 };
00182 
00183 std::string
00184 IDPath::
00185 GetComponentID() const
00186 {
00187   PathElementTypeVector::const_reverse_iterator pos;
00188   STLStringVector::const_reverse_iterator posTag = m_ElementTags.rbegin();
00189 
00190   for (pos = m_ElementTypes.rbegin(); pos!=m_ElementTypes.rend(); pos++, posTag++)
00191   {
00192     if (*pos == IDPath::PTComponent) return *posTag;
00193   }
00194   return "";
00195 };
00196 
00197 std::string
00198 IDPath::
00199 ToStr() const
00200 {
00201   std::string sPath;
00202 
00203   if (Size() == 0) return sPath;
00204 
00205   if (this->m_ElementTypes[0] != IDPath::PTAnyDescendant)
00206   {
00207     if (this->IsAbsolute()) sPath = "/";
00208   }
00209 
00210   for (unsigned int i = 0; i<m_ElementTypes.size(); i++)
00211   {
00212     if (this->m_ElementTypes[i] == IDPath::PTAnyChild) sPath += "*";
00213     else if (this->m_ElementTypes[i] == IDPath::PTAnyDescendant) sPath += "//";
00214     else if (this->m_ElementTypes[i] == IDPath::PTComponent) sPath += this->m_ElementTags[i];
00215     else if (this->m_ElementTypes[i] == IDPath::PTParameter) sPath += "@"+this->m_ElementTags[i];
00216                 else if (this->m_ElementTypes[i] == IDPath::PTMedia) sPath += "#"+this->m_ElementTags[i];
00217     else if (this->m_ElementTypes[i] == IDPath::PTParent) sPath += "..";
00218                 else if (this->m_ElementTypes[i] == IDPath::PTSelf) sPath += ".";
00219 
00220     if ((i < m_ElementTypes.size()-1) && (this->m_ElementTypes[0] != IDPath::PTAnyDescendant))
00221     { //if it isn't the last element and it is not "//" a "/" is needed as seperator
00222       sPath += "/";
00223     }
00224   }
00225 
00226   return sPath;
00227 };
00228 
00229 bool
00230 IDPath::
00231 operator == (const IDPath& path) const
00232 {
00233   return IDPathesMatch(*this,path);
00234 };
00235 
00236 bool
00237 IDPath::
00238 Equals(const IDPath& path) const
00239 {
00240         return this->ToStr() == path.ToStr();
00241 };
00242 
00243 bool
00244 IDPath::
00245 ChildOf(const IDPath& path) const
00246 {
00247         std::string sTag;
00248         PathElementType pe = GetComponent(this->Size()-1,sTag);
00249         if (pe == IDPath::PTNULL) return false;
00250         if (pe == IDPath::PTAnyChild) sTag = "*";
00251         if (pe == IDPath::PTMedia) sTag = "#"+sTag;
00252         if (pe == IDPath::PTParameter) sTag = "@"+sTag;
00253 
00254         sTag = ".//"+sTag;
00255 
00256         IDPath childPath = path + sTag;
00257 
00258         return this->operator ==(childPath);
00259 };
00260 
00261 IDPath&
00262 IDPath::
00263 operator = (const IDPath& path)
00264 {
00265   if (&path == this) return *this;
00266 
00267   Reset();
00268 
00269   this->m_bAbsolute = path.IsAbsolute();
00270 
00271   for (unsigned int i = 0; i<path.Size(); i++)
00272   {
00273     std::string sTag;
00274     PathElementType token = path.GetComponent(i,sTag);
00275     this->AddComponent(token,sTag);
00276   }
00277 
00278   return *this;
00279 };
00280 
00281 IDPath&
00282 IDPath::
00283 operator = (const std::string& path)
00284 {
00285   TokenType token;
00286   std::string sSubPath;
00287   std::string sTag;
00288 
00289   Reset();
00290 
00291   bool bProceed = this->GetFirstToken(path,token,sTag,sSubPath);
00292   this->SetAbsolute(token == IDPath::TTSlash);
00293 
00294   while (bProceed)
00295   {
00296     if (token != IDPath::TTSlash)
00297     {
00298       if (token == IDPath::TTComponent)
00299       { //component, parameter or media?
00300         std::string sComponentID = "";
00301         PathElementType pe = GetComponentType(sTag,sComponentID);
00302         this->AddComponent(pe, sComponentID);
00303       }
00304       else
00305       { 
00306         this->AddComponent((IDPath::PathElementType)token,"");
00307         //all other tokens have the same ID like their corresponding path element types
00308         //and they have no tags.
00309       }
00310     }
00311     bProceed = this->GetFirstToken(sSubPath,token,sTag,sSubPath);
00312   }
00313 
00314   return *this;
00315 };
00316 
00317 IDPath&
00318 IDPath::
00319 operator = (const char* path)
00320 {
00321   std::string sTemp = path;
00322   *this = sTemp;
00323   return *this;
00324 };
00325 
00326 IDPath
00327 IDPath::
00328 TransformIDPath(const IDPath& origin) const
00329 {
00330   return origin + (*this);
00331 };
00332 
00333 IDPath
00334 IDPath::
00335 operator + (const IDPath& modPath) const
00336 {
00337   if (modPath.IsAbsolute()) return modPath;
00338 
00339   IDPath newPath = *this;
00340   IDPath newModPath = modPath;
00341 
00342   std::string sTag;
00343   PathElementType token = newModPath.GetFirstComponent(sTag);
00344 
00345   while ((token == IDPath::PTParent) || (token == IDPath::PTSelf))
00346   {
00347     newModPath = newModPath.GetSubIDPath();
00348 
00349     if (token == IDPath::PTParent) newPath = newPath.GetParentIDPath();
00350 
00351     token = newModPath.GetFirstComponent(sTag);
00352   }
00353 
00354   return Concat(newPath, newModPath);
00355 };
00356 
00357 IDPath
00358 IDPath::Concat(const IDPath& path1, const IDPath& path2)
00359 {
00360   IDPath newPath = path1;
00361   for (unsigned int i = 0; i<path2.Size(); i++)
00362   {
00363     std::string sTag;
00364     PathElementType token = path2.GetComponent(i,sTag);
00365     newPath.AddComponent(token,sTag);
00366   }
00367 
00368   return newPath;
00369 };
00370 
00371 IDPath::IDPath():XMLStreamObject(cXML_IDPath)
00372 {
00373   Reset();
00374 };
00375 
00376 IDPath::
00377 IDPath(const IDPath& path):XMLStreamObject(cXML_IDPath)
00378 {
00379   *this = path;
00380 };
00381 
00382 IDPath::
00383 IDPath(const std::string& path):XMLStreamObject(cXML_IDPath)
00384 {
00385   *this = path;
00386 };
00387 
00388 IDPath::
00389 IDPath(const char* path):XMLStreamObject(cXML_IDPath)
00390 {
00391   *this = path;
00392 };
00393 
00394 IDPath::
00395 ~IDPath() {};
00396 
00397 void
00398 IDPath::
00399 Reset()
00400 {
00401   this->m_bAbsolute = true;
00402   this->m_ElementTags.clear();
00403   this->m_ElementTypes.clear();
00404 };
00405 
00406 void
00407 IDPath::
00408 SubElementLoadProcessing(const std::string& rsXMLSubTag, const std::string& rsXMLSubElement, const std::string& rsXMLSubData)
00409 {
00410   *this = rsXMLSubData;
00411 };
00412 
00413 std::string
00414 IDPath::
00415 SaveData(const unsigned int& iDepth, bool& bHasSubElements) const
00416 {
00417   bHasSubElements = false;
00418   return this->ToStr();
00419 };
00420 
00421 IDPath
00422 IDPath::
00423 AssembleIDPath(const unsigned int& iFirstID, const unsigned int& iLastID) const
00424 {
00425   IDPath newPath;
00426   newPath.SetAbsolute(false);
00427 
00428   if ((iFirstID<0)||(iFirstID>=this->Size())) return newPath;
00429 
00430   unsigned int iActLastID = iLastID;
00431 
00432   if (iLastID>=Size()) iActLastID = Size()-1;
00433 
00434   for (unsigned int i = iFirstID; i<=iActLastID; i++)
00435   {
00436     std::string sTag;
00437     PathElementType token = this->GetComponent(i,sTag);
00438     newPath.AddComponent(token,sTag);
00439   }
00440 
00441   return newPath;
00442 };
00443 
00444 bool
00445 IDPath::
00446 IDPathesMatch(const IDPath& left, const IDPath& right)
00447 {
00448   if ((left.IsEmpty())&&(right.IsEmpty())) return true;
00449   else if (left.IsEmpty()||right.IsEmpty()) return false;
00450 //  if (left.IsAbsolute() != right.IsAbsolute()) return false;
00451 
00452   std::string sLeftComp;
00453   std::string sRightComp;
00454 
00455   PathElementType leftToken = left.GetFirstComponent(sLeftComp);
00456   PathElementType rightToken = right.GetFirstComponent(sRightComp);
00457 
00458   if ((leftToken == IDPath::PTAnyDescendant) || (rightToken == IDPath::PTAnyDescendant))
00459   {
00460     IDPath search = right;
00461     IDPath pattern = left.GetSubIDPath();
00462     
00463                 if (rightToken == IDPath::PTAnyDescendant) 
00464     {
00465       search = left;
00466       pattern = right.GetSubIDPath();
00467                 };
00468 
00469     while (!search.IsEmpty())
00470           {
00471                         if (IDPathesMatch(search,pattern)) return true;
00472                         search = search.GetSubIDPath();
00473                 };
00474 
00475     return false;
00476     //if one token is double slashed and no match is found yet there will be no match anyway
00477     //it also handels the fact when both pathes are double slashed as a nested recursion.
00478   }
00479 
00480   if (((leftToken == IDPath::PTAnyChild) || (rightToken == IDPath::PTAnyChild)) ||
00481       ((sLeftComp==sRightComp) && (rightToken==leftToken)))
00482   { //untill now everythin is legal, proceed to next part of the pathes.
00483     return IDPathesMatch(left.GetSubIDPath(),right.GetSubIDPath());
00484   }
00485   
00486   return false;
00487 };
00488 
00489 bool
00490 IDPath::
00491 GetFirstToken(const std::string& sIDPath, TokenType& token, std::string& sFirstTag, std::string& sSubPath )
00492 {
00493   std::string sPath = sIDPath;
00494 
00495   unsigned int pos = sPath.find_first_of("/");
00496         if ((pos==0) && (sPath.size()>1))
00497         {
00498                 if (sPath[1]=='/') pos = 1;
00499         }
00500 
00501   unsigned int subPos = pos+1;
00502   if ((subPos >= sPath.size())||(pos==std::string::npos)) sSubPath = "";
00503   else sSubPath = sPath.substr(subPos);
00504 
00505   sFirstTag = sPath.substr(0,pos);
00506  
00507   if (sFirstTag =="") token = TTSlash;
00508   else if (sFirstTag =="/") token = TTDSlash;
00509   else if (sFirstTag ==".") token = TTDot;
00510   else if (sFirstTag =="..") token = TTDDot;
00511   else if (sFirstTag =="*") token = TTWildcard;
00512   else token = TTComponent;
00513 
00514   if (sPath.empty()) return false;
00515   return true;
00516 };
00517 
00518 IDPath::PathElementType
00519 IDPath::
00520 GetComponentType(const std::string& sTokenTag, std::string& sComponentID)
00521 {
00522   unsigned int pos = sTokenTag.find_first_of("@");
00523         if (pos==0)
00524   { //it's an attibute / parameter
00525     if (sTokenTag.size()<2) throwStaticExceptionMacro("Error, while converting string to IDPath. Parameter specified, but parameter name missing.");
00526     sComponentID = sTokenTag.substr(1);
00527     return IDPath::PTParameter;
00528   }
00529 
00530   pos = sTokenTag.find_first_of("#");
00531         if (pos==0)
00532   { //it's a media component
00533     if (sTokenTag.size()<2) throwStaticExceptionMacro("Error, while converting string to IDPath. Media specified, but media name missing.");
00534     sComponentID = sTokenTag.substr(1);
00535     return IDPath::PTMedia;
00536   }
00537 
00538   pos = sTokenTag.find_first_of("::");
00539         if (pos!=-1)
00540   { //it has an axis definition.
00541     if (sTokenTag.substr(0,pos) == "attribute")
00542     {
00543       if (sTokenTag.size()<pos+3) throwStaticExceptionMacro("Error, while converting string to IDPath. Parameter specified, but parameter name missing.");
00544       sComponentID = sTokenTag.substr(pos+2);
00545       return IDPath::PTParameter;
00546     }
00547 
00548     if (sTokenTag.substr(0,pos) == "media")
00549     {
00550       if (sTokenTag.size()<pos+3) throwStaticExceptionMacro("Error, while converting string to IDPath. Media specified, but media name missing.");
00551       sComponentID = sTokenTag.substr(pos+2);
00552       return IDPath::PTMedia;
00553     }
00554   }
00555 
00556   sComponentID = sTokenTag;
00557   return IDPath::PTComponent;
00558 };
00559 
00560 IDPath
00561 IDPath::
00562 Parameter(const std::string& sParameterName, unsigned long lValueID, unsigned long lLayerID)
00563 {
00564   IDPath result;
00565   result.SetAbsolute(false);
00566   result.AddComponent(IDPath::PTParameter,sParameterName);
00567 
00568   if (lValueID || lLayerID)
00569   { //if a layer or value ID is not default (so not 0), add the layer to the IDPath
00570     result.AddComponent(IDPath::PTComponent,Convert::ToStr(lLayerID));
00571   }
00572 
00573   if (lValueID)
00574   { //if a value ID is not default (so not 0) , add the value ID to the IDPath
00575     result.AddComponent(IDPath::PTComponent,Convert::ToStr(lValueID));
00576   }
00577 
00578   return result;
00579 };
00580 
00581 IDPath
00582 IDPath::
00583 Media(const std::string& sMediaName)
00584 {
00585   IDPath result;
00586   result.SetAbsolute(false);
00587   result.AddComponent(IDPath::PTMedia,sMediaName);
00588   return result;
00589 };
00590 
00591 void DispatchParameterIDPath(const IDPath& parameterID, std::string& sParameterName, unsigned long& riItemPos, unsigned long& riLayer)
00592 {
00593   riItemPos = 0;
00594   riLayer = 0;
00595   sParameterName = "";
00596   std::string sTemp;
00597 
00598   //ensure that the first component is the parameter
00599   IDPath parameterOnlyID = parameterID.GetParameterIDPath();
00600 
00601   if (parameterOnlyID.IsEmpty()) throwStaticExceptionMacro("IDPath is no parameter selection, hence not suitable for this function. Passed path: "<<parameterID.ToStr());
00602 
00603   parameterOnlyID.GetComponent(0,sParameterName);
00604 
00605   if (parameterOnlyID.GetComponent(1,sTemp) == IDPath::PTComponent)
00606   { //this should be a layer specificion
00607     if (!Convert::IsAInt(sTemp)) throwStaticExceptionMacro("IDPath seems to be invalid. Component tag after attribut element must be an integer specifying the layer. Found tag: "<<sTemp);
00608     riLayer = Convert::ToInt(sTemp);
00609   }
00610 
00611   if (parameterOnlyID.GetComponent(2,sTemp) == IDPath::PTComponent)
00612   { //this should be a layer specificion
00613     if (!Convert::IsAInt(sTemp)) throwStaticExceptionMacro("IDPath seems to be invalid. 2nd component tag after attribut element must be an integer specifying the value position. Found tag: "<<sTemp);
00614     riItemPos = Convert::ToInt(sTemp);
00615   }
00616 };
00617 
00618 } //end of namespace FREE

Generated at Sat Oct 13 16:02:18 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000