void Access::initBroadcasterAndChanges()

in main/configmgr/source/access.cxx [471:832]


void Access::initBroadcasterAndChanges(
    Modifications::Node const & modifications, Broadcaster * broadcaster,
    std::vector< css::util::ElementChange > * allChanges)
{
    OSL_ASSERT(broadcaster != 0);
    comphelper::SequenceAsVector< css::beans::PropertyChangeEvent > propChanges;
    bool collectPropChanges = !propertiesChangeListeners_.empty();
    for (Modifications::Node::Children::const_iterator i(
             modifications.children.begin());
         i != modifications.children.end(); ++i)
    {
        rtl::Reference< ChildAccess > child(getChild(i->first));
        if (child.is()) {
            switch (child->getNode()->kind()) {
            case Node::KIND_LOCALIZED_PROPERTY:
                if (!i->second.children.empty()) {
                    if (Components::allLocales(getRootAccess()->getLocale())) {
                        child->initBroadcasterAndChanges(
                            i->second, broadcaster, allChanges);
                            //TODO: if allChanges==0, recurse only into children
                            // w/ listeners
                    } else {
                        //TODO: filter child mods that are irrelevant for
                        // locale:
                        for (ContainerListeners::iterator j(
                                 containerListeners_.begin());
                             j != containerListeners_.end(); ++j)
                        {
                            broadcaster->
                                addContainerElementReplacedNotification(
                                    *j,
                                    css::container::ContainerEvent(
                                        static_cast< cppu::OWeakObject * >(
                                            this),
                                        css::uno::makeAny(i->first),
                                        css::uno::Any(), css::uno::Any()));
                                //TODO: non-void Element, ReplacedElement
                        }
                        PropertyChangeListeners::iterator j(
                            propertyChangeListeners_.find(i->first));
                        if (j != propertyChangeListeners_.end()) {
                            for (PropertyChangeListenersElement::iterator k(
                                     j->second.begin());
                                 k != j->second.end(); ++k)
                            {
                                broadcaster->addPropertyChangeNotification(
                                    *k,
                                    css::beans::PropertyChangeEvent(
                                        static_cast< cppu::OWeakObject * >(
                                            this),
                                        i->first, false, -1, css::uno::Any(),
                                        css::uno::Any()));
                            }
                        }
                        j = propertyChangeListeners_.find(rtl::OUString());
                        if (j != propertyChangeListeners_.end()) {
                            for (PropertyChangeListenersElement::iterator k(
                                     j->second.begin());
                                 k != j->second.end(); ++k)
                            {
                                broadcaster->addPropertyChangeNotification(
                                    *k,
                                    css::beans::PropertyChangeEvent(
                                        static_cast< cppu::OWeakObject * >(
                                            this),
                                        i->first, false, -1, css::uno::Any(),
                                        css::uno::Any()));
                            }
                        }
                        if (allChanges != 0) {
                            allChanges->push_back(
                                css::util::ElementChange(
                                    css::uno::makeAny(
                                        child->getRelativePathRepresentation()),
                                    css::uno::Any(), css::uno::Any()));
                                //TODO: non-void Element, ReplacedElement
                        }
                        if (collectPropChanges) {
                            propChanges.push_back(
                                css::beans::PropertyChangeEvent(
                                    static_cast< cppu::OWeakObject * >(this),
                                    i->first, false, -1, css::uno::Any(),
                                    css::uno::Any()));
                        }
                    }
                }
                // else: spurious Modifications::Node not representing a change
                break;
            case Node::KIND_LOCALIZED_VALUE:
                OSL_ASSERT(
                    Components::allLocales(getRootAccess()->getLocale()));
                for (ContainerListeners::iterator j(
                         containerListeners_.begin());
                     j != containerListeners_.end(); ++j)
                {
                    broadcaster->addContainerElementReplacedNotification(
                        *j,
                        css::container::ContainerEvent(
                            static_cast< cppu::OWeakObject * >(this),
                            css::uno::makeAny(i->first), child->asValue(),
                            css::uno::Any()));
                        //TODO: distinguish add/modify; non-void ReplacedElement
                }
                if (allChanges != 0) {
                    allChanges->push_back(
                        css::util::ElementChange(
                            css::uno::makeAny(
                                child->getRelativePathRepresentation()),
                            child->asValue(), css::uno::Any()));
                        //TODO: non-void ReplacedElement
                }
                OSL_ASSERT(!collectPropChanges);
                break;
            case Node::KIND_PROPERTY:
                {
                    for (ContainerListeners::iterator j(
                             containerListeners_.begin());
                         j != containerListeners_.end(); ++j)
                    {
                        broadcaster->addContainerElementReplacedNotification(
                            *j,
                            css::container::ContainerEvent(
                                static_cast< cppu::OWeakObject * >(this),
                                css::uno::makeAny(i->first), child->asValue(),
                                css::uno::Any()));
                            //TODO: distinguish add/remove/modify; non-void
                            // ReplacedElement
                    }
                    PropertyChangeListeners::iterator j(
                        propertyChangeListeners_.find(i->first));
                    if (j != propertyChangeListeners_.end()) {
                        for (PropertyChangeListenersElement::iterator k(
                                 j->second.begin());
                             k != j->second.end(); ++k)
                        {
                            broadcaster->addPropertyChangeNotification(
                                *k,
                                css::beans::PropertyChangeEvent(
                                    static_cast< cppu::OWeakObject * >(this),
                                    i->first, false, -1, css::uno::Any(),
                                    css::uno::Any()));
                        }
                    }
                    j = propertyChangeListeners_.find(rtl::OUString());
                    if (j != propertyChangeListeners_.end()) {
                        for (PropertyChangeListenersElement::iterator k(
                                 j->second.begin());
                             k != j->second.end(); ++k)
                        {
                            broadcaster->addPropertyChangeNotification(
                                *k,
                                css::beans::PropertyChangeEvent(
                                    static_cast< cppu::OWeakObject * >(this),
                                    i->first, false, -1, css::uno::Any(),
                                    css::uno::Any()));
                        }
                    }
                    if (allChanges != 0) {
                        allChanges->push_back(
                            css::util::ElementChange(
                                css::uno::makeAny(
                                    child->getRelativePathRepresentation()),
                                child->asValue(), css::uno::Any()));
                            //TODO: non-void ReplacedElement
                    }
                    if (collectPropChanges) {
                        propChanges.push_back(
                            css::beans::PropertyChangeEvent(
                                static_cast< cppu::OWeakObject * >(this),
                                i->first, false, -1, css::uno::Any(),
                                css::uno::Any()));
                    }
                }
                break;
            case Node::KIND_GROUP:
            case Node::KIND_SET:
                if (i->second.children.empty()) {
                    if (child->getNode()->getTemplateName().getLength() != 0) {
                        for (ContainerListeners::iterator j(
                                 containerListeners_.begin());
                             j != containerListeners_.end(); ++j)
                        {
                            broadcaster->
                                addContainerElementInsertedNotification(
                                    *j,
                                    css::container::ContainerEvent(
                                        static_cast< cppu::OWeakObject * >(
                                            this),
                                        css::uno::makeAny(i->first),
                                        child->asValue(), css::uno::Any()));
                        }
                        if (allChanges != 0) {
                            allChanges->push_back(
                                css::util::ElementChange(
                                    css::uno::makeAny(
                                        child->getRelativePathRepresentation()),
                                    css::uno::Any(), css::uno::Any()));
                                //TODO: non-void Element, ReplacedElement
                        }
                    }
                    // else: spurious Modifications::Node not representing a
                    // change
                } else {
                    child->initBroadcasterAndChanges(
                        i->second, broadcaster, allChanges);
                        //TODO: if allChanges==0, recurse only into children w/
                        // listeners
                }
                break;
            }
        } else {
            switch (getNode()->kind()) {
            case Node::KIND_LOCALIZED_PROPERTY:
                // Removed localized property value:
                OSL_ASSERT(
                    Components::allLocales(getRootAccess()->getLocale()));
                for (ContainerListeners::iterator j(
                         containerListeners_.begin());
                     j != containerListeners_.end(); ++j)
                {
                    broadcaster->addContainerElementRemovedNotification(
                        *j,
                        css::container::ContainerEvent(
                            static_cast< cppu::OWeakObject * >(this),
                            css::uno::makeAny(i->first), 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
                }
                OSL_ASSERT(!collectPropChanges);
                break;
            case Node::KIND_GROUP:
                {
                    // Removed (non-localized) extension property:
                    for (ContainerListeners::iterator j(
                             containerListeners_.begin());
                         j != containerListeners_.end(); ++j)
                    {
                        broadcaster->addContainerElementRemovedNotification(
                            *j,
                            css::container::ContainerEvent(
                                static_cast< cppu::OWeakObject * >(this),
                                css::uno::makeAny(i->first), css::uno::Any(),
                                css::uno::Any()));
                            //TODO: non-void ReplacedElement
                    }
                    PropertyChangeListeners::iterator j(
                        propertyChangeListeners_.find(i->first));
                    if (j != propertyChangeListeners_.end()) {
                        for (PropertyChangeListenersElement::iterator k(
                                 j->second.begin());
                             k != j->second.end(); ++k)
                        {
                            broadcaster->addPropertyChangeNotification(
                                *k,
                                css::beans::PropertyChangeEvent(
                                    static_cast< cppu::OWeakObject * >(this),
                                    i->first, false, -1, css::uno::Any(),
                                    css::uno::Any()));
                        }
                    }
                    j = propertyChangeListeners_.find(rtl::OUString());
                    if (j != propertyChangeListeners_.end()) {
                        for (PropertyChangeListenersElement::iterator k(
                                 j->second.begin());
                             k != j->second.end(); ++k)
                        {
                            broadcaster->addPropertyChangeNotification(
                                *k,
                                css::beans::PropertyChangeEvent(
                                    static_cast< cppu::OWeakObject * >(this),
                                    i->first, false, -1, css::uno::Any(),
                                    css::uno::Any()));
                        }
                    }
                    if (allChanges != 0) {
                        rtl::OUStringBuffer path(
                            getRelativePathRepresentation());
                        if (path.getLength() != 0) {
                            path.append(sal_Unicode('/'));
                        }
                        path.append(i->first);
                        allChanges->push_back(
                            css::util::ElementChange(
                                css::uno::makeAny(path.makeStringAndClear()),
                                css::uno::Any(), css::uno::Any()));
                            //TODO: non-void ReplacedElement
                    }
                    if (collectPropChanges) {
                        propChanges.push_back(
                            css::beans::PropertyChangeEvent(
                                static_cast< cppu::OWeakObject * >(this),
                                i->first, false, -1, css::uno::Any(),
                                css::uno::Any()));
                    }
                }
                break;
            case Node::KIND_SET:
                // Removed set member:
                if (i->second.children.empty()) {
                    for (ContainerListeners::iterator j(
                             containerListeners_.begin());
                         j != containerListeners_.end(); ++j)
                    {
                        broadcaster->addContainerElementRemovedNotification(
                            *j,
                            css::container::ContainerEvent(
                                static_cast< cppu::OWeakObject * >(this),
                                css::uno::makeAny(i->first),
                                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;
            default:
                OSL_ASSERT(false); // this cannot happen
                break;
            }
        }
    }
    if (!propChanges.empty()) {
        css::uno::Sequence< css::beans::PropertyChangeEvent > seq(
            propChanges.getAsConstList());
        for (PropertiesChangeListeners::iterator i(
                 propertiesChangeListeners_.begin());
             i != propertiesChangeListeners_.end(); ++i)
        {
            broadcaster->addPropertiesChangeNotification(*i, seq);
        }
    }
}