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 #include "precompiled_sd.hxx"
25 
26 #include "framework/Configuration.hxx"
27 
28 #include "framework/FrameworkHelper.hxx"
29 #include <comphelper/stl_types.hxx>
30 
31 
32 
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::drawing::framework;
36 using ::sd::framework::FrameworkHelper;
37 using ::rtl::OUString;
38 
39 #undef VERBOSE
40 
41 namespace {
42 /** Use the XResourceId::compareTo() method to implement a compare operator
43     for STL containers.
44 */
45 class XResourceIdLess
46     : 	public ::std::binary_function <Reference<XResourceId>, Reference<XResourceId>, bool>
47 {
48 public:
operator ()(const Reference<XResourceId> & rId1,const Reference<XResourceId> & rId2) const49     bool operator () (const Reference<XResourceId>& rId1, const Reference<XResourceId>& rId2) const
50 	{
51         return rId1->compareTo(rId2) == -1;
52     }
53 };
54 
55 } // end of anonymous namespace
56 
57 
58 
59 
60 namespace sd { namespace framework {
61 
62 
63 class Configuration::ResourceContainer
64     : public ::std::set<Reference<XResourceId>, XResourceIdLess>
65 {
66 public:
ResourceContainer(void)67     ResourceContainer (void) {}
68 };
69 
70 
71 
72 
73 //----- Service ---------------------------------------------------------------
74 
Configuration_createInstance(const Reference<XComponentContext> & rxContext)75 Reference<XInterface> SAL_CALL Configuration_createInstance (
76     const Reference<XComponentContext>& rxContext)
77 {
78     (void)rxContext;
79     return Reference<XInterface>(static_cast<XWeak*>(new Configuration(NULL,false)));
80 }
81 
82 
83 
84 
Configuration_getImplementationName(void)85 OUString Configuration_getImplementationName (void) throw(RuntimeException)
86 {
87     return OUString(RTL_CONSTASCII_USTRINGPARAM(
88         "com.sun.star.comp.Draw.framework.configuration.Configuration"));
89 }
90 
91 
92 
93 
Configuration_getSupportedServiceNames(void)94 Sequence<rtl::OUString> SAL_CALL Configuration_getSupportedServiceNames (void)
95     throw (RuntimeException)
96 {
97 	static const OUString sServiceName(OUString::createFromAscii(
98         "com.sun.star.drawing.framework.Configuration"));
99 	return Sequence<rtl::OUString>(&sServiceName, 1);
100 }
101 
102 
103 
104 
105 //===== Configuration =========================================================
106 
Configuration(const Reference<XConfigurationControllerBroadcaster> & rxBroadcaster,bool bBroadcastRequestEvents)107 Configuration::Configuration (
108     const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster,
109     bool bBroadcastRequestEvents)
110     : ConfigurationInterfaceBase(MutexOwner::maMutex),
111       mpResourceContainer(new ResourceContainer()),
112       mxBroadcaster(rxBroadcaster),
113       mbBroadcastRequestEvents(bBroadcastRequestEvents)
114 {
115 }
116 
117 
118 
Configuration(const Reference<XConfigurationControllerBroadcaster> & rxBroadcaster,bool bBroadcastRequestEvents,const ResourceContainer & rResourceContainer)119 Configuration::Configuration (
120     const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster,
121     bool bBroadcastRequestEvents,
122     const ResourceContainer& rResourceContainer)
123     : ConfigurationInterfaceBase(MutexOwner::maMutex),
124       mpResourceContainer(new ResourceContainer(rResourceContainer)),
125       mxBroadcaster(rxBroadcaster),
126       mbBroadcastRequestEvents(bBroadcastRequestEvents)
127 {
128 }
129 
130 
131 
132 
~Configuration(void)133 Configuration::~Configuration (void)
134 {
135 }
136 
137 
138 
139 
disposing(void)140 void SAL_CALL Configuration::disposing (void)
141 {
142     ::osl::MutexGuard aGuard (maMutex);
143     mpResourceContainer->clear();
144     mxBroadcaster = NULL;
145 }
146 
147 
148 
149 
150 //----- XConfiguration --------------------------------------------------------
151 
addResource(const Reference<XResourceId> & rxResourceId)152 void SAL_CALL Configuration::addResource (const Reference<XResourceId>& rxResourceId)
153     throw (RuntimeException)
154 {
155     ThrowIfDisposed();
156 
157     if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0)
158         throw ::com::sun::star::lang::IllegalArgumentException();
159 
160     if (mpResourceContainer->find(rxResourceId) == mpResourceContainer->end())
161     {
162 #ifdef VERBOSE
163     OSL_TRACE("Configuration::addResource() %s",
164         OUStringToOString(
165             FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
166 #endif
167         mpResourceContainer->insert(rxResourceId);
168         PostEvent(rxResourceId, true);
169     }
170 }
171 
172 
173 
174 
removeResource(const Reference<XResourceId> & rxResourceId)175 void SAL_CALL Configuration::removeResource (const Reference<XResourceId>& rxResourceId)
176     throw (RuntimeException)
177 {
178     ThrowIfDisposed();
179 
180     if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0)
181         throw ::com::sun::star::lang::IllegalArgumentException();
182 
183     ResourceContainer::iterator iResource (mpResourceContainer->find(rxResourceId));
184     if (iResource != mpResourceContainer->end())
185     {
186 #ifdef VERBOSE
187     OSL_TRACE("Configuration::removeResource() %s",
188         OUStringToOString(
189             FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
190 #endif
191         PostEvent(rxResourceId,false);
192         mpResourceContainer->erase(iResource);
193     }
194 }
195 
196 
197 
198 
getResources(const Reference<XResourceId> & rxAnchorId,const::rtl::OUString & rsResourceURLPrefix,AnchorBindingMode eMode)199 Sequence<Reference<XResourceId> > SAL_CALL Configuration::getResources (
200     const Reference<XResourceId>& rxAnchorId,
201     const ::rtl::OUString& rsResourceURLPrefix,
202     AnchorBindingMode eMode)
203     throw (::com::sun::star::uno::RuntimeException)
204 {
205     ::osl::MutexGuard aGuard (maMutex);
206     ThrowIfDisposed();
207 
208     bool bFilterResources (rsResourceURLPrefix.getLength() > 0);
209 
210     // Collect the matching resources in a vector.
211     ::std::vector<Reference<XResourceId> > aResources;
212     ResourceContainer::const_iterator iResource;
213     for (iResource=mpResourceContainer->begin();
214          iResource!=mpResourceContainer->end();
215          ++iResource)
216     {
217         if ( ! (*iResource)->isBoundTo(rxAnchorId,eMode))
218             continue;
219 
220 
221         if (bFilterResources)
222         {
223             // Apply the given resource prefix as filter.
224 
225             // Make sure that the resource is bound directly to the anchor.
226             if (eMode != AnchorBindingMode_DIRECT
227                 && ! (*iResource)->isBoundTo(rxAnchorId, AnchorBindingMode_DIRECT))
228             {
229                 continue;
230             }
231 
232             // Make sure that the resource URL matches the given prefix.
233             if ( ! (*iResource)->getResourceURL().match(rsResourceURLPrefix))
234             {
235                 continue;
236             }
237         }
238 
239         aResources.push_back(*iResource);
240     }
241 
242     // Copy the resources from the vector into a new sequence.
243     Sequence<Reference<XResourceId> > aResult (aResources.size());
244     for (sal_uInt32 nIndex=0; nIndex<aResources.size(); ++nIndex)
245         aResult[nIndex] = aResources[nIndex];
246 
247     return aResult;
248 }
249 
250 
251 
252 
hasResource(const Reference<XResourceId> & rxResourceId)253 sal_Bool SAL_CALL Configuration::hasResource (const Reference<XResourceId>& rxResourceId)
254     throw (RuntimeException)
255 {
256     ::osl::MutexGuard aGuard (maMutex);
257     ThrowIfDisposed();
258 
259     return rxResourceId.is()
260         && mpResourceContainer->find(rxResourceId) != mpResourceContainer->end();
261 }
262 
263 
264 
265 
266 //----- XCloneable ------------------------------------------------------------
267 
createClone(void)268 Reference<util::XCloneable> SAL_CALL Configuration::createClone (void)
269     throw (RuntimeException)
270 {
271     ::osl::MutexGuard aGuard (maMutex);
272     ThrowIfDisposed();
273 
274     Configuration* pConfiguration = new Configuration(
275         mxBroadcaster,
276         mbBroadcastRequestEvents,
277         *mpResourceContainer);
278 
279     return Reference<util::XCloneable>(pConfiguration);
280 }
281 
282 
283 
284 
285 //----- XNamed ----------------------------------------------------------------
286 
getName(void)287 OUString SAL_CALL Configuration::getName (void)
288     throw (RuntimeException)
289 {
290     ::osl::MutexGuard aGuard (maMutex);
291     OUString aString;
292 
293 	if (rBHelper.bDisposed || rBHelper.bInDispose)
294         aString += OUString::createFromAscii("DISPOSED ");
295     aString += OUString::createFromAscii("Configuration[");
296 
297     ResourceContainer::const_iterator iResource;
298     for (iResource=mpResourceContainer->begin();
299          iResource!=mpResourceContainer->end();
300          ++iResource)
301     {
302         if (iResource != mpResourceContainer->begin())
303             aString += OUString::createFromAscii(", ");
304         aString += FrameworkHelper::ResourceIdToString(*iResource);
305     }
306     aString += OUString::createFromAscii("]");
307 
308     return aString;
309 }
310 
311 
312 
313 
setName(const OUString & rsName)314 void SAL_CALL Configuration::setName (const OUString& rsName)
315     throw (RuntimeException)
316 {
317     (void)rsName; // rsName is ignored.
318 }
319 
320 
321 
322 
323 
324 // ----------------------------------------------------------------------------
325 
PostEvent(const Reference<XResourceId> & rxResourceId,const bool bActivation)326 void Configuration::PostEvent (
327     const Reference<XResourceId>& rxResourceId,
328     const bool bActivation)
329 {
330     OSL_ASSERT(rxResourceId.is());
331 
332     if (mxBroadcaster.is())
333     {
334         ConfigurationChangeEvent aEvent;
335         aEvent.ResourceId = rxResourceId;
336         if (bActivation)
337             if (mbBroadcastRequestEvents)
338                 aEvent.Type = FrameworkHelper::msResourceActivationRequestEvent;
339             else
340                 aEvent.Type = FrameworkHelper::msResourceActivationEvent;
341         else
342             if (mbBroadcastRequestEvents)
343                 aEvent.Type = FrameworkHelper::msResourceDeactivationRequestEvent;
344             else
345                 aEvent.Type = FrameworkHelper::msResourceDeactivationEvent;
346         aEvent.Configuration = this;
347 
348         mxBroadcaster->notifyEvent(aEvent);
349     }
350 }
351 
352 
353 
354 
ThrowIfDisposed(void) const355 void Configuration::ThrowIfDisposed (void) const
356     throw (::com::sun::star::lang::DisposedException)
357 {
358 	if (rBHelper.bDisposed || rBHelper.bInDispose)
359 	{
360         throw lang::DisposedException (
361             OUString(RTL_CONSTASCII_USTRINGPARAM(
362                 "Configuration object has already been disposed")),
363             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
364     }
365 }
366 
367 
368 
369 
370 //=============================================================================
371 
AreConfigurationsEquivalent(const Reference<XConfiguration> & rxConfiguration1,const Reference<XConfiguration> & rxConfiguration2)372 bool AreConfigurationsEquivalent (
373     const Reference<XConfiguration>& rxConfiguration1,
374     const Reference<XConfiguration>& rxConfiguration2)
375 {
376     if (rxConfiguration1.is() != rxConfiguration2.is())
377         return false;
378     if ( ! rxConfiguration1.is() && ! rxConfiguration2.is())
379         return true;
380 
381     // Get the lists of resources from the two given configurations.
382     const Sequence<Reference<XResourceId> > aResources1(
383         rxConfiguration1->getResources(
384             NULL, OUString(), AnchorBindingMode_INDIRECT));
385     const Sequence<Reference<XResourceId> > aResources2(
386         rxConfiguration2->getResources(
387             NULL, OUString(), AnchorBindingMode_INDIRECT));
388 
389     // When the number of resources differ then the configurations can not
390     // be equivalent.
391     const sal_Int32 nCount (aResources1.getLength());
392     const sal_Int32 nCount2 (aResources2.getLength());
393     if (nCount != nCount2)
394         return false;
395 
396     // Comparison of the two lists of resource ids relies on their
397     // ordering.
398     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
399     {
400         const Reference<XResourceId> xResource1 (aResources1[nIndex]);
401         const Reference<XResourceId> xResource2 (aResources2[nIndex]);
402         if (xResource1.is() && xResource2.is())
403         {
404             if (xResource1->compareTo(xResource2) != 0)
405                 return false;
406         }
407         else if (xResource1.is() != xResource2.is())
408         {
409             return false;
410         }
411     }
412 
413     return true;
414 }
415 
416 } } // end of namespace sd::framework
417