xref: /aoo41x/main/configmgr/source/data.cxx (revision cdf0e10c)
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_configmgr.hxx"
29*cdf0e10cSrcweir #include "sal/config.h"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <algorithm>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
34*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
35*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
36*cdf0e10cSrcweir #include "osl/diagnose.h"
37*cdf0e10cSrcweir #include "rtl/ref.hxx"
38*cdf0e10cSrcweir #include "rtl/string.h"
39*cdf0e10cSrcweir #include "rtl/textenc.h"
40*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
41*cdf0e10cSrcweir #include "rtl/ustring.h"
42*cdf0e10cSrcweir #include "rtl/ustring.hxx"
43*cdf0e10cSrcweir #include "sal/types.h"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include "additions.hxx"
46*cdf0e10cSrcweir #include "data.hxx"
47*cdf0e10cSrcweir #include "groupnode.hxx"
48*cdf0e10cSrcweir #include "node.hxx"
49*cdf0e10cSrcweir #include "nodemap.hxx"
50*cdf0e10cSrcweir #include "setnode.hxx"
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir namespace configmgr {
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir namespace {
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir namespace css = com::sun::star;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir bool decode(
59*cdf0e10cSrcweir     rtl::OUString const & encoded, sal_Int32 begin, sal_Int32 end,
60*cdf0e10cSrcweir     rtl::OUString * decoded)
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir     OSL_ASSERT(
63*cdf0e10cSrcweir         begin >= 0 && begin <= end && end <= encoded.getLength() &&
64*cdf0e10cSrcweir         decoded != 0);
65*cdf0e10cSrcweir     rtl::OUStringBuffer buf;
66*cdf0e10cSrcweir     while (begin != end) {
67*cdf0e10cSrcweir         sal_Unicode c = encoded[begin++];
68*cdf0e10cSrcweir         if (c == '&') {
69*cdf0e10cSrcweir             if (encoded.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("amp;"), begin))
70*cdf0e10cSrcweir             {
71*cdf0e10cSrcweir                 buf.append(sal_Unicode('&'));
72*cdf0e10cSrcweir                 begin += RTL_CONSTASCII_LENGTH("amp;");
73*cdf0e10cSrcweir             } else if (encoded.matchAsciiL(
74*cdf0e10cSrcweir                            RTL_CONSTASCII_STRINGPARAM("quot;"), begin))
75*cdf0e10cSrcweir             {
76*cdf0e10cSrcweir                 buf.append(sal_Unicode('"'));
77*cdf0e10cSrcweir                 begin += RTL_CONSTASCII_LENGTH("quot;");
78*cdf0e10cSrcweir             } else if (encoded.matchAsciiL(
79*cdf0e10cSrcweir                            RTL_CONSTASCII_STRINGPARAM("apos;"), begin))
80*cdf0e10cSrcweir             {
81*cdf0e10cSrcweir                 buf.append(sal_Unicode('\''));
82*cdf0e10cSrcweir                 begin += RTL_CONSTASCII_LENGTH("apos;");
83*cdf0e10cSrcweir             } else {
84*cdf0e10cSrcweir                 return false;
85*cdf0e10cSrcweir             }
86*cdf0e10cSrcweir             OSL_ASSERT(begin <= end);
87*cdf0e10cSrcweir         } else {
88*cdf0e10cSrcweir             buf.append(c);
89*cdf0e10cSrcweir         }
90*cdf0e10cSrcweir     }
91*cdf0e10cSrcweir     *decoded = buf.makeStringAndClear();
92*cdf0e10cSrcweir     return true;
93*cdf0e10cSrcweir }
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir rtl::OUString Data::createSegment(
98*cdf0e10cSrcweir     rtl::OUString const & templateName, rtl::OUString const & name)
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir     if (templateName.getLength() == 0) {
101*cdf0e10cSrcweir         return name;
102*cdf0e10cSrcweir     }
103*cdf0e10cSrcweir     rtl::OUStringBuffer buf(templateName);
104*cdf0e10cSrcweir         //TODO: verify template name contains no bad chars?
105*cdf0e10cSrcweir     buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("['"));
106*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < name.getLength(); ++i) {
107*cdf0e10cSrcweir         sal_Unicode c = name[i];
108*cdf0e10cSrcweir         switch (c) {
109*cdf0e10cSrcweir         case '&':
110*cdf0e10cSrcweir             buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("&amp;"));
111*cdf0e10cSrcweir             break;
112*cdf0e10cSrcweir         case '"':
113*cdf0e10cSrcweir             buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("&quot;"));
114*cdf0e10cSrcweir             break;
115*cdf0e10cSrcweir         case '\'':
116*cdf0e10cSrcweir             buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("&apos;"));
117*cdf0e10cSrcweir             break;
118*cdf0e10cSrcweir         default:
119*cdf0e10cSrcweir             buf.append(c);
120*cdf0e10cSrcweir             break;
121*cdf0e10cSrcweir         }
122*cdf0e10cSrcweir     }
123*cdf0e10cSrcweir     buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("']"));
124*cdf0e10cSrcweir     return buf.makeStringAndClear();
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir sal_Int32 Data::parseSegment(
128*cdf0e10cSrcweir     rtl::OUString const & path, sal_Int32 index, rtl::OUString * name,
129*cdf0e10cSrcweir     bool * setElement, rtl::OUString * templateName)
130*cdf0e10cSrcweir {
131*cdf0e10cSrcweir     OSL_ASSERT(
132*cdf0e10cSrcweir         index >= 0 && index <= path.getLength() && name != 0 &&
133*cdf0e10cSrcweir         setElement != 0);
134*cdf0e10cSrcweir     sal_Int32 i = index;
135*cdf0e10cSrcweir     while (i < path.getLength() && path[i] != '/' && path[i] != '[') {
136*cdf0e10cSrcweir         ++i;
137*cdf0e10cSrcweir     }
138*cdf0e10cSrcweir     if (i == path.getLength() || path[i] == '/') {
139*cdf0e10cSrcweir         *name = path.copy(index, i - index);
140*cdf0e10cSrcweir         *setElement = false;
141*cdf0e10cSrcweir         return i;
142*cdf0e10cSrcweir     }
143*cdf0e10cSrcweir     if (templateName != 0) {
144*cdf0e10cSrcweir         if (i - index == 1 && path[index] == '*') {
145*cdf0e10cSrcweir             *templateName = rtl::OUString();
146*cdf0e10cSrcweir         } else {
147*cdf0e10cSrcweir             *templateName = path.copy(index, i - index);
148*cdf0e10cSrcweir         }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir     if (++i == path.getLength()) {
151*cdf0e10cSrcweir         return -1;
152*cdf0e10cSrcweir     }
153*cdf0e10cSrcweir     sal_Unicode del = path[i++];
154*cdf0e10cSrcweir     if (del != '\'' && del != '"') {
155*cdf0e10cSrcweir         return -1;
156*cdf0e10cSrcweir     }
157*cdf0e10cSrcweir     sal_Int32 j = path.indexOf(del, i);
158*cdf0e10cSrcweir     if (j == -1 || j + 1 == path.getLength() || path[j + 1] != ']' ||
159*cdf0e10cSrcweir         !decode(path, i, j, name))
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         return -1;
162*cdf0e10cSrcweir     }
163*cdf0e10cSrcweir     *setElement = true;
164*cdf0e10cSrcweir     return j + 2;
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir rtl::OUString Data::fullTemplateName(
168*cdf0e10cSrcweir     rtl::OUString const & component, rtl::OUString const & name)
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir     if (component.indexOf(':') != -1 || name.indexOf(':') != -1) {
171*cdf0e10cSrcweir         throw css::uno::RuntimeException(
172*cdf0e10cSrcweir             (rtl::OUString(
173*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
174*cdf0e10cSrcweir                     "bad component/name pair containing colon ")) +
175*cdf0e10cSrcweir              component + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
176*cdf0e10cSrcweir              name),
177*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
178*cdf0e10cSrcweir     }
179*cdf0e10cSrcweir     rtl::OUStringBuffer buf(component);
180*cdf0e10cSrcweir     buf.append(sal_Unicode(':'));
181*cdf0e10cSrcweir     buf.append(name);
182*cdf0e10cSrcweir     return buf.makeStringAndClear();
183*cdf0e10cSrcweir }
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir bool Data::equalTemplateNames(
186*cdf0e10cSrcweir     rtl::OUString const & shortName, rtl::OUString const & longName)
187*cdf0e10cSrcweir {
188*cdf0e10cSrcweir     if (shortName.indexOf(':') == -1) {
189*cdf0e10cSrcweir         sal_Int32 i = longName.indexOf(':') + 1;
190*cdf0e10cSrcweir         OSL_ASSERT(i > 0);
191*cdf0e10cSrcweir         return
192*cdf0e10cSrcweir             rtl_ustr_compare_WithLength(
193*cdf0e10cSrcweir                 shortName.getStr(), shortName.getLength(),
194*cdf0e10cSrcweir                 longName.getStr() + i, longName.getLength() - i) ==
195*cdf0e10cSrcweir             0;
196*cdf0e10cSrcweir     } else {
197*cdf0e10cSrcweir         return shortName == longName;
198*cdf0e10cSrcweir     }
199*cdf0e10cSrcweir }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir rtl::Reference< Node > Data::findNode(
202*cdf0e10cSrcweir     int layer, NodeMap const & map, rtl::OUString const & name)
203*cdf0e10cSrcweir {
204*cdf0e10cSrcweir     NodeMap::const_iterator i(map.find(name));
205*cdf0e10cSrcweir     return i == map.end() || i->second->getLayer() > layer
206*cdf0e10cSrcweir         ? rtl::Reference< Node >() : i->second;
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir rtl::Reference< Node > Data::resolvePathRepresentation(
210*cdf0e10cSrcweir     rtl::OUString const & pathRepresentation,
211*cdf0e10cSrcweir     rtl::OUString * canonicRepresentation, Path * path, int * finalizedLayer)
212*cdf0e10cSrcweir     const
213*cdf0e10cSrcweir {
214*cdf0e10cSrcweir     if (pathRepresentation.getLength() == 0 || pathRepresentation[0] != '/') {
215*cdf0e10cSrcweir         throw css::uno::RuntimeException(
216*cdf0e10cSrcweir             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
217*cdf0e10cSrcweir              pathRepresentation),
218*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
219*cdf0e10cSrcweir     }
220*cdf0e10cSrcweir     rtl::OUString seg;
221*cdf0e10cSrcweir     bool setElement;
222*cdf0e10cSrcweir     rtl::OUString templateName;
223*cdf0e10cSrcweir     sal_Int32 n = parseSegment(pathRepresentation, 1, &seg, &setElement, 0);
224*cdf0e10cSrcweir     if (n == -1 || setElement)
225*cdf0e10cSrcweir     {
226*cdf0e10cSrcweir         throw css::uno::RuntimeException(
227*cdf0e10cSrcweir             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
228*cdf0e10cSrcweir              pathRepresentation),
229*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
230*cdf0e10cSrcweir     }
231*cdf0e10cSrcweir     NodeMap::const_iterator i(components.find(seg));
232*cdf0e10cSrcweir     rtl::OUStringBuffer canonic;
233*cdf0e10cSrcweir     if (path != 0) {
234*cdf0e10cSrcweir         path->clear();
235*cdf0e10cSrcweir     }
236*cdf0e10cSrcweir     rtl::Reference< Node > parent;
237*cdf0e10cSrcweir     int finalized = NO_LAYER;
238*cdf0e10cSrcweir     for (rtl::Reference< Node > p(i == components.end() ? 0 : i->second);;) {
239*cdf0e10cSrcweir         if (!p.is()) {
240*cdf0e10cSrcweir             return p;
241*cdf0e10cSrcweir         }
242*cdf0e10cSrcweir         if (canonicRepresentation != 0) {
243*cdf0e10cSrcweir             canonic.append(sal_Unicode('/'));
244*cdf0e10cSrcweir             canonic.append(createSegment(templateName, seg));
245*cdf0e10cSrcweir         }
246*cdf0e10cSrcweir         if (path != 0) {
247*cdf0e10cSrcweir             path->push_back(seg);
248*cdf0e10cSrcweir         }
249*cdf0e10cSrcweir         finalized = std::min(finalized, p->getFinalized());
250*cdf0e10cSrcweir         if (n != pathRepresentation.getLength() &&
251*cdf0e10cSrcweir             pathRepresentation[n++] != '/')
252*cdf0e10cSrcweir         {
253*cdf0e10cSrcweir             throw css::uno::RuntimeException(
254*cdf0e10cSrcweir                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
255*cdf0e10cSrcweir                  pathRepresentation),
256*cdf0e10cSrcweir                 css::uno::Reference< css::uno::XInterface >());
257*cdf0e10cSrcweir         }
258*cdf0e10cSrcweir         // for backwards compatibility, ignore a final slash
259*cdf0e10cSrcweir         if (n == pathRepresentation.getLength()) {
260*cdf0e10cSrcweir             if (canonicRepresentation != 0) {
261*cdf0e10cSrcweir                 *canonicRepresentation = canonic.makeStringAndClear();
262*cdf0e10cSrcweir             }
263*cdf0e10cSrcweir             if (finalizedLayer != 0) {
264*cdf0e10cSrcweir                 *finalizedLayer = finalized;
265*cdf0e10cSrcweir             }
266*cdf0e10cSrcweir             return p;
267*cdf0e10cSrcweir         }
268*cdf0e10cSrcweir         parent = p;
269*cdf0e10cSrcweir         templateName = rtl::OUString();
270*cdf0e10cSrcweir         n = parseSegment(
271*cdf0e10cSrcweir             pathRepresentation, n, &seg, &setElement, &templateName);
272*cdf0e10cSrcweir         if (n == -1) {
273*cdf0e10cSrcweir             throw css::uno::RuntimeException(
274*cdf0e10cSrcweir                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
275*cdf0e10cSrcweir                  pathRepresentation),
276*cdf0e10cSrcweir                 css::uno::Reference< css::uno::XInterface >());
277*cdf0e10cSrcweir         }
278*cdf0e10cSrcweir         // For backwards compatibility, allow set members to be accessed with
279*cdf0e10cSrcweir         // simple path segments, like group members:
280*cdf0e10cSrcweir         p = p->getMember(seg);
281*cdf0e10cSrcweir         if (setElement) {
282*cdf0e10cSrcweir             switch (parent->kind()) {
283*cdf0e10cSrcweir             case Node::KIND_LOCALIZED_PROPERTY:
284*cdf0e10cSrcweir                 if (templateName.getLength() != 0) {
285*cdf0e10cSrcweir                     throw css::uno::RuntimeException(
286*cdf0e10cSrcweir                         (rtl::OUString(
287*cdf0e10cSrcweir                             RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
288*cdf0e10cSrcweir                          pathRepresentation),
289*cdf0e10cSrcweir                     css::uno::Reference< css::uno::XInterface >());
290*cdf0e10cSrcweir                 }
291*cdf0e10cSrcweir                 break;
292*cdf0e10cSrcweir             case Node::KIND_SET:
293*cdf0e10cSrcweir                 if (templateName.getLength() != 0 &&
294*cdf0e10cSrcweir                     !dynamic_cast< SetNode * >(parent.get())->isValidTemplate(
295*cdf0e10cSrcweir                         templateName))
296*cdf0e10cSrcweir                 {
297*cdf0e10cSrcweir                     throw css::uno::RuntimeException(
298*cdf0e10cSrcweir                         (rtl::OUString(
299*cdf0e10cSrcweir                             RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
300*cdf0e10cSrcweir                          pathRepresentation),
301*cdf0e10cSrcweir                     css::uno::Reference< css::uno::XInterface >());
302*cdf0e10cSrcweir                 }
303*cdf0e10cSrcweir                 break;
304*cdf0e10cSrcweir             default:
305*cdf0e10cSrcweir                 throw css::uno::RuntimeException(
306*cdf0e10cSrcweir                     (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
307*cdf0e10cSrcweir                      pathRepresentation),
308*cdf0e10cSrcweir                     css::uno::Reference< css::uno::XInterface >());
309*cdf0e10cSrcweir             }
310*cdf0e10cSrcweir             if (templateName.getLength() != 0 && p != 0) {
311*cdf0e10cSrcweir                 OSL_ASSERT(p->getTemplateName().getLength() != 0);
312*cdf0e10cSrcweir                 if (!equalTemplateNames(templateName, p->getTemplateName())) {
313*cdf0e10cSrcweir                     throw css::uno::RuntimeException(
314*cdf0e10cSrcweir                         (rtl::OUString(
315*cdf0e10cSrcweir                             RTL_CONSTASCII_USTRINGPARAM("bad path ")) +
316*cdf0e10cSrcweir                          pathRepresentation),
317*cdf0e10cSrcweir                         css::uno::Reference< css::uno::XInterface >());
318*cdf0e10cSrcweir                 }
319*cdf0e10cSrcweir             }
320*cdf0e10cSrcweir         }
321*cdf0e10cSrcweir     }
322*cdf0e10cSrcweir }
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir rtl::Reference< Node > Data::getTemplate(
325*cdf0e10cSrcweir     int layer, rtl::OUString const & fullName) const
326*cdf0e10cSrcweir {
327*cdf0e10cSrcweir     return findNode(layer, templates, fullName);
328*cdf0e10cSrcweir }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir Additions * Data::addExtensionXcuAdditions(
331*cdf0e10cSrcweir     rtl::OUString const & url, int layer)
332*cdf0e10cSrcweir {
333*cdf0e10cSrcweir     rtl::Reference< ExtensionXcu > item(new ExtensionXcu);
334*cdf0e10cSrcweir     ExtensionXcuAdditions::iterator i(
335*cdf0e10cSrcweir         extensionXcuAdditions_.insert(
336*cdf0e10cSrcweir             ExtensionXcuAdditions::value_type(
337*cdf0e10cSrcweir                 url, rtl::Reference< ExtensionXcu >())).first);
338*cdf0e10cSrcweir     if (i->second.is()) {
339*cdf0e10cSrcweir         throw css::uno::RuntimeException(
340*cdf0e10cSrcweir             (rtl::OUString(
341*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
342*cdf0e10cSrcweir                     "already added extension xcu ")) +
343*cdf0e10cSrcweir              url),
344*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
345*cdf0e10cSrcweir     }
346*cdf0e10cSrcweir     i->second = item;
347*cdf0e10cSrcweir     item->layer = layer;
348*cdf0e10cSrcweir     return &item->additions;
349*cdf0e10cSrcweir }
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir rtl::Reference< Data::ExtensionXcu > Data::removeExtensionXcuAdditions(
352*cdf0e10cSrcweir     rtl::OUString const & url)
353*cdf0e10cSrcweir {
354*cdf0e10cSrcweir     ExtensionXcuAdditions::iterator i(extensionXcuAdditions_.find(url));
355*cdf0e10cSrcweir     if (i == extensionXcuAdditions_.end()) {
356*cdf0e10cSrcweir         // This can happen, as migration of pre OOo 3.3 UserInstallation
357*cdf0e10cSrcweir         // extensions in dp_registry::backend::configuration::BackendImpl::
358*cdf0e10cSrcweir         // PackageImpl::processPackage_ can cause just-in-time creation of
359*cdf0e10cSrcweir         // extension xcu files that are never added via addExtensionXcuAdditions
360*cdf0e10cSrcweir         // (also, there might be url spelling differences between calls to
361*cdf0e10cSrcweir         // addExtensionXcuAdditions and removeExtensionXcuAdditions?):
362*cdf0e10cSrcweir         OSL_TRACE(
363*cdf0e10cSrcweir             "unknown configmgr::Data::removeExtensionXcuAdditions(%s)",
364*cdf0e10cSrcweir             rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr());
365*cdf0e10cSrcweir         return rtl::Reference< ExtensionXcu >();
366*cdf0e10cSrcweir     }
367*cdf0e10cSrcweir     rtl::Reference< ExtensionXcu > item(i->second);
368*cdf0e10cSrcweir     extensionXcuAdditions_.erase(i);
369*cdf0e10cSrcweir     return item;
370*cdf0e10cSrcweir }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir }
373