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 NodeWriteLocker writeLocker(linkDirectory); 75 fListener->PackageLinkNodeAdded(linkDirectory); 76 } 77 } 78 79 return B_OK; 80} 81 82 83void 84PackageLinksDirectory::RemovePackage(Package* package) 85{ 86 NodeWriteLocker writeLocker(this); 87 88 // get the package's link directory and remove the package from it 89 PackageLinkDirectory* linkDirectory = package->LinkDirectory(); 90 if (linkDirectory == NULL) 91 return; 92 93 BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory); 94 95 linkDirectory->RemovePackage(package, fListener); 96 97 // if empty, remove the link directory itself 98 if (linkDirectory->IsEmpty()) { 99 if (fListener != NULL) { 100 NodeWriteLocker linkDirectoryWriteLocker(linkDirectory); 101 fListener->PackageLinkNodeRemoved(linkDirectory); 102 } 103 104 RemoveChild(linkDirectory); 105 } 106} 107 108 109void 110PackageLinksDirectory::UpdatePackageDependencies(Package* package) 111{ 112 NodeWriteLocker writeLocker(this); 113 114 PackageLinkDirectory* linkDirectory = package->LinkDirectory(); 115 if (linkDirectory == NULL) 116 return; 117 118 linkDirectory->UpdatePackageDependencies(package, fListener); 119} 120 121