1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include "tools/SdGlobalResourceContainer.hxx" 32 33 #include <algorithm> 34 #include <vector> 35 36 using namespace ::com::sun::star; 37 using namespace ::com::sun::star::uno; 38 39 40 namespace sd { 41 42 43 //===== SdGlobalResourceContainer::Implementation ============================= 44 45 class SdGlobalResourceContainer::Implementation 46 { 47 private: 48 friend class SdGlobalResourceContainer; 49 static SdGlobalResourceContainer* mpInstance; 50 51 ::osl::Mutex maMutex; 52 53 /** All instances of SdGlobalResource in this vector are owned by the 54 container and will be destroyed when the container is destroyed. 55 */ 56 typedef ::std::vector<SdGlobalResource*> ResourceList; 57 ResourceList maResources; 58 59 typedef ::std::vector<boost::shared_ptr<SdGlobalResource> > SharedResourceList; 60 SharedResourceList maSharedResources; 61 62 typedef ::std::vector<Reference<XInterface> > XInterfaceResourceList; 63 XInterfaceResourceList maXInterfaceResources; 64 }; 65 66 67 68 69 // static 70 SdGlobalResourceContainer& SdGlobalResourceContainer::Instance (void) 71 { 72 DBG_ASSERT(Implementation::mpInstance!=NULL, 73 "SdGlobalResourceContainer::Instance(): instance has been deleted"); 74 // Maybe we should throw an exception when the instance has been deleted. 75 return *Implementation::mpInstance; 76 } 77 78 SdGlobalResourceContainer* 79 SdGlobalResourceContainer::Implementation::mpInstance = NULL; 80 81 82 83 84 //===== SdGlobalResourceContainer ============================================= 85 86 void SdGlobalResourceContainer::AddResource ( 87 ::std::auto_ptr<SdGlobalResource> pResource) 88 { 89 ::osl::MutexGuard aGuard (mpImpl->maMutex); 90 91 Implementation::ResourceList::iterator iResource; 92 iResource = ::std::find ( 93 mpImpl->maResources.begin(), 94 mpImpl->maResources.end(), 95 pResource.get()); 96 if (iResource == mpImpl->maResources.end()) 97 mpImpl->maResources.push_back(pResource.get()); 98 else 99 { 100 // Because the given resource is an auto_ptr it is highly unlikely 101 // that we come here. But who knows? 102 DBG_ASSERT (false, 103 "SdGlobalResourceContainer:AddResource(): Resource added twice."); 104 } 105 // We can not put the auto_ptr into the vector so we release the 106 // auto_ptr and document that we take ownership explicitly. 107 pResource.release(); 108 } 109 110 111 112 113 void SdGlobalResourceContainer::AddResource ( 114 ::boost::shared_ptr<SdGlobalResource> pResource) 115 { 116 ::osl::MutexGuard aGuard (mpImpl->maMutex); 117 118 Implementation::SharedResourceList::iterator iResource; 119 iResource = ::std::find ( 120 mpImpl->maSharedResources.begin(), 121 mpImpl->maSharedResources.end(), 122 pResource); 123 if (iResource == mpImpl->maSharedResources.end()) 124 mpImpl->maSharedResources.push_back(pResource); 125 else 126 { 127 DBG_ASSERT (false, 128 "SdGlobalResourceContainer:AddResource(): Resource added twice."); 129 } 130 } 131 132 133 134 135 void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxResource) 136 { 137 ::osl::MutexGuard aGuard (mpImpl->maMutex); 138 139 Implementation::XInterfaceResourceList::iterator iResource; 140 iResource = ::std::find ( 141 mpImpl->maXInterfaceResources.begin(), 142 mpImpl->maXInterfaceResources.end(), 143 rxResource); 144 if (iResource == mpImpl->maXInterfaceResources.end()) 145 mpImpl->maXInterfaceResources.push_back(rxResource); 146 else 147 { 148 DBG_ASSERT (false, 149 "SdGlobalResourceContainer:AddResource(): Resource added twice."); 150 } 151 } 152 153 154 155 SdGlobalResourceContainer::SdGlobalResourceContainer (void) 156 : mpImpl (new SdGlobalResourceContainer::Implementation()) 157 { 158 Implementation::mpInstance = this; 159 } 160 161 162 163 164 SdGlobalResourceContainer::~SdGlobalResourceContainer (void) 165 { 166 ::osl::MutexGuard aGuard (mpImpl->maMutex); 167 168 // Release the resources in reversed order of their addition to the 169 // container. This is because a resource A added before resource B 170 // may have been created due to a request of B. Thus B depends on A and 171 // should be destroyed first. 172 Implementation::ResourceList::reverse_iterator iResource; 173 for (iResource = mpImpl->maResources.rbegin(); 174 iResource != mpImpl->maResources.rend(); 175 ++iResource) 176 { 177 delete *iResource; 178 } 179 180 // The SharedResourceList has not to be released manually. We just 181 // assert resources that are still held by someone other than us. 182 Implementation::SharedResourceList::reverse_iterator iSharedResource; 183 for (iSharedResource = mpImpl->maSharedResources.rbegin(); 184 iSharedResource != mpImpl->maSharedResources.rend(); 185 ++iSharedResource) 186 { 187 if ( ! iSharedResource->unique()) 188 { 189 SdGlobalResource* pResource = iSharedResource->get(); 190 OSL_TRACE(" %p %d", pResource, iSharedResource->use_count()); 191 DBG_ASSERT(iSharedResource->unique(), 192 "SdGlobalResource still held in ~SdGlobalResourceContainer"); 193 } 194 } 195 196 Implementation::XInterfaceResourceList::reverse_iterator iXInterfaceResource; 197 for (iXInterfaceResource = mpImpl->maXInterfaceResources.rbegin(); 198 iXInterfaceResource != mpImpl->maXInterfaceResources.rend(); 199 ++iXInterfaceResource) 200 { 201 Reference<lang::XComponent> xComponent (*iXInterfaceResource, UNO_QUERY); 202 *iXInterfaceResource = NULL; 203 if (xComponent.is()) 204 xComponent->dispose(); 205 } 206 207 DBG_ASSERT(Implementation::mpInstance == this, 208 "~SdGlobalResourceContainer(): more than one instance of singleton"); 209 Implementation::mpInstance = NULL; 210 } 211 212 213 214 215 } // end of namespace sd 216