|
NCBI C++ ToolKit
|
00001 /* $Id: gb_ui_data_source.cpp 25238 2012-02-14 16:11:43Z ucko $ 00002 * =========================================================================== 00003 * 00004 * PUBLIC DOMAIN NOTICE 00005 * National Center for Biotechnology Information 00006 * 00007 * This software/database is a "United States Government Work" under the 00008 * terms of the United States Copyright Act. It was written as part of 00009 * the author's official duties as a United States Government employee and 00010 * thus cannot be copyrighted. This software/database is freely available 00011 * to the public for use. The National Library of Medicine and the U.S. 00012 * Government have not placed any restriction on its use or reproduction. 00013 * 00014 * Although all reasonable efforts have been taken to ensure the accuracy 00015 * and reliability of the software and data, the NLM and the U.S. 00016 * Government do not and cannot warrant the performance or results that 00017 * may be obtained by using this software or data. The NLM and the U.S. 00018 * Government disclaim all warranties, express or implied, including 00019 * warranties of performance, merchantability or fitness for any particular 00020 * purpose. 00021 * 00022 * Please cite the author in any work or product based on this material. 00023 * 00024 * =========================================================================== 00025 * 00026 * Authors: Andrey Yazhuk 00027 * 00028 */ 00029 00030 #include <ncbi_pch.hpp> 00031 00032 #include <corelib/ncbiexec.hpp> 00033 #include <corelib/ncbi_process.hpp> 00034 #include <corelib/ncbi_system.hpp> 00035 00036 #include <gui/packages/pkg_sequence/gb_ui_data_source.hpp> 00037 00038 #include "gb_load_option_panel.hpp" 00039 00040 #include <gui/core/app_tasks.hpp> 00041 #include <gui/core/app_explorer_service.hpp> 00042 #include <gui/core/named_pipe.hpp> 00043 00044 #include <gui/framework/workbench.hpp> 00045 #include <gui/framework/app_task_service.hpp> 00046 #include <gui/framework/app_job_task.hpp> 00047 00048 #include <gui/widgets/wx/wx_utils.hpp> 00049 #include <gui/widgets/wx/fileartprov.hpp> 00050 #include <gui/widgets/wx/ui_command.hpp> 00051 #include <gui/widgets/wx/message_box.hpp> 00052 #include <gui/widgets/wx/wx_utils.hpp> 00053 #include <gui/widgets/wx/sys_path.hpp> 00054 00055 #include <objmgr/object_manager.hpp> 00056 #include <objtools/data_loaders/genbank/gbloader.hpp> 00057 #include <connect/services/neticache_client.hpp> 00058 00059 #include <gui/objects/ProjectItem.hpp> 00060 #include <gui/objutils/registry.hpp> 00061 #include <gui/utils/extension_impl.hpp> 00062 00063 00064 #include <wx/menu.h> 00065 #include <wx/filename.h> 00066 00067 BEGIN_NCBI_SCOPE 00068 USING_SCOPE(objects); 00069 00070 static const char* kGenBankLoadOption = "Data from GenBank"; 00071 00072 /////////////////////////////////////////////////////////////////////////////// 00073 /// CGenBankDSEvtHandler - wxEvtHandler-derived adapter for GenBank data source. 00074 00075 class CGenBankDSEvtHandler : public wxEvtHandler 00076 { 00077 DECLARE_EVENT_TABLE(); 00078 public: 00079 CGenBankDSEvtHandler(IWorkbench* workbench) 00080 : m_Workbench(workbench) { 00081 } 00082 void OnLoadFromGenBank(wxCommandEvent& event) 00083 { 00084 if(m_Workbench) { 00085 COpenDlgTask* task = new COpenDlgTask(m_Workbench, kGenBankLoadOption); 00086 00087 CAppTaskService* task_srv = m_Workbench->GetServiceByType<CAppTaskService>(); 00088 task_srv->AddTask(*task); 00089 } 00090 } 00091 protected: 00092 IWorkbench* m_Workbench; 00093 }; 00094 00095 00096 BEGIN_EVENT_TABLE(CGenBankDSEvtHandler, wxEvtHandler) 00097 EVT_MENU(eCmdLoadFromGenBank, CGenBankDSEvtHandler::OnLoadFromGenBank) 00098 END_EVENT_TABLE(); 00099 00100 00101 /////////////////////////////////////////////////////////////////////////////// 00102 /// CGenBankUIDataSource 00103 00104 static const char* kGB_DS_Icon = "icon::gb_data_source"; 00105 00106 CGenBankUIDataSource::CGenBankUIDataSource(CGenBankUIDataSourceType& type) 00107 : m_Type(&type), 00108 m_Descr("GenBank", kGB_DS_Icon), 00109 m_SrvLocator(NULL), 00110 m_Open(false) 00111 { 00112 } 00113 00114 CGenBankUIDataSource::~CGenBankUIDataSource() 00115 { 00116 } 00117 00118 00119 string CGenBankUIDataSource::GetExtensionIdentifier() const 00120 { 00121 return "genbank_data_source"; 00122 } 00123 00124 00125 string CGenBankUIDataSource::GetExtensionLabel() const 00126 { 00127 return "GenBank Data Source"; 00128 } 00129 00130 00131 void CGenBankUIDataSource::SetServiceLocator(IServiceLocator* locator) 00132 { 00133 m_SrvLocator = locator; 00134 } 00135 00136 00137 IExplorerItemCmdContributor::TContribution 00138 CGenBankUIDataSource::GetMenu(TItemRefVector& items, 00139 CAppExplorerService& app_service) 00140 { 00141 IExplorerItemCmdContributor::TContribution contrib; 00142 00143 /// this is not a good solution, but simple 00144 IWorkbench* workbench = dynamic_cast<IWorkbench*>(m_SrvLocator); 00145 00146 if(items.size() != 1 || workbench == NULL) { 00147 return contrib; // return empty object - nothin to contribute 00148 } 00149 00150 CUICommandRegistry& cmd_reg = CUICommandRegistry::GetInstance(); 00151 00152 CExplorerItem* item = items[0].GetPointer(); 00153 int type = app_service.GetItemType(*item); 00154 00155 if(type == CAppExplorerService::eDataSource) { 00156 CAppExplorerService::TDataSourceTreeItem* ds_item = 00157 dynamic_cast<CAppExplorerService::TDataSourceTreeItem*>(item); 00158 00159 if(ds_item) { 00160 CIRef<IUIDataSource> ds = ds_item->GetData(); 00161 CGenBankUIDataSource* gb_ds = dynamic_cast<CGenBankUIDataSource*>(ds.GetPointer()); 00162 00163 if(gb_ds) { 00164 wxMenu* menu = new wxMenu; 00165 menu->Append(wxID_SEPARATOR, wxT("Top Actions")); 00166 cmd_reg.AppendMenuItem(*menu, eCmdLoadFromGenBank); 00167 00168 contrib.first = menu; 00169 contrib.second = new CGenBankDSEvtHandler(workbench); 00170 } 00171 } 00172 } 00173 return contrib; 00174 } 00175 00176 00177 IUIDataSourceType& CGenBankUIDataSource::GetType() const 00178 { 00179 return *m_Type; 00180 } 00181 00182 00183 const IUIObject& CGenBankUIDataSource::GetDescr() 00184 { 00185 return m_Descr; 00186 } 00187 00188 00189 bool CGenBankUIDataSource::IsOpen() 00190 { 00191 return m_Open; 00192 } 00193 00194 //static const char* kCmdExtPoint = "scoped_objects::cmd_contributor"; 00195 static const char* kAppExpCmdExtPoint = "project_tree_view::context_menu::item_cmd_contributor"; 00196 00197 bool CGenBankUIDataSource::Open() 00198 { 00199 if (m_Open) { 00200 LOG_POST(Error << "CGenBankUIDataSource::Open(): " 00201 "attempt to open already open data source"); 00202 return false; 00203 } 00204 00205 CStopWatch sw; 00206 sw.Start(); 00207 00208 /// register itself as menu contributor 00209 CIRef<IExtensionRegistry> reg = CExtensionRegistry::GetInstance(); 00210 reg->AddExtension(kAppExpCmdExtPoint, *this); 00211 00212 /// initialize the object manager 00213 CGuiRegistry& registry = CGuiRegistry::GetInstance(); 00214 CGuiRegistry::TReadWriteView view = 00215 registry.GetReadWriteView("GBENCH.Services.ObjectManager"); 00216 00217 m_ObjMgr = CObjectManager::GetInstance(); 00218 00219 // general genbank loader options 00220 int priority = view.GetInt("Priority", 99); 00221 00222 // caching options 00223 string cache_path = FnToStdString(CSysPath::ResolvePath(wxT("<home>/cache"))); 00224 wxString system_cache_path = FnToWxString(cache_path); 00225 if (sizeof(void*) == 8) 00226 system_cache_path.append(wxT("64")); 00227 00228 {{ 00229 /// make sure we can write in the cache path directory 00230 if ( !wxFileName::DirExists(system_cache_path) ) { 00231 if ( !wxFileName::Mkdir(system_cache_path) ) { 00232 LOG_POST(Error << "Error creating cache path (" 00233 << system_cache_path.ToUTF8() << "); caching will be disabled"); 00234 } else { 00235 LOG_POST(Info << "Created cache path: " << system_cache_path.ToUTF8()); 00236 } 00237 } else { 00238 // clean sqlite cash if previous launch of GBench ended with crash 00239 if (registry.GetBool("GBENCH.Application.CrashDetected", false)) { 00240 ::wxRemoveFile(wxFileName(system_cache_path, wxT("cache_ids.db")).GetFullPath()); 00241 ::wxRemoveFile(wxFileName(system_cache_path, wxT("cache_blobs.db")).GetFullPath()); 00242 } 00243 } 00244 }} 00245 00246 int cache_age = view.GetInt("CacheAge", 5); 00247 if (cache_age == 0) { 00248 cache_age = 5; // keep objects for 5 days (default) 00249 } 00250 00251 /// ID resolution time in hours 00252 int id_resolution_time = view.GetInt("IdResolutionTime", 24); 00253 if (id_resolution_time > 24 * 3) { 00254 id_resolution_time = 24 * 3; // correct the unreasonable value 00255 } 00256 00257 wxString objmgr_config_path = 00258 CSysPath::ResolvePathExisting(wxT("<home>/gbench-objmgr.ini, ") 00259 wxT("<std>/etc/gbench-objmgr.ini")); 00260 00261 if (objmgr_config_path.empty()) { 00262 CGBDataLoader::RegisterInObjectManager(*m_ObjMgr); 00263 } else { 00264 CMemoryRegistry reg; 00265 CNcbiIfstream istr(objmgr_config_path.fn_str(), ios::binary|ios::in); 00266 reg.Read(istr); 00267 00268 // disable cache in the second instance 00269 if (!CGBenchPipe::IsOpen()) { 00270 reg.Set("genbank", "loader_method", "id2"); 00271 } else { 00272 // override variables as needed 00273 reg.Set("genbank/cache/id_cache/sqlite3", "database", 00274 cache_path + "/cache_ids.db"); 00275 reg.Set("genbank/cache/id_cache/sqlite3", "cache_age", 00276 NStr::IntToString(id_resolution_time * (60*60))); 00277 reg.Set("genbank/cache/blob_cache/sqlite3", "database", 00278 cache_path + "/cache_blobs.db"); 00279 reg.Set("genbank/cache/blob_cache/sqlite3", "cache_age", 00280 NStr::IntToString(cache_age * (24*60*60))); 00281 } 00282 00283 // now, create the GenBank data loader 00284 string msg; 00285 CGBDataLoader::TRegisterLoaderInfo rinfo; 00286 try { 00287 CConfig cfg(reg); 00288 rinfo = 00289 CGBDataLoader::RegisterInObjectManager 00290 (*m_ObjMgr, 00291 *cfg.GetTree(), CObjectManager::eDefault, priority); 00292 } 00293 catch (CException& e) { 00294 msg = "An error occurred while creating the GenBank connection\n("; 00295 msg += e.GetMsg(); 00296 msg += ")"; 00297 } 00298 catch (std::exception& e) { 00299 msg = "An error occurred while creating the GenBank connection\n("; 00300 msg += e.what(); 00301 msg += ")"; 00302 } 00303 00304 if ( !msg.empty() ) { 00305 /// fall back to standard initialization 00306 LOG_POST(Error << msg); 00307 CGBDataLoader::RegisterInObjectManager(*CObjectManager::GetInstance()); 00308 } 00309 } 00310 00311 string t = NStr::DoubleToString(sw.Elapsed(), 3); 00312 LOG_POST(Info << "Registered GenBank Data Source - " << t << " sec"); 00313 00314 m_Open = true; 00315 return true; 00316 } 00317 00318 00319 bool CGenBankUIDataSource::Close() 00320 { 00321 if (m_Open) { 00322 00323 /// remove itself from menu contribution points 00324 CIRef<IExtensionRegistry> reg = CExtensionRegistry::GetInstance(); 00325 reg->RemoveExtension(kAppExpCmdExtPoint, *this); 00326 00327 try { 00328 bool revoked = m_ObjMgr->RevokeDataLoader("GBLOADER"); 00329 if (!revoked) { 00330 CDataLoader* dl = m_ObjMgr->FindDataLoader("GBLOADER"); 00331 CGBDataLoader* gbdl = dynamic_cast<CGBDataLoader*>(dl); 00332 if (gbdl) { 00333 gbdl->CloseCache(); 00334 } 00335 } 00336 } 00337 catch(std::exception&) 00338 { 00339 LOG_POST(Error << "Cannot revoke genbank dataloader"); 00340 } 00341 00342 /// finally, drop the object manager 00343 CObjectManager* ptr = m_ObjMgr.Release(); 00344 00345 if (ptr) { 00346 if ( !ptr->ReferencedOnlyOnce() ) { 00347 LOG_POST(Error << "CGenBankUIDataSource::ShutDownService(): " 00348 "object manager still referenced"); 00349 } 00350 } 00351 00352 m_Open = false; 00353 return true; 00354 } 00355 return false; 00356 } 00357 00358 00359 void CGenBankUIDataSource::EditProperties() 00360 { 00361 //TODO 00362 } 00363 00364 00365 IUIToolManager* CGenBankUIDataSource::GetLoadManager() 00366 { 00367 // TODO may need to link the manager to this particular datasource 00368 return new CGenBankUILoadManager(); 00369 } 00370 00371 00372 /////////////////////////////////////////////////////////////////////////////// 00373 /// CGenBankUIDataSourceType 00374 CGenBankUIDataSourceType::CGenBankUIDataSourceType() 00375 : m_Descr("GenBank Connection", "") 00376 { 00377 wxFileArtProvider* provider = GetDefaultFileArtProvider(); 00378 provider->RegisterFileAlias(ToWxString(kGB_DS_Icon), 00379 wxT("gb_data_source.png")); 00380 } 00381 00382 00383 const IUIObject& CGenBankUIDataSourceType::GetDescr() 00384 { 00385 return m_Descr; 00386 } 00387 00388 00389 IUIDataSource* CGenBankUIDataSourceType::CreateDataSource() 00390 { 00391 return new CGenBankUIDataSource(*this); 00392 } 00393 00394 00395 bool CGenBankUIDataSourceType::AutoCreateDefaultDataSource() 00396 { 00397 return true; // we want to create default "GenBank" datasource 00398 } 00399 00400 00401 string CGenBankUIDataSourceType::GetExtensionIdentifier() const 00402 { 00403 static string ext_id("genbank_data_source_type"); 00404 return ext_id; 00405 } 00406 00407 00408 string CGenBankUIDataSourceType::GetExtensionLabel() const 00409 { 00410 return m_Descr.GetLabel(); 00411 } 00412 00413 00414 00415 /////////////////////////////////////////////////////////////////////////////// 00416 /// CGenBankUILoadManager 00417 CGenBankUILoadManager::CGenBankUILoadManager() 00418 : m_SrvLocator(NULL), 00419 m_ParentWindow(NULL), 00420 m_Descriptor(kGenBankLoadOption, ""), 00421 m_State(eInvalid), 00422 m_OptionPanel(NULL), 00423 m_ProjectSelPanel(NULL) 00424 { 00425 } 00426 00427 00428 void CGenBankUILoadManager::SetServiceLocator(IServiceLocator* srv_locator) 00429 { 00430 m_SrvLocator = srv_locator; 00431 } 00432 00433 00434 void CGenBankUILoadManager::SetParentWindow(wxWindow* parent) 00435 { 00436 m_ParentWindow = parent; 00437 } 00438 00439 00440 const IUIObject& CGenBankUILoadManager::GetDescriptor() const 00441 { 00442 return m_Descriptor; 00443 } 00444 00445 00446 void CGenBankUILoadManager::InitUI() 00447 { 00448 m_State = eSelectAcc; 00449 } 00450 00451 00452 void CGenBankUILoadManager::CleanUI() 00453 { 00454 m_State = eInvalid; 00455 if(m_OptionPanel) { 00456 m_SavedInput = m_OptionPanel->GetInput(); 00457 m_OptionPanel = NULL; // window is destroyed by the system 00458 } 00459 m_ProjectSelPanel = NULL; 00460 } 00461 00462 00463 wxPanel* CGenBankUILoadManager::GetCurrentPanel() 00464 { 00465 if(m_State == eSelectAcc) { 00466 if(m_OptionPanel == NULL) { 00467 m_OptionPanel = new CGenBankLoadOptionPanel(m_ParentWindow); 00468 m_OptionPanel->SetInput(m_SavedInput); 00469 } 00470 return m_OptionPanel; 00471 } else if(m_State == eSelectProject) { 00472 if(m_ProjectSelPanel == NULL) { 00473 CIRef<CProjectService> srv = m_SrvLocator->GetServiceByType<CProjectService>(); 00474 00475 m_ProjectSelPanel = new CProjectSelectorPanel(m_ParentWindow); 00476 m_ProjectSelPanel->SetProjectService(srv); 00477 m_ProjectSelPanel->SetParams(m_ProjectParams); 00478 m_ProjectSelPanel->TransferDataToWindow(); 00479 } 00480 return m_ProjectSelPanel; 00481 } 00482 return NULL; 00483 } 00484 00485 00486 bool CGenBankUILoadManager::CanDo(EAction action) 00487 { 00488 switch(m_State) { 00489 case eSelectAcc: 00490 return action == eNext; 00491 case eSelectProject: 00492 return action == eBack || action == eNext; 00493 case eCompleted: 00494 return false; // nothing left to do 00495 default: 00496 _ASSERT(false); 00497 return false; 00498 } 00499 } 00500 00501 00502 bool CGenBankUILoadManager::IsFinalState() 00503 { 00504 return m_State == eSelectProject; 00505 } 00506 00507 00508 bool CGenBankUILoadManager::IsCompletedState() 00509 { 00510 return m_State == eCompleted; 00511 } 00512 00513 00514 bool CGenBankUILoadManager::DoTransition(EAction action, wxPanel* currPanel) 00515 { 00516 if(m_State == eSelectAcc && action == eNext) { 00517 if (m_OptionPanel->IsInputValid()) { 00518 m_State = eSelectProject; 00519 return true; 00520 } 00521 return false; 00522 } else if( m_State == eSelectProject) { 00523 if(action == eBack) { 00524 m_State = eSelectAcc; 00525 return true; 00526 } else if(action == eNext) { 00527 if(m_ProjectSelPanel->TransferDataFromWindow()) { 00528 m_State = eCompleted; 00529 return true; 00530 } 00531 return false; 00532 } 00533 } 00534 _ASSERT(false); 00535 return false; 00536 } 00537 00538 00539 IAppTask* CGenBankUILoadManager::GetTask() 00540 { 00541 // extract parameters from the dialog panels 00542 vector< CRef<CObject> > ids = m_OptionPanel->GetSeqIds(); 00543 00544 m_ProjectSelPanel->GetParams(m_ProjectParams); 00545 string folder_name = m_ProjectParams.m_CreateFolder ? m_ProjectParams.m_FolderName : ""; 00546 00547 // create loading Job 00548 CIRef<CProjectService> srv = m_SrvLocator->GetServiceByType<CProjectService>(); 00549 CGenBankLoadingJob* job = new CGenBankLoadingJob(srv.GetPointer(), ids); 00550 00551 m_ProjectSelPanel->GetParams(m_ProjectParams); 00552 00553 CDataLoadingOptions& options = job->GetOptions(); 00554 m_ProjectParams.ToLoadingOptions(options); 00555 00556 // create a wrapper task 00557 CDataLoadingAppTask* task = new CDataLoadingAppTask(*job); 00558 return task; 00559 } 00560 00561 00562 void CGenBankUILoadManager::SetRegistryPath(const string& path) 00563 { 00564 m_RegPath = path; // store for later use 00565 } 00566 00567 00568 static const char* kIdsInputTag = "IdsInput"; 00569 static const char* kProjectParamsTag = "ProjectParams"; 00570 00571 00572 void CGenBankUILoadManager::SaveSettings() const 00573 { 00574 if( ! m_RegPath.empty()) { 00575 CGuiRegistry& gui_reg = CGuiRegistry::GetInstance(); 00576 CGuiRegistry::TReadWriteView view = gui_reg.GetReadWriteView(m_RegPath); 00577 00578 /// remember the selected Format (only if m_OptionPanel exists) 00579 if(m_OptionPanel) 00580 m_SavedInput = m_OptionPanel->GetInput(); 00581 00582 string encoded = NStr::URLEncode(m_SavedInput); 00583 if (encoded.size() < 10000) { 00584 // do not save large texts 00585 view.Set(kIdsInputTag, encoded); 00586 } 00587 00588 /// save Project Panel settings 00589 m_ProjectParams.SaveSettings(view, kProjectParamsTag); 00590 } 00591 } 00592 00593 00594 void CGenBankUILoadManager::LoadSettings() 00595 { 00596 if( ! m_RegPath.empty()) { 00597 CGuiRegistry& gui_reg = CGuiRegistry::GetInstance(); 00598 CGuiRegistry::TReadView view = gui_reg.GetReadView(m_RegPath); 00599 00600 string encoded = view.GetString(kIdsInputTag, kEmptyStr); 00601 m_SavedInput = NStr::URLDecode(encoded); 00602 00603 /// load Project Panel settings 00604 m_ProjectParams.LoadSettings(view, kProjectParamsTag); 00605 } 00606 } 00607 00608 00609 /////////////////////////////////////////////////////////////////////////////// 00610 /// CGenBankLoadingJob 00611 00612 CGenBankLoadingJob::CGenBankLoadingJob(CProjectService* service, const IIdsVec& ids) 00613 : CDataLoadingAppJob(service), 00614 m_Ids(ids) 00615 { 00616 CFastMutexGuard lock(m_Mutex); 00617 00618 int n = m_Ids.size(); 00619 string s = NStr::IntToString(n) + (n == 1 ? " id" : " ids"); 00620 m_Descr = "Loading " + s + " from GenBank"; 00621 } 00622 00623 00624 void CGenBankLoadingJob::x_CreateProjectItems() 00625 { 00626 /// a scope for ID validation 00627 CRef<CScope> scope(new CScope(*CObjectManager::GetInstance())); 00628 scope->AddDefaults(); 00629 00630 // iterate by ids and create items 00631 for( size_t i = 0; i < m_Ids.size(); i++ ) { 00632 CSeq_id* seq_id = dynamic_cast<CSeq_id*> (m_Ids[i].GetPointer()); 00633 CSeq_loc* seq_loc = dynamic_cast<CSeq_loc*> (m_Ids[i].GetPointer()); 00634 00635 if (seq_id == 0 && seq_loc == 0) { 00636 LOG_POST(Error << "CGenBankLoadingJob::x_CreateProjectItems(): " 00637 "Invalid object type to open."); 00638 continue; 00639 } 00640 00641 // validate the ID 00642 /*CScope::TIds ids = scope->GetIds(*id); 00643 if (ids.size() == 0) { 00644 ERR_POST("CGenBankLoadingJob::x_CreateProjectItems() - " << 00645 "Cannot resolve id '" + id->AsFastaString() + "'"); 00646 } else */{ 00647 // create a Project Item 00648 CRef<CProjectItem> item(new CProjectItem()); 00649 if (seq_id) 00650 item->SetItem().SetId(*seq_id); 00651 else 00652 item->SetObject(*seq_loc); 00653 00654 string label = item->GetLabelByData(scope.GetPointer()); 00655 item->SetLabel(label); 00656 00657 m_Items.push_back(item); 00658 } 00659 } 00660 } 00661 00662 00663 END_NCBI_SCOPE
1.7.5.1
Modified on Wed May 23 13:07:36 2012 by modify_doxy.py rev. 337098