1 #ifndef _hpp_tools_vdb_config_util_ 2 #define _hpp_tools_vdb_config_util_ 3 4 /*============================================================================== 5 * 6 * PUBLIC DOMAIN NOTICE 7 * National Center for Biotechnology Information 8 * 9 * This software/database is a "United States Government Work" under the 10 * terms of the United States Copyright Act. It was written as part of 11 * the author's official duties as a United States Government employee and 12 * thus cannot be copyrighted. This software/database is freely available 13 * to the public for use. The National Library of Medicine and the U.S. 14 * Government have not placed any restriction on its use or reproduction. 15 * 16 * Although all reasonable efforts have been taken to ensure the accuracy 17 * and reliability of the software and data, the NLM and the U.S. 18 * Government do not and cannot warrant the performance or results that 19 * may be obtained by using this software or data. The NLM and the U.S. 20 * Government disclaim all warranties, express or implied, including 21 * warranties of performance, merchantability or fitness for any particular 22 * purpose. 23 * 24 * Please cite the author in any work or product based on this material. 25 * 26 * =========================================================================== 27 * 28 */ 29 30 #include <klib/out.h> /* OUTMSG */ 31 #include <klib/printf.h> /* string_printf */ 32 #include <klib/text.h> /* String */ 33 34 #include <kfg/config.h> /* KConfig */ 35 #include <kfs/directory.h> /* KDirectory */ 36 37 #include <kfs/file.h> /* KFile */ 38 39 #include <map> 40 #include <string> 41 #include <vector> 42 43 #include <cstring> 44 45 static const bool DEBUG(false); 46 47 #define RELEASE(type, obj) do { rc_t rc2 = type##Release(obj); \ 48 if (rc2 && !rc) { rc = rc2; } obj = NULL; } while (false) 49 50 51 class CNoncopyable { 52 public: CNoncopyable(void)53 CNoncopyable(void) {} 54 protected: ~CNoncopyable(void)55 ~CNoncopyable(void) {} 56 private: 57 // Prohibit copy constructor and assignment operator 58 CNoncopyable(const CNoncopyable&); 59 const CNoncopyable& operator=(const CNoncopyable&); 60 }; 61 62 rc_t StringRelease(const String *self); 63 64 class CString : CNoncopyable { 65 const String *m_Self; 66 67 public: CString(const String * self)68 CString(const String *self) : m_Self(self) {} 69 ~CString()70 ~CString() { free((void*)m_Self); } 71 Get(void) const72 const String* Get(void) const { return m_Self; } GetString(void) const73 std::string GetString(void) const { 74 const char *s = GetCString(); 75 if (s == NULL) 76 return ""; 77 return s; 78 } GetCString(void) const79 const char* GetCString(void) const { 80 if (Empty()) 81 return NULL; 82 return m_Self->addr; 83 } 84 Empty(void) const85 bool Empty(void) const { 86 return 87 m_Self == NULL || m_Self->addr == NULL || m_Self->addr[0] == '\0'; 88 } 89 Equals(const CString & aString) const90 bool Equals(const CString &aString) const { 91 const String *string = aString.Get(); 92 93 if (m_Self == NULL && string == NULL) 94 return true; 95 return StringEqual(m_Self, string); 96 } 97 Equals(const char * buffer,size_t bsize=~0) const98 bool Equals(const char *buffer, size_t bsize = ~0) const { 99 if (bsize == (size_t)~0) { 100 bsize = string_size(buffer); 101 } 102 103 if (m_Self == NULL) { 104 return buffer == NULL || bsize == 0; 105 } 106 107 String s; 108 StringInit(&s, buffer, bsize, (uint32_t)bsize + 1); 109 110 return StringEqual(m_Self, &s); 111 } 112 }; 113 114 class CStdIn : CNoncopyable { 115 const KFile *m_Self; 116 uint64_t m_Pos; 117 118 public: CStdIn(void)119 CStdIn(void) : m_Self(NULL), m_Pos(0) { 120 rc_t rc = KFileMakeStdIn(&m_Self); 121 if (rc != 0) { 122 throw rc; 123 } 124 } 125 ~CStdIn(void)126 ~CStdIn(void) { KFileRelease(m_Self); } 127 Read1(void)128 char Read1(void) { 129 char buf[9] = ""; 130 rc_t rc = Read(buf, sizeof buf); 131 if (rc != 0) { 132 return -1; 133 } 134 return buf[0]; 135 } 136 137 rc_t Read(char *buffer, size_t bsize, size_t *num_read = NULL); 138 }; 139 140 class CKDirectory : CNoncopyable { 141 KDirectory *m_Self; 142 const uint32_t m_PrivateAccess; 143 const uint32_t m_PublicAccess; 144 public: CKDirectory(void)145 CKDirectory(void) 146 : m_Self(NULL), m_PrivateAccess(0700), m_PublicAccess(0775) 147 { 148 rc_t rc = KDirectoryNativeDir(&m_Self); 149 if (rc != 0) 150 throw rc; 151 } ~CKDirectory()152 ~CKDirectory() { KDirectoryRelease(m_Self); } CheckPrivateAccess(const CString & path,bool & updated,bool verbose) const153 rc_t CheckPrivateAccess(const CString &path, bool &updated, bool verbose) 154 const 155 { return CheckAccess(path, updated, true, verbose); } 156 rc_t CheckPublicAccess(const CString &path, bool verbose = false) const; CreateNonExistingPrivateDir(const CString & path,bool verbose=false) const157 rc_t CreateNonExistingPrivateDir(const CString &path, bool verbose = false) 158 const 159 { return CreateNonExistingDir(path, m_PrivateAccess, verbose); } 160 rc_t CreateNonExistingPublicDir(bool verbose, const char *path, ...) const; CreateNonExistingPublicDir(const std::string & path,bool verbose=false) const161 rc_t CreateNonExistingPublicDir(const std::string &path, 162 bool verbose = false) const 163 { return CreateNonExistingDir(path, m_PublicAccess, verbose, true); } CreateNonExistingPublicDir(const CString & path,bool verbose=false) const164 rc_t CreateNonExistingPublicDir(const CString &path, bool verbose = false) 165 const 166 { return CreateNonExistingDir(path, m_PublicAccess, verbose); } CreatePublicDir(const std::string & path,bool verbose=false)167 rc_t CreatePublicDir(const std::string &path, bool verbose = false) { 168 return CreateNonExistingDir(path, m_PublicAccess, verbose, false); 169 } 170 rc_t CanWriteFile(const CString &dir, bool verbose = false) const; Exists(const std::string & path) const171 bool Exists(const std::string &path) const { return Exists(path.c_str()); } 172 bool Exists(const CString &path) const; IsDirectory(const std::string & path) const173 bool IsDirectory(const std::string &path) const { 174 return IsDirectory(path.c_str()); 175 } 176 bool IsDirectory(const char *path, ...) const; 177 std::string Canonical ( const char * path ) const; 178 private: Exists(const char * path) const179 bool Exists(const char *path) const 180 { return KDirectoryPathType(m_Self, path) != kptNotFound; } 181 rc_t CreateNonExistingDir(const CString &path, 182 uint32_t access, bool verbose) const; 183 rc_t CreateNonExistingDir(const std::string &path, 184 uint32_t access, bool verbose, bool chekExistance) const; 185 rc_t CreateNonExistingDir(bool verbose, 186 uint32_t access, const char *path, va_list args) const; 187 rc_t CheckAccess(const CString &path, bool &updated, bool isPrivate, 188 bool verbose = false) const; 189 }; 190 191 class CKConfigNode : CNoncopyable { 192 const KConfigNode *m_Self; 193 194 public: CKConfigNode(const KConfigNode * self)195 CKConfigNode(const KConfigNode *self) 196 : m_Self(self) 197 {} 198 ~CKConfigNode(void)199 ~CKConfigNode(void) { 200 KConfigNodeRelease(m_Self); 201 } 202 OpenNodeRead(const std::string & path) const203 const KConfigNode* OpenNodeRead(const std::string &path) const { 204 const KConfigNode *node = NULL; 205 rc_t rc = KConfigNodeOpenNodeRead(m_Self, &node, path.c_str()); 206 if (rc != 0) { 207 return NULL; 208 } 209 return node; 210 } 211 ReadBool(const std::string & path) const212 bool ReadBool(const std::string &path) const { 213 return ReadString(path) == "true"; 214 } 215 ReadString(const std::string & path) const216 std::string ReadString(const std::string &path) const { 217 const KConfigNode *node = NULL; 218 rc_t rc = KConfigNodeOpenNodeRead(m_Self, &node, path.c_str()); 219 if (rc != 0) { 220 return ""; 221 } 222 223 String *result = NULL; 224 rc = KConfigNodeReadString(node, &result); 225 std::string r; 226 if (rc == 0) { 227 assert(result); 228 r = result->addr; 229 } 230 231 RELEASE(String, result); 232 RELEASE(KConfigNode, node); 233 234 return r; 235 } 236 }; 237 238 class CKConfig : CNoncopyable { 239 KConfig *m_Self; 240 bool m_Updated; 241 const char *m_RepositoryRemoteAuxDisabled; 242 const char *m_RepositoryRemoteMainDisabled; 243 const char *m_RepositoryUserRoot; 244 public: 245 CKConfig(bool verbose = false); ~CKConfig(void)246 ~CKConfig(void) 247 { KConfigRelease(m_Self); } Get(void) const248 KConfig* Get(void) const { return m_Self; } 249 void Reload(bool verbose = false); Updated(void)250 void Updated ( void ) { m_Updated = true; } IsUpdated(void) const251 bool IsUpdated ( void ) const { return m_Updated; } 252 rc_t Commit(void); 253 const KConfigNode* OpenNodeRead(const char *path, ...) const; 254 bool IsRemoteRepositoryDisabled(void) const; ReadDefaultConfig(void) const255 const String* ReadDefaultConfig(void) const 256 { return ReadString("/config/default"); } ReadHome(void) const257 const String* ReadHome(void) const { return ReadString("HOME"); } ReadNcbiHome(void) const258 const String* ReadNcbiHome(void) const { return ReadString("NCBI_HOME"); } ReadUserRepositoryRootPath(void) const259 const String* ReadUserRepositoryRootPath(void) const 260 { return ReadString(m_RepositoryUserRoot); } 261 rc_t DisableRemoteRepository(bool disable); 262 rc_t UpdateUserRepositoryRootPath(const CString &path); UpdateUserRepositoryRootPath(const char * buffer,size_t size)263 rc_t UpdateUserRepositoryRootPath(const char *buffer, size_t size) { 264 return UpdateNode(m_RepositoryUserRoot, buffer, false, size); 265 } 266 rc_t FixResolverCgiNodes ( void ); 267 bool NodeExists(const std::string &path) const; 268 rc_t UpdateNode(bool verbose, const char *value, const char *name, ...); 269 rc_t UpdateNode(const char *path, const char *buffer, 270 bool verbose = false, size_t size = ~0); UpdateNode(const std::string & path,const char * buffer)271 rc_t UpdateNode(const std::string &path, const char *buffer) { 272 return UpdateNode(path.c_str(), buffer); 273 } UpdateNode(const std::string & path,const std::string & buffer)274 rc_t UpdateNode(const std::string &path, const std::string &buffer) { 275 return UpdateNode(path.c_str(), buffer.c_str()); 276 } 277 rc_t CreateRemoteRepositories(bool fix = false); 278 rc_t CreateUserRepository(std::string name = "", bool fix = false); 279 const String* ReadString(const char *path) const; 280 }; 281 282 class CSplitter : CNoncopyable { 283 const char *m_Start; 284 size_t m_Size; 285 286 public: CSplitter(const std::string & s)287 CSplitter(const std::string &s) : m_Start(s.c_str()), m_Size(s.size()) {} CSplitter(const String * s)288 CSplitter(const String *s) : m_Start(NULL), m_Size(0) { 289 if (s == NULL) { 290 return; 291 } 292 m_Start = s->addr; 293 m_Size = s->len; 294 SkipEmpties(); 295 } HasNext(void) const296 bool HasNext(void) const { return m_Size != 0; } Next(void)297 const std::string Next(void) { 298 if (!HasNext()) { 299 return ""; 300 } 301 const char *s = m_Start; 302 const char *end = string_chr(m_Start, m_Size, ':'); 303 size_t n = m_Size; 304 if (end != NULL) { 305 n = end - m_Start; 306 m_Start = end + 1; 307 if (m_Size >= n + 1) { 308 m_Size -= n + 1; 309 } 310 else { 311 m_Size = 0; 312 } 313 } 314 else { 315 m_Start = NULL; 316 m_Size = 0; 317 } 318 SkipEmpties(); 319 return std::string(s, n); 320 } 321 static rc_t Test(void); 322 323 private: SkipEmpties(void)324 void SkipEmpties(void) { 325 while (m_Size > 0 && m_Start != NULL && *m_Start == ':') { 326 --m_Size; 327 ++m_Start; 328 } 329 } 330 }; 331 332 class CAppVolume { 333 std::string m_Type; 334 std::string m_Path; 335 336 public: CAppVolume(const std::string & type="",const std::string & path="")337 CAppVolume(const std::string &type = "", const std::string &path = "") 338 : m_Type(type) 339 , m_Path(path) 340 {} 341 GetPath(void) const342 std::string GetPath(void) const { return m_Path; } 343 Update(CKConfig & kfg,const char * node,const std::string & appVolPath,bool verbose=false) const344 rc_t Update(CKConfig &kfg, const char *node, 345 const std::string &appVolPath, bool verbose = false) const 346 { 347 if (DEBUG) { 348 OUTMSG(("CAppVolume::Update(%s, %s)\n", node, appVolPath.c_str())); 349 } 350 351 return kfg.UpdateNode(verbose, m_Path.c_str(), 352 "%s/%s/%s", node, appVolPath.c_str(), m_Type.c_str()); 353 } 354 Dump(const char * node,const std::string & appVolPath) const355 void Dump(const char *node, const std::string &appVolPath) const { 356 OUTMSG(("%s/%s/%s = \"%s\"\n", node, appVolPath.c_str(), 357 m_Type.c_str(), m_Path.c_str())); 358 } 359 }; 360 361 class CApp : CNoncopyable { 362 bool m_HasVolume; 363 const std::string m_AppVolPath; 364 typedef std::map<const std::string, CAppVolume> TCAppVolumes; 365 TCAppVolumes m_Volumes; 366 367 public: 368 typedef TCAppVolumes::const_iterator TCAppVolumesCI; 369 CApp(const std::string & root,const std::string & name,const std::string & type,const std::string & path)370 CApp(const std::string &root, const std::string &name, 371 const std::string &type, const std::string &path) 372 : m_HasVolume(false), m_AppVolPath("apps/" + name + "/volumes") 373 { 374 Update(root, name, type, path); 375 } 376 CApp(const CKDirectory &dir, const CKConfigNode &rep, 377 const std::string &root, const std::string &name); 378 Update(const std::string & root,const std::string & name,const std::string & type,const std::string & path)379 void Update(const std::string &root, const std::string &name, 380 const std::string &type, const std::string &path) 381 { 382 m_Volumes[type] = CAppVolume(type, path); 383 } Update(const CKDirectory & dir,const CKConfigNode & rep,const std::string & root,const std::string & name) const384 void Update(const CKDirectory &dir, const CKConfigNode &rep, 385 const std::string &root, const std::string &name) const 386 { 387 assert(0); 388 } Update(CKConfig & kfg,const char * node,bool verbose=false) const389 rc_t Update(CKConfig &kfg, const char *node, bool verbose = false) const { 390 rc_t rc = 0; 391 for (TCAppVolumesCI it = m_Volumes.begin(); it != m_Volumes.end(); ++it) 392 { 393 rc_t r2 = (*it).second.Update(kfg, node, m_AppVolPath, verbose); 394 if (r2 != 0 && rc == 0) { 395 rc = r2; 396 } 397 } 398 return rc; 399 } Dump(const char * node) const400 void Dump(const char *node) const { 401 for (TCAppVolumesCI it = m_Volumes.begin(); it != m_Volumes.end(); ++it) 402 { 403 (*it).second.Dump(node, m_AppVolPath); 404 } 405 } 406 VolumesBegin(void) const407 TCAppVolumesCI VolumesBegin(void) const { return m_Volumes.begin(); } VolumesEnd(void) const408 TCAppVolumesCI VolumesEnd(void) const { return m_Volumes.end(); } 409 }; 410 411 class CApps : public std::map<const std::string, CApp*> { 412 public: 413 typedef std::map<const std::string, CApp*>::const_iterator TCI; 414 typedef std::map<const std::string, CApp*>::iterator TI; 415 ~CApps(void)416 ~CApps(void) { 417 for (TCI it = begin(); it != end(); ++it) { 418 delete((*it).second); 419 } 420 } 421 Update(const CKDirectory & dir,const CKConfigNode & rep,const std::string & root,const std::string & name)422 void Update(const CKDirectory &dir, const CKConfigNode &rep, 423 const std::string &root, const std::string &name) 424 { 425 TCI it = find(name); 426 if (it == end()) { 427 insert(std::pair<const std::string, CApp*> 428 (name, new CApp(dir, rep, root, name))); 429 } 430 else { 431 (*it).second->Update(dir, rep, root, name); 432 } 433 } 434 Update(const std::string & root,const std::string & name,const std::string & type,const std::string & path)435 void Update(const std::string &root, const std::string &name, 436 const std::string &type, const std::string &path) 437 { 438 if (DEBUG) { 439 OUTMSG(("CApps.Update(%s)\n", name.c_str())); 440 } 441 442 TI it = find(name); 443 if (it == end()) { 444 if (DEBUG) { 445 OUTMSG(("CApps.Update(not found)\n")); 446 } 447 insert(std::pair<const std::string, CApp*> 448 (name, new CApp(root, name, type, path))); 449 } 450 else { 451 if (DEBUG) { 452 OUTMSG(("CApps.Update(found)\n")); 453 } 454 (*it).second->Update(root, name, type, path); 455 } 456 } 457 }; 458 459 class CRepository : CNoncopyable { 460 bool m_Disabled; 461 const std::string m_Category; // user/site/remote 462 const std::string m_SubCategory; // main/aux/protected 463 const std::string m_Name; 464 std::string m_Root; 465 CApps m_Apps; 466 RootExists(void) const467 bool RootExists(void) const { return m_Root.size() > 0; } 468 469 protected: 470 CRepository(const std::string &category, const std::string &type, 471 const std::string &name, const std::string &root); 472 CRepository(const CKDirectory &dir, const CKConfigNode &repo, 473 const std::string &category, const std::string &subCategory, 474 const std::string &name); 475 SetRoot(const std::string & root)476 void SetRoot(const std::string &root) { m_Root = root; } FixFileVolume(void)477 void FixFileVolume(void) 478 { m_Apps.Update(m_Root, "file", "flat", "files"); } FixNakmerVolume(const std::string & name,const std::string & path)479 void FixNakmerVolume(const std::string &name, 480 const std::string &path) 481 { m_Apps.Update(m_Root, "nakmer", name, path); } FixNannotVolume(const std::string & name,const std::string & path)482 void FixNannotVolume(const std::string &name, 483 const std::string &path) 484 { m_Apps.Update(m_Root, "nannot", name, path); } FixRefseqVolume(void)485 void FixRefseqVolume(void) 486 { m_Apps.Update(m_Root, "refseq", "refseq", "refseq"); } FixRefseqVolume(const std::string & name,const std::string & path)487 void FixRefseqVolume(const std::string &name, 488 const std::string &path) 489 { m_Apps.Update(m_Root, "sra", name, path); } FixWgsVolume(const std::string & name)490 void FixWgsVolume(const std::string &name) 491 { m_Apps.Update(m_Root, "wgs", name, "wgs"); } 492 rc_t Update(CKConfig &kfg, std::string &node, bool verbose = false); 493 494 public: ClearApps(void)495 void ClearApps(void) { m_Apps.clear(); } 496 virtual std::string Dump(void) const; 497 bool Is(const std::string &subCategory, const std::string &name = "") 498 const; GetCategory(void) const499 std::string GetCategory(void) const { return m_Category; } GetSubCategory(void) const500 std::string GetSubCategory(void) const { return m_SubCategory; } GetName(void) const501 std::string GetName(void) const { return m_Name; } GetRoot(void) const502 std::string GetRoot(void) const { return m_Root; } Disable(bool disable)503 void Disable(bool disable) { m_Disabled = disable; } 504 AppsBegin(void) const505 CApps::TCI AppsBegin(void) const { return m_Apps.begin(); } AppsEnd(void) const506 CApps::TCI AppsEnd(void) const { return m_Apps.end(); } 507 }; 508 509 class CRemoteRepository : public CRepository { 510 std::string m_ResolverCgi; 511 512 static bool EndsWith(const std::string &stack, char needle); 513 static std::string GetCgi(const std::string &stack, char needle); 514 static std::string GetRoot(const std::string &stack, char needle); FixApps(void)515 void FixApps(void) { 516 FixNakmerVolume("fuseNAKMER", "sadb"); 517 FixNannotVolume("fuseNANNOT", "sadb"); 518 FixRefseqVolume(); 519 FixRefseqVolume("fuse1000", "sra-instant/reads/ByRun/sra"); 520 FixWgsVolume("fuseWGS"); 521 } Update(CKConfig & kfg,bool verbose=false)522 rc_t Update(CKConfig &kfg, bool verbose = false) { 523 std::string node; 524 rc_t rc = CRepository::Update(kfg, node, verbose); 525 if (rc != 0) { 526 return rc; 527 } 528 return kfg.UpdateNode(verbose, 529 m_ResolverCgi.c_str(), "%s/resolver-cgi", node.c_str()); 530 } 531 532 public: CRemoteRepository(const CKDirectory & dir,const CKConfigNode & repo,const std::string & type,const std::string & name)533 CRemoteRepository(const CKDirectory &dir, const CKConfigNode &repo, 534 const std::string &type, const std::string &name) 535 : CRepository(dir, repo, "remote", type, name) 536 , m_ResolverCgi(repo.ReadString("resolver-cgi")) 537 {} CRemoteRepository(const std::string & category,const std::string & name,const std::string & root)538 CRemoteRepository(const std::string &category, 539 const std::string &name, const std::string &root) 540 : CRepository("remote", category, name, GetRoot(root, 'i')) 541 , m_ResolverCgi(GetCgi(root, 'i')) 542 { 543 if (m_ResolverCgi.size() == 0) { 544 FixApps(); 545 } 546 } 547 Dump(void) const548 virtual std::string Dump(void) const { 549 std::string node(CRepository::Dump()); 550 if (m_ResolverCgi.size() > 0) { 551 OUTMSG(("%s/resolver-cgi = \"%s\"\n", 552 node.c_str(), m_ResolverCgi.c_str())); 553 } 554 return node; 555 } 556 rc_t Fix(CKConfig &kfg, bool disable, bool verbose = false); 557 }; 558 559 class CUserRepositories; 560 class CUserConfigData : CNoncopyable { 561 std::string m_DefaultRoot; 562 std::string m_CurrentRoot; 563 bool m_CacheEnabled; 564 565 public: 566 CUserConfigData(const CUserRepositories &repos, const CString &dflt); 567 GetCurrentRoot(void) const568 std::string GetCurrentRoot(void) const { return m_CurrentRoot; } GetDefaultRoot(void) const569 std::string GetDefaultRoot(void) const { return m_DefaultRoot; } GetCacheEnabled(void) const570 bool GetCacheEnabled(void) const { return m_CacheEnabled; } 571 SetCurrentRoot(const std::string & path)572 void SetCurrentRoot(const std::string &path) { m_CurrentRoot = path; } SetCacheEnabled(bool enabled)573 void SetCacheEnabled(bool enabled) { m_CacheEnabled = enabled; } 574 }; 575 576 class CUserRepository : public CRepository { 577 bool m_CacheEnabled; 578 FixApps(void)579 void FixApps(void) { 580 FixFileVolume(); 581 FixNakmerVolume("nakmerFlat", "nannot"); 582 FixNannotVolume("nannotFlat", "nannot"); 583 FixRefseqVolume(); 584 FixRefseqVolume("sraFlat", "sra"); 585 FixWgsVolume("wgsFlat"); 586 } 587 rc_t Fix(CKConfig &kfg, 588 const CUserConfigData *data, const std::string *root); Update(CKConfig & kfg,bool verbose=false)589 rc_t Update(CKConfig &kfg, bool verbose = false) { 590 std::string node; 591 rc_t rc = CRepository::Update(kfg, node, verbose); 592 if (rc != 0) { 593 return rc; 594 } 595 return kfg.UpdateNode(verbose, m_CacheEnabled ? "true" : "false", 596 "%s/cache-enabled", node.c_str()); 597 } 598 599 public: CUserRepository(const CKDirectory & dir,const CKConfigNode & repo,const std::string & type,const std::string & name)600 CUserRepository(const CKDirectory &dir, const CKConfigNode &repo, 601 const std::string &type, const std::string &name) 602 : CRepository(dir, repo, "user", type, name) 603 , m_CacheEnabled(repo.ReadBool("cache-enabled")) 604 {} CUserRepository(const std::string & category,const std::string & name,const std::string & root)605 CUserRepository(const std::string &category, 606 const std::string &name, const std::string &root) 607 : CRepository("user", category, name, root), m_CacheEnabled(true) 608 { 609 FixApps(); 610 } 611 Dump(void) const612 virtual std::string Dump(void) const { 613 const std::string node(CRepository::Dump()); 614 OUTMSG(("%s/cache-enabled = \"%s\"\n", node.c_str(), 615 m_CacheEnabled ? "true" : "false")); 616 return node; 617 } 618 IsCacheEnabled(void) const619 bool IsCacheEnabled(void) const { return m_CacheEnabled; } Fix(CKConfig & kfg,const std::string & root)620 void Fix(CKConfig &kfg, const std::string &root) { Fix(kfg, NULL, &root); } Fix(CKConfig & kfg,const CUserConfigData * data)621 void Fix(CKConfig &kfg, const CUserConfigData *data) { 622 Fix(kfg, data, NULL); 623 } 624 }; 625 626 class CUserRepositories : std::vector<CUserRepository*> { 627 typedef std::vector<CUserRepository*>::const_iterator TCI; 628 typedef std::vector<CUserRepository*>::iterator TI; 629 const CUserRepository *FindMainPublic(void) const; 630 631 public: ~CUserRepositories(void)632 ~CUserRepositories(void) { 633 for (TCI it = begin(); it != end(); ++it) { 634 free(*it); 635 } 636 } 637 638 rc_t Load(const CKConfig &kfg, const CKDirectory &dir); GetMainPublicRoot(void) const639 std::string GetMainPublicRoot(void) const { 640 const CUserRepository *r = FindMainPublic(); 641 if (r == NULL) { 642 return ""; 643 } 644 return r->GetRoot(); 645 } IsMainPublicCacheEnabled(void) const646 bool IsMainPublicCacheEnabled(void) const { 647 const CUserRepository *r = FindMainPublic(); 648 if (r == NULL) { 649 return true; 650 } 651 return r->IsCacheEnabled(); 652 } Fix(CKConfig & kfg,const CUserConfigData & data)653 void Fix(CKConfig &kfg, const CUserConfigData &data) { 654 bool publicMainFound = false; 655 for (TI it = begin(); it != end(); ++it) { 656 CUserRepository *r = *it; 657 assert(r); 658 if (r->Is("main", "public")) { 659 r->Fix(kfg, &data); 660 publicMainFound = true; 661 } 662 else { 663 r->Fix(kfg, data.GetDefaultRoot()); 664 } 665 } 666 if (!publicMainFound) { 667 CUserRepository *r = new CUserRepository("main", "public", ""); 668 r->Fix(kfg, &data); 669 push_back(r); 670 } 671 } 672 rc_t MkAppVolumes(const CKDirectory &dir, bool verbose = false) 673 const; 674 }; 675 676 class CRemoteRepositories : std::vector<CRemoteRepository*> { 677 typedef std::vector<CRemoteRepository*>::const_iterator TCI; 678 679 public: ~CRemoteRepositories(void)680 ~CRemoteRepositories(void) { 681 for (TCI it = begin(); it != end(); ++it) { free(*it); } 682 } 683 684 rc_t Load(const CKConfig &kfg, const CKDirectory &dir); 685 IsDisabled(void) const686 bool IsDisabled(void) const { return false; } 687 void Fix(CKConfig &kfg, bool disable, bool verbose = false); 688 }; 689 690 691 #endif // _hpp_tools_vdb_config_util_ 692