13a7cf181SAndrew Rist /**************************************************************
23a7cf181SAndrew Rist *
33a7cf181SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
43a7cf181SAndrew Rist * or more contributor license agreements. See the NOTICE file
53a7cf181SAndrew Rist * distributed with this work for additional information
63a7cf181SAndrew Rist * regarding copyright ownership. The ASF licenses this file
73a7cf181SAndrew Rist * to you under the Apache License, Version 2.0 (the
83a7cf181SAndrew Rist * "License"); you may not use this file except in compliance
93a7cf181SAndrew Rist * with the License. You may obtain a copy of the License at
103a7cf181SAndrew Rist *
113a7cf181SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
123a7cf181SAndrew Rist *
133a7cf181SAndrew Rist * Unless required by applicable law or agreed to in writing,
143a7cf181SAndrew Rist * software distributed under the License is distributed on an
153a7cf181SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
163a7cf181SAndrew Rist * KIND, either express or implied. See the License for the
173a7cf181SAndrew Rist * specific language governing permissions and limitations
183a7cf181SAndrew Rist * under the License.
193a7cf181SAndrew Rist *
203a7cf181SAndrew Rist *************************************************************/
213a7cf181SAndrew Rist
223a7cf181SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "precompiled_configmgr.hxx"
25cdf0e10cSrcweir #include "sal/config.h"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <algorithm>
28cdf0e10cSrcweir #include <cstddef>
29cdf0e10cSrcweir #include <list>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "com/sun/star/beans/Optional.hpp"
32cdf0e10cSrcweir #include "com/sun/star/beans/UnknownPropertyException.hpp"
33cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp"
34cdf0e10cSrcweir #include "com/sun/star/container/NoSuchElementException.hpp"
35cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetException.hpp"
36cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp"
37cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx"
38cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp"
39cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
40cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
41cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
42cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
43cdf0e10cSrcweir #include "osl/conditn.hxx"
44cdf0e10cSrcweir #include "osl/diagnose.h"
45cdf0e10cSrcweir #include "osl/file.hxx"
46cdf0e10cSrcweir #include "osl/mutex.hxx"
47cdf0e10cSrcweir #include "osl/thread.hxx"
48cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
49cdf0e10cSrcweir #include "rtl/logfile.h"
50cdf0e10cSrcweir #include "rtl/ref.hxx"
51cdf0e10cSrcweir #include "rtl/string.h"
52cdf0e10cSrcweir #include "rtl/textenc.h"
53cdf0e10cSrcweir #include "rtl/ustring.h"
54cdf0e10cSrcweir #include "rtl/ustring.hxx"
55cdf0e10cSrcweir #include "sal/types.h"
56cdf0e10cSrcweir #include "salhelper/simplereferenceobject.hxx"
57cdf0e10cSrcweir
58cdf0e10cSrcweir #include "additions.hxx"
59cdf0e10cSrcweir #include "components.hxx"
60cdf0e10cSrcweir #include "data.hxx"
61cdf0e10cSrcweir #include "lock.hxx"
62cdf0e10cSrcweir #include "modifications.hxx"
63cdf0e10cSrcweir #include "node.hxx"
64cdf0e10cSrcweir #include "nodemap.hxx"
65cdf0e10cSrcweir #include "parsemanager.hxx"
66cdf0e10cSrcweir #include "partial.hxx"
67cdf0e10cSrcweir #include "rootaccess.hxx"
68cdf0e10cSrcweir #include "writemodfile.hxx"
69cdf0e10cSrcweir #include "xcdparser.hxx"
70cdf0e10cSrcweir #include "xcuparser.hxx"
71cdf0e10cSrcweir #include "xcsparser.hxx"
72cdf0e10cSrcweir
73cdf0e10cSrcweir namespace configmgr {
74cdf0e10cSrcweir
75cdf0e10cSrcweir namespace {
76cdf0e10cSrcweir
77cdf0e10cSrcweir namespace css = com::sun::star;
78cdf0e10cSrcweir
79cdf0e10cSrcweir struct UnresolvedListItem {
80cdf0e10cSrcweir rtl::OUString name;
81cdf0e10cSrcweir rtl::Reference< ParseManager > manager;
82cdf0e10cSrcweir
UnresolvedListItemconfigmgr::__anonee42b4e90111::UnresolvedListItem83cdf0e10cSrcweir UnresolvedListItem(
84cdf0e10cSrcweir rtl::OUString const & theName,
85cdf0e10cSrcweir rtl::Reference< ParseManager > theManager):
86cdf0e10cSrcweir name(theName), manager(theManager) {}
87cdf0e10cSrcweir };
88cdf0e10cSrcweir
89cdf0e10cSrcweir typedef std::list< UnresolvedListItem > UnresolvedList;
90cdf0e10cSrcweir
parseXcsFile(rtl::OUString const & url,int layer,Data & data,Partial const * partial,Modifications * modifications,Additions * additions)91cdf0e10cSrcweir void parseXcsFile(
92cdf0e10cSrcweir rtl::OUString const & url, int layer, Data & data, Partial const * partial,
93cdf0e10cSrcweir Modifications * modifications, Additions * additions)
94cdf0e10cSrcweir SAL_THROW((
95cdf0e10cSrcweir css::container::NoSuchElementException, css::uno::RuntimeException))
96cdf0e10cSrcweir {
97cdf0e10cSrcweir OSL_ASSERT(partial == 0 && modifications == 0 && additions == 0);
98cdf0e10cSrcweir (void) partial; (void) modifications; (void) additions;
99cdf0e10cSrcweir OSL_VERIFY(
100cdf0e10cSrcweir rtl::Reference< ParseManager >(
101cdf0e10cSrcweir new ParseManager(url, new XcsParser(layer, data)))->parse());
102cdf0e10cSrcweir }
103cdf0e10cSrcweir
parseXcuFile(rtl::OUString const & url,int layer,Data & data,Partial const * partial,Modifications * modifications,Additions * additions)104cdf0e10cSrcweir void parseXcuFile(
105cdf0e10cSrcweir rtl::OUString const & url, int layer, Data & data, Partial const * partial,
106cdf0e10cSrcweir Modifications * modifications, Additions * additions)
107cdf0e10cSrcweir SAL_THROW((
108cdf0e10cSrcweir css::container::NoSuchElementException, css::uno::RuntimeException))
109cdf0e10cSrcweir {
110cdf0e10cSrcweir OSL_VERIFY(
111cdf0e10cSrcweir rtl::Reference< ParseManager >(
112cdf0e10cSrcweir new ParseManager(
113cdf0e10cSrcweir url,
114cdf0e10cSrcweir new XcuParser(
115cdf0e10cSrcweir layer, data, partial, modifications, additions)))->
116cdf0e10cSrcweir parse());
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
expand(rtl::OUString const & str)119cdf0e10cSrcweir rtl::OUString expand(rtl::OUString const & str) {
120cdf0e10cSrcweir rtl::OUString s(str);
121cdf0e10cSrcweir rtl::Bootstrap::expandMacros(s); //TODO: detect failure
122cdf0e10cSrcweir return s;
123cdf0e10cSrcweir }
124cdf0e10cSrcweir
canRemoveFromLayer(int layer,rtl::Reference<Node> const & node)125cdf0e10cSrcweir bool canRemoveFromLayer(int layer, rtl::Reference< Node > const & node) {
126cdf0e10cSrcweir OSL_ASSERT(node.is());
127cdf0e10cSrcweir if (node->getLayer() > layer && node->getLayer() < Data::NO_LAYER) {
128cdf0e10cSrcweir return false;
129cdf0e10cSrcweir }
130cdf0e10cSrcweir switch (node->kind()) {
131cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY:
132cdf0e10cSrcweir case Node::KIND_GROUP:
133cdf0e10cSrcweir for (NodeMap::iterator i(node->getMembers().begin());
134cdf0e10cSrcweir i != node->getMembers().end(); ++i)
135cdf0e10cSrcweir {
136cdf0e10cSrcweir if (!canRemoveFromLayer(layer, i->second)) {
137cdf0e10cSrcweir return false;
138cdf0e10cSrcweir }
139cdf0e10cSrcweir }
140cdf0e10cSrcweir return true;
141cdf0e10cSrcweir case Node::KIND_SET:
142cdf0e10cSrcweir return node->getMembers().empty();
143cdf0e10cSrcweir default: // Node::KIND_PROPERTY, Node::KIND_LOCALIZED_VALUE
144cdf0e10cSrcweir return true;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
148cdf0e10cSrcweir static bool singletonCreated = false;
149cdf0e10cSrcweir static Components * singleton = 0;
150cdf0e10cSrcweir
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
153cdf0e10cSrcweir class Components::WriteThread:
154cdf0e10cSrcweir public osl::Thread, public salhelper::SimpleReferenceObject
155cdf0e10cSrcweir {
156cdf0e10cSrcweir public:
operator new(std::size_t size)157cdf0e10cSrcweir static void * operator new(std::size_t size)
158cdf0e10cSrcweir { return Thread::operator new(size); }
159cdf0e10cSrcweir
operator delete(void * pointer)160cdf0e10cSrcweir static void operator delete(void * pointer)
161cdf0e10cSrcweir { Thread::operator delete(pointer); }
162cdf0e10cSrcweir
163cdf0e10cSrcweir WriteThread(
164cdf0e10cSrcweir rtl::Reference< WriteThread > * reference, Components & components,
165cdf0e10cSrcweir rtl::OUString const & url, Data const & data);
166cdf0e10cSrcweir
flush()167cdf0e10cSrcweir void flush() { delay_.set(); }
168cdf0e10cSrcweir
169cdf0e10cSrcweir private:
~WriteThread()170cdf0e10cSrcweir virtual ~WriteThread() {}
171cdf0e10cSrcweir
172cdf0e10cSrcweir virtual void SAL_CALL run();
173cdf0e10cSrcweir
onTerminated()174cdf0e10cSrcweir virtual void SAL_CALL onTerminated() { release(); }
175cdf0e10cSrcweir
176cdf0e10cSrcweir rtl::Reference< WriteThread > * reference_;
177cdf0e10cSrcweir Components & components_;
178cdf0e10cSrcweir rtl::OUString url_;
179cdf0e10cSrcweir Data const & data_;
180cdf0e10cSrcweir osl::Condition delay_;
181cdf0e10cSrcweir };
182cdf0e10cSrcweir
WriteThread(rtl::Reference<WriteThread> * reference,Components & components,rtl::OUString const & url,Data const & data)183cdf0e10cSrcweir Components::WriteThread::WriteThread(
184cdf0e10cSrcweir rtl::Reference< WriteThread > * reference, Components & components,
185cdf0e10cSrcweir rtl::OUString const & url, Data const & data):
186cdf0e10cSrcweir reference_(reference), components_(components), url_(url), data_(data)
187cdf0e10cSrcweir {
188cdf0e10cSrcweir OSL_ASSERT(reference != 0);
189cdf0e10cSrcweir acquire();
190cdf0e10cSrcweir }
191cdf0e10cSrcweir
run()192cdf0e10cSrcweir void Components::WriteThread::run() {
193cdf0e10cSrcweir TimeValue t = { 1, 0 }; // 1 sec
194cdf0e10cSrcweir delay_.wait(&t); // must not throw; result_error is harmless and ignored
195cdf0e10cSrcweir osl::MutexGuard g(lock); // must not throw
196cdf0e10cSrcweir try {
197cdf0e10cSrcweir try {
198cdf0e10cSrcweir writeModFile(components_, url_, data_);
199cdf0e10cSrcweir } catch (css::uno::RuntimeException & e) {
200cdf0e10cSrcweir // Silently ignore write errors, instead of aborting:
201cdf0e10cSrcweir OSL_TRACE(
202cdf0e10cSrcweir "configmgr error writing modifications: %s",
203cdf0e10cSrcweir rtl::OUStringToOString(
204cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr());
205cdf0e10cSrcweir }
206cdf0e10cSrcweir } catch (...) {
207cdf0e10cSrcweir reference_->clear();
208cdf0e10cSrcweir throw;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir reference_->clear();
211cdf0e10cSrcweir }
212cdf0e10cSrcweir
getSingleton(css::uno::Reference<css::uno::XComponentContext> const & context)213cdf0e10cSrcweir Components & Components::getSingleton(
214cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context)
215cdf0e10cSrcweir {
216cdf0e10cSrcweir OSL_ASSERT(context.is());
217cdf0e10cSrcweir if (!singletonCreated) {
218cdf0e10cSrcweir singletonCreated = true;
219cdf0e10cSrcweir static Components theSingleton(context);
220cdf0e10cSrcweir singleton = &theSingleton;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir if (singleton == 0) {
223cdf0e10cSrcweir throw css::uno::RuntimeException(
224cdf0e10cSrcweir rtl::OUString(
225cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
226cdf0e10cSrcweir "configmgr no Components singleton")),
227cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
228cdf0e10cSrcweir }
229cdf0e10cSrcweir return *singleton;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
allLocales(rtl::OUString const & locale)232cdf0e10cSrcweir bool Components::allLocales(rtl::OUString const & locale) {
233cdf0e10cSrcweir return locale.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("*"));
234cdf0e10cSrcweir }
235cdf0e10cSrcweir
resolvePathRepresentation(rtl::OUString const & pathRepresentation,rtl::OUString * canonicRepresentation,Path * path,int * finalizedLayer) const236cdf0e10cSrcweir rtl::Reference< Node > Components::resolvePathRepresentation(
237cdf0e10cSrcweir rtl::OUString const & pathRepresentation,
238cdf0e10cSrcweir rtl::OUString * canonicRepresentation, Path * path, int * finalizedLayer)
239cdf0e10cSrcweir const
240cdf0e10cSrcweir {
241cdf0e10cSrcweir return data_.resolvePathRepresentation(
242cdf0e10cSrcweir pathRepresentation, canonicRepresentation, path, finalizedLayer);
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
getTemplate(int layer,rtl::OUString const & fullName) const245cdf0e10cSrcweir rtl::Reference< Node > Components::getTemplate(
246cdf0e10cSrcweir int layer, rtl::OUString const & fullName) const
247cdf0e10cSrcweir {
248cdf0e10cSrcweir return data_.getTemplate(layer, fullName);
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
addRootAccess(rtl::Reference<RootAccess> const & access)251cdf0e10cSrcweir void Components::addRootAccess(rtl::Reference< RootAccess > const & access) {
252cdf0e10cSrcweir roots_.insert(access.get());
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
removeRootAccess(RootAccess * access)255cdf0e10cSrcweir void Components::removeRootAccess(RootAccess * access) {
256cdf0e10cSrcweir roots_.erase(access);
257cdf0e10cSrcweir }
258cdf0e10cSrcweir
initGlobalBroadcaster(Modifications const & modifications,rtl::Reference<RootAccess> const & exclude,Broadcaster * broadcaster)259cdf0e10cSrcweir void Components::initGlobalBroadcaster(
260cdf0e10cSrcweir Modifications const & modifications,
261cdf0e10cSrcweir rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster)
262cdf0e10cSrcweir {
263cdf0e10cSrcweir //TODO: Iterate only over roots w/ listeners:
264cdf0e10cSrcweir for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) {
265cdf0e10cSrcweir rtl::Reference< RootAccess > root;
266cdf0e10cSrcweir if ((*i)->acquireCounting() > 1) {
267cdf0e10cSrcweir root.set(*i); // must not throw
268cdf0e10cSrcweir }
269cdf0e10cSrcweir (*i)->releaseNondeleting();
270cdf0e10cSrcweir if (root.is()) {
271cdf0e10cSrcweir if (root != exclude) {
272cdf0e10cSrcweir Path path(root->getAbsolutePath());
273cdf0e10cSrcweir Modifications::Node const * mods = &modifications.getRoot();
274cdf0e10cSrcweir for (Path::iterator j(path.begin()); j != path.end(); ++j) {
275cdf0e10cSrcweir Modifications::Node::Children::const_iterator k(
276cdf0e10cSrcweir mods->children.find(*j));
277cdf0e10cSrcweir if (k == mods->children.end()) {
278cdf0e10cSrcweir mods = 0;
279cdf0e10cSrcweir break;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir mods = &k->second;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir //TODO: If the complete tree of which root is a part is deleted,
284cdf0e10cSrcweir // or replaced, mods will be null, but some of the listeners
285cdf0e10cSrcweir // from within root should probably fire nonetheless:
286cdf0e10cSrcweir if (mods != 0) {
287cdf0e10cSrcweir root->initBroadcaster(*mods, broadcaster);
288cdf0e10cSrcweir }
289cdf0e10cSrcweir }
290cdf0e10cSrcweir }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir }
293cdf0e10cSrcweir
addModification(Path const & path)294cdf0e10cSrcweir void Components::addModification(Path const & path) {
295cdf0e10cSrcweir data_.modifications.add(path);
296cdf0e10cSrcweir }
297cdf0e10cSrcweir
writeModifications()298cdf0e10cSrcweir void Components::writeModifications() {
299cdf0e10cSrcweir if (!writeThread_.is()) {
300cdf0e10cSrcweir writeThread_ = new WriteThread(
301cdf0e10cSrcweir &writeThread_, *this, getModificationFileUrl(), data_);
302cdf0e10cSrcweir writeThread_->create();
303cdf0e10cSrcweir }
304cdf0e10cSrcweir }
305cdf0e10cSrcweir
flushModifications()306cdf0e10cSrcweir void Components::flushModifications() {
307cdf0e10cSrcweir rtl::Reference< WriteThread > thread;
308cdf0e10cSrcweir {
309cdf0e10cSrcweir osl::MutexGuard g(lock);
310cdf0e10cSrcweir thread = writeThread_;
311cdf0e10cSrcweir }
312cdf0e10cSrcweir if (thread.is()) {
313cdf0e10cSrcweir thread->flush();
314cdf0e10cSrcweir thread->join();
315cdf0e10cSrcweir }
316cdf0e10cSrcweir }
317cdf0e10cSrcweir
insertExtensionXcsFile(bool shared,rtl::OUString const & fileUri)318cdf0e10cSrcweir void Components::insertExtensionXcsFile(
319cdf0e10cSrcweir bool shared, rtl::OUString const & fileUri)
320cdf0e10cSrcweir {
321cdf0e10cSrcweir try {
322cdf0e10cSrcweir parseXcsFile(fileUri, shared ? 9 : 13, data_, 0, 0, 0);
323cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
324cdf0e10cSrcweir throw css::uno::RuntimeException(
325cdf0e10cSrcweir (rtl::OUString(
326cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
327cdf0e10cSrcweir "insertExtensionXcsFile does not exist: ")) +
328cdf0e10cSrcweir e.Message),
329cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
330cdf0e10cSrcweir }
331cdf0e10cSrcweir }
332cdf0e10cSrcweir
insertExtensionXcuFile(bool shared,rtl::OUString const & fileUri,Modifications * modifications)333cdf0e10cSrcweir void Components::insertExtensionXcuFile(
334cdf0e10cSrcweir bool shared, rtl::OUString const & fileUri, Modifications * modifications)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir OSL_ASSERT(modifications != 0);
337cdf0e10cSrcweir int layer = shared ? 10 : 14;
338cdf0e10cSrcweir Additions * adds = data_.addExtensionXcuAdditions(fileUri, layer);
339cdf0e10cSrcweir try {
340cdf0e10cSrcweir parseXcuFile(fileUri, layer, data_, 0, modifications, adds);
341cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
342cdf0e10cSrcweir data_.removeExtensionXcuAdditions(fileUri);
343cdf0e10cSrcweir throw css::uno::RuntimeException(
344cdf0e10cSrcweir (rtl::OUString(
345cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
346cdf0e10cSrcweir "insertExtensionXcuFile does not exist: ")) +
347cdf0e10cSrcweir e.Message),
348cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
349cdf0e10cSrcweir }
350cdf0e10cSrcweir }
351cdf0e10cSrcweir
removeExtensionXcuFile(rtl::OUString const & fileUri,Modifications * modifications)352cdf0e10cSrcweir void Components::removeExtensionXcuFile(
353cdf0e10cSrcweir rtl::OUString const & fileUri, Modifications * modifications)
354cdf0e10cSrcweir {
355cdf0e10cSrcweir //TODO: Ideally, exactly the data coming from the specified xcu file would
356cdf0e10cSrcweir // be removed. However, not enough information is recorded in the in-memory
357cdf0e10cSrcweir // data structures to do so. So, as a workaround, all those set elements
358cdf0e10cSrcweir // that were freshly added by the xcu and have afterwards been left
359cdf0e10cSrcweir // unchanged or have only had their properties changed in the user layer are
360cdf0e10cSrcweir // removed (and nothing else). The heuristic to determine
361cdf0e10cSrcweir // whether a node has been left unchanged is to check the layer ID (as
362cdf0e10cSrcweir // usual) and additionally to check that the node does not recursively
363cdf0e10cSrcweir // contain any non-empty sets (multiple extension xcu files are merged into
364cdf0e10cSrcweir // one layer, so checking layer ID alone is not enough). Since
365cdf0e10cSrcweir // item->additions records all additions of set members in textual order,
366cdf0e10cSrcweir // the latter check works well when iterating through item->additions in
367cdf0e10cSrcweir // reverse order.
368cdf0e10cSrcweir OSL_ASSERT(modifications != 0);
369cdf0e10cSrcweir rtl::Reference< Data::ExtensionXcu > item(
370cdf0e10cSrcweir data_.removeExtensionXcuAdditions(fileUri));
371cdf0e10cSrcweir if (item.is()) {
372cdf0e10cSrcweir for (Additions::reverse_iterator i(item->additions.rbegin());
373cdf0e10cSrcweir i != item->additions.rend(); ++i)
374cdf0e10cSrcweir {
375cdf0e10cSrcweir rtl::Reference< Node > parent;
376cdf0e10cSrcweir NodeMap const * map = &data_.components;
377cdf0e10cSrcweir rtl::Reference< Node > node;
378cdf0e10cSrcweir for (Path::const_iterator j(i->begin()); j != i->end(); ++j) {
379cdf0e10cSrcweir parent = node;
380cdf0e10cSrcweir node = Data::findNode(Data::NO_LAYER, *map, *j);
381cdf0e10cSrcweir if (!node.is()) {
382cdf0e10cSrcweir break;
383cdf0e10cSrcweir }
384cdf0e10cSrcweir map = &node->getMembers();
385cdf0e10cSrcweir }
386cdf0e10cSrcweir if (node.is()) {
387cdf0e10cSrcweir OSL_ASSERT(parent.is());
388cdf0e10cSrcweir if (parent->kind() == Node::KIND_SET) {
389cdf0e10cSrcweir OSL_ASSERT(
390cdf0e10cSrcweir node->kind() == Node::KIND_GROUP ||
391cdf0e10cSrcweir node->kind() == Node::KIND_SET);
392cdf0e10cSrcweir if (canRemoveFromLayer(item->layer, node)) {
393cdf0e10cSrcweir parent->getMembers().erase(i->back());
394cdf0e10cSrcweir data_.modifications.remove(*i);
395cdf0e10cSrcweir modifications->add(*i);
396cdf0e10cSrcweir }
397cdf0e10cSrcweir }
398cdf0e10cSrcweir }
399cdf0e10cSrcweir }
400cdf0e10cSrcweir writeModifications();
401cdf0e10cSrcweir }
402cdf0e10cSrcweir }
403cdf0e10cSrcweir
insertModificationXcuFile(rtl::OUString const & fileUri,std::set<rtl::OUString> const & includedPaths,std::set<rtl::OUString> const & excludedPaths,Modifications * modifications)404cdf0e10cSrcweir void Components::insertModificationXcuFile(
405cdf0e10cSrcweir rtl::OUString const & fileUri,
406cdf0e10cSrcweir std::set< rtl::OUString > const & includedPaths,
407cdf0e10cSrcweir std::set< rtl::OUString > const & excludedPaths,
408cdf0e10cSrcweir Modifications * modifications)
409cdf0e10cSrcweir {
410cdf0e10cSrcweir OSL_ASSERT(modifications != 0);
411cdf0e10cSrcweir Partial part(includedPaths, excludedPaths);
412cdf0e10cSrcweir try {
413cdf0e10cSrcweir parseFileLeniently(
414cdf0e10cSrcweir &parseXcuFile, fileUri, Data::NO_LAYER, data_, &part, modifications,
415cdf0e10cSrcweir 0);
416cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
417cdf0e10cSrcweir OSL_TRACE(
418cdf0e10cSrcweir "configmgr error inserting non-existing %s: %s",
419cdf0e10cSrcweir rtl::OUStringToOString(fileUri, RTL_TEXTENCODING_UTF8).getStr(),
420cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
421cdf0e10cSrcweir }
422cdf0e10cSrcweir }
423cdf0e10cSrcweir
getExternalValue(rtl::OUString const & descriptor)424cdf0e10cSrcweir css::beans::Optional< css::uno::Any > Components::getExternalValue(
425cdf0e10cSrcweir rtl::OUString const & descriptor)
426cdf0e10cSrcweir {
427cdf0e10cSrcweir sal_Int32 i = descriptor.indexOf(' ');
428cdf0e10cSrcweir if (i <= 0) {
429cdf0e10cSrcweir throw css::uno::RuntimeException(
430cdf0e10cSrcweir (rtl::OUString(
431cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("bad external value descriptor ")) +
432cdf0e10cSrcweir descriptor),
433cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
434cdf0e10cSrcweir }
435cdf0e10cSrcweir //TODO: Do not make calls with mutex locked:
436cdf0e10cSrcweir rtl::OUString name(descriptor.copy(0, i));
437cdf0e10cSrcweir ExternalServices::iterator j(externalServices_.find(name));
438cdf0e10cSrcweir if (j == externalServices_.end()) {
439cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > service;
440cdf0e10cSrcweir try {
441cdf0e10cSrcweir service = css::uno::Reference< css::lang::XMultiComponentFactory >(
442cdf0e10cSrcweir context_->getServiceManager(), css::uno::UNO_SET_THROW)->
443cdf0e10cSrcweir createInstanceWithContext(name, context_);
444cdf0e10cSrcweir } catch (css::uno::RuntimeException &) {
445cdf0e10cSrcweir // Assuming these exceptions are real errors:
446cdf0e10cSrcweir throw;
447cdf0e10cSrcweir } catch (css::uno::Exception & e) {
448cdf0e10cSrcweir // Assuming these exceptions indicate that the service is not
449cdf0e10cSrcweir // installed:
450cdf0e10cSrcweir OSL_TRACE(
451cdf0e10cSrcweir "createInstance(%s) failed with %s",
452cdf0e10cSrcweir rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
453cdf0e10cSrcweir rtl::OUStringToOString(
454cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr());
455cdf0e10cSrcweir }
456cdf0e10cSrcweir css::uno::Reference< css::beans::XPropertySet > propset;
457cdf0e10cSrcweir if (service.is()) {
458cdf0e10cSrcweir propset = css::uno::Reference< css::beans::XPropertySet >(
459cdf0e10cSrcweir service, css::uno::UNO_QUERY_THROW);
460cdf0e10cSrcweir }
461cdf0e10cSrcweir j = externalServices_.insert(
462cdf0e10cSrcweir ExternalServices::value_type(name, propset)).first;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir css::beans::Optional< css::uno::Any > value;
465cdf0e10cSrcweir if (j->second.is()) {
466cdf0e10cSrcweir try {
467cdf0e10cSrcweir if (!(j->second->getPropertyValue(descriptor.copy(i + 1)) >>=
468cdf0e10cSrcweir value))
469cdf0e10cSrcweir {
470cdf0e10cSrcweir throw css::uno::RuntimeException(
471cdf0e10cSrcweir (rtl::OUString(
472cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
473cdf0e10cSrcweir "cannot obtain external value through ")) +
474cdf0e10cSrcweir descriptor),
475cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
476cdf0e10cSrcweir }
477cdf0e10cSrcweir } catch (css::beans::UnknownPropertyException & e) {
478cdf0e10cSrcweir throw css::uno::RuntimeException(
479cdf0e10cSrcweir (rtl::OUString(
480cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
481cdf0e10cSrcweir "unknwon external value descriptor ID: ")) +
482cdf0e10cSrcweir e.Message),
483cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
484cdf0e10cSrcweir } catch (css::lang::WrappedTargetException & e) {
485cdf0e10cSrcweir throw css::uno::RuntimeException(
486cdf0e10cSrcweir (rtl::OUString(
487cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
488cdf0e10cSrcweir "cannot obtain external value: ")) +
489cdf0e10cSrcweir e.Message),
490cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
491cdf0e10cSrcweir }
492cdf0e10cSrcweir }
493cdf0e10cSrcweir return value;
494cdf0e10cSrcweir }
495cdf0e10cSrcweir
Components(css::uno::Reference<css::uno::XComponentContext> const & context)496cdf0e10cSrcweir Components::Components(
497cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context):
498cdf0e10cSrcweir context_(context)
499cdf0e10cSrcweir {
500cdf0e10cSrcweir OSL_ASSERT(context.is());
501cdf0e10cSrcweir RTL_LOGFILE_TRACE_AUTHOR("configmgr", "sb", "begin parsing");
502cdf0e10cSrcweir parseXcsXcuLayer(
503cdf0e10cSrcweir 0,
504cdf0e10cSrcweir expand(
505cdf0e10cSrcweir rtl::OUString(
506cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry"))));
507cdf0e10cSrcweir parseModuleLayer(
508cdf0e10cSrcweir 2,
509cdf0e10cSrcweir expand(
510cdf0e10cSrcweir rtl::OUString(
511cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
512cdf0e10cSrcweir "$OOO_BASE_DIR/share/registry/modules"))));
513cdf0e10cSrcweir parseResLayer(
514cdf0e10cSrcweir 3,
515cdf0e10cSrcweir expand(
516cdf0e10cSrcweir rtl::OUString(
517cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry"))));
518*910823aeSJürgen Schmidt parseXcsXcuIniLayer(
519cdf0e10cSrcweir 7,
520cdf0e10cSrcweir expand(
521cdf0e10cSrcweir rtl::OUString(
522cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
523cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
524cdf0e10cSrcweir ":BUNDLED_EXTENSIONS_USER}/registry/"
525cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration."
526cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))),
527cdf0e10cSrcweir false);
528cdf0e10cSrcweir parseXcsXcuIniLayer(
529cdf0e10cSrcweir 9,
530cdf0e10cSrcweir expand(
531cdf0e10cSrcweir rtl::OUString(
532cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
533cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
534cdf0e10cSrcweir ":SHARED_EXTENSIONS_USER}/registry/"
535cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration."
536cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))),
537cdf0e10cSrcweir true);
538cdf0e10cSrcweir parseXcsXcuLayer(
539cdf0e10cSrcweir 11,
540cdf0e10cSrcweir expand(
541cdf0e10cSrcweir rtl::OUString(
542cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
543cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
544cdf0e10cSrcweir ":UNO_USER_PACKAGES_CACHE}/registry/"
545cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration."
546cdf0e10cSrcweir "PackageRegistryBackend/registry"))));
547cdf0e10cSrcweir // can be dropped once old UserInstallation format can no longer exist
548cdf0e10cSrcweir // (probably OOo 4)
549cdf0e10cSrcweir parseXcsXcuIniLayer(
550cdf0e10cSrcweir 13,
551cdf0e10cSrcweir expand(
552cdf0e10cSrcweir rtl::OUString(
553cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
554cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
555cdf0e10cSrcweir ":UNO_USER_PACKAGES_CACHE}/registry/"
556cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration."
557cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))),
558cdf0e10cSrcweir true);
559cdf0e10cSrcweir parseModificationLayer();
560cdf0e10cSrcweir RTL_LOGFILE_TRACE_AUTHOR("configmgr", "sb", "end parsing");
561cdf0e10cSrcweir }
562cdf0e10cSrcweir
~Components()563cdf0e10cSrcweir Components::~Components() {}
564cdf0e10cSrcweir
parseFileLeniently(FileParser * parseFile,rtl::OUString const & url,int layer,Data & data,Partial const * partial,Modifications * modifications,Additions * additions)565cdf0e10cSrcweir void Components::parseFileLeniently(
566cdf0e10cSrcweir FileParser * parseFile, rtl::OUString const & url, int layer, Data & data,
567cdf0e10cSrcweir Partial const * partial, Modifications * modifications,
568cdf0e10cSrcweir Additions * additions)
569cdf0e10cSrcweir {
570cdf0e10cSrcweir OSL_ASSERT(parseFile != 0);
571cdf0e10cSrcweir try {
572cdf0e10cSrcweir (*parseFile)(url, layer, data, partial, modifications, additions);
573cdf0e10cSrcweir } catch (css::container::NoSuchElementException &) {
574cdf0e10cSrcweir throw;
575cdf0e10cSrcweir } catch (css::uno::Exception & e) { //TODO: more specific exception catching
576cdf0e10cSrcweir // Silently ignore invalid XML files, instead of completely preventing
577cdf0e10cSrcweir // OOo from starting:
578cdf0e10cSrcweir OSL_TRACE(
579cdf0e10cSrcweir "configmgr error reading %s: %s",
580cdf0e10cSrcweir rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr(),
581cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
582cdf0e10cSrcweir }
583cdf0e10cSrcweir }
584cdf0e10cSrcweir
parseFiles(int layer,rtl::OUString const & extension,FileParser * parseFile,rtl::OUString const & url,bool recursive)585cdf0e10cSrcweir void Components::parseFiles(
586cdf0e10cSrcweir int layer, rtl::OUString const & extension, FileParser * parseFile,
587cdf0e10cSrcweir rtl::OUString const & url, bool recursive)
588cdf0e10cSrcweir {
589cdf0e10cSrcweir osl::Directory dir(url);
590cdf0e10cSrcweir switch (dir.open()) {
591cdf0e10cSrcweir case osl::FileBase::E_None:
592cdf0e10cSrcweir break;
593cdf0e10cSrcweir case osl::FileBase::E_NOENT:
594cdf0e10cSrcweir if (!recursive) {
595cdf0e10cSrcweir return;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir // fall through
598cdf0e10cSrcweir default:
599cdf0e10cSrcweir throw css::uno::RuntimeException(
600cdf0e10cSrcweir (rtl::OUString(
601cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) +
602cdf0e10cSrcweir url),
603cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
604cdf0e10cSrcweir }
605cdf0e10cSrcweir for (;;) {
606cdf0e10cSrcweir osl::DirectoryItem i;
607cdf0e10cSrcweir osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
608cdf0e10cSrcweir if (rc == osl::FileBase::E_NOENT) {
609cdf0e10cSrcweir break;
610cdf0e10cSrcweir }
611cdf0e10cSrcweir if (rc != osl::FileBase::E_None) {
612cdf0e10cSrcweir throw css::uno::RuntimeException(
613cdf0e10cSrcweir (rtl::OUString(
614cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) +
615cdf0e10cSrcweir url),
616cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
617cdf0e10cSrcweir }
618cdf0e10cSrcweir osl::FileStatus stat(
619cdf0e10cSrcweir FileStatusMask_Type | FileStatusMask_FileName |
620cdf0e10cSrcweir FileStatusMask_FileURL);
621cdf0e10cSrcweir if (i.getFileStatus(stat) != osl::FileBase::E_None) {
622cdf0e10cSrcweir throw css::uno::RuntimeException(
623cdf0e10cSrcweir (rtl::OUString(
624cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) +
625cdf0e10cSrcweir url),
626cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
627cdf0e10cSrcweir }
628cdf0e10cSrcweir if (stat.getFileType() == osl::FileStatus::Directory) { //TODO: symlinks
629cdf0e10cSrcweir parseFiles(layer, extension, parseFile, stat.getFileURL(), true);
630cdf0e10cSrcweir } else {
631cdf0e10cSrcweir rtl::OUString file(stat.getFileName());
632cdf0e10cSrcweir if (file.getLength() >= extension.getLength() &&
633cdf0e10cSrcweir file.match(extension, file.getLength() - extension.getLength()))
634cdf0e10cSrcweir {
635cdf0e10cSrcweir try {
636cdf0e10cSrcweir parseFileLeniently(
637cdf0e10cSrcweir parseFile, stat.getFileURL(), layer, data_, 0, 0, 0);
638cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
639cdf0e10cSrcweir throw css::uno::RuntimeException(
640cdf0e10cSrcweir (rtl::OUString(
641cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
642cdf0e10cSrcweir "stat'ed file does not exist: ")) +
643cdf0e10cSrcweir e.Message),
644cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
645cdf0e10cSrcweir }
646cdf0e10cSrcweir }
647cdf0e10cSrcweir }
648cdf0e10cSrcweir }
649cdf0e10cSrcweir }
650cdf0e10cSrcweir
parseFileList(int layer,FileParser * parseFile,rtl::OUString const & urls,rtl::Bootstrap const & ini,bool recordAdditions)651cdf0e10cSrcweir void Components::parseFileList(
652cdf0e10cSrcweir int layer, FileParser * parseFile, rtl::OUString const & urls,
653cdf0e10cSrcweir rtl::Bootstrap const & ini, bool recordAdditions)
654cdf0e10cSrcweir {
655cdf0e10cSrcweir for (sal_Int32 i = 0;;) {
656cdf0e10cSrcweir rtl::OUString url(urls.getToken(0, ' ', i));
657cdf0e10cSrcweir if (url.getLength() != 0) {
658cdf0e10cSrcweir ini.expandMacrosFrom(url); //TODO: detect failure
659cdf0e10cSrcweir Additions * adds = 0;
660cdf0e10cSrcweir if (recordAdditions) {
661cdf0e10cSrcweir adds = data_.addExtensionXcuAdditions(url, layer);
662cdf0e10cSrcweir }
663cdf0e10cSrcweir try {
664cdf0e10cSrcweir parseFileLeniently(parseFile, url, layer, data_, 0, 0, adds);
665cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
666cdf0e10cSrcweir OSL_TRACE(
667cdf0e10cSrcweir "configmgr file does not exist: %s",
668cdf0e10cSrcweir rtl::OUStringToOString(
669cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr());
670cdf0e10cSrcweir if (adds != 0) {
671cdf0e10cSrcweir data_.removeExtensionXcuAdditions(url);
672cdf0e10cSrcweir }
673cdf0e10cSrcweir }
674cdf0e10cSrcweir }
675cdf0e10cSrcweir if (i == -1) {
676cdf0e10cSrcweir break;
677cdf0e10cSrcweir }
678cdf0e10cSrcweir }
679cdf0e10cSrcweir }
680cdf0e10cSrcweir
parseXcdFiles(int layer,rtl::OUString const & url)681cdf0e10cSrcweir void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
682cdf0e10cSrcweir osl::Directory dir(url);
683cdf0e10cSrcweir switch (dir.open()) {
684cdf0e10cSrcweir case osl::FileBase::E_None:
685cdf0e10cSrcweir break;
686cdf0e10cSrcweir case osl::FileBase::E_NOENT:
687cdf0e10cSrcweir return;
688cdf0e10cSrcweir default:
689cdf0e10cSrcweir throw css::uno::RuntimeException(
690cdf0e10cSrcweir (rtl::OUString(
691cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) +
692cdf0e10cSrcweir url),
693cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
694cdf0e10cSrcweir }
695cdf0e10cSrcweir UnresolvedList unres;
696cdf0e10cSrcweir XcdParser::Dependencies deps;
697cdf0e10cSrcweir for (;;) {
698cdf0e10cSrcweir osl::DirectoryItem i;
699cdf0e10cSrcweir osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
700cdf0e10cSrcweir if (rc == osl::FileBase::E_NOENT) {
701cdf0e10cSrcweir break;
702cdf0e10cSrcweir }
703cdf0e10cSrcweir if (rc != osl::FileBase::E_None) {
704cdf0e10cSrcweir throw css::uno::RuntimeException(
705cdf0e10cSrcweir (rtl::OUString(
706cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) +
707cdf0e10cSrcweir url),
708cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
709cdf0e10cSrcweir }
710cdf0e10cSrcweir osl::FileStatus stat(
711cdf0e10cSrcweir FileStatusMask_Type | FileStatusMask_FileName |
712cdf0e10cSrcweir FileStatusMask_FileURL);
713cdf0e10cSrcweir if (i.getFileStatus(stat) != osl::FileBase::E_None) {
714cdf0e10cSrcweir throw css::uno::RuntimeException(
715cdf0e10cSrcweir (rtl::OUString(
716cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) +
717cdf0e10cSrcweir url),
718cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
719cdf0e10cSrcweir }
720cdf0e10cSrcweir if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks
721cdf0e10cSrcweir rtl::OUString file(stat.getFileName());
722cdf0e10cSrcweir if (file.getLength() >= RTL_CONSTASCII_LENGTH(".xcd") &&
723cdf0e10cSrcweir file.matchAsciiL(
724cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".xcd"),
725cdf0e10cSrcweir file.getLength() - RTL_CONSTASCII_LENGTH(".xcd")))
726cdf0e10cSrcweir {
727cdf0e10cSrcweir rtl::OUString name(
728cdf0e10cSrcweir file.copy(
729cdf0e10cSrcweir 0, file.getLength() - RTL_CONSTASCII_LENGTH(".xcd")));
730cdf0e10cSrcweir rtl::Reference< ParseManager > manager;
731cdf0e10cSrcweir try {
732cdf0e10cSrcweir manager = new ParseManager(
733cdf0e10cSrcweir stat.getFileURL(), new XcdParser(layer, deps, data_));
734cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) {
735cdf0e10cSrcweir throw css::uno::RuntimeException(
736cdf0e10cSrcweir (rtl::OUString(
737cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
738cdf0e10cSrcweir "stat'ed file does not exist: ")) +
739cdf0e10cSrcweir e.Message),
740cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
741cdf0e10cSrcweir }
742cdf0e10cSrcweir if (manager->parse()) {
743cdf0e10cSrcweir deps.insert(name);
744cdf0e10cSrcweir } else {
745cdf0e10cSrcweir unres.push_back(UnresolvedListItem(name, manager));
746cdf0e10cSrcweir }
747cdf0e10cSrcweir }
748cdf0e10cSrcweir }
749cdf0e10cSrcweir }
750cdf0e10cSrcweir while (!unres.empty()) {
751cdf0e10cSrcweir bool resolved = false;
752cdf0e10cSrcweir for (UnresolvedList::iterator i(unres.begin()); i != unres.end();) {
753cdf0e10cSrcweir if (i->manager->parse()) {
754cdf0e10cSrcweir deps.insert(i->name);
755cdf0e10cSrcweir unres.erase(i++);
756cdf0e10cSrcweir resolved = true;
757cdf0e10cSrcweir } else {
758cdf0e10cSrcweir ++i;
759cdf0e10cSrcweir }
760cdf0e10cSrcweir }
761cdf0e10cSrcweir if (!resolved) {
762cdf0e10cSrcweir throw css::uno::RuntimeException(
763cdf0e10cSrcweir (rtl::OUString(
764cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
765cdf0e10cSrcweir "xcd: unresolved dependencies in ")) +
766cdf0e10cSrcweir url),
767cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
768cdf0e10cSrcweir }
769cdf0e10cSrcweir }
770cdf0e10cSrcweir }
771cdf0e10cSrcweir
parseXcsXcuLayer(int layer,rtl::OUString const & url)772cdf0e10cSrcweir void Components::parseXcsXcuLayer(int layer, rtl::OUString const & url) {
773cdf0e10cSrcweir parseXcdFiles(layer, url);
774cdf0e10cSrcweir parseFiles(
775cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcs")),
776cdf0e10cSrcweir &parseXcsFile,
777cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/schema")), false);
778cdf0e10cSrcweir parseFiles(
779cdf0e10cSrcweir layer + 1, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
780cdf0e10cSrcweir &parseXcuFile,
781cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/data")), false);
782cdf0e10cSrcweir }
783cdf0e10cSrcweir
parseXcsXcuIniLayer(int layer,rtl::OUString const & url,bool recordAdditions)784cdf0e10cSrcweir void Components::parseXcsXcuIniLayer(
785cdf0e10cSrcweir int layer, rtl::OUString const & url, bool recordAdditions)
786cdf0e10cSrcweir {
787cdf0e10cSrcweir //TODO: rtl::Bootstrap::getFrom "first trie[s] to retrieve the value via the
788cdf0e10cSrcweir // global function"
789cdf0e10cSrcweir rtl::Bootstrap ini(url);
790cdf0e10cSrcweir rtl::OUString urls;
791cdf0e10cSrcweir if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SCHEMA")), urls))
792cdf0e10cSrcweir {
793cdf0e10cSrcweir parseFileList(layer, &parseXcsFile, urls, ini, false);
794cdf0e10cSrcweir }
795cdf0e10cSrcweir if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DATA")), urls))
796cdf0e10cSrcweir {
797cdf0e10cSrcweir parseFileList(layer + 1, &parseXcuFile, urls, ini, recordAdditions);
798cdf0e10cSrcweir }
799cdf0e10cSrcweir }
800cdf0e10cSrcweir
parseModuleLayer(int layer,rtl::OUString const & url)801cdf0e10cSrcweir void Components::parseModuleLayer(int layer, rtl::OUString const & url) {
802cdf0e10cSrcweir parseFiles(
803cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
804cdf0e10cSrcweir &parseXcuFile, url, false);
805cdf0e10cSrcweir }
806cdf0e10cSrcweir
parseResLayer(int layer,rtl::OUString const & url)807cdf0e10cSrcweir void Components::parseResLayer(int layer, rtl::OUString const & url) {
808cdf0e10cSrcweir rtl::OUString resUrl(
809cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/res")));
810cdf0e10cSrcweir parseXcdFiles(layer, resUrl);
811cdf0e10cSrcweir parseFiles(
812cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
813cdf0e10cSrcweir &parseXcuFile, resUrl, false);
814cdf0e10cSrcweir }
815cdf0e10cSrcweir
getModificationFileUrl() const816cdf0e10cSrcweir rtl::OUString Components::getModificationFileUrl() const {
817cdf0e10cSrcweir return expand(
818cdf0e10cSrcweir rtl::OUString(
819cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
820*910823aeSJürgen Schmidt "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap")
821cdf0e10cSrcweir ":UserInstallation}/user/registrymodifications.xcu")));
822cdf0e10cSrcweir }
823cdf0e10cSrcweir
parseModificationLayer()824cdf0e10cSrcweir void Components::parseModificationLayer() {
825cdf0e10cSrcweir try {
826cdf0e10cSrcweir parseFileLeniently(
827cdf0e10cSrcweir &parseXcuFile, getModificationFileUrl(), Data::NO_LAYER, data_, 0,
828cdf0e10cSrcweir 0, 0);
829cdf0e10cSrcweir } catch (css::container::NoSuchElementException &) {
830cdf0e10cSrcweir OSL_TRACE(
831cdf0e10cSrcweir "configmgr user registrymodifications.xcu does not (yet) exist");
832cdf0e10cSrcweir // Migrate old user layer data (can be removed once migration is no
833cdf0e10cSrcweir // longer relevant, probably OOo 4; also see hack for xsi namespace in
834cdf0e10cSrcweir // xmlreader::XmlReader::registerNamespaceIri):
835cdf0e10cSrcweir parseFiles(
836cdf0e10cSrcweir Data::NO_LAYER, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
837cdf0e10cSrcweir &parseXcuFile,
838cdf0e10cSrcweir expand(
839cdf0e10cSrcweir rtl::OUString(
840cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
841*910823aeSJürgen Schmidt "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap")
842cdf0e10cSrcweir ":UserInstallation}/user/registry/data"))),
843cdf0e10cSrcweir false);
844cdf0e10cSrcweir }
845cdf0e10cSrcweir }
846cdf0e10cSrcweir
847cdf0e10cSrcweir }
848