NCBI C++ ToolKit
ui_tool_registry.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ui_tool_registry.cpp 39666 2017-10-25 16:01:13Z katargir $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Andrey Yazhuk
27  */
28 
29 #include <ncbi_pch.hpp>
30 
31 #include <corelib/ncbistd.hpp>
32 #include <corelib/ncbistl.hpp>
33 #include <corelib/ncbireg.hpp>
34 #include <corelib/ncbifile.hpp>
35 
38 
41 
42 #include <stdio.h>
43 #include <set>
44 
45 #include <wx/filename.h>
46 #include <wx/dir.h>
47 
49 
50 
51 ///////////////////////////////////////////////////////////////////////////////
52 /// CUIToolRegistry
53 
56 
57 
59 {
60 }
61 
62 
64 {
65  Clear();
66 }
67 
68 
70 {
71  CMutexGuard LOCK(s_Mutex);
74 }
75 
76 
78 {
80  GetInstance()->Clear();
81  Reset();
82 }
83 
84 
86 {
87  if ( !sm_Instance ) {
88  CMutexGuard LOCK(s_Mutex);
89  if ( !sm_Instance ) {
91  }
92  }
93 
94  return sm_Instance.GetPointer();
95 }
96 
97 
98 void CUIToolRegistry::RegisterTool(IUITool* prototype, const string& tool_id)
99 {
100  _ASSERT(prototype);
101  if(!prototype)
102  return;
103  bool registered = false;
104  const string& name = prototype->GetName();
105  auto it = m_NameToId.find(name);
106 
107  if (it == m_NameToId.end()) { // first time - register
108 
109  string ltool_id = tool_id;
110  if (ltool_id.empty())
111  ltool_id = name;
112  if (m_IdToRec.count(ltool_id) == 0) {
113  m_NameToId[name] = ltool_id;
114  // create a registration record for the method
116  rec->m_Tool = prototype;
117  m_IdToRec[ltool_id] = rec;
118  registered = true;
119  }
120  }
121  if (!registered) {
122  ERR_POST("CUIToolRegistry::RegisterTool() - " << name <<
123  " method already registered");
124  }
125 }
126 
127 
128 void CUIToolRegistry::RegisterTemplateTool(const string& class_name,
129  ITemplateUITool* prototype)
130 {
131  _ASSERT(prototype);
132 
134  if(it != m_ClassToTemplate.end()) {
135  _ASSERT(false);
136  ERR_POST("CUIToolRegistry::RegisterTemplateTool() - class " <<
137  class_name << " already registred");
138  } else {
139  IUITool* tool = dynamic_cast<IUITool*>(prototype);
140  if(tool) {
141  m_ClassToTemplate[class_name] = CIRef<IUITool>(tool);
142  } else {
143  _ASSERT(false);
144  ERR_POST("CUIToolRegistry::RegisterTemplateTool() - prototype "
145  << " does implement IUITool interface.");
146  }
147  }
148 }
149 
150 
151 bool CUIToolRegistry::IsToolRegistered(const string& name) const
152 {
153  return m_NameToId.count(name) > 0 || m_IdToRec.count(name) > 0;
154 }
155 
156 
157 static const char* kRegTag = "Scoring Tool Registry";
158 
160 {
161  ITERATE (TDirList, path_iter, dirs) {
162 
163  wxString path_name = CSysPath::ResolvePath(*path_iter);
164  if( !wxFileName::DirExists(path_name) ) {
165  LOG_POST(Info << kRegTag << ": Directory \"" << path_name.ToUTF8() << "\" does not exist");
166  } else {
167  // scan this directory
168  // we consider all files in this directory to be scoring method definitions
169 
170  wxString filename;
171  wxFileName fname(path_name, wxEmptyString);
172  wxDir dir(path_name);
173  bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES);
174  while ( cont ) {
175  fname.SetFullName(filename);
176  x_ReadToolInfo(fname.GetFullPath());
177  cont = dir.GetNext(&filename);
178  }
179  }
180  }
181 }
182 
183 
184 static const char* kInvalidDef = " - invalid method definition: ";
185 
186 
187 bool CUIToolRegistry::x_ReadToolInfo(const wxString& full_path)
188 {
189  string error;
190  CNcbiIfstream is(full_path.fn_str());
191 
192  if( ! is) {
193  ERR_POST(kRegTag << " - failed to read alignment scoring method: " << full_path.ToUTF8());
194  return false;
195  }
196 
197  try {
198  CNcbiRegistry reg(is);
199 
200  string tool_class = reg.GetString("Info", "Tool", "");
201  if(tool_class.empty()) {
202  // try the old key
203  tool_class = reg.GetString("Info", "Method", "");
204  }
205  // check if Tool Class is registered
206  TStrToTool::iterator it_class = m_ClassToTemplate.find(tool_class);
207  if(it_class == m_ClassToTemplate.end()) {
208  ERR_POST(kRegTag << kInvalidDef << " method \"" << tool_class
209  << "\" is not registered. Definition file: " << full_path.ToUTF8());
210  return false;
211  }
212 
213  string tool_id = reg.GetString("Info", "Id", "");
214  if (tool_id.empty()) {
215  tool_id = wxFileName::FileName(full_path).GetFullName();
216  }
217  if (m_IdToRec.count(tool_id) != 0) {
218  ERR_POST(kRegTag << kInvalidDef << "Tool \"" << tool_id
219  << " is already registered. Definition file: " << full_path.ToUTF8());
220  return false;
221  }
222 
223  IUITool* clone = it_class->second->Clone();
224  CIRef<ITemplateUITool> method(dynamic_cast<ITemplateUITool*>(clone));
225  _ASSERT(method);
226 
227  if(method->LoadInfo(reg)) {
228  string method_name = clone->GetName();
229 
230  // check if Tool Name is empty
231  if (method_name.empty()) {
232  ERR_POST(kRegTag << kInvalidDef << "Name is empty in " << full_path.ToUTF8());
233  return false;
234  }
235 
236  // check if Tool Name is unique
237  TNameToId::iterator it_name = m_NameToId.find(method_name);
238  if(it_name != m_NameToId.end()) {
239  ERR_POST(kRegTag << kInvalidDef << "Name \"" << method_name
240  << " is already registered. Definition file: " << full_path.ToUTF8());
241  return false;
242  }
243  m_NameToId[method_name] = tool_id;
244  // create a registration record for the method
246  rec->m_Tool = clone;
247  // rec->m_Template = method;
248  rec->m_FileName = full_path;
249 
250  m_IdToRec[tool_id] = rec; // register
251  return true;
252  }
253  } catch (CException& e) {
254  error = e.GetMsg();
255  } catch (std::exception& e) {
256  error = e.what();
257  }
258  ERR_POST(kRegTag << kInvalidDef << " in file \"" << full_path.ToUTF8() << "\" " << error);
259  return false;
260 }
261 
262 
263 const static char* kFailedToRead = " - failed to read alignment scoring method: ";
264 
266  const wxString& full_path)
267 {
268  CNcbiIfstream is(full_path.fn_str());
269 
270  if( ! is) {
272  << "cannot open file \"" << full_path.ToUTF8() << "\"");
273  return false;
274  }
275 
276  CNcbiRegistry reg(is);
277 
278  bool ok = false;
279  string error;
280  try {
281  ok = method.Load(reg);
282  } catch(CException& e) {
283  error = e.GetMsg();
284  } catch(std::exception& e) {
285  error = e.what();
286  }
287  if( ! ok) {
289  << " in \"" << full_path.ToUTF8() << "\"");
290  }
291  return ok;
292 }
293 
294 
295 void CUIToolRegistry::GetToolNames(vector<string>& names) const
296 {
297  names.reserve(m_NameToId.size());
298  ITERATE(TNameToId, it_r, m_NameToId) {
299  names.push_back(it_r->first);
300  }
301 }
302 
303 
304 void CUIToolRegistry::GetToolNames(vector<string>& names, ISelector& selector) const
305 {
306 
307  ITERATE(TNameToId, it_r, m_NameToId){
308  auto it = m_IdToRec.find(it_r->second);
309  _ASSERT(it != m_IdToRec.end());
310  if (it == m_IdToRec.end())
311  continue;
312  const STemplateToolRecord& rec = *it->second;
313  if(selector.Select(*rec.m_Tool)) {
314  names.push_back(it_r->first);
315  }
316  }
317 }
318 
319 
320 
321 void CUIToolRegistry::GetTools(vector<CConstIRef<IUITool> >& tools, ISelector& selector) const
322 {
324  const STemplateToolRecord& rec = *it->second;
325  // const STemplateToolRecord& rec = *it_r->second;
326  const IUITool& tool = *rec.m_Tool;
327  if(selector.Select(tool)) {
328  tools.push_back(CConstIRef<IUITool>(&tool));
329  }
330  }
331 }
332 
333 void CUIToolRegistry::GetToolId(const string& name, string& tool_id) const
334 {
335  auto it_name = m_NameToId.find(name);
336  _ASSERT(it_name != m_NameToId.end());
337  if (it_name == m_NameToId.end())
338  tool_id = name;
339  else
340  tool_id = it_name->second;
341 }
342 
343 
345 {
346 
347  string tool_id = name;
348 
349  auto it_r = m_NameToId.find(name);
350  if (it_r != m_NameToId.end()) { // else see if name is tool_id
351  tool_id = it_r->second;
352  }
353  auto it = m_IdToRec.find(tool_id);
354  if (it == m_IdToRec.end())
355  return 0;
356  return it->second.get();
357 }
358 
359 
360 
361 string CUIToolRegistry::GetToolDescription(const string& name) const
362 {
363  const STemplateToolRecord* rec = x_GetToolRecByName(name);
364  if (rec)
365  return rec->m_Tool->GetDescription();
366 
367  static string descr("not implemented");
368  return descr;
369 }
370 
371 
373 {
374 
375  const STemplateToolRecord* rec = x_GetToolRecByName(method_name);
376  if (rec) {
377  const IUITool& proto = *rec->m_Tool;
378  // create the instance
379  CIRef<IUITool> clone(proto.Clone());
380  if (rec->m_FileName.IsEmpty()) // came from RegisterTool
381  return clone;
382 
383  ITemplateUITool* tool =
384  dynamic_cast<ITemplateUITool*>(clone.GetPointer());
385  _ASSERT(tool);
386  if(x_LoadTemplateTool(*tool, rec->m_FileName))
387  return clone; // success
388  }
389 
390  return CIRef<IUITool>(0);
391 }
392 
393 
395 {
396  m_NameToId.clear();
397  m_IdToRec.clear();
399 }
400 
401 
402 
403 bool CUIToolRegistry::MRUListExists(const string& list) const
404 {
406  return it != m_NameToMRUList.end();
407 }
408 
409 
410 static const int kDefMRUSize = 10;
411 static const int kMaxMRUSize = 20;
412 
413 
414 void CUIToolRegistry::CreateMRUList(const string& list, int size)
415 {
416  if(MRUListExists(list)) {
417  _ASSERT(false);
418  ERR_POST("CUIToolRegistry::CreateMRUList() - MRU list " + list + " already exists.");
419  } else {
420  if(size < 1 || size > kMaxMRUSize) {
421  _ASSERT(false);
422  size = kDefMRUSize;
423  }
424  m_NameToMRUList[list] = TMRUList(size);
425  }
426 }
427 
428 
429 void CUIToolRegistry::SetMaxMRUSize(const string& list, int size)
430 {
432  if(it != m_NameToMRUList.end()) {
433  if(size < 1 || size > kMaxMRUSize) {
434  _ASSERT(false);
435  ERR_POST("CUIToolRegistry::SetMaxMRUSize() - the provided value " <<
436  size << " is out of range.");
437  } else {
438  it->second.SetMaxSize(size);
439  }
440  } else {
441  _ASSERT(false);
442  ERR_POST("CUIToolRegistry::SetMaxMRUSize() - the list " << list << " does not exist");
443  }
444 }
445 
446 
447 void CUIToolRegistry::SetMRUToolNames(const string& list_name, const vector<string>& tool_names)
448 {
450  if(it == m_NameToMRUList.end()) {
451  _ASSERT(false);
452  ERR_POST("CUIToolRegistry::SetMRUToolNames() - the list " << list_name
453  << " does not exist");
454  } else {
455  list<string> tmp;
456  set<string> dups;
457  ITERATE(vector<string>, it_n, tool_names) {
458  const string& name = *it_n;
459  if(IsToolRegistered(name) && dups.insert(name).second ) {
460  tmp.push_back(name);
461  }
462  }
463 
464  it->second.SetItems(tmp);
465  }
466 }
467 
468 
469 void CUIToolRegistry::GetMRUToolNames(const string& list_name, vector<string>& tool_names)
470 {
472  if(it == m_NameToMRUList.end()) {
473  _ASSERT(false);
474  ERR_POST("CUIToolRegistry::SetMRUToolNames() - the list " << list_name <<
475  " does not exist");
476  } else {
477  const TMRUList& mru = it->second;
478  const list<string>& items = mru.GetItems();
479 
480  //tool_names.insert(tool_names.begin(), items.begin(), items.end());
481  std::copy(items.begin(), items.end(), back_inserter(tool_names));
482  }
483 }
484 
485 
486 void CUIToolRegistry::AddToolToMRU(const string& list_name, const string& tool_name)
487 {
489  if(it == m_NameToMRUList.end()) {
490  _ASSERT(false);
491  ERR_POST("CUIToolRegistry::SetMRUToolNames() - the list " << list_name <<
492  " does not exist");
493  } else {
494  it->second.AddItem(tool_name);
495  }
496 }
497 
498 void CUIToolRegistry::SetRegistryPath(const string& path)
499 {
500  m_RegPath = path; // store for later use
501 }
502 
503 static const char* kMRUSectionRegKey = "MRU Lists";
504 
506 {
507  if( ! m_RegPath.empty()) {
509  /// load MRU lists
511 
513 
514  /// all key in mru_view should correspond to MRU lists
516  mru_view.GetKeys(keys);
517  ITERATE(CRegistryReadView::TKeys, it, keys) {
518  const CRegistryReadView::SKeyInfo& key = *it;
519  _ASSERT(key.type == objects::CUser_field::C_Data::e_Strs);
520 
521  string list_name = key.key;
522  vector<string> names;
523  mru_view.GetStringVec(list_name, names);
524 
525  CreateMRUList(list_name);
526  SetMRUToolNames(list_name, names);
527  }
528  } else {
529  _ASSERT(false);
530  ERR_POST("CUIToolRegistry::LoadSettings() - empty registry path.");
531  }
532 }
533 
534 
536 {
537  if( ! m_RegPath.empty()) {
539  CRegistryWriteView view = gui_reg.GetWriteView(m_RegPath);
541 
543  const string& list_name = it->first;
544 
545  const TMRUList& mru = it->second;
546  const list<string>& items = mru.GetItems();
547 
548  mru_view.Set(list_name, items);
549  }
550  } else {
551  _ASSERT(false);
552  ERR_POST("CUIToolRegistry::LoadSettings() - empty registry path.");
553  }
554 }
555 
556 
static string MakeKey(const string &section, const string &key, const string &delim=CGuiRegistry::kDecimalDot)
create a key from a section and a subkey
Definition: registry.cpp:504
CRegistryWriteView GetWriteView(const string &section)
get a read-write view at a particular level.
Definition: registry.cpp:462
static CGuiRegistry & GetInstance()
access the application-wide singleton
Definition: registry.cpp:400
CRegistryReadView GetReadView(const string &section) const
get a read-only view at a particular level.
Definition: registry.cpp:428
const TItems & GetItems() const
Definition: mru_list.hpp:96
CNcbiRegistry –.
Definition: ncbireg.hpp:913
class CRegistryReadView provides a nested hierarchical view at a particular key.
Definition: reg_view.hpp:58
list< SKeyInfo > TKeys
retrieve information about all keys in the registry
Definition: reg_view.hpp:68
void GetStringVec(const string &key, vector< string > &val) const
Definition: reg_view.cpp:263
void GetKeys(TKeys &keys) const
Retrieve information about all keys in this view.
Definition: reg_view.cpp:284
CRegistryWriteView GetWriteView(const string &section)
Definition: reg_view.cpp:491
void Set(const string &key, int val)
access a named key at this level, with no recursion
Definition: reg_view.cpp:533
static wxString ResolvePath(const wxString &path, const wxString &rel_name)
Utility function to hide the platform specifics of locating our standard directories and files.
Definition: sys_path.cpp:106
virtual bool Select(const IUITool &tool)=0
CUIToolRegistry - is a registry providing access to various tools registred in the application.
TStrToTool m_ClassToTemplate
static void ShutDown()
void CreateMRUList(const string &list_name, int size=10)
virtual void SaveSettings() const
void GetToolNames(vector< string > &names) const
returns names for all Tools available
bool IsToolRegistered(const string &class_name) const
const STemplateToolRecord * x_GetToolRecByName(const string &name) const
static CUIToolRegistry * GetInstance()
void GetMRUToolNames(const string &list_name, vector< string > &tool_names)
void LoadTemplateToolsInfo(TDirList &dirs)
loads descriptors for all template methods installed in the system
TIdToTempRec m_IdToRec
static void Reset()
list< wxString > TDirList
void AddToolToMRU(const string &list, const string &tool_name)
add a method to the MRU list
bool x_LoadTemplateTool(ITemplateUITool &method, const wxString &full_path)
bool MRUListExists(const string &list_name) const
void RegisterTool(IUITool *prototype, const string &tool_id=NcbiEmptyString)
register a concrete method, every method shall be registered only once the Regisrty assumes ownership...
TNameToMRUList m_NameToMRUList
CIRef< IUITool > CreateToolInstance(const string &method_name)
factory method, returns NULL if name is invalid.
virtual void LoadSettings()
virtual void SetRegistryPath(const string &path)
void Clear()
clears descriptors and unregisters all methods
bool x_ReadToolInfo(const wxString &full_path)
void SetMaxMRUSize(const string &list_name, int size)
void RegisterTemplateTool(const string &class_name, ITemplateUITool *prototype)
register a template method with its class name the Regisrty assumes ownership of the provided object
CMRUList< string > TMRUList
static CRef< CUIToolRegistry > sm_Instance
CUIToolRegistry.
void GetToolId(const string &name, string &tool_id) const
string GetToolDescription(const string &name) const
void SetMRUToolNames(const string &list_name, const vector< string > &tool_names)
void GetTools(vector< CConstIRef< IUITool > > &tools, ISelector &selector) const
ITemplateUITool.
Definition: ui_tool.hpp:76
virtual bool Load(CNcbiRegistry &reg)
Definition: ui_tool.cpp:51
IUITool represents an abstract algorithm that is bound to a UI component.
Definition: ui_tool.hpp:59
virtual IUITool * Clone() const =0
virtual string GetName() const =0
returns unique name of the method that is used in UI to identify it
size_type size() const
Definition: map.hpp:148
const_iterator end() const
Definition: map.hpp:152
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
Include a standard set of the NCBI C++ Toolkit most basic headers.
static const struct name_t names[]
static char tmp[3200]
Definition: utf8.c:42
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
bool ReferencedOnlyOnce(void) const THROWS_NONE
Check if object is referenced only once.
Definition: ncbiobj.hpp:475
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Process information in the NCBI Registry, including working with configuration files.
The NCBI C++/STL use hints.
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
#define _ASSERT
DEFINE_STATIC_MUTEX(s_Mutex)
static const int kMaxMRUSize
static const char * kMRUSectionRegKey
static const int kDefMRUSize
static const char * kInvalidDef
static const char * kRegTag
static const char * kFailedToRead
Modified on Tue Apr 23 07:37:06 2024 by modify_doxy.py rev. 669887