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 17 PackageLinksDirectory::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 27 PackageLinksDirectory::~PackageLinksDirectory() 28 { 29 } 30 31 32 timespec 33 PackageLinksDirectory::ModifiedTime() const 34 { 35 return fModifiedTime; 36 } 37 38 39 status_t 40 PackageLinksDirectory::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(package); 52 if (error != B_OK) 53 RETURN_ERROR(error); 54 55 // add the link directory 56 DirectoryWriteLocker 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 linkDirectoryReference.Unset(); 68 69 linkDirectory = otherLinkDirectory; 70 linkDirectory->AddPackage(package, fListener); 71 } else { 72 // No entry is in the way, so just add the link directory. 73 AddChild(linkDirectory); 74 75 if (fListener != NULL) 76 fListener->PackageLinkNodeAdded(linkDirectory); 77 } 78 79 return B_OK; 80 } 81 82 83 void 84 PackageLinksDirectory::RemovePackage(Package* package) 85 { 86 DirectoryWriteLocker 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 DirectoryWriteLocker linkDirectoryWriteLocker(linkDirectory); 101 fListener->PackageLinkNodeRemoved(linkDirectory); 102 } 103 104 RemoveChild(linkDirectory); 105 } 106 } 107 108 109 void 110 PackageLinksDirectory::UpdatePackageDependencies(Package* package) 111 { 112 DirectoryWriteLocker writeLocker(this); 113 114 PackageLinkDirectory* linkDirectory = package->LinkDirectory(); 115 if (linkDirectory == NULL) 116 return; 117 118 linkDirectory->UpdatePackageDependencies(package, fListener); 119 } 120 121