merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / treemgr / nodeimplobj.cxx
blob139bf808151e9ba8d739989fdff012aaa9d9658c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nodeimplobj.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
33 #include <stdio.h>
34 #include "nodeimplobj.hxx"
37 #include "nodechange.hxx"
38 #include "nodechangeinfo.hxx"
39 #include "nodechangeimpl.hxx"
40 #include "valuenode.hxx"
41 #include "change.hxx"
42 #include "viewaccess.hxx"
43 #include "viewfactory.hxx"
45 namespace configmgr
47 namespace configuration
49 //-----------------------------------------------------------------------------
50 // Value Nodes
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 // class DeferredValueElementNodeImpl
55 //-----------------------------------------------------------------------------
57 // Group Nodes
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
61 // class DeferredGroupNodeImpl
62 //-----------------------------------------------------------------------------
64 DeferredGroupNodeImpl::DeferredGroupNodeImpl(sharable::GroupNode * const& _aNodeRef)
65 : GroupNodeImpl(_aNodeRef)
66 , m_aChanges()
69 //-----------------------------------------------------------------------------
71 DeferredGroupNodeImpl::~DeferredGroupNodeImpl()
74 //-----------------------------------------------------------------------------
76 ValueMemberNode DeferredGroupNodeImpl::makeValueMember(rtl::OUString const& _aName, bool _bForUpdate)
78 MemberChanges::iterator it = m_aChanges.find(_aName);
80 if (it != m_aChanges.end())
82 if (!it->second.is())
83 OSL_ENSURE(_aName.getLength() == 0, "ERROR: Found empty change reference");
85 else if (_bForUpdate || it->second->isChange()) // found one
86 return ValueMemberNode(it->second);
88 else // leftover non-change
89 m_aChanges.erase(it);
91 // if not found continue with default
94 sharable::ValueNode * original = getOriginalValueNode(_aName);
96 if (_bForUpdate) // create a new change
98 if (original != 0)
100 rtl::Reference<ValueMemberNode::DeferredImpl> aNewChange(new ValueMemberNode::DeferredImpl(original));
101 m_aChanges[_aName] = aNewChange;
103 return ValueMemberNode(aNewChange);
107 return GroupNodeImpl::makeValueMember(original);
109 //-----------------------------------------------------------------------------
111 bool DeferredGroupNodeImpl::hasChanges() const
113 for (MemberChanges::const_iterator it = m_aChanges.begin(); it != m_aChanges.end(); ++it)
115 if (!it->second.is())
117 // empty element is present -> marked as changed
118 OSL_ASSERT(it->first.getLength() == 0);
119 return true;
122 if (it->second->isChange())
123 return true;
126 return false;
128 //-----------------------------------------------------------------------------
130 void DeferredGroupNodeImpl::collectValueChanges(NodeChanges& rChanges, Tree* pParentTree, unsigned int nNode) const
132 for (MemberChanges::const_iterator it = m_aChanges.begin(); it != m_aChanges.end(); ++it)
134 if (it->second.is())
136 OSL_ASSERT(it->first.getLength() != 0);
137 if (ValueChangeImpl* pValueChange = it->second->collectChange())
139 pValueChange->setTarget(pParentTree,nNode,it->first);
141 rChanges.add( NodeChange(pValueChange) );
143 else // leftover non-change
144 OSL_ENSURE(!it->second->isChange(), "Got no change from a changing value") ;
146 else
147 OSL_ASSERT(it->first.getLength() == 0);
150 //-----------------------------------------------------------------------------
152 rtl::Reference<ValueMemberNode::DeferredImpl> DeferredGroupNodeImpl::findValueChange(rtl::OUString const& aName)
154 rtl::Reference<ValueMemberNode::DeferredImpl> aResult;
156 MemberChanges::iterator it = m_aChanges.find(aName);
158 if (it != m_aChanges.end())
160 if (it->second.is() )
162 if (it->second->isChange())
164 aResult = it->second;
167 else // leftover non-change -> drop
169 m_aChanges.erase(it);
172 else
173 OSL_ENSURE(aName.getLength() == 0, "ERROR: Found empty change reference");
176 return aResult;
179 //-----------------------------------------------------------------------------
181 std::auto_ptr<SubtreeChange> DeferredGroupNodeImpl::preCommitValueChanges()
183 std::auto_ptr<SubtreeChange> aRet;
185 if (!m_aChanges.empty())
187 sharable::Node * originalData = this->getOriginalNodeAccess();
188 aRet.reset( new SubtreeChange( originalData->getName(),
189 originalData->getAttributes() ) );
191 for (MemberChanges::iterator pos = m_aChanges.begin(); pos != m_aChanges.end(); )
193 MemberChanges::iterator it = pos++; // this is used to allow erasing below
195 if (!it->second.is())
197 OSL_ASSERT(it->first.getLength() == 0);
199 else if (it->second->isChange())
201 std::auto_ptr<ValueChange> aValueChange = it->second->preCommitChange();
202 if (aValueChange.get())
204 std::auto_ptr<Change> aBaseChange(aValueChange.release());
205 aRet->addChange( aBaseChange );
207 else
208 OSL_ENSURE(false, "Got no change from a changed member");
210 else // found left-over non-change
211 m_aChanges.erase(it);
213 if (m_aChanges.empty()) aRet.reset();
216 return aRet;
218 //-----------------------------------------------------------------------------
220 void DeferredGroupNodeImpl::finishCommit(SubtreeChange& rChanges)
222 OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
224 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
225 it != stop;
226 ++it)
228 rtl::OUString aValueName(it->getNodeName());
230 MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
232 if (itStoredChange != m_aChanges.end())
234 ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
235 OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
236 if (valueChange == 0) throw Exception("Unexpected type of element change");
238 rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
239 OSL_ENSURE( aStoredChange.is(), "Found empty change object for Member value change");
241 if (aStoredChange.is())
243 aStoredChange->finishCommit(*valueChange);
244 OSL_ENSURE(!aStoredChange->isChange(),"ValueChange is not moot after finishCommit");
247 m_aChanges.erase( itStoredChange ); // remove finished change
249 else
250 OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
254 OSL_DEBUG_ONLY( m_aChanges.erase( rtl::OUString() ) ); // remove change marker (if present)
255 OSL_ENSURE(m_aChanges.empty(), "Found unprocessed changes to values in group");
257 m_aChanges.clear(); // remove all pending stuff and marker
259 //-----------------------------------------------------------------------------
261 void DeferredGroupNodeImpl::revertCommit(SubtreeChange& rChanges)
263 OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
265 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
266 it != stop;
267 ++it)
269 rtl::OUString aValueName(it->getNodeName());
271 MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
273 if (itStoredChange != m_aChanges.end())
275 ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
276 OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
277 if (valueChange == 0) continue;
279 rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
280 OSL_ENSURE( aStoredChange.is(), "Cannot restore change: found empty change object for Member value change");
282 if (aStoredChange.is())
284 aStoredChange->revertCommit(*valueChange);
285 OSL_ENSURE(!aStoredChange->isChange(),"ValueChange is not moot after reverting - will be discarded nevertheless");
287 m_aChanges.erase( itStoredChange ); // remove change if it is moot
289 else
290 OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
293 //-----------------------------------------------------------------------------
295 void DeferredGroupNodeImpl::failedCommit(SubtreeChange& rChanges)
297 OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
299 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
300 it != stop;
301 ++it)
303 rtl::OUString aValueName(it->getNodeName());
305 MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
307 if (itStoredChange != m_aChanges.end())
309 ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
310 OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
311 if (valueChange == 0) continue;
313 rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
314 OSL_ENSURE( aStoredChange.is(), "Cannot recover from failed change: found empty change object for Member value change");
316 if (aStoredChange.is())
317 aStoredChange->failedCommit(*valueChange);
319 if (!aStoredChange->isChange())
320 m_aChanges.erase( itStoredChange ); // remove change if it is moot
323 else
324 OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
327 OSL_DEBUG_ONLY( m_aChanges.erase( rtl::OUString() ) ); // remove change marker (if present)
328 OSL_ENSURE(m_aChanges.empty(), "RevertCommit: Found unprocessed changes to values in group");
330 m_aChanges.clear(); // discard all pending stuff and marker
332 //-----------------------------------------------------------------------------
335 void DeferredGroupNodeImpl::markChanged()
337 // special mark: a NULL rtl::Reference<ValueMemberNode::DeferredImpl> at empty name
338 m_aChanges.insert( MemberChanges::value_type() );
340 //-----------------------------------------------------------------------------
342 // Set nodes
343 //-----------------------------------------------------------------------------
346 //-----------------------------------------------------------------------------
347 // class DeferredTreeSetNodeImpl
348 //-----------------------------------------------------------------------------
350 DeferredSetNodeImpl::DeferredSetNodeImpl(sharable::SetNode * const& _aNodeRef, Template* pTemplate)
351 : SetNodeImpl(_aNodeRef,pTemplate)
352 , m_aChangedData()
353 , m_bChanged(false)
354 , m_bDefault(false)
357 //-----------------------------------------------------------------------------
359 bool DeferredSetNodeImpl::doIsEmpty() const
361 if (m_aChangedData.isEmpty())
362 return SetNodeImpl::doIsEmpty();
364 // look for added elements
365 {for(ElementSet::ConstIterator it = m_aChangedData.begin(), stop = m_aChangedData.end();
366 it != stop;
367 ++it)
369 if (it->isValid()) return false;
373 // look for elements in the base set that are not 'deleted' (the changes are all deletions here)
374 {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
375 it != stop;
376 ++it)
378 if (!m_aChangedData.hasElement(it->first)) return false;
381 return true;
383 //-----------------------------------------------------------------------------
385 ElementTree* DeferredSetNodeImpl::doFindElement(rtl::OUString const& aName)
387 ElementTreeData* pElement = m_aChangedData.getElement(aName);
388 if (!pElement)
389 pElement = SetNodeImpl::getStoredElement(aName);
391 return pElement ? pElement->get() : 0;
393 //-----------------------------------------------------------------------------
395 SetNodeVisitor::Result DeferredSetNodeImpl::doDispatchToElements(SetNodeVisitor& aVisitor)
397 SetNodeVisitor::Result eRet = SetNodeVisitor::CONTINUE;
398 // look for elements in the base set that are not hidden by changes
399 {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
400 it != stop && eRet != SetNodeVisitor::DONE;
401 ++it)
403 if (m_aChangedData.getElement(it->first) == 0)
405 OSL_ASSERT(it->second.isValid());
406 eRet = aVisitor.visit(SetEntry(it->second.get()));
410 // look for added elements
411 {for(ElementSet::ConstIterator it = m_aChangedData.begin(), stop = m_aChangedData.end();
412 it != stop && eRet != SetNodeVisitor::DONE;
413 ++it)
415 if (it->isValid())
417 eRet = aVisitor.visit(SetEntry(it->get()));
420 return eRet;
422 //-----------------------------------------------------------------------------
424 bool DeferredSetNodeImpl::hasChanges() const
426 return m_bChanged || !m_aChangedData.isEmpty();
428 //-----------------------------------------------------------------------------
430 void DeferredSetNodeImpl::collectElementChanges(NodeChanges& rChanges) const
432 // collect added and deleted nodes
433 {for(ElementSet::Data::const_iterator it = m_aChangedData.beginNative(), stop = m_aChangedData.endNative();
434 it != stop;
435 ++it)
437 ElementTreeData const* pOriginal = SetNodeImpl::getStoredElement(it->first);
439 if (it->second.isValid()) // added one
441 if (pOriginal)
443 rChanges.add(NodeChange(implCreateReplace(it->first,it->second,*pOriginal)));
445 else
447 rChanges.add(NodeChange(implCreateInsert(it->first,it->second)));
450 else
452 if (pOriginal)
454 rChanges.add(NodeChange(implCreateRemove(it->first,*pOriginal)));
457 //else nothing to do
461 // collect preexisting nodes
462 // if (!containsValues()) // value elements ar immutable !
463 {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
464 it != stop;
465 ++it)
467 if (m_aChangedData.getElement(it->first) == 0)
469 OSL_ASSERT(it->second.isValid());
470 view::ViewTreeAccess aElementView(it->second.get());
472 if (aElementView.hasChanges())
473 aElementView.collectChanges(rChanges);
478 //-----------------------------------------------------------------------------
480 void DeferredSetNodeImpl::markChanged()
482 m_bChanged = true;
484 //-----------------------------------------------------------------------------
486 void DeferredSetNodeImpl::doTransferElements(ElementSet& rReplacement)
488 // transfer preexisting nodes (unless replaced/deleted)
489 {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
490 it != stop;
491 ++it)
493 if (m_aChangedData.getElement(it->first) == 0)
495 OSL_ASSERT(it->second.isValid());
497 rReplacement.insertElement(it->first,it->second);
501 // commit added and deleted nodes
503 ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
504 ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
506 while(it != stop)
508 if (it->second.isValid())
509 rReplacement.insertElement(it->first,it->second);
511 ++it;
512 m_aChangedData.removeElement(it->first);
516 m_bChanged = false;
518 //-----------------------------------------------------------------------------
520 void DeferredSetNodeImpl::rebuildElement(rtl::OUString const& _aName, ElementTreeData const& _aElement)
522 Tree* pContext = this->getParentTree();
523 OSL_ENSURE(pContext, "Context tree must be set before rebuilding");
525 rtl::Reference<view::ViewStrategy> xContextBehavior = pContext->getViewBehavior();
527 sharable::TreeFragment * elementAccessor = this->getDataAccess()->getElement(_aName);
528 OSL_ENSURE(elementAccessor != 0, "Element Tree not found in data");
530 OSL_ENSURE(_aElement.isValid(), "Element not found in view");
531 _aElement->rebuild(xContextBehavior, elementAccessor);
534 //-----------------------------------------------------------------------------
535 std::auto_ptr<SubtreeChange> DeferredSetNodeImpl::preCommitChanges(std::vector< rtl::Reference<ElementTree> >& _rRemovedElements)
537 sharable::Node * originalData = this->getOriginalNodeAccess();
538 // now first get the name of this node
539 rtl::OUString sSetName = originalData->getName();
541 // and make a SubtreeChange
542 std::auto_ptr<SubtreeChange> pSetChange( new SubtreeChange(sSetName,
543 getElementTemplate()->getName(),
544 getElementTemplate()->getModule(),
545 originalData->getAttributes() ) );
547 // commit preexisting nodes
549 for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
550 it != stop;
551 ++it)
553 if (m_aChangedData.getElement(it->first) == 0)
555 OSL_ASSERT(it->second.isValid());
556 OSL_ENSURE( !m_bDefault || it->second.inDefault, "m_bDefault is inconsistent");
558 view::ViewTreeAccess aElementView(it->second.get());
559 std::auto_ptr<SubtreeChange> pNewChange = aElementView.preCommitChanges(_rRemovedElements);
560 if (pNewChange.get() != 0)
562 //OSL_ENSURE( !containsValues(), "Unexpected change generated by value set element");
563 std::auto_ptr<Change> pNewChangeBase( pNewChange.release() );
564 pSetChange->addChange(pNewChangeBase);
570 // commit added and deleted nodes
572 ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
573 ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
575 while(it != stop)
577 rtl::OUString aName = it->first;
578 ElementTreeData aNewElement = it->second;
580 ElementTreeData* pOriginal = SetNodeImpl::getStoredElement(aName);
582 if (aNewElement.isValid())
584 rtl::Reference< data::TreeSegment > aAddedTree = aNewElement->releaseOwnedTree();
585 if (!aAddedTree.is())
587 throw Exception("INTERNAL ERROR: Could not find data for the added ElementTree");
590 OSL_ENSURE( !m_bDefault || aNewElement.inDefault, "m_bDefault is inconsistent");
592 AddNode* pAddNode = new AddNode(aAddedTree, aName, aNewElement.inDefault );
594 std::auto_ptr<Change> pNewChange( pAddNode );
596 if (pOriginal)
597 pAddNode->setReplacing();
599 pSetChange->addChange(pNewChange);
601 else
603 if (pOriginal)
605 OSL_ENSURE( !m_bDefault || aNewElement.inDefault, "m_bDefault is inconsistent");
607 std::auto_ptr<Change> pNewChange( new RemoveNode(aName,aNewElement.inDefault) );
609 pSetChange->addChange(pNewChange);
611 //else nothing to do
614 // collect removed or replaced element
615 if (pOriginal)
616 _rRemovedElements.push_back( pOriginal->tree );
618 ++it;
621 return pSetChange;
623 //-----------------------------------------------------------------------------
625 void DeferredSetNodeImpl::finishCommit(SubtreeChange& rChanges)
627 OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
628 OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
629 "ERROR: Element template of change does not match the template of the set");
630 OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
631 "ERROR: Element template module of change does not match the template of the set");
633 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
634 it != stop;
635 ++it)
637 rtl::OUString aElementName(it->getNodeName());
639 ElementTreeData* pOriginal = getStoredElement(aElementName);
641 if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
643 ElementTreeData aOriginal;
644 if (pOriginal)
646 aOriginal = *pOriginal;
647 OSL_ASSERT(aOriginal.isValid());
649 else
650 OSL_ASSERT(!aOriginal.isValid());
652 // handle a added, replaced or deleted node
653 rtl::Reference< data::TreeSegment > aRemovedTree;
655 if (pNewElement->isValid())
657 AddNode * addNode = dynamic_cast< AddNode * >(&*it);
658 OSL_ENSURE(addNode != 0, "Unexpected type of element change");
659 if (addNode == 0) throw Exception("Unexpected type of element change");
661 aRemovedTree = addNode->getReplacedTree();
662 OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
663 OSL_ASSERT( addNode->isReplacing() == (bool) aRemovedTree.is() );
665 if (aOriginal.isValid())
666 SetNodeImpl::replaceElement(aElementName,*pNewElement);
668 else
669 SetNodeImpl::insertElement(aElementName,*pNewElement);
671 this->rebuildElement(aElementName,*pNewElement);
673 else
675 RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
676 OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
677 if (removeNode == 0) throw Exception("Unexpected type of element change");
679 aRemovedTree = removeNode->getRemovedTree();
681 OSL_ASSERT(aOriginal.isValid());
682 if (aOriginal.isValid())
683 SetNodeImpl::removeElement(aElementName);
685 // handle a added or deleted node
686 if (aOriginal.isValid() && aRemovedTree.is())
688 OSL_ENSURE(aRemovedTree.is(), "Cannot take over the removed node");
690 aOriginal->takeTreeAndRebuild(aRemovedTree);
692 m_aChangedData.removeElement(aElementName);
694 else
696 // handle preexisting nodes
697 //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
698 OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
699 SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
700 OSL_ENSURE(subtreeChange != 0, "Unexpected type of element change");
702 if (subtreeChange == 0) throw Exception("Unexpected set element change");
704 if (pOriginal && pOriginal->isValid())
705 view::ViewTreeAccess(pOriginal->get()).finishCommit(*subtreeChange);
708 m_bChanged = false;
710 OSL_ENSURE(m_aChangedData.isEmpty(), "ERROR: Uncommitted changes left in set node");
712 //-----------------------------------------------------------------------------
714 void DeferredSetNodeImpl::revertCommit(SubtreeChange& rChanges)
716 OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
717 OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
718 "ERROR: Element template of change does not match the template of the set");
719 OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
720 "ERROR: Element template module of change does not match the template of the set");
723 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
724 it != stop;
725 ++it)
727 rtl::OUString aElementName(it->getNodeName());
729 ElementTreeData* pOriginal = getStoredElement(aElementName);
731 if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
733 // handle a added, replaced or deleted node
734 rtl::Reference< data::TreeSegment > pRemovedTree;
736 if (pNewElement->isValid())
738 AddNode * addNode = dynamic_cast< AddNode * >(&*it);
739 OSL_ENSURE(addNode != 0, "Unexpected type of element change");
740 if (addNode == 0) throw Exception("Unexpected type of element change");
742 pRemovedTree = addNode->getReplacedTree();
743 OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
744 OSL_ASSERT( addNode->isReplacing() == (0!=pRemovedTree.is()) );
746 OSL_ENSURE(!addNode->wasInserted(), "Cannot retract new node: Change was integrated");
748 rtl::Reference< data::TreeSegment > aAddedTree = addNode->getNewTree();
749 OSL_ENSURE(aAddedTree.is(), "Cannot restore new node: Change lost ownership");
751 // restore the tree
752 (*pNewElement)->takeTreeBack(aAddedTree);
754 else
756 RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
757 OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
758 if (removeNode == 0) throw Exception("Unexpected type of element change");
760 pRemovedTree = removeNode->getRemovedTree();
762 OSL_ASSERT(pOriginal);
763 OSL_ASSERT((0 != pOriginal) == (0!=pRemovedTree.is()) );
765 OSL_ENSURE(pRemovedTree.is(), "Possible problems reverting removed node: Change took ownership");
766 // try handle a added or deleted node
767 if (pOriginal)
769 OSL_ASSERT(pOriginal->isValid());
770 (*pOriginal)->takeTreeAndRebuild(pRemovedTree);
771 OSL_DEBUG_ONLY(pRemovedTree.clear());
773 OSL_ENSURE(!pRemovedTree.is(), "Could not revert removed node: Nowhere to put ownership");
775 else
777 // handle preexisting nodes
778 //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
779 OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
780 SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
781 OSL_ENSURE(subtreeChange != 0, "Unexpected set element change");
783 if (subtreeChange == 0) throw Exception("Unexpected set element change");
785 if (pOriginal && pOriginal->isValid())
786 view::ViewTreeAccess(pOriginal->get()).revertCommit(*subtreeChange);
790 //-----------------------------------------------------------------------------
792 void DeferredSetNodeImpl::failedCommit(SubtreeChange& rChanges)
794 OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
795 OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
796 "ERROR: Element template of change does not match the template of the set");
797 OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
798 "ERROR: Element template module of change does not match the template of the set");
800 for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
801 it != stop;
802 ++it)
804 rtl::OUString aElementName(it->getNodeName());
806 ElementTreeData* pOriginal = getStoredElement(aElementName);
808 if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
810 ElementTreeData aOriginal;
811 if (pOriginal)
813 aOriginal = *pOriginal;
814 OSL_ASSERT(aOriginal.isValid());
816 else
817 OSL_ASSERT(!aOriginal.isValid());
819 // handle a added, replaced or deleted node
820 rtl::Reference< data::TreeSegment > aRemovedTree;
822 if (pNewElement->isValid())
824 AddNode * addNode = dynamic_cast< AddNode * >(&*it);
825 OSL_ENSURE(addNode != 0, "Unexpected type of element change");
826 if (addNode == 0) throw Exception("Unexpected type of element change");
828 aRemovedTree = addNode->getReplacedTree();
829 OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
830 OSL_ASSERT( addNode->isReplacing() == (bool) aRemovedTree.is() );
832 if (addNode->wasInserted())
833 { // it has been integrated into the master tree
834 OSL_ENSURE(getDataAccess()->getElement(aElementName) == addNode->getInsertedTree(),
835 "Internal Error: Inserted tree address does not match actual data");
837 // so add it
838 if (aOriginal.isValid())
839 SetNodeImpl::replaceElement(aElementName,*pNewElement);
841 else
842 SetNodeImpl::insertElement(aElementName,*pNewElement);
844 this->rebuildElement(aElementName,*pNewElement);
846 else // Change not done; need to restore new node (element will be released into the wild then)
848 rtl::Reference< data::TreeSegment > aAddedTree = addNode->getNewTree();
850 OSL_ENSURE(aAddedTree.is(), "Unexpected: added node is gone, but where ? May cause invalid references");
851 (*pNewElement)->takeTreeBack(aAddedTree);
852 detach(*pNewElement);
855 else
857 RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
858 OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
859 if (removeNode == 0) throw Exception("Unexpected type of element change");
861 aRemovedTree = removeNode->getRemovedTree();
863 OSL_ASSERT(aOriginal.isValid());
864 if (aRemovedTree.is() && getDataAccess()->getElement(aElementName) == 0)
866 // really removed - then remove the originel
867 if (aOriginal.isValid())
868 SetNodeImpl::removeElement(aElementName);
872 // handle a added or deleted node
873 if (aOriginal.isValid() && aRemovedTree.is())
875 aOriginal->takeTreeAndRebuild(aRemovedTree);
876 //aOriginal->getAccess().makeDirect();
877 OSL_DEBUG_ONLY(aRemovedTree.clear());
879 OSL_ENSURE(!aRemovedTree.is(), "Could not revert removed node: Nowhere to put ownership");
881 m_aChangedData.removeElement(aElementName);
883 else
885 // handle preexisting nodes
886 //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
887 OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
888 SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
889 OSL_ENSURE(subtreeChange != 0, "Unexpected set element change");
891 if (subtreeChange == 0) throw Exception("Unexpected set element change");
893 if (pOriginal && pOriginal->isValid())
894 view::ViewTreeAccess(pOriginal->get()).recoverFailedCommit(*subtreeChange);
897 m_bChanged = false;
898 m_bDefault = false;
900 OSL_ENSURE(m_aChangedData.isEmpty(), "ERROR: Uncommitted changes left in set node");
902 //-----------------------------------------------------------------------------
904 void DeferredSetNodeImpl::insertNewElement(rtl::OUString const& aName, ElementTreeData const& aNewElement)
906 attach(aNewElement,aName);
907 try
909 // put the new element into the changed set
910 ElementTreeData* pAddedElement = m_aChangedData.getElement(aName);
911 if (pAddedElement)
913 OSL_ENSURE(!pAddedElement->isValid(),"WARNING: Element being inserted was already there - replacing");
914 detach(m_aChangedData.replaceElement(aName,aNewElement));
916 else
918 m_aChangedData.insertElement(aName, aNewElement);
920 m_bChanged = true;
921 m_bDefault = false;
923 catch (std::exception&)
925 detach(aNewElement);
926 throw;
929 //-------------------------------------------------------------------------
931 void DeferredSetNodeImpl::removeOldElement(rtl::OUString const& aName)
933 // put an empty (dummy) element into the changed set
934 ElementTreeData* pAddedElement = m_aChangedData.getElement(aName);
935 if (pAddedElement)
937 OSL_ENSURE(pAddedElement->isValid(),"WARNING: Element being removed was already removed");
938 detach(m_aChangedData.replaceElement(aName, ElementTreeData()));
939 m_bChanged = true;
940 m_bDefault = false;
942 else
944 m_aChangedData.insertElement(aName, ElementTreeData());
947 // now check the original one
948 ElementTreeData* pOldElement = getStoredElement(aName);
949 if (pOldElement)
951 OSL_ASSERT(pOldElement->isValid());
952 detach(*pOldElement);
953 m_bChanged = true;
954 m_bDefault = false;
956 else // just clear things out
958 m_aChangedData.removeElement(aName);
961 OSL_ENSURE(pOldElement || pAddedElement,"WARNING: Element being removed was not found in set");
963 //-----------------------------------------------------------------------------
965 SetElementChangeImpl* DeferredSetNodeImpl::doAdjustChangedElement(NodeChangesInformation& rLocalChanges, rtl::OUString const& aName, Change const& aChange)
967 if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
969 if (ElementTreeData* pElement = getStoredElement(aName))
971 OSL_ASSERT(pElement->isValid());
973 if (SubtreeChange const * subtreeChange = dynamic_cast< SubtreeChange const * >(&aChange))
975 // recurse to element tree - but do not notify those changes (?)
976 Tree * elementTree = pElement->get();
978 NodeChangesInformation aIgnoredChanges;
979 view::getViewBehavior(elementTree)->adjustToChanges(aIgnoredChanges, view::getRootNode(elementTree), *subtreeChange);
981 else
983 OSL_ENSURE(dynamic_cast<ValueChange const * >(&aChange) != 0, "Unexpected kind of change to value set element" );
984 //OSL_ENSURE( containsValues(), "Unexpected kind of change: Value change applied to tree set element" );
988 else
990 // could be changed to do an insert instead (?)
991 OSL_ENSURE( false, "Changed Element didn't exist before it was removed/replaced" );
994 if (pLocalElement->isValid())
996 // we have a complete replacement for the changed node
997 ElementTreeData aLocalElement = *pLocalElement;
999 // also signal something happened
1000 return implCreateReplace(aName,aLocalElement,aLocalElement);
1002 else
1004 // already removed locally - should be notified by different route (if applicable)
1005 return NULL;
1008 else
1010 return SetNodeImpl::doAdjustChangedElement( rLocalChanges,aName,aChange);
1013 //-----------------------------------------------------------------------------
1015 SetElementChangeImpl* DeferredSetNodeImpl::doAdjustToAddedElement(rtl::OUString const& aName, AddNode const& aAddNodeChange, ElementTreeData const& aNewElement)
1017 m_bDefault = false;
1018 if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
1020 // We have another element replacing ours - what do we do ?
1021 if (hasStoredElement(aName))
1023 OSL_ENSURE( aAddNodeChange.isReplacing(), "Added Element already exists - replacing" );
1025 this->replaceElement(aName,aNewElement);
1027 else
1029 OSL_ENSURE( !aAddNodeChange.isReplacing(), "Replaced Element doesn't exist - simply adding" );
1030 this->insertElement(aName,aNewElement);
1034 if (pLocalElement->isValid()) // ours remains a valid replacement
1036 ElementTreeData aLocalElement = *pLocalElement;
1038 // just signal something happened
1039 return implCreateReplace(aName,aLocalElement,aLocalElement);
1041 else // had been removed locally
1043 // signal what happened
1044 return implCreateInsert(aName,aNewElement);
1047 else
1049 return SetNodeImpl::implAdjustToAddedElement(aName,aNewElement,aAddNodeChange.isReplacing());
1052 //-----------------------------------------------------------------------------
1054 SetElementChangeImpl* DeferredSetNodeImpl::doAdjustToRemovedElement(rtl::OUString const& aName, RemoveNode const& /*aRemoveNodeChange*/)
1056 m_bDefault = false;
1057 if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
1059 if (hasStoredElement(aName))
1061 // take away the original
1062 this->removeElement(aName);
1065 if (pLocalElement->isValid()) // remains a valid replacement
1067 ElementTreeData aLocalElement = *pLocalElement;
1069 // signal something happened
1070 return implCreateReplace(aName,aLocalElement,aLocalElement);
1072 else // already was removed locally
1074 return 0;
1077 else
1079 return SetNodeImpl::implAdjustToRemovedElement(aName);
1082 //-----------------------------------------------------------------------------
1084 void DeferredSetNodeImpl::doDifferenceToDefaultState(SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree)
1086 if (!m_bDefault)
1088 implDifferenceToDefaultState(_rChangeToDefault,_rDefaultTree);
1090 ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
1091 ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
1093 while(it != stop)
1095 rtl::OUString aName = it->first;
1096 ElementTreeData aElement = it->second;
1098 Change* pChange = _rChangeToDefault.getChange( aName );
1099 OSL_ENSURE(pChange == NULL || dynamic_cast< AddNode * >(pChange) != 0 || dynamic_cast< RemoveNode * >(pChange) != 0,
1100 "Unexpected change type found in difference to default tree");
1102 if (pChange == NULL)
1104 std::auto_ptr<INode> aDefaultNode = _rDefaultTree.removeChild(aName);
1105 OSL_ENSURE( aDefaultNode.get(), "Error: unused Default tree not found after SetNodeImpl::implDifferenceToDefaultState");
1107 rtl::OUString aElementTypeName = _rDefaultTree.getElementTemplateName();
1108 OSL_ENSURE( _rDefaultTree.isSetNode(), "Error: missing set template information in default data");
1110 rtl::Reference< data::TreeSegment > aDefaultTree = data::TreeSegment::create(aDefaultNode,aElementTypeName);
1111 OSL_ENSURE(aDefaultTree.is(), "Error: unused Default tree not accessible after SetNodeImpl::implDifferenceToDefaultState");
1113 AddNode* pAddIt = new AddNode(aDefaultTree, aName, true );
1115 std::auto_ptr<Change> pNewChange( pAddIt );
1117 if (aElement.isValid())
1119 OSL_ENSURE(!aElement.inDefault, "Default element replaced by default");
1120 pAddIt->setReplacing();
1123 _rChangeToDefault.addChange(pNewChange);
1126 else if (AddNode * addNode = dynamic_cast< AddNode * >(pChange))
1128 // adjust the AddNode - remove the original expected node
1129 addNode->clearReplacedTree();
1131 if (aElement.isValid())
1133 if (aElement.inDefault)
1135 // change already done locally
1136 _rChangeToDefault.removeChange(aName);
1138 else // adjust here
1139 addNode->setReplacing();
1142 else
1143 OSL_ENSURE(!addNode->isReplacing(),"Could not unmark the 'replacing' state of an AddNode");
1145 else if (RemoveNode * removeNode = dynamic_cast< RemoveNode * >(pChange))
1147 if (aElement.isValid())
1149 OSL_ENSURE(!aElement.inDefault, "Default element replaced by default");
1150 // adjust the RemoveNode - remove the original expected node
1151 removeNode->clearRemovedTree();
1153 else
1155 // change already done locally
1156 _rChangeToDefault.removeChange(aName);
1158 // TODO: mark local removal as to-default
1163 //-----------------------------------------------------------------------------