Kaydet (Commit) d6688c4c authored tarafından sb's avatar sb

#i101955# notification support, continued (still to be continued; at least no…

#i101955# notification support, continued (still to be continued; at least no longer fails miserably now)
üst 5ab6b21f
This diff is collapsed.
......@@ -143,7 +143,7 @@ public:
virtual bool isFinalized() = 0;
virtual void initGlobalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster);
Modifications const & modifications, Broadcaster * broadcaster);
using OWeakObject::acquire;
using OWeakObject::release;
......@@ -167,7 +167,7 @@ protected:
virtual void clearListeners() throw ();
virtual void initLocalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster);
Modifications const & modifications, Broadcaster * broadcaster);
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
......@@ -506,6 +506,8 @@ private:
void checkFinalized();
void checkKnownProperty(rtl::OUString const & descriptor);
rtl::Reference< ChildAccess > getFreeSetMember(
com::sun::star::uno::Any const & value);
......
......@@ -48,6 +48,7 @@
#include "components.hxx"
#include "data.hxx"
#include "modifications.hxx"
#include "node.hxx"
#include "parsemanager.hxx"
#include "rootaccess.hxx"
......@@ -136,9 +137,10 @@ void Components::removeRootAccess(RootAccess * access) {
}
void Components::initGlobalBroadcaster(
Modifications const & globalModifications,
Modifications const & modifications,
rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster)
{
//TODO: Iterate only over roots w/ listeners:
for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) {
rtl::Reference< RootAccess > root;
if ((*i)->acquireCounting() > 1) {
......@@ -147,7 +149,23 @@ void Components::initGlobalBroadcaster(
(*i)->releaseNondeleting();
if (root.is()) {
if (root != exclude) {
root->initGlobalBroadcaster(globalModifications, broadcaster);
Path path(root->getAbsolutePath());
Modifications const * mods = &modifications;
for (Path::iterator j(path.begin()); j != path.end(); ++j) {
Modifications::Children::const_iterator k(
mods->children.find(*j));
if (k == mods->children.end()) {
mods = 0;
break;
}
mods = &k->second;
}
//TODO: If the complete tree of which root is a part is deleted,
// or replaced, mods will be null, but some of the listeners
// from within root should probably fire nonetheless:
if (mods != 0) {
root->initGlobalBroadcaster(*mods, broadcaster);
}
}
}
}
......
......@@ -70,7 +70,7 @@ public:
void removeRootAccess(RootAccess * access);
void initGlobalBroadcaster(
Modifications const & globalModifications,
Modifications const & modifications,
rtl::Reference< RootAccess > const & exclude,
Broadcaster * broadcaster);
......
......@@ -37,37 +37,24 @@
namespace configmgr {
namespace {
bool isPrefix(Path const & prefix, Path const & path) {
if (prefix.size() > path.size()) {
return false;
}
Path::const_iterator i1(prefix.begin());
Path::const_iterator i2(path.begin());
while (i1 != prefix.end()) {
if (*i1++ != *i2++) {
return false;
}
}
return true;
}
}
void Modifications::add(Path const & path) {
//TODO: performance
for (List::iterator i(list.begin()); i != list.end();) {
if (isPrefix(*i, path)) {
return;
}
if (isPrefix(path, *i)) {
list.erase(i++);
Modifications * mod = this;
bool wasPresent = false;
for (Path::const_iterator i(path.begin()); i != path.end(); ++i) {
Children::iterator j(mod->children.find(*i));
if (j == mod->children.end()) {
if (wasPresent && mod->children.empty()) {
return;
}
j = mod->children.insert(Children::value_type(*i, Modifications())).
first;
wasPresent = false;
} else {
++i;
wasPresent = true;
}
mod = &j->second;
}
list.push_back(path);
mod->children.clear();
}
}
......@@ -32,19 +32,18 @@
#include "sal/config.h"
#include <list>
#include "boost/noncopyable.hpp"
#include <map>
#include "path.hxx"
namespace rtl { class OUString; }
namespace configmgr {
struct Modifications: private boost::noncopyable {
public:
typedef std::list< Path > List;
struct Modifications {
typedef std::map< rtl::OUString, Modifications > Children;
List list;
Children children;
void add(Path const & path);
};
......
......@@ -75,26 +75,16 @@ RootAccess::RootAccess(
pathRepresentation_(pathRepresentation), locale_(locale), update_(update)
{}
Path RootAccess::getAbsolutePath() {
getNode();
return path_;
}
void RootAccess::initGlobalBroadcaster(
Modifications const & globalModifications, Broadcaster * broadcaster)
Modifications const & modifications, Broadcaster * broadcaster)
{
OSL_ASSERT(broadcaster != 0);
//TODO: only for matching modifications:
for (ChangesListeners::iterator i(changesListeners_.begin());
i != changesListeners_.end(); ++i)
{
broadcaster->addChangesNotification(
*i,
css::util::ChangesEvent(
static_cast< cppu::OWeakObject * >(this),
css::uno::makeAny(
css::uno::Reference< css::uno::XInterface >(
static_cast< cppu::OWeakObject * >(this))),
//TODO: XInterface or something else?
css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
}
Access::initGlobalBroadcaster(globalModifications, broadcaster);
Access::initGlobalBroadcaster(modifications, broadcaster);
//TODO: handle changesListeners_
}
void RootAccess::acquire() throw () {
......@@ -118,11 +108,6 @@ RootAccess::~RootAccess() {
Components::singleton().removeRootAccess(this);
}
Path RootAccess::getAbsolutePath() {
getNode();
return path_;
}
Path RootAccess::getRelativePath() {
return Path();
}
......@@ -201,25 +186,10 @@ void RootAccess::clearListeners() throw() {
}
void RootAccess::initLocalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster)
Modifications const & modifications, Broadcaster * broadcaster)
{
OSL_ASSERT(broadcaster != 0);
//TODO: only for matching modifications:
for (ChangesListeners::iterator i(changesListeners_.begin());
i != changesListeners_.end(); ++i)
{
broadcaster->addChangesNotification(
*i,
css::util::ChangesEvent(
static_cast< cppu::OWeakObject * >(this),
css::uno::makeAny(
css::uno::Reference< css::uno::XInterface >(
static_cast< cppu::OWeakObject * >(this))),
//TODO: XInterface or something else?
css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
}
Access::initLocalBroadcaster(localModifications, broadcaster);
Access::initLocalBroadcaster(modifications, broadcaster);
//TODO: handle changesListeners_
}
css::uno::Any RootAccess::queryInterface(css::uno::Type const & aType)
......
......@@ -69,8 +69,10 @@ public:
rtl::OUString const & pathRepresenation, rtl::OUString const & locale,
bool update);
virtual Path getAbsolutePath();
virtual void initGlobalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster);
Modifications const & modifications, Broadcaster * broadcaster);
virtual void SAL_CALL acquire() throw ();
......@@ -83,8 +85,6 @@ public:
private:
virtual ~RootAccess();
virtual Path getAbsolutePath();
virtual Path getRelativePath();
virtual rtl::OUString getRelativePathRepresentation();
......@@ -107,7 +107,7 @@ private:
virtual void clearListeners() throw ();
virtual void initLocalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster);
Modifications const & modifications, Broadcaster * broadcaster);
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
......
......@@ -437,6 +437,105 @@ void writeNode(
}
}
void writeModifications(
oslFileHandle handle, rtl::OUString const & grandparentPathRepresentation,
rtl::OUString const & parentName, rtl::Reference< Node > const & parent,
rtl::OUString const & nodeName, rtl::Reference< Node > const & node,
Modifications const & modifications)
{
if (modifications.children.empty()) {
OSL_ASSERT(parent.is());
// components themselves have no parent but must have children
if (node.is()) {
writeData(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
writeAttributeValue(
handle,
(grandparentPathRepresentation +
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
Data::createSegment(parent->getTemplateName(), parentName)));
writeData(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
writeNode(handle, parent, nodeName, node);
writeData(handle, RTL_CONSTASCII_STRINGPARAM("</item>"));
// It is never necessary to write the oor:mandatory attribute, as it
// cannot be set via the UNO API.
} else {
writeData(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
switch (parent->kind()) {
case Node::KIND_LOCALIZED_PROPERTY:
writeAttributeValue(handle, grandparentPathRepresentation);
writeData(
handle, RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
writeAttributeValue(handle, parentName);
writeData(
handle,
RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\"><value"));
if (nodeName.getLength() != 0) {
writeData(
handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
writeAttributeValue(handle, nodeName);
writeData(handle, RTL_CONSTASCII_STRINGPARAM("\""));
}
writeData(
handle,
RTL_CONSTASCII_STRINGPARAM(
" oor:op=\"remove\"/></prop></item>"));
break;
case Node::KIND_GROUP:
OSL_ASSERT(
dynamic_cast< GroupNode * >(parent.get())->isExtensible());
writeAttributeValue(
handle,
(grandparentPathRepresentation +
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
Data::createSegment(
parent->getTemplateName(), parentName)));
writeData(
handle, RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
writeAttributeValue(handle, nodeName);
writeData(
handle,
RTL_CONSTASCII_STRINGPARAM(
"\" oor:op=\"remove\"/></item>"));
break;
case Node::KIND_SET:
writeAttributeValue(
handle,
(grandparentPathRepresentation +
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
Data::createSegment(
parent->getTemplateName(), parentName)));
writeData(
handle, RTL_CONSTASCII_STRINGPARAM("\"><node oor:name=\""));
writeAttributeValue(handle, nodeName);
writeData(
handle,
RTL_CONSTASCII_STRINGPARAM(
"\" oor:op=\"remove\"/></item>"));
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
} else {
rtl::OUString parentPathRep;
if (parent.is()) { // components themselves have no parent
parentPathRep = grandparentPathRepresentation +
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
Data::createSegment(parent->getTemplateName(), parentName);
}
OSL_ASSERT(node.is());
for (Modifications::Children::const_iterator i(
modifications.children.begin());
i != modifications.children.end(); ++i)
{
writeModifications(
handle, parentPathRep, nodeName, node, i->first,
node->getMember(i->first), i->second);
}
}
}
}
void writeModFile(rtl::OUString const & url, Data const & data) {
......@@ -475,102 +574,15 @@ void writeModFile(rtl::OUString const & url, Data const & data) {
//TODO: Do not write back information about those removed items that did not
// come from the .xcs/.xcu files, anyway (but had been added dynamically
// instead):
for (Modifications::List::const_iterator j(data.modifications.list.begin());
j != data.modifications.list.end(); ++j)
for (Modifications::Children::const_iterator j(
data.modifications.children.begin());
j != data.modifications.children.end(); ++j)
{
Path::const_iterator k(j->begin());
OSL_ASSERT(k != j->end());
rtl::OUString parentName(*k++);
rtl::Reference< Node > parent(
Data::findNode(Data::NO_LAYER, data.components, parentName));
OSL_ASSERT(parent.is() && k != j->end());
rtl::OUString nodeName;
rtl::Reference< Node > node;
rtl::OUStringBuffer pathRep; // up to grandparent segment
for (;;) {
nodeName = *k++;
node = parent->getMember(nodeName);
if (k == j->end()) {
break;
}
OSL_ASSERT(node.is());
pathRep.append(sal_Unicode('/'));
pathRep.append(
Data::createSegment(parent->getTemplateName(), parentName));
parent = node;
parentName = nodeName;
}
if (node.is()) {
writeData(
tmp.handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
pathRep.append(sal_Unicode('/'));
pathRep.append(
Data::createSegment(parent->getTemplateName(), parentName));
writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("\">"));
writeNode(tmp.handle, parent, nodeName, node);
writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</item>"));
// It is never necessary to write the oor:mandatory attribute, as it
// cannot be set via the UNO API.
} else {
writeData(
tmp.handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
switch (parent->kind()) {
case Node::KIND_LOCALIZED_PROPERTY:
writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
writeAttributeValue(tmp.handle, parentName);
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\"><value"));
if (nodeName.getLength() != 0) {
writeData(
tmp.handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
writeAttributeValue(tmp.handle, nodeName);
writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("\""));
}
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM(
" oor:op=\"remove\"/></prop></item>"));
break;
case Node::KIND_GROUP:
OSL_ASSERT(
dynamic_cast< GroupNode * >(parent.get())->isExtensible());
pathRep.append(sal_Unicode('/'));
pathRep.append(
Data::createSegment(parent->getTemplateName(), parentName));
writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
writeAttributeValue(tmp.handle, nodeName);
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM(
"\" oor:op=\"remove\"/></item>"));
break;
case Node::KIND_SET:
pathRep.append(sal_Unicode('/'));
pathRep.append(
Data::createSegment(parent->getTemplateName(), parentName));
writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM("\"><node oor:name=\""));
writeAttributeValue(tmp.handle, nodeName);
writeData(
tmp.handle,
RTL_CONSTASCII_STRINGPARAM(
"\" oor:op=\"remove\"/></item>"));
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
writeModifications(
tmp.handle, rtl::OUString(), rtl::OUString(),
rtl::Reference< Node >(), j->first,
Data::findNode(Data::NO_LAYER, data.components, j->first),
j->second);
}
writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>"));
oslFileError e = osl_closeFile(tmp.handle);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment