PluginConfigCache.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:15k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: PluginConfigCache.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 20:42:56  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: PluginConfigCache.cpp,v 1000.2 2004/06/01 20:42:56 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Robert G. Smith
  35.  *
  36.  * File Description:
  37.  *   CPluginConfigCache is a collection of saved (or saveable) configuration values
  38.  *  for plugins.  It is the parent container class streamed in and out of ASN.1 files
  39.  *  to persist these configuration values.
  40.  *   The contents of a Cache are CPluginConfigValues, indexed by their type and style
  41.  *  names. It is intended that 'type' would refer to the type of the data and 'style'
  42.  *  to the saved data values.
  43.  *
  44.  * Remark:
  45.  *   This code was originally generated by application DATATOOL
  46.  *   using specifications from the data definition file
  47.  *   'plugin.asn'.
  48.  */
  49. // standard includes
  50. // generated includes
  51. #include <ncbi_pch.hpp>
  52. #include <gui/config/PluginConfigCache.hpp>
  53. #include <gui/config/PluginConfigValues.hpp>
  54. #include <algorithm>
  55. // generated classes
  56. BEGIN_NCBI_SCOPE
  57. BEGIN_objects_SCOPE // namespace ncbi::objects::
  58. //
  59. // simple functor to check if a type matches a given value
  60. //
  61. struct STypeMatches
  62. {
  63.     STypeMatches(const string& val) : m_Key(val) {}
  64.     bool operator() (const CRef<CPluginConfigValues>& pcv) const
  65.     {
  66.         return pcv->TypeMatches(m_Key);
  67.     }
  68. private:
  69.     const string& m_Key;
  70. };
  71. // destructor
  72. CPluginConfigCache::~CPluginConfigCache(void)
  73. {
  74. }
  75. // merge two PCC's together, presumably from different files.
  76. //  the other_pcc's values over-write this one's,
  77. //  when the type, style and key are duplicates. 
  78. // Think of it as a data preserving assignment.
  79. CPluginConfigCache& CPluginConfigCache::Merge(const CPluginConfigCache& other_pcc)
  80. {
  81.     if (&other_pcc == this)
  82.         return *this;
  83.     
  84.     // for all PCVs from other_pcc
  85.     const TData& other_data = other_pcc.GetData();
  86.     ITERATE(TData, pcv_it, other_data) {
  87.         const CPluginConfigValues& other_pcv = **pcv_it;
  88.         SavePCV(other_pcv); // merge PCV's as units.
  89. /*
  90.         // If we already have this one, merge it over the old one.
  91.         // else just add it.
  92.         const TData::iterator& pcv_it2 = 
  93.             s_FindPCV(other_pcv.GetId().GetType(), other_pcv.GetId().GetStyle(), SetData());
  94.         if (pcv_it2 != SetData().end()) {
  95.             (*pcv_it2)->Assign(other_pcv);
  96.         }
  97.         else {
  98.             SavePCV(other_pcv);
  99.         }
  100. */
  101.     }
  102.     return *this;
  103. }
  104. // accessors
  105. bool CPluginConfigCache::HasPCV(const string& type, const string& style) const
  106. {
  107.     if (CanGetData()) {
  108.         const TData& pcv_list = GetData();
  109.         const TData::const_iterator& pcv_it = s_FindPCV(type, style, pcv_list);
  110.         return (pcv_it != pcv_list.end());
  111.     }
  112.     return false;
  113. }
  114. const CPluginConfigValues& CPluginConfigCache::GetPCV(const string& type, const string& style) const
  115. {
  116.     const TData& pcv_list = GetData();
  117.     const TData::const_iterator& pcv_it = s_FindPCV(type, style, pcv_list);
  118.     if (pcv_it == pcv_list.end())
  119.         ThrowUnassigned(0);
  120.     return **pcv_it;
  121. }
  122. CPluginConfigCache::TData CPluginConfigCache::GetPCVsByType(const string& aType) const
  123. {
  124.     TData   pcvs_out;
  125.     const TData&    pcvs_in = GetData();
  126.     
  127.     TData::const_iterator pcv_it =
  128.         find_if(pcvs_in.begin(), pcvs_in.end(), STypeMatches(aType));
  129.     while (pcv_it != pcvs_in.end()) {
  130.         pcvs_out.push_back(*pcv_it);        
  131.         pcv_it = find_if(++pcv_it, pcvs_in.end(), STypeMatches(aType));
  132.     }
  133.     return pcvs_out;
  134. }
  135. list<string> CPluginConfigCache::GetStyleNamesByType(const string& aType) const
  136. {
  137.     list<string> styles;
  138.     const TData&    pcvs_in = GetData();
  139.     
  140.     TData::const_iterator pcv_end = pcvs_in.end();
  141.     TData::const_iterator pcv_it =
  142.         find_if(pcvs_in.begin(), pcv_end, STypeMatches(aType));
  143.     while (pcv_it != pcv_end) {
  144.         styles.push_back((*pcv_it)->GetId().GetStyle());        
  145.         pcv_it = find_if(++pcv_it, pcv_end, STypeMatches(aType));
  146.     }
  147.     return styles;    
  148. }
  149. const string&
  150. CPluginConfigCache::GetStringByKey(const CPluginConfigValues& pcv,
  151.                                    const string& key,
  152.                                    const string& delim) const
  153. {
  154.     try {
  155.         // what kind of PCV is this?
  156.         if (pcv.CanGetByKey()) {
  157.             return pcv.GetStringByKey(key, delim);
  158.         } else if (pcv.CanGetByType()) {
  159.             // Split the key into the part before the first delimiter and the part after.
  160.             string key1, key2;
  161.             NStr::SplitInTwo(key, delim, key1, key2);
  162.             _ASSERT( ! key1.empty()); // no empty key parts.
  163.             
  164.             if ( ! key2.empty()) {
  165.                 // look up style name with first part of the key as the type
  166.                 const string& style = pcv.GetStyleByType(key1);
  167.                 // using that 'included' PCV look up our value with the rest of the key.
  168.                 // Note: no infinite recursion here since the key keeps getting shorter.
  169.                 return GetStringByKey(key1, style, key2, delim);
  170.             }
  171.             // else only single part key, but this PCV contains references
  172.             // to other PCVs not to values.
  173.             // Drop through and throw.
  174.         }
  175.         // else data not set. Drop through and throw.
  176.     } catch (CSerialException&) {
  177.         // our key wasn't found. Look in another set of values with this type
  178.         // HOW do we check for infinite loops/recursion ???
  179.         if (pcv.CanGetRefer_to_style()) {
  180.             return GetStringByKey(pcv.GetId().GetType(), pcv.GetRefer_to_style(), key, delim);
  181.         }
  182.         // still not found. Throw.
  183.     }
  184.     pcv.ThrowUnassigned(2);
  185.     static const string s;
  186.     return s; // NOT REACHED. Stops compiler warnings.
  187. }
  188. CPluginConfigValues&    // return the key/value PCV we actually store stuff in.
  189. CPluginConfigCache::AddKeyString(              // this will be pcv if typekey is empty.
  190.     CPluginConfigValues& pcv,   // the PCV we will start adding stuff to.
  191.     const string& typekey,      // type names for 'include' PCV(s)
  192.     const string& key,          // data key.
  193.     const string& value,        // data to store.
  194.     const string& delim         // delimiter for both typekey and key.
  195.     )
  196. {
  197.     if (typekey.empty()) {  // PCV is just data not references to other PCVs.
  198.         // _ASSERT(pcv.CanAddKeys()); // if not we just wipe out the 'include' there already.
  199.         pcv.AddKeyString(key, value, delim);
  200.         return pcv;
  201.     }
  202.     // Split the key into the part before the first delimiter and the part after.
  203.     string typekey1, typekey2;
  204.     NStr::SplitInTwo(typekey, delim, typekey1, typekey2);
  205.     _ASSERT( ! typekey1.empty()); // no empty key parts.
  206.     string style;
  207.     try {
  208.         style = pcv.GetStyleByType(typekey1);
  209.     } catch (const CSerialException&) {
  210.         style = "default";
  211.     }
  212.     // _ASSERT(pcv.CanAddPCId()); // if not we just wipe out the keyvals there already.
  213.     // Add the reference in this PCV
  214.     pcv.AddPCId(typekey1, style); 
  215.     // Find or Add the PCV we are referring to and continue there.
  216.     // Recursive but typekey keeps getting shorter.
  217.     return AddKeyString(typekey1, style, typekey2, key, value, delim);
  218. }
  219. bool CPluginConfigCache::DelKeyvalue(
  220.     CPluginConfigValues& pcv,
  221.     const string& key, 
  222.     const string& delim
  223.     )
  224. {
  225.     // what kind of PCV is this?
  226.     if ( pcv.CanGetByKey()  &&  pcv.DelKeyval(key, delim) ) {
  227.         return true;
  228.     } else if (pcv.CanGetByType()) {
  229.         // Split the key into the part before the first delimiter and the part after.
  230.         string key1, key2;
  231.         NStr::SplitInTwo(key, delim, key1, key2);
  232.         _ASSERT( ! key1.empty()); // no empty key parts.
  233.         
  234.         if ( ! key2.empty()) {
  235.             // look up style name with first part of the key as the type
  236.             const string& style = pcv.GetStyleByType(key1);
  237.             // using that 'included' PCV look up our value with the rest of the key.
  238.             // Note: no infinite recursion here since the key keeps getting shorter.
  239.             return DelKeyvalue(key1, style, key2, delim);
  240.         }
  241.         // else only single part key, but this PCV contains references
  242.         // to other PCVs not to values.
  243.     }
  244.         // our key wasn't found. Look in another set of values with this type
  245.     // HOW do we check for infinite loops/recursion ???
  246.     if (pcv.CanGetRefer_to_style()) {
  247.         return DelKeyvalue(pcv.GetId().GetType(), pcv.GetRefer_to_style(), key, delim);
  248.     }
  249.     // still not found.
  250.     return false;    
  251. }
  252. // Set of values mutators
  253. CPluginConfigValues& CPluginConfigCache::SetPCV(const string& type, const string& style) 
  254. {
  255.     TData& pcv_list = SetData();
  256.     const TData::iterator& pcv_it = s_FindPCV(type, style, pcv_list);
  257.     if (pcv_it == pcv_list.end()) {
  258.         CRef<CPluginConfigValues> pcv_new(new CPluginConfigValues(type, style));
  259.         pcv_list.push_back(pcv_new);
  260.         return *pcv_new;
  261.     }
  262.     return **pcv_it;
  263. }
  264. // duplicate the argument and store it in the Cache,
  265. // if there is no other with this type and style.
  266. // else replace that one with this one.
  267. CPluginConfigValues& CPluginConfigCache::SavePCV(const CPluginConfigValues& pcv)
  268. {
  269.     TData& pcv_list = SetData();
  270.     const string& type = pcv.GetId().GetType();
  271.     const string& style = pcv.GetId().GetStyle();
  272.     TData::iterator pcv_it = s_FindPCV(type, style, pcv_list);
  273.     if (pcv_it == pcv_list.end()) {
  274.         CRef<CPluginConfigValues> pcv_new(new CPluginConfigValues());
  275.         pcv_new->Assign(pcv);
  276.         pcv_list.push_back(pcv_new);
  277.         return *pcv_new;
  278.     }
  279.     (*pcv_it)->Assign(pcv);
  280.     return **pcv_it;
  281. }
  282. // duplicate a PCV giving the new copy a new style name.
  283. CPluginConfigValues& CPluginConfigCache::DupPCV(const string& type, const string& oldstyle, const string& newstyle)
  284. {
  285.     if (oldstyle == newstyle)
  286.         return SetPCV(type,  oldstyle);
  287.         
  288.     const CPluginConfigValues& pcv_old = GetPCV(type, oldstyle);
  289.         
  290.     TData& pcv_list = SetData();
  291.     TData::iterator pcv_it = s_FindPCV(type, newstyle, pcv_list);
  292.     if (pcv_it == pcv_list.end()) {
  293.         CRef<CPluginConfigValues> pcv_new(new CPluginConfigValues());
  294.         pcv_new->Assign(pcv_old);
  295.         pcv_new->SetId().SetStyle(newstyle);
  296.         pcv_list.push_back(pcv_new);
  297.         return *pcv_new;
  298.     }
  299.     (*pcv_it)->Assign(pcv_old);
  300.     (*pcv_it)->SetId().SetStyle(newstyle);
  301.     return **pcv_it;
  302. }
  303. void CPluginConfigCache::DeletePCV(const string& type, const string& style)
  304. {
  305.     TData& pcv_list = SetData();
  306.     TData::iterator pcv_it = s_FindPCV(type, style, pcv_list);
  307.     if (pcv_it != pcv_list.end()) {
  308.         pcv_list.erase(pcv_it);
  309.     }
  310.     return;
  311. }
  312. // comparison functor
  313. class TypeStyleMatches {
  314. public:
  315.     TypeStyleMatches(const string& i, const string& s) 
  316.         : type(i), style(s) {}
  317.     
  318.     bool operator()(const CRef<CPluginConfigValues>& pcv) {
  319.         return pcv->TypeMatches(type) && pcv->StyleMatches(style);
  320.     }
  321. private:
  322.     const string& type;
  323.     const string& style;
  324. };
  325.  
  326. CPluginConfigCache::TData::const_iterator
  327. CPluginConfigCache::s_FindPCV(const string& type, const string& style, const CPluginConfigCache::TData& pcvs)
  328. {
  329.     _ASSERT (!type.empty());
  330.     _ASSERT (!style.empty());
  331.     return find_if(pcvs.begin(), pcvs.end(), TypeStyleMatches(type, style));
  332. }
  333. CPluginConfigCache::TData::iterator
  334. CPluginConfigCache::s_FindPCV(const string& type, const string& style, CPluginConfigCache::TData& pcvs)
  335. {
  336.     _ASSERT (!type.empty());
  337.     _ASSERT (!style.empty());
  338.     return find_if(pcvs.begin(), pcvs.end(), TypeStyleMatches(type, style));
  339. }
  340. string CPluginConfigCache::MakeUniqueStyle(const string& type, const string& style) const
  341. {
  342.     string  new_style(style);
  343.     unsigned long     suffix_number = 0;
  344.     
  345.     while (HasPCV(type, new_style)) {
  346.         new_style = style + " " + NStr::UIntToString(++suffix_number);
  347.     }
  348.     
  349.     return new_style;
  350. }
  351. END_objects_SCOPE // namespace ncbi::objects::
  352. END_NCBI_SCOPE
  353. /*
  354. * ===========================================================================
  355. *
  356. * $Log: PluginConfigCache.cpp,v $
  357. * Revision 1000.2  2004/06/01 20:42:56  gouriano
  358. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  359. *
  360. * Revision 1.3  2004/05/21 22:27:39  gorelenk
  361. * Added PCH ncbi_pch.hpp
  362. *
  363. * Revision 1.2  2003/11/21 12:49:12  rsmith
  364. * Add ability to delete values by key.
  365. *
  366. * Revision 1.1  2003/10/10 17:43:04  rsmith
  367. * moved from gui/plugin to gui/config
  368. *
  369. * Revision 1.10  2003/08/26 19:35:07  rsmith
  370. * add methods to get a list of style names for a particular type
  371. * and to return an unused style name, give a type and style.
  372. *
  373. * Revision 1.9  2003/08/19 18:36:08  rsmith
  374. * use SplitInTwo instead of duplicating code.
  375. *
  376. * Revision 1.8  2003/08/19 18:16:53  rsmith
  377. * delete ExistsPCV, redundant with HasPCV.
  378. * new method AddKeyString.
  379. * Merge merges PCVs as units. Does not recursively merge their values.
  380. *
  381. * Revision 1.7  2003/08/13 21:40:13  ucko
  382. * CPluginConfigCache::Merge: avoid shadowing pcv_it
  383. *
  384. * Revision 1.6  2003/08/13 20:36:47  rsmith
  385. * get rid of include of find_if.hpp
  386. *
  387. * Revision 1.5  2003/08/13 20:21:44  rsmith
  388. * Add Merge method and get rid of FindIf
  389. *
  390. * Revision 1.4  2003/08/06 13:10:31  dicuccio
  391. * Replaced std::find_if() with FindIf() - work-around for MSVC's broken STL
  392. * implementation (no const_mem_fun1_t<>)
  393. *
  394. * Revision 1.3  2003/08/05 19:23:49  meric
  395. * Modified GetStringByKey() return value to avoid compiler warnings
  396. *
  397. * Revision 1.2  2003/08/05 19:01:36  rsmith
  398. * change members used in mem_fun to satisfy certain compilers.
  399. *
  400. * Revision 1.1  2003/08/05 17:35:59  rsmith
  401. * Classes to allow saving of plugin's configuration values as ASN.1.
  402. *
  403. *
  404. * ===========================================================================
  405. */
  406. /* Original file checksum: lines: 64, chars: 1901, CRC32: 6f975f95 */