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