1/* 2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "PackageLinksDirectory.h" 8 9#include <AutoDeleter.h> 10 11#include "DebugSupport.h" 12#include "PackageLinkDirectory.h" 13#include "PackageLinksListener.h" 14#include "Utils.h" 15 16 17PackageLinksDirectory::PackageLinksDirectory() 18 : 19 Directory(0), 20 fListener(NULL) 21 // the ID needs to be assigned later, when added to a volume 22{ 23 get_real_time(fModifiedTime); 24} 25 26 27PackageLinksDirectory::~PackageLinksDirectory() 28{ 29} 30 31 32timespec 33PackageLinksDirectory::ModifiedTime() const 34{ 35 return fModifiedTime; 36} 37 38 39status_t 40PackageLinksDirectory::AddPackage(Package* package) 41{ 42 // Create a package link directory -- there might already be one, but since 43 // that's unlikely, we don't bother to check and recheck later. 44 PackageLinkDirectory* linkDirectory 45 = new(std::nothrow) PackageLinkDirectory; 46 if (linkDirectory == NULL) 47 return B_NO_MEMORY; 48 BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory, 49 true); 50 51 status_t error = linkDirectory->Init(this, package); 52 if (error != B_OK) 53 RETURN_ERROR(error); 54 55 // add the link directory 56 NodeWriteLocker writeLocker(this); 57 if (Node* child = FindChild(linkDirectory->Name())) { 58 // There already is an entry with the name. 59 PackageLinkDirectory* otherLinkDirectory 60 = dynamic_cast<PackageLinkDirectory*>(child); 61 if (otherLinkDirectory == NULL) 62 RETURN_ERROR(B_BAD_VALUE); 63 64 // There's already a package link directory. Delete the one we created 65 // and add the package to the pre-existing one. 66 linkDirectory->RemovePackage(package, NULL); 67 linkDirectory = otherLinkDirectory; 68 linkDirectory->AddPackage(package, fListener); 69 } else { 70 // No entry is in the way, so just add the link directory. 71 AddChild(linkDirectory); 72 73 if (fListener != NULL) 74 linkDirectory->NotifyDirectoryAdded(fListener); 75 } 76 77 return B_OK; 78} 79 80 81void 82PackageLinksDirectory::RemovePackage(Package* package) 83{ 84 NodeWriteLocker writeLocker(this); 85 86 // get the package's link directory and remove the package from it 87 PackageLinkDirectory* linkDirectory = package->LinkDirectory(); 88 if (linkDirectory == NULL) 89 return; 90 91 BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory); 92 93 linkDirectory->RemovePackage(package, fListener); 94 95 // if empty, remove the link directory itself 96 if (linkDirectory->IsEmpty()) { 97 if (fListener != NULL) { 98 NodeWriteLocker linkDirectoryWriteLocker(linkDirectory); 99 fListener->PackageLinkNodeRemoved(linkDirectory); 100 } 101 102 RemoveChild(linkDirectory); 103 } 104} 105 106 107void 108PackageLinksDirectory::UpdatePackageDependencies(Package* package) 109{ 110 NodeWriteLocker writeLocker(this); 111 112 PackageLinkDirectory* linkDirectory = package->LinkDirectory(); 113 if (linkDirectory == NULL) 114 return; 115 116 linkDirectory->UpdatePackageDependencies(package, fListener); 117} 118 119