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