diff options
author | sb <sb@openoffice.org> | 2010-09-22 10:27:02 +0200 |
---|---|---|
committer | sb <sb@openoffice.org> | 2010-09-22 10:27:02 +0200 |
commit | 36fa44d9be3a3c2e1aaa894c20976cd485bc5ae2 (patch) | |
tree | f823739b4e0cabb40541c6bb01588a0d5d065673 /configmgr | |
parent | b72a3cc8522b078022b5ae437807970a342fd10c (diff) | |
parent | bd1092ebc0b329883d1c079d598a73f3af4cd548 (diff) |
sb129: merged in DEV300_m88
Diffstat (limited to 'configmgr')
-rw-r--r-- | configmgr/source/README | 1 | ||||
-rw-r--r-- | configmgr/source/access.cxx | 23 | ||||
-rw-r--r-- | configmgr/source/additions.hxx | 43 | ||||
-rw-r--r-- | configmgr/source/broadcaster.cxx | 63 | ||||
-rw-r--r-- | configmgr/source/components.cxx | 136 | ||||
-rw-r--r-- | configmgr/source/components.hxx | 15 | ||||
-rw-r--r-- | configmgr/source/data.cxx | 44 | ||||
-rw-r--r-- | configmgr/source/data.hxx | 23 | ||||
-rw-r--r-- | configmgr/source/modifications.cxx | 21 | ||||
-rw-r--r-- | configmgr/source/modifications.hxx | 2 | ||||
-rw-r--r-- | configmgr/source/update.cxx | 17 | ||||
-rw-r--r-- | configmgr/source/xcdparser.cxx | 2 | ||||
-rw-r--r-- | configmgr/source/xcsparser.cxx | 10 | ||||
-rw-r--r-- | configmgr/source/xcuparser.cxx | 30 | ||||
-rw-r--r-- | configmgr/source/xcuparser.hxx | 6 |
15 files changed, 363 insertions, 73 deletions
diff --git a/configmgr/source/README b/configmgr/source/README index e662dd2fd577..f26c68ecf7c0 100644 --- a/configmgr/source/README +++ b/configmgr/source/README @@ -67,6 +67,7 @@ writemodfile.cxx broadcaster.cxx Notification management. +additions.hxx update.cxx Extension manager interface. diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index 190db364cdfe..eda60e6d612a 100644 --- a/configmgr/source/access.cxx +++ b/configmgr/source/access.cxx @@ -798,13 +798,22 @@ void Access::initBroadcasterAndChanges( css::uno::Any(), css::uno::Any())); //TODO: non-void ReplacedElement } - //TODO: if (allChanges != 0) { - // allChanges->push_back( - // css::util::ElementChange( - // css::uno::makeAny(...), - // css::uno::Any(), css::uno::Any())); - // //TODO: non-void ReplacedElement - //} + if (allChanges != 0) { + rtl::OUStringBuffer path( + getRelativePathRepresentation()); + if (path.getLength() != 0) { + path.append(sal_Unicode('/')); + } + path.append( + Data::createSegment( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), + i->first)); + allChanges->push_back( + css::util::ElementChange( + css::uno::makeAny(path.makeStringAndClear()), + css::uno::Any(), css::uno::Any())); + //TODO: non-void ReplacedElement + } } // else: spurious Modifications::Node not representing a change break; diff --git a/configmgr/source/additions.hxx b/configmgr/source/additions.hxx new file mode 100644 index 000000000000..f34373c7f742 --- /dev/null +++ b/configmgr/source/additions.hxx @@ -0,0 +1,43 @@ +/************************************************************************* +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ + +#ifndef INCLUDED_CONFIGMGR_SOURCE_ADDITIONS_HXX +#define INCLUDED_CONFIGMGR_SOURCE_ADDITIONS_HXX + +#include "sal/config.h" + +#include <list> + +#include "path.hxx" + +namespace configmgr { + +typedef std::list< Path > Additions; + +} + +#endif diff --git a/configmgr/source/broadcaster.cxx b/configmgr/source/broadcaster.cxx index bb77039dcc8f..ab59d333d6d3 100644 --- a/configmgr/source/broadcaster.cxx +++ b/configmgr/source/broadcaster.cxx @@ -32,13 +32,17 @@ #include "com/sun/star/beans/XPropertyChangeListener.hpp" #include "com/sun/star/container/XContainerListener.hpp" #include "com/sun/star/lang/DisposedException.hpp" +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" #include "com/sun/star/lang/XEventListener.hpp" +#include "com/sun/star/uno/Any.hxx" #include "com/sun/star/uno/Exception.hpp" #include "com/sun/star/uno/Reference.hxx" -#include "com/sun/star/uno/RuntimeException.hpp" #include "com/sun/star/uno/XInterface.hpp" #include "com/sun/star/util/XChangesListener.hpp" +#include "cppuhelper/exc_hlp.hxx" #include "osl/diagnose.hxx" +#include "rtl/string.h" +#include "rtl/ustrbuf.hxx" #include "rtl/ustring.h" #include "rtl/ustring.hxx" @@ -50,6 +54,13 @@ namespace { namespace css = com::sun::star; +void appendMessage( + rtl::OUStringBuffer & buffer, css::uno::Exception const & exception) +{ + buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("; ")); + buffer.append(exception.Message); +} + } void Broadcaster::addDisposeNotification( @@ -108,14 +119,16 @@ void Broadcaster::addChangesNotification( } void Broadcaster::send() { - bool exception = false; + css::uno::Any exception; + rtl::OUStringBuffer messages; for (DisposeNotifications::iterator i(disposeNotifications_.begin()); i != disposeNotifications_.end(); ++i) { try { i->listener->disposing(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (ContainerNotifications::iterator i( @@ -125,8 +138,9 @@ void Broadcaster::send() { try { i->listener->elementInserted(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (ContainerNotifications::iterator i( @@ -136,8 +150,9 @@ void Broadcaster::send() { try { i->listener->elementRemoved(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (ContainerNotifications::iterator i( @@ -147,8 +162,9 @@ void Broadcaster::send() { try { i->listener->elementReplaced(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (PropertyChangeNotifications::iterator i( @@ -158,8 +174,9 @@ void Broadcaster::send() { try { i->listener->propertyChange(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (PropertiesChangeNotifications::iterator i( @@ -169,8 +186,9 @@ void Broadcaster::send() { try { i->listener->propertiesChange(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } for (ChangesNotifications::iterator i(changesNotifications_.begin()); @@ -178,16 +196,19 @@ void Broadcaster::send() { try { i->listener->changesOccurred(i->event); } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception &) { - exception = true; + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); } } - if (exception) { //TODO - throw css::uno::RuntimeException( - rtl::OUString( + if (exception.hasValue()) { + throw css::lang::WrappedTargetRuntimeException( + (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( - "configmgr exceptions during listener notification")), - css::uno::Reference< css::uno::XInterface >()); + "configmgr exceptions during listener notification")) + + messages.makeStringAndClear()), + css::uno::Reference< css::uno::XInterface >(), + exception); } } diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index 64e57a5ddebe..d4a65a47e365 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -54,10 +54,12 @@ #include "rtl/ustring.hxx" #include "sal/types.h" +#include "additions.hxx" #include "components.hxx" #include "data.hxx" #include "modifications.hxx" #include "node.hxx" +#include "nodemap.hxx" #include "parsemanager.hxx" #include "partial.hxx" #include "rootaccess.hxx" @@ -86,12 +88,12 @@ typedef std::list< UnresolvedListItem > UnresolvedList; void parseXcsFile( rtl::OUString const & url, int layer, Data & data, Partial const * partial, - Modifications * modifications) + Modifications * modifications, Additions * additions) SAL_THROW(( css::container::NoSuchElementException, css::uno::RuntimeException)) { - OSL_ASSERT(partial == 0 && modifications == 0); - (void) partial; (void) modifications; + OSL_ASSERT(partial == 0 && modifications == 0 && additions == 0); + (void) partial; (void) modifications; (void) additions; OSL_VERIFY( rtl::Reference< ParseManager >( new ParseManager(url, new XcsParser(layer, data)))->parse()); @@ -99,14 +101,16 @@ void parseXcsFile( void parseXcuFile( rtl::OUString const & url, int layer, Data & data, Partial const * partial, - Modifications * modifications) + Modifications * modifications, Additions * additions) SAL_THROW(( css::container::NoSuchElementException, css::uno::RuntimeException)) { OSL_VERIFY( rtl::Reference< ParseManager >( new ParseManager( - url, new XcuParser(layer, data, partial, modifications)))-> + url, + new XcuParser( + layer, data, partial, modifications, additions)))-> parse()); } @@ -116,6 +120,29 @@ rtl::OUString expand(rtl::OUString const & str) { return s; } +bool canRemoveFromLayer(int layer, rtl::Reference< Node > const & node) { + OSL_ASSERT(node.is()); + if (node->getLayer() > layer && node->getLayer() < Data::NO_LAYER) { + return false; + } + switch (node->kind()) { + case Node::KIND_LOCALIZED_PROPERTY: + case Node::KIND_GROUP: + for (NodeMap::iterator i(node->getMembers().begin()); + i != node->getMembers().end(); ++i) + { + if (!canRemoveFromLayer(layer, i->second)) { + return false; + } + } + return true; + case Node::KIND_SET: + return node->getMembers().empty(); + default: // Node::KIND_PROPERTY, Node::KIND_LOCALIZED_VALUE + return true; + } +} + static bool singletonCreated = false; static Components * singleton = 0; @@ -218,7 +245,7 @@ void Components::insertExtensionXcsFile( bool shared, rtl::OUString const & fileUri) { try { - parseXcsFile(fileUri, shared ? 9 : 13, data_, 0, 0); + parseXcsFile(fileUri, shared ? 9 : 13, data_, 0, 0, 0); } catch (css::container::NoSuchElementException & e) { throw css::uno::RuntimeException( (rtl::OUString( @@ -233,9 +260,12 @@ void Components::insertExtensionXcuFile( bool shared, rtl::OUString const & fileUri, Modifications * modifications) { OSL_ASSERT(modifications != 0); + int layer = shared ? 10 : 14; + Additions * adds = data_.addExtensionXcuAdditions(fileUri, layer); try { - parseXcuFile(fileUri, shared ? 10 : 14, data_, 0, modifications); + parseXcuFile(fileUri, layer, data_, 0, modifications, adds); } catch (css::container::NoSuchElementException & e) { + data_.removeExtensionXcuAdditions(fileUri); throw css::uno::RuntimeException( (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( @@ -245,6 +275,58 @@ void Components::insertExtensionXcuFile( } } +void Components::removeExtensionXcuFile( + rtl::OUString const & fileUri, Modifications * modifications) +{ + //TODO: Ideally, exactly the data coming from the specified xcu file would + // be removed. However, not enough information is recorded in the in-memory + // data structures to do so. So, as a workaround, all those set elements + // that were freshly added by the xcu and have afterwards been left + // unchanged or have only had their properties changed in the user layer are + // removed (and nothing else). The heuristic to determine + // whether a node has been left unchanged is to check the layer ID (as + // usual) and additionally to check that the node does not recursively + // contain any non-empty sets (multiple extension xcu files are merged into + // one layer, so checking layer ID alone is not enough). Since + // item->additions records all additions of set members in textual order, + // the latter check works well when iterating through item->additions in + // reverse order. + OSL_ASSERT(modifications != 0); + rtl::Reference< Data::ExtensionXcu > item( + data_.removeExtensionXcuAdditions(fileUri)); + if (item.is()) { + for (Additions::reverse_iterator i(item->additions.rbegin()); + i != item->additions.rend(); ++i) + { + rtl::Reference< Node > parent; + NodeMap const * map = &data_.components; + rtl::Reference< Node > node; + for (Path::const_iterator j(i->begin()); j != i->end(); ++j) { + parent = node; + node = Data::findNode(Data::NO_LAYER, *map, *j); + if (!node.is()) { + break; + } + map = &node->getMembers(); + } + if (node.is()) { + OSL_ASSERT(parent.is()); + if (parent->kind() == Node::KIND_SET) { + OSL_ASSERT( + node->kind() == Node::KIND_GROUP || + node->kind() == Node::KIND_SET); + if (canRemoveFromLayer(item->layer, node)) { + parent->getMembers().erase(i->back()); + data_.modifications.remove(*i); + modifications->add(*i); + } + } + } + } + writeModifications(); + } +} + void Components::insertModificationXcuFile( rtl::OUString const & fileUri, std::set< rtl::OUString > const & includedPaths, @@ -254,7 +336,7 @@ void Components::insertModificationXcuFile( OSL_ASSERT(modifications != 0); try { Partial part(includedPaths, excludedPaths); - parseXcuFile(fileUri, Data::NO_LAYER, data_, &part, modifications); + parseXcuFile(fileUri, Data::NO_LAYER, data_, &part, modifications, 0); } catch (css::uno::Exception & e) { //TODO: more specific exception catching OSL_TRACE( "configmgr error inserting %s: %s", @@ -377,7 +459,8 @@ Components::Components( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") ":BUNDLED_EXTENSIONS_USER}/registry/" "com.sun.star.comp.deployment.configuration." - "PackageRegistryBackend/configmgr.ini")))); + "PackageRegistryBackend/configmgr.ini"))), + false); parseXcsXcuIniLayer( 9, expand( @@ -386,8 +469,9 @@ Components::Components( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") ":SHARED_EXTENSIONS_USER}/registry/" "com.sun.star.comp.deployment.configuration." - "PackageRegistryBackend/configmgr.ini")))); - parseXcsXcuLayer( //TODO: migrate + "PackageRegistryBackend/configmgr.ini"))), + true); + parseXcsXcuLayer( 11, expand( rtl::OUString( @@ -396,6 +480,8 @@ Components::Components( ":UNO_USER_PACKAGES_CACHE}/registry/" "com.sun.star.comp.deployment.configuration." "PackageRegistryBackend/registry")))); + // can be dropped once old UserInstallation format can no longer exist + // (probably OOo 4) parseXcsXcuIniLayer( 13, expand( @@ -404,7 +490,8 @@ Components::Components( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") ":UNO_USER_PACKAGES_CACHE}/registry/" "com.sun.star.comp.deployment.configuration." - "PackageRegistryBackend/configmgr.ini")))); + "PackageRegistryBackend/configmgr.ini"))), + true); try { parseModificationLayer(); } catch (css::uno::Exception & e) { //TODO: more specific exception catching @@ -470,7 +557,7 @@ void Components::parseFiles( file.match(extension, file.getLength() - extension.getLength())) { try { - (*parseFile)(stat.getFileURL(), layer, data_, 0, 0); + (*parseFile)(stat.getFileURL(), layer, data_, 0, 0, 0); } catch (css::container::NoSuchElementException & e) { throw css::uno::RuntimeException( (rtl::OUString( @@ -486,19 +573,26 @@ void Components::parseFiles( void Components::parseFileList( int layer, FileParser * parseFile, rtl::OUString const & urls, - rtl::Bootstrap const & ini) + rtl::Bootstrap const & ini, bool recordAdditions) { for (sal_Int32 i = 0;;) { rtl::OUString url(urls.getToken(0, ' ', i)); if (url.getLength() != 0) { ini.expandMacrosFrom(url); //TODO: detect failure + Additions * adds = 0; + if (recordAdditions) { + adds = data_.addExtensionXcuAdditions(url, layer); + } try { - (*parseFile)(url, layer, data_, 0, 0); + (*parseFile)(url, layer, data_, 0, 0, adds); } catch (css::container::NoSuchElementException & e) { OSL_TRACE( "configmgr file does not exist: %s", rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8).getStr()); + if (adds != 0) { + data_.removeExtensionXcuAdditions(url); + } } } if (i == -1) { @@ -610,18 +704,20 @@ void Components::parseXcsXcuLayer(int layer, rtl::OUString const & url) { url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/data")), false); } -void Components::parseXcsXcuIniLayer(int layer, rtl::OUString const & url) { +void Components::parseXcsXcuIniLayer( + int layer, rtl::OUString const & url, bool recordAdditions) +{ //TODO: rtl::Bootstrap::getFrom "first trie[s] to retrieve the value via the // global function" rtl::Bootstrap ini(url); rtl::OUString urls; if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SCHEMA")), urls)) { - parseFileList(layer, &parseXcsFile, urls, ini); + parseFileList(layer, &parseXcsFile, urls, ini, false); } if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DATA")), urls)) { - parseFileList(layer + 1, &parseXcuFile, urls, ini); + parseFileList(layer + 1, &parseXcuFile, urls, ini, recordAdditions); } } @@ -650,12 +746,12 @@ rtl::OUString Components::getModificationFileUrl() const { void Components::parseModificationLayer() { try { - parseXcuFile(getModificationFileUrl(), Data::NO_LAYER, data_, 0, 0); + parseXcuFile(getModificationFileUrl(), Data::NO_LAYER, data_, 0, 0, 0); } catch (css::container::NoSuchElementException &) { OSL_TRACE( "configmgr user registrymodifications.xcu does not (yet) exist"); // Migrate old user layer data (can be removed once migration is no - // longer relevant; also see hack for xsi namespace in + // longer relevant, probably OOo 4; also see hack for xsi namespace in // xmlreader::XmlReader::registerNamespaceIri): parseFiles( Data::NO_LAYER, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")), diff --git a/configmgr/source/components.hxx b/configmgr/source/components.hxx index 2e635680c1ce..880ac95d34a8 100644 --- a/configmgr/source/components.hxx +++ b/configmgr/source/components.hxx @@ -38,7 +38,10 @@ #include "com/sun/star/uno/Reference.hxx" #include "rtl/ref.hxx" +#include "additions.hxx" #include "data.hxx" +#include "modifications.hxx" +#include "nodemap.hxx" #include "path.hxx" namespace com { namespace sun { namespace star { @@ -56,7 +59,6 @@ namespace rtl { namespace configmgr { class Broadcaster; -class Modifications; class Node; class Partial; class RootAccess; @@ -98,6 +100,9 @@ public: bool shared, rtl::OUString const & fileUri, Modifications * modifications); + void removeExtensionXcuFile( + rtl::OUString const & fileUri, Modifications * modifications); + void insertModificationXcuFile( rtl::OUString const & fileUri, std::set< rtl::OUString > const & includedPaths, @@ -109,7 +114,8 @@ public: private: typedef void FileParser( - rtl::OUString const &, int, Data &, Partial const *, Modifications *); + rtl::OUString const &, int, Data &, Partial const *, Modifications *, + Additions *); Components( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > @@ -123,13 +129,14 @@ private: void parseFileList( int layer, FileParser * parseFile, rtl::OUString const & urls, - rtl::Bootstrap const & ini); + rtl::Bootstrap const & ini, bool recordAdditions); void parseXcdFiles(int layer, rtl::OUString const & url); void parseXcsXcuLayer(int layer, rtl::OUString const & url); - void parseXcsXcuIniLayer(int layer, rtl::OUString const & url); + void parseXcsXcuIniLayer( + int layer, rtl::OUString const & url, bool recordAdditions); void parseModuleLayer(int layer, rtl::OUString const & url); diff --git a/configmgr/source/data.cxx b/configmgr/source/data.cxx index e12f9596940b..50466ca0532c 100644 --- a/configmgr/source/data.cxx +++ b/configmgr/source/data.cxx @@ -36,11 +36,13 @@ #include "osl/diagnose.h" #include "rtl/ref.hxx" #include "rtl/string.h" +#include "rtl/textenc.h" #include "rtl/ustrbuf.hxx" #include "rtl/ustring.h" #include "rtl/ustring.hxx" #include "sal/types.h" +#include "additions.hxx" #include "data.hxx" #include "groupnode.hxx" #include "node.hxx" @@ -325,4 +327,46 @@ rtl::Reference< Node > Data::getTemplate( return findNode(layer, templates, fullName); } +Additions * Data::addExtensionXcuAdditions( + rtl::OUString const & url, int layer) +{ + rtl::Reference< ExtensionXcu > item(new ExtensionXcu); + ExtensionXcuAdditions::iterator i( + extensionXcuAdditions_.insert( + ExtensionXcuAdditions::value_type( + url, rtl::Reference< ExtensionXcu >())).first); + if (i->second.is()) { + throw css::uno::RuntimeException( + (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "already added extension xcu ")) + + url), + css::uno::Reference< css::uno::XInterface >()); + } + i->second = item; + item->layer = layer; + return &item->additions; +} + +rtl::Reference< Data::ExtensionXcu > Data::removeExtensionXcuAdditions( + rtl::OUString const & url) +{ + ExtensionXcuAdditions::iterator i(extensionXcuAdditions_.find(url)); + if (i == extensionXcuAdditions_.end()) { + // This can happen, as migration of pre OOo 3.3 UserInstallation + // extensions in dp_registry::backend::configuration::BackendImpl:: + // PackageImpl::processPackage_ can cause just-in-time creation of + // extension xcu files that are never added via addExtensionXcuAdditions + // (also, there might be url spelling differences between calls to + // addExtensionXcuAdditions and removeExtensionXcuAdditions?): + OSL_TRACE( + "unknown configmgr::Data::removeExtensionXcuAdditions(%s)", + rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr()); + return rtl::Reference< ExtensionXcu >(); + } + rtl::Reference< ExtensionXcu > item(i->second); + extensionXcuAdditions_.erase(i); + return item; +} + } diff --git a/configmgr/source/data.hxx b/configmgr/source/data.hxx index 52353d066b67..8f5f7af0d86e 100644 --- a/configmgr/source/data.hxx +++ b/configmgr/source/data.hxx @@ -31,18 +31,20 @@ #include "sal/config.h" #include <climits> +#include <map> #include <vector> #include "boost/noncopyable.hpp" #include "rtl/ref.hxx" +#include "rtl/ustring.hxx" #include "sal/types.h" +#include "salhelper/simplereferenceobject.hxx" +#include "additions.hxx" #include "modifications.hxx" #include "nodemap.hxx" #include "path.hxx" -namespace rtl { class OUString; } - namespace configmgr { class Node; @@ -50,6 +52,11 @@ class Node; struct Data: private boost::noncopyable { enum { NO_LAYER = INT_MAX }; + struct ExtensionXcu: public salhelper::SimpleReferenceObject { + int layer; + Additions additions; + }; + NodeMap templates; NodeMap components; @@ -80,6 +87,18 @@ struct Data: private boost::noncopyable { rtl::Reference< Node > getTemplate( int layer, rtl::OUString const & fullName) const; + + Additions * addExtensionXcuAdditions( + rtl::OUString const & url, int layer); + + rtl::Reference< ExtensionXcu > removeExtensionXcuAdditions( + rtl::OUString const & url); + +private: + typedef std::map< rtl::OUString, rtl::Reference< ExtensionXcu > > + ExtensionXcuAdditions; + + ExtensionXcuAdditions extensionXcuAdditions_; }; } diff --git a/configmgr/source/modifications.cxx b/configmgr/source/modifications.cxx index 2ad3b5ef8bd1..add18ceaa1ea 100644 --- a/configmgr/source/modifications.cxx +++ b/configmgr/source/modifications.cxx @@ -59,6 +59,27 @@ void Modifications::add(Path const & path) { p->children.clear(); } +void Modifications::remove(Path const & path) { + OSL_ASSERT(!path.empty()); + Node * p = &root_; + for (Path::const_iterator i(path.begin());;) { + Node::Children::iterator j(p->children.find(*i)); + if (j == p->children.end()) { + break; + } + if (++i == path.end()) { + p->children.erase(j); + if (p->children.empty()) { + Path parent(path); + parent.pop_back(); + remove(parent); + } + break; + } + p = &j->second; + } +} + Modifications::Node const & Modifications::getRoot() const { return root_; } diff --git a/configmgr/source/modifications.hxx b/configmgr/source/modifications.hxx index e29a10150148..c28b1aadd192 100644 --- a/configmgr/source/modifications.hxx +++ b/configmgr/source/modifications.hxx @@ -54,6 +54,8 @@ public: void add(Path const & path); + void remove(Path const & path); + Node const & getRoot() const; private: diff --git a/configmgr/source/update.cxx b/configmgr/source/update.cxx index 4c1d59d5d054..403b761a5abd 100644 --- a/configmgr/source/update.cxx +++ b/configmgr/source/update.cxx @@ -89,6 +89,9 @@ private: sal_Bool shared, rtl::OUString const & fileUri) throw (css::uno::RuntimeException); + virtual void SAL_CALL removeExtensionXcuFile(rtl::OUString const & fileUri) + throw (css::uno::RuntimeException); + virtual void SAL_CALL insertModificationXcuFile( rtl::OUString const & fileUri, css::uno::Sequence< rtl::OUString > const & includedPaths, @@ -120,6 +123,20 @@ void Service::insertExtensionXcuFile( bc.send(); } +void Service::removeExtensionXcuFile(rtl::OUString const & fileUri) + throw (css::uno::RuntimeException) +{ + Broadcaster bc; + { + osl::MutexGuard g(lock); + Modifications mods; + Components::getSingleton().removeExtensionXcuFile(fileUri, &mods); + Components::getSingleton().initGlobalBroadcaster( + mods, rtl::Reference< RootAccess >(), &bc); + } + bc.send(); +} + void Service::insertModificationXcuFile( rtl::OUString const & fileUri, css::uno::Sequence< rtl::OUString > const & includedPaths, diff --git a/configmgr/source/xcdparser.cxx b/configmgr/source/xcdparser.cxx index b8092866cb4e..a7b66fe60157 100644 --- a/configmgr/source/xcdparser.cxx +++ b/configmgr/source/xcdparser.cxx @@ -139,7 +139,7 @@ bool XcdParser::startElement( if (nsId == ParseManager::NAMESPACE_OOR && name.equals(RTL_CONSTASCII_STRINGPARAM("component-data"))) { - nestedParser_ = new XcuParser(layer_ + 1, data_, 0, 0); + nestedParser_ = new XcuParser(layer_ + 1, data_, 0, 0, 0); nesting_ = 1; return nestedParser_->startElement(reader, nsId, name); } diff --git a/configmgr/source/xcsparser.cxx b/configmgr/source/xcsparser.cxx index 1c9cd53d7b9a..1deb8e9f3029 100644 --- a/configmgr/source/xcsparser.cxx +++ b/configmgr/source/xcsparser.cxx @@ -322,15 +322,19 @@ void XcsParser::endElement(xmlreader::XmlReader const & reader) { } else { switch (state_) { case STATE_COMPONENT_SCHEMA: + // To support old, broken extensions with .xcs files that contain + // empty <component-schema> elements: + state_ = STATE_COMPONENT_DONE; + break; + case STATE_TEMPLATES: + state_ = STATE_TEMPLATES_DONE; + break; case STATE_TEMPLATES_DONE: throw css::uno::RuntimeException( (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("no component element in ")) + reader.getUrl()), css::uno::Reference< css::uno::XInterface >()); - case STATE_TEMPLATES: - state_ = STATE_TEMPLATES_DONE; - break; case STATE_COMPONENT_DONE: break; default: diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx index 8a39a3a231ec..1a9575bb6726 100644 --- a/configmgr/source/xcuparser.cxx +++ b/configmgr/source/xcuparser.cxx @@ -69,12 +69,13 @@ namespace css = com::sun::star; XcuParser::XcuParser( int layer, Data & data, Partial const * partial, - Modifications * broadcastModifications): + Modifications * broadcastModifications, Additions * additions): valueParser_(layer), data_(data), partial_(partial), broadcastModifications_(broadcastModifications), - recordModifications_(layer == Data::NO_LAYER), + additions_(additions), recordModifications_(layer == Data::NO_LAYER), trackPath_( - partial_ != 0 || broadcastModifications_ != 0 || recordModifications_) + partial_ != 0 || broadcastModifications_ != 0 || additions_ != 0 || + recordModifications_) {} XcuParser::~XcuParser() {} @@ -627,7 +628,7 @@ void XcuParser::handleLocpropValue( pop = true; } if (trackPath_) { - recordModification(); + recordModification(false); if (pop) { path_.pop_back(); } @@ -641,7 +642,7 @@ void XcuParser::handleLocpropValue( locprop->getMembers().erase(i); } state_.push(State(true)); - recordModification(); + recordModification(false); break; default: throw css::uno::RuntimeException( @@ -755,7 +756,7 @@ void XcuParser::handleUnknownGroupProp( prop->setFinalized(valueParser_.getLayer()); } state_.push(State(prop, name, state_.top().locked)); - recordModification(); + recordModification(false); break; } // fall through @@ -805,7 +806,7 @@ void XcuParser::handlePlainGroupProp( property, (state_.top().locked || finalizedLayer < valueParser_.getLayer()))); - recordModification(); + recordModification(false); break; case OPERATION_REMOVE: if (!property->isExtension()) { @@ -819,7 +820,7 @@ void XcuParser::handlePlainGroupProp( } group->getMembers().erase(propertyIndex); state_.push(State(true)); // ignore children - recordModification(); + recordModification(false); break; } } @@ -868,7 +869,7 @@ void XcuParser::handleLocalizedGroupProp( replacement, name, (state_.top().locked || finalizedLayer < valueParser_.getLayer()))); - recordModification(); + recordModification(false); } break; case OPERATION_REMOVE: @@ -1073,7 +1074,7 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { member->setFinalized(finalizedLayer); member->setMandatory(mandatoryLayer); state_.push(State(member, name, false)); - recordModification(); + recordModification(i == set->getMembers().end()); } break; case OPERATION_FUSE: @@ -1087,7 +1088,7 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { member->setFinalized(finalizedLayer); member->setMandatory(mandatoryLayer); state_.push(State(member, name, false)); - recordModification(); + recordModification(true); } } else { state_.push( @@ -1107,15 +1108,18 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { set->getMembers().erase(i); } state_.push(State(true)); - recordModification(); + recordModification(false); break; } } -void XcuParser::recordModification() { +void XcuParser::recordModification(bool addition) { if (broadcastModifications_ != 0) { broadcastModifications_->add(path_); } + if (addition && additions_ != 0) { + additions_->push_back(path_); + } if (recordModifications_) { data_.modifications.add(path_); } diff --git a/configmgr/source/xcuparser.hxx b/configmgr/source/xcuparser.hxx index 802ed1cd8e50..6cd600c8aab1 100644 --- a/configmgr/source/xcuparser.hxx +++ b/configmgr/source/xcuparser.hxx @@ -36,6 +36,7 @@ #include "rtl/ustring.hxx" #include "xmlreader/xmlreader.hxx" +#include "additions.hxx" #include "node.hxx" #include "nodemap.hxx" #include "parser.hxx" @@ -60,7 +61,7 @@ class XcuParser: public Parser { public: XcuParser( int layer, Data & data, Partial const * partial, - Modifications * broadcastModifications); + Modifications * broadcastModifications, Additions * additions); private: virtual ~XcuParser(); @@ -110,7 +111,7 @@ private: void handleSetNode(xmlreader::XmlReader & reader, SetNode * set); - void recordModification(); + void recordModification(bool addition); struct State { rtl::Reference< Node > node; // empty iff ignore or <items> @@ -143,6 +144,7 @@ private: Data & data_; Partial const * partial_; Modifications * broadcastModifications_; + Additions * additions_; bool recordModifications_; bool trackPath_; rtl::OUString componentName_; |