1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "precompiled_sd.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include "framework/ResourceId.hxx"
31*cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
32*cdf0e10cSrcweir #include "tools/SdGlobalResourceContainer.hxx"
33*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
35*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
36*cdf0e10cSrcweir #include <rtl/ref.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir using namespace ::com::sun::star;
39*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
40*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
41*cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
42*cdf0e10cSrcweir using ::rtl::OUString;
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir /** When the USE_OPTIMIZATIONS symbol is defined then at some optimizations
45*cdf0e10cSrcweir     are activated that work only together with XResourceId objects that are
46*cdf0e10cSrcweir     implemented by the ResourceId class.  For other implementations of when
47*cdf0e10cSrcweir     the USE_OPTIMIZATIONS symbol is not defined then alternative code is
48*cdf0e10cSrcweir     used instead.
49*cdf0e10cSrcweir */
50*cdf0e10cSrcweir #define USE_OPTIMIZATIONS
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir namespace sd { namespace framework {
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir Reference<XInterface> SAL_CALL ResourceId_createInstance (
55*cdf0e10cSrcweir     const Reference<XComponentContext>& rxContext)
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir     (void)rxContext;
58*cdf0e10cSrcweir     return Reference<XInterface>(static_cast<XWeak*>(new ::sd::framework::ResourceId()));
59*cdf0e10cSrcweir }
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir ::rtl::OUString ResourceId_getImplementationName (void) throw(RuntimeException)
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir     return ::rtl::OUString(
67*cdf0e10cSrcweir         RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.ResourceId"));
68*cdf0e10cSrcweir }
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir Sequence<rtl::OUString> SAL_CALL ResourceId_getSupportedServiceNames (void)
74*cdf0e10cSrcweir     throw (RuntimeException)
75*cdf0e10cSrcweir {
76*cdf0e10cSrcweir 	static const ::rtl::OUString sServiceName(
77*cdf0e10cSrcweir         ::rtl::OUString::createFromAscii("com.sun.star.drawing.framework.ResourceId"));
78*cdf0e10cSrcweir 	return Sequence<rtl::OUString>(&sServiceName, 1);
79*cdf0e10cSrcweir }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir //===== ResourceId ============================================================
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir WeakReference<util::XURLTransformer> ResourceId::mxURLTransformerWeak;
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir ResourceId::ResourceId (void)
89*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
90*cdf0e10cSrcweir       maResourceURLs(0),
91*cdf0e10cSrcweir       mpURL()
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir }
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir ResourceId::ResourceId (
99*cdf0e10cSrcweir     const std::vector<OUString>& rResourceURLs)
100*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
101*cdf0e10cSrcweir       maResourceURLs(rResourceURLs),
102*cdf0e10cSrcweir       mpURL()
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir     ParseResourceURL();
105*cdf0e10cSrcweir }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir ResourceId::ResourceId (
111*cdf0e10cSrcweir     const OUString& rsResourceURL)
112*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
113*cdf0e10cSrcweir       maResourceURLs(1, rsResourceURL),
114*cdf0e10cSrcweir       mpURL()
115*cdf0e10cSrcweir {
116*cdf0e10cSrcweir     // Handle the special case of an empty resource URL.
117*cdf0e10cSrcweir     if (rsResourceURL.getLength() == 0)
118*cdf0e10cSrcweir         maResourceURLs.clear();
119*cdf0e10cSrcweir     ParseResourceURL();
120*cdf0e10cSrcweir }
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir ResourceId::ResourceId (
126*cdf0e10cSrcweir     const OUString& rsResourceURL,
127*cdf0e10cSrcweir     const OUString& rsAnchorURL)
128*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
129*cdf0e10cSrcweir       maResourceURLs(2),
130*cdf0e10cSrcweir       mpURL()
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir     maResourceURLs[0] = rsResourceURL;
133*cdf0e10cSrcweir     maResourceURLs[1] = rsAnchorURL;
134*cdf0e10cSrcweir     ParseResourceURL();
135*cdf0e10cSrcweir }
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir ResourceId::ResourceId (
141*cdf0e10cSrcweir     const OUString& rsResourceURL,
142*cdf0e10cSrcweir     const ::std::vector<OUString>& rAnchorURLs)
143*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
144*cdf0e10cSrcweir       maResourceURLs(1+rAnchorURLs.size()),
145*cdf0e10cSrcweir       mpURL()
146*cdf0e10cSrcweir {
147*cdf0e10cSrcweir     maResourceURLs[0] = rsResourceURL;
148*cdf0e10cSrcweir     for (sal_uInt32 nIndex=0; nIndex<rAnchorURLs.size(); ++nIndex)
149*cdf0e10cSrcweir         maResourceURLs[nIndex+1] = rAnchorURLs[nIndex];
150*cdf0e10cSrcweir     ParseResourceURL();
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir ResourceId::ResourceId (
157*cdf0e10cSrcweir     const OUString& rsResourceURL,
158*cdf0e10cSrcweir     const OUString& rsFirstAnchorURL,
159*cdf0e10cSrcweir     const Sequence<OUString>& rAnchorURLs)
160*cdf0e10cSrcweir     : ResourceIdInterfaceBase(),
161*cdf0e10cSrcweir       maResourceURLs(2+rAnchorURLs.getLength()),
162*cdf0e10cSrcweir       mpURL()
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     maResourceURLs[0] = rsResourceURL;
165*cdf0e10cSrcweir     maResourceURLs[1] = rsFirstAnchorURL;
166*cdf0e10cSrcweir     for (sal_Int32 nIndex=0; nIndex<rAnchorURLs.getLength(); ++nIndex)
167*cdf0e10cSrcweir         maResourceURLs[nIndex+2] = rAnchorURLs[nIndex];
168*cdf0e10cSrcweir     ParseResourceURL();
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir ResourceId::~ResourceId (void)
175*cdf0e10cSrcweir {
176*cdf0e10cSrcweir     mpURL.reset();
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir OUString SAL_CALL
183*cdf0e10cSrcweir     ResourceId::getResourceURL (void)
184*cdf0e10cSrcweir     throw(com::sun::star::uno::RuntimeException)
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir     if (!maResourceURLs.empty())
187*cdf0e10cSrcweir         return maResourceURLs[0];
188*cdf0e10cSrcweir     else
189*cdf0e10cSrcweir         return OUString();
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir util::URL SAL_CALL
196*cdf0e10cSrcweir     ResourceId::getFullResourceURL (void)
197*cdf0e10cSrcweir  throw(com::sun::star::uno::RuntimeException)
198*cdf0e10cSrcweir {
199*cdf0e10cSrcweir     if (mpURL.get() != NULL)
200*cdf0e10cSrcweir         return *mpURL;
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir     Reference<util::XURLTransformer> xURLTransformer (mxURLTransformerWeak);
203*cdf0e10cSrcweir     if (xURLTransformer.is() && !maResourceURLs.empty() )
204*cdf0e10cSrcweir     {
205*cdf0e10cSrcweir         mpURL.reset(new util::URL);
206*cdf0e10cSrcweir         mpURL->Complete = maResourceURLs[0];
207*cdf0e10cSrcweir         xURLTransformer->parseStrict(*mpURL);
208*cdf0e10cSrcweir         return *mpURL;
209*cdf0e10cSrcweir     }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir     util::URL aURL;
212*cdf0e10cSrcweir     if (!maResourceURLs.empty())
213*cdf0e10cSrcweir         aURL.Complete = maResourceURLs[0];
214*cdf0e10cSrcweir     return aURL;
215*cdf0e10cSrcweir }
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir sal_Bool SAL_CALL
221*cdf0e10cSrcweir     ResourceId::hasAnchor (void)
222*cdf0e10cSrcweir     throw (RuntimeException)
223*cdf0e10cSrcweir {
224*cdf0e10cSrcweir     return maResourceURLs.size()>1;
225*cdf0e10cSrcweir }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir Reference<XResourceId> SAL_CALL
231*cdf0e10cSrcweir     ResourceId::getAnchor (void)
232*cdf0e10cSrcweir     throw (RuntimeException)
233*cdf0e10cSrcweir {
234*cdf0e10cSrcweir     ::rtl::Reference<ResourceId> rResourceId (new ResourceId());
235*cdf0e10cSrcweir     const sal_Int32 nAnchorCount (maResourceURLs.size()-1);
236*cdf0e10cSrcweir     if (nAnchorCount > 0)
237*cdf0e10cSrcweir     {
238*cdf0e10cSrcweir         rResourceId->maResourceURLs.resize(nAnchorCount);
239*cdf0e10cSrcweir         for (sal_Int32 nIndex=0; nIndex<nAnchorCount; ++nIndex)
240*cdf0e10cSrcweir             rResourceId->maResourceURLs[nIndex] = maResourceURLs[nIndex+1];
241*cdf0e10cSrcweir     }
242*cdf0e10cSrcweir     return Reference<XResourceId>(rResourceId.get());
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir Sequence<OUString> SAL_CALL
249*cdf0e10cSrcweir     ResourceId::getAnchorURLs (void)
250*cdf0e10cSrcweir     throw (RuntimeException)
251*cdf0e10cSrcweir {
252*cdf0e10cSrcweir     const sal_Int32 nAnchorCount (maResourceURLs.size() - 1);
253*cdf0e10cSrcweir     if (nAnchorCount > 0)
254*cdf0e10cSrcweir     {
255*cdf0e10cSrcweir         Sequence<OUString> aAnchorURLs (nAnchorCount);
256*cdf0e10cSrcweir         for (sal_Int32 nIndex=0; nIndex<nAnchorCount; ++nIndex)
257*cdf0e10cSrcweir             aAnchorURLs[nIndex] = maResourceURLs[nIndex+1];
258*cdf0e10cSrcweir         return aAnchorURLs;
259*cdf0e10cSrcweir     }
260*cdf0e10cSrcweir     else
261*cdf0e10cSrcweir         return Sequence<OUString>();
262*cdf0e10cSrcweir }
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir OUString SAL_CALL
268*cdf0e10cSrcweir     ResourceId::getResourceTypePrefix (void)
269*cdf0e10cSrcweir     throw (RuntimeException)
270*cdf0e10cSrcweir {
271*cdf0e10cSrcweir     if (!maResourceURLs.empty() )
272*cdf0e10cSrcweir     {
273*cdf0e10cSrcweir         // Return the "private:resource/<type>/" prefix.
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir         // Get the the prefix that ends with the second "/".
276*cdf0e10cSrcweir         const OUString& rsResourceURL (maResourceURLs[0]);
277*cdf0e10cSrcweir         sal_Int32 nPrefixEnd (rsResourceURL.indexOf(sal_Unicode('/'), 0));
278*cdf0e10cSrcweir         if (nPrefixEnd >= 0)
279*cdf0e10cSrcweir             nPrefixEnd = rsResourceURL.indexOf(sal_Unicode('/'), nPrefixEnd+1) + 1;
280*cdf0e10cSrcweir         else
281*cdf0e10cSrcweir             nPrefixEnd = 0;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir         return rsResourceURL.copy(0,nPrefixEnd);
284*cdf0e10cSrcweir     }
285*cdf0e10cSrcweir     else
286*cdf0e10cSrcweir         return OUString();
287*cdf0e10cSrcweir }
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir sal_Int16 SAL_CALL
293*cdf0e10cSrcweir     ResourceId::compareTo (const Reference<XResourceId>& rxResourceId)
294*cdf0e10cSrcweir     throw (RuntimeException)
295*cdf0e10cSrcweir {
296*cdf0e10cSrcweir     sal_Int16 nResult (0);
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir     if ( ! rxResourceId.is())
299*cdf0e10cSrcweir     {
300*cdf0e10cSrcweir         // The empty reference is interpreted as empty resource id object.
301*cdf0e10cSrcweir         if (!maResourceURLs.empty())
302*cdf0e10cSrcweir             nResult = +1;
303*cdf0e10cSrcweir         else
304*cdf0e10cSrcweir             nResult = 0;
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir     else
307*cdf0e10cSrcweir     {
308*cdf0e10cSrcweir         ResourceId* pId = NULL;
309*cdf0e10cSrcweir #ifdef USE_OPTIMIZATIONS
310*cdf0e10cSrcweir         pId = dynamic_cast<ResourceId*>(rxResourceId.get());
311*cdf0e10cSrcweir #endif
312*cdf0e10cSrcweir         if (pId != NULL)
313*cdf0e10cSrcweir         {
314*cdf0e10cSrcweir             // We have direct access to the implementation of the given
315*cdf0e10cSrcweir             // resource id object.
316*cdf0e10cSrcweir             nResult = CompareToLocalImplementation(*pId);
317*cdf0e10cSrcweir         }
318*cdf0e10cSrcweir         else
319*cdf0e10cSrcweir         {
320*cdf0e10cSrcweir             // We have to do the comparison via the UNO interface of the
321*cdf0e10cSrcweir             // given resource id object.
322*cdf0e10cSrcweir             nResult = CompareToExternalImplementation(rxResourceId);
323*cdf0e10cSrcweir         }
324*cdf0e10cSrcweir     }
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir     return nResult;
327*cdf0e10cSrcweir }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir sal_Int16 ResourceId::CompareToLocalImplementation (const ResourceId& rId) const
333*cdf0e10cSrcweir {
334*cdf0e10cSrcweir     sal_Int16 nResult (0);
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir     const sal_uInt32 nLocalURLCount (maResourceURLs.size());
337*cdf0e10cSrcweir     const sal_uInt32 nURLCount(rId.maResourceURLs.size());
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     // Start comparison with the top most anchors.
340*cdf0e10cSrcweir     for (sal_Int32 nIndex=nURLCount-1,nLocalIndex=nLocalURLCount-1;
341*cdf0e10cSrcweir          nIndex>=0 && nLocalIndex>=0;
342*cdf0e10cSrcweir          --nIndex,--nLocalIndex)
343*cdf0e10cSrcweir     {
344*cdf0e10cSrcweir         const OUString sLocalURL (maResourceURLs[nLocalIndex]);
345*cdf0e10cSrcweir         const OUString sURL (rId.maResourceURLs[nIndex]);
346*cdf0e10cSrcweir         const sal_Int32 nLocalResult (sURL.compareTo(sLocalURL));
347*cdf0e10cSrcweir         if (nLocalResult != 0)
348*cdf0e10cSrcweir         {
349*cdf0e10cSrcweir             if (nLocalResult < 0)
350*cdf0e10cSrcweir                 nResult = -1;
351*cdf0e10cSrcweir             else
352*cdf0e10cSrcweir                 nResult = +1;
353*cdf0e10cSrcweir             break;
354*cdf0e10cSrcweir         }
355*cdf0e10cSrcweir     }
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir     if (nResult == 0)
358*cdf0e10cSrcweir     {
359*cdf0e10cSrcweir         // No difference found yet.  When the lengths are the same then the
360*cdf0e10cSrcweir         // two resource ids are equivalent.  Otherwise the shorter comes
361*cdf0e10cSrcweir         // first.
362*cdf0e10cSrcweir         if (nLocalURLCount != nURLCount)
363*cdf0e10cSrcweir         {
364*cdf0e10cSrcweir             if (nLocalURLCount < nURLCount)
365*cdf0e10cSrcweir                 nResult = -1;
366*cdf0e10cSrcweir             else
367*cdf0e10cSrcweir                 nResult = +1;
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir     return nResult;
372*cdf0e10cSrcweir }
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir sal_Int16 ResourceId::CompareToExternalImplementation (const Reference<XResourceId>& rxId) const
378*cdf0e10cSrcweir {
379*cdf0e10cSrcweir     sal_Int16 nResult (0);
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir     const Sequence<OUString> aAnchorURLs (rxId->getAnchorURLs());
382*cdf0e10cSrcweir     const sal_uInt32 nLocalURLCount (maResourceURLs.size());
383*cdf0e10cSrcweir     const sal_uInt32 nURLCount(1+aAnchorURLs.getLength());
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir     // Start comparison with the top most anchors.
386*cdf0e10cSrcweir     sal_Int32 nLocalResult (0);
387*cdf0e10cSrcweir     for (sal_Int32 nIndex=nURLCount-1,nLocalIndex=nLocalURLCount-1;
388*cdf0e10cSrcweir          nIndex>=0&&nLocalIndex>=0;
389*cdf0e10cSrcweir          --nIndex,--nLocalIndex)
390*cdf0e10cSrcweir     {
391*cdf0e10cSrcweir         if (nIndex == 0 )
392*cdf0e10cSrcweir             nLocalResult = maResourceURLs[nIndex].compareTo(rxId->getResourceURL());
393*cdf0e10cSrcweir         else
394*cdf0e10cSrcweir             nLocalResult = maResourceURLs[nIndex].compareTo(aAnchorURLs[nIndex-1]);
395*cdf0e10cSrcweir         if (nLocalResult != 0)
396*cdf0e10cSrcweir         {
397*cdf0e10cSrcweir             if (nLocalResult < 0)
398*cdf0e10cSrcweir                 nResult = -1;
399*cdf0e10cSrcweir             else
400*cdf0e10cSrcweir                 nResult = +1;
401*cdf0e10cSrcweir             break;
402*cdf0e10cSrcweir         }
403*cdf0e10cSrcweir     }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir     if (nResult == 0)
406*cdf0e10cSrcweir     {
407*cdf0e10cSrcweir         // No difference found yet.  When the lengths are the same then the
408*cdf0e10cSrcweir         // two resource ids are equivalent.  Otherwise the shorter comes
409*cdf0e10cSrcweir         // first.
410*cdf0e10cSrcweir         if (nLocalURLCount != nURLCount)
411*cdf0e10cSrcweir         {
412*cdf0e10cSrcweir             if (nLocalURLCount < nURLCount)
413*cdf0e10cSrcweir                 nResult = -1;
414*cdf0e10cSrcweir             else
415*cdf0e10cSrcweir                 nResult = +1;
416*cdf0e10cSrcweir         }
417*cdf0e10cSrcweir     }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     return nResult;
420*cdf0e10cSrcweir }
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir sal_Bool SAL_CALL
426*cdf0e10cSrcweir     ResourceId::isBoundTo (
427*cdf0e10cSrcweir         const Reference<XResourceId>& rxResourceId,
428*cdf0e10cSrcweir         AnchorBindingMode eMode)
429*cdf0e10cSrcweir     throw (RuntimeException)
430*cdf0e10cSrcweir {
431*cdf0e10cSrcweir     if ( ! rxResourceId.is())
432*cdf0e10cSrcweir     {
433*cdf0e10cSrcweir         // An empty reference is interpreted as empty resource id.
434*cdf0e10cSrcweir         return IsBoundToAnchor(NULL, NULL, eMode);
435*cdf0e10cSrcweir     }
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir     ResourceId* pId = NULL;
438*cdf0e10cSrcweir #ifdef USE_OPTIMIZATIONS
439*cdf0e10cSrcweir     pId = dynamic_cast<ResourceId*>(rxResourceId.get());
440*cdf0e10cSrcweir #endif
441*cdf0e10cSrcweir     if (pId != NULL)
442*cdf0e10cSrcweir     {
443*cdf0e10cSrcweir         return IsBoundToAnchor(pId->maResourceURLs, eMode);
444*cdf0e10cSrcweir     }
445*cdf0e10cSrcweir     else
446*cdf0e10cSrcweir     {
447*cdf0e10cSrcweir         const OUString sResourceURL (rxResourceId->getResourceURL());
448*cdf0e10cSrcweir         const Sequence<OUString> aAnchorURLs (rxResourceId->getAnchorURLs());
449*cdf0e10cSrcweir         return IsBoundToAnchor(&sResourceURL, &aAnchorURLs, eMode);
450*cdf0e10cSrcweir     }
451*cdf0e10cSrcweir }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir sal_Bool SAL_CALL
457*cdf0e10cSrcweir     ResourceId::isBoundToURL (
458*cdf0e10cSrcweir         const OUString& rsAnchorURL,
459*cdf0e10cSrcweir         AnchorBindingMode eMode)
460*cdf0e10cSrcweir     throw (RuntimeException)
461*cdf0e10cSrcweir {
462*cdf0e10cSrcweir     return IsBoundToAnchor(&rsAnchorURL, NULL, eMode);
463*cdf0e10cSrcweir }
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir Reference<XResourceId> SAL_CALL
469*cdf0e10cSrcweir     ResourceId::clone (void)
470*cdf0e10cSrcweir     throw(RuntimeException)
471*cdf0e10cSrcweir {
472*cdf0e10cSrcweir     return new ResourceId(maResourceURLs);
473*cdf0e10cSrcweir }
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir //----- XInitialization -------------------------------------------------------
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir void SAL_CALL ResourceId::initialize (const Sequence<Any>& aArguments)
481*cdf0e10cSrcweir     throw (RuntimeException)
482*cdf0e10cSrcweir {
483*cdf0e10cSrcweir     sal_uInt32 nCount (aArguments.getLength());
484*cdf0e10cSrcweir     for (sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex)
485*cdf0e10cSrcweir     {
486*cdf0e10cSrcweir         OUString sResourceURL;
487*cdf0e10cSrcweir         if (aArguments[nIndex] >>= sResourceURL)
488*cdf0e10cSrcweir             maResourceURLs.push_back(sResourceURL);
489*cdf0e10cSrcweir         else
490*cdf0e10cSrcweir         {
491*cdf0e10cSrcweir             Reference<XResourceId> xAnchor;
492*cdf0e10cSrcweir             if (aArguments[nIndex] >>= xAnchor)
493*cdf0e10cSrcweir             {
494*cdf0e10cSrcweir                 if (xAnchor.is())
495*cdf0e10cSrcweir                 {
496*cdf0e10cSrcweir                     maResourceURLs.push_back(xAnchor->getResourceURL());
497*cdf0e10cSrcweir                     Sequence<OUString> aAnchorURLs (xAnchor->getAnchorURLs());
498*cdf0e10cSrcweir                     for (sal_Int32 nURLIndex=0; nURLIndex<aAnchorURLs.getLength(); ++nURLIndex)
499*cdf0e10cSrcweir                     {
500*cdf0e10cSrcweir                         maResourceURLs.push_back(aAnchorURLs[nURLIndex]);
501*cdf0e10cSrcweir                     }
502*cdf0e10cSrcweir                 }
503*cdf0e10cSrcweir             }
504*cdf0e10cSrcweir         }
505*cdf0e10cSrcweir     }
506*cdf0e10cSrcweir     ParseResourceURL();
507*cdf0e10cSrcweir }
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir //-----------------------------------------------------------------------------
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir /** When eMode is DIRECTLY then the anchor of the called object and the
515*cdf0e10cSrcweir     anchor represented by the given sequence of anchor URLs have to be
516*cdf0e10cSrcweir     identical.   When eMode is RECURSIVE then the anchor of the called
517*cdf0e10cSrcweir     object has to start with the given anchor URLs.
518*cdf0e10cSrcweir */
519*cdf0e10cSrcweir bool ResourceId::IsBoundToAnchor (
520*cdf0e10cSrcweir     const OUString* psFirstAnchorURL,
521*cdf0e10cSrcweir     const Sequence<OUString>* paAnchorURLs,
522*cdf0e10cSrcweir     AnchorBindingMode eMode) const
523*cdf0e10cSrcweir {
524*cdf0e10cSrcweir     const sal_uInt32 nLocalAnchorURLCount (maResourceURLs.size() - 1);
525*cdf0e10cSrcweir     const bool bHasFirstAnchorURL (psFirstAnchorURL!=NULL);
526*cdf0e10cSrcweir     const sal_uInt32 nAnchorURLCount ((bHasFirstAnchorURL?1:0)
527*cdf0e10cSrcweir         + (paAnchorURLs!=NULL ? paAnchorURLs->getLength() : 0));
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir     // Check the lengths.
530*cdf0e10cSrcweir     if (nLocalAnchorURLCount<nAnchorURLCount ||
531*cdf0e10cSrcweir         (eMode==AnchorBindingMode_DIRECT && nLocalAnchorURLCount!=nAnchorURLCount))
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         return false;
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     // Compare the nAnchorURLCount bottom-most anchor URLs of this resource
537*cdf0e10cSrcweir     // id and the given anchor.
538*cdf0e10cSrcweir     sal_uInt32 nOffset = 0;
539*cdf0e10cSrcweir     if (paAnchorURLs != NULL)
540*cdf0e10cSrcweir     {
541*cdf0e10cSrcweir         sal_uInt32 nCount = paAnchorURLs->getLength();
542*cdf0e10cSrcweir         while (nOffset < nCount)
543*cdf0e10cSrcweir         {
544*cdf0e10cSrcweir             if ( ! maResourceURLs[nLocalAnchorURLCount - nOffset].equals(
545*cdf0e10cSrcweir                 (*paAnchorURLs)[nCount - 1 - nOffset]))
546*cdf0e10cSrcweir             {
547*cdf0e10cSrcweir                 return false;
548*cdf0e10cSrcweir             }
549*cdf0e10cSrcweir             ++nOffset;
550*cdf0e10cSrcweir         }
551*cdf0e10cSrcweir     }
552*cdf0e10cSrcweir     if (bHasFirstAnchorURL)
553*cdf0e10cSrcweir     {
554*cdf0e10cSrcweir         if ( ! psFirstAnchorURL->equals(maResourceURLs[nLocalAnchorURLCount - nOffset]))
555*cdf0e10cSrcweir             return false;
556*cdf0e10cSrcweir     }
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir     return true;
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir bool ResourceId::IsBoundToAnchor (
565*cdf0e10cSrcweir     const ::std::vector<OUString>& rAnchorURLs,
566*cdf0e10cSrcweir     AnchorBindingMode eMode) const
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     const sal_uInt32 nLocalAnchorURLCount (maResourceURLs.size() - 1);
569*cdf0e10cSrcweir     const sal_uInt32 nAnchorURLCount (rAnchorURLs.size());
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir     // Check the lengths.
572*cdf0e10cSrcweir     if (nLocalAnchorURLCount<nAnchorURLCount ||
573*cdf0e10cSrcweir         (eMode==AnchorBindingMode_DIRECT && nLocalAnchorURLCount!=nAnchorURLCount))
574*cdf0e10cSrcweir     {
575*cdf0e10cSrcweir         return false;
576*cdf0e10cSrcweir     }
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir     // Compare the nAnchorURLCount bottom-most anchor URLs of this resource
579*cdf0e10cSrcweir     // id and the given anchor.
580*cdf0e10cSrcweir     for (sal_uInt32 nOffset=0; nOffset<nAnchorURLCount; ++nOffset)
581*cdf0e10cSrcweir     {
582*cdf0e10cSrcweir         if ( ! maResourceURLs[nLocalAnchorURLCount - nOffset].equals(
583*cdf0e10cSrcweir             rAnchorURLs[nAnchorURLCount - 1 - nOffset]))
584*cdf0e10cSrcweir         {
585*cdf0e10cSrcweir             return false;
586*cdf0e10cSrcweir         }
587*cdf0e10cSrcweir     }
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir     return true;
590*cdf0e10cSrcweir }
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir void ResourceId::ParseResourceURL (void)
596*cdf0e10cSrcweir {
597*cdf0e10cSrcweir     ::osl::Guard< ::osl::Mutex > aGuard (::osl::Mutex::getGlobalMutex());
598*cdf0e10cSrcweir     Reference<util::XURLTransformer> xURLTransformer (mxURLTransformerWeak);
599*cdf0e10cSrcweir     if ( ! xURLTransformer.is())
600*cdf0e10cSrcweir     {
601*cdf0e10cSrcweir         // Create the URL transformer.
602*cdf0e10cSrcweir         Reference<lang::XMultiServiceFactory> xServiceManager (
603*cdf0e10cSrcweir             ::comphelper::getProcessServiceFactory());
604*cdf0e10cSrcweir         xURLTransformer = Reference<util::XURLTransformer>(
605*cdf0e10cSrcweir             xServiceManager->createInstance(
606*cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),
607*cdf0e10cSrcweir             UNO_QUERY);
608*cdf0e10cSrcweir         mxURLTransformerWeak = xURLTransformer;
609*cdf0e10cSrcweir         SdGlobalResourceContainer::Instance().AddResource(
610*cdf0e10cSrcweir             Reference<XInterface>(xURLTransformer,UNO_QUERY));
611*cdf0e10cSrcweir     }
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir     if (xURLTransformer.is() && !maResourceURLs.empty() )
614*cdf0e10cSrcweir     {
615*cdf0e10cSrcweir         mpURL.reset(new util::URL);
616*cdf0e10cSrcweir         mpURL->Complete = maResourceURLs[0];
617*cdf0e10cSrcweir         xURLTransformer->parseStrict(*mpURL);
618*cdf0e10cSrcweir         if (mpURL->Main == maResourceURLs[0])
619*cdf0e10cSrcweir             mpURL.reset();
620*cdf0e10cSrcweir         else
621*cdf0e10cSrcweir             maResourceURLs[0] = mpURL->Main;
622*cdf0e10cSrcweir     }
623*cdf0e10cSrcweir }
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir } } // end of namespace sd::framework
627