1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nodeimplobj.cxx,v $
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"
34 #include "nodeimplobj.hxx"
37 #include "nodechange.hxx"
38 #include "nodechangeinfo.hxx"
39 #include "nodechangeimpl.hxx"
40 #include "valuenode.hxx"
42 #include "viewaccess.hxx"
43 #include "viewfactory.hxx"
47 namespace configuration
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 // class DeferredValueElementNodeImpl
55 //-----------------------------------------------------------------------------
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
61 // class DeferredGroupNodeImpl
62 //-----------------------------------------------------------------------------
64 DeferredGroupNodeImpl::DeferredGroupNodeImpl(sharable::GroupNode
* const& _aNodeRef
)
65 : GroupNodeImpl(_aNodeRef
)
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())
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
91 // if not found continue with default
94 sharable::ValueNode
* original
= getOriginalValueNode(_aName
);
96 if (_bForUpdate
) // create a new change
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);
122 if (it
->second
->isChange())
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
)
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") ;
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
);
173 OSL_ENSURE(aName
.getLength() == 0, "ERROR: Found empty change reference");
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
);
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();
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();
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
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();
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
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();
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
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 //-----------------------------------------------------------------------------
343 //-----------------------------------------------------------------------------
346 //-----------------------------------------------------------------------------
347 // class DeferredTreeSetNodeImpl
348 //-----------------------------------------------------------------------------
350 DeferredSetNodeImpl::DeferredSetNodeImpl(sharable::SetNode
* const& _aNodeRef
, Template
* pTemplate
)
351 : SetNodeImpl(_aNodeRef
,pTemplate
)
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();
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();
378 if (!m_aChangedData
.hasElement(it
->first
)) return false;
383 //-----------------------------------------------------------------------------
385 ElementTree
* DeferredSetNodeImpl::doFindElement(rtl::OUString
const& aName
)
387 ElementTreeData
* pElement
= m_aChangedData
.getElement(aName
);
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
;
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
;
417 eRet
= aVisitor
.visit(SetEntry(it
->get()));
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();
437 ElementTreeData
const* pOriginal
= SetNodeImpl::getStoredElement(it
->first
);
439 if (it
->second
.isValid()) // added one
443 rChanges
.add(NodeChange(implCreateReplace(it
->first
,it
->second
,*pOriginal
)));
447 rChanges
.add(NodeChange(implCreateInsert(it
->first
,it
->second
)));
454 rChanges
.add(NodeChange(implCreateRemove(it
->first
,*pOriginal
)));
461 // collect preexisting nodes
462 // if (!containsValues()) // value elements ar immutable !
463 {for(ElementSet::Data::const_iterator it
= SetNodeImpl::beginElementSet(), stop
= SetNodeImpl::endElementSet();
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()
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();
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();
508 if (it
->second
.isValid())
509 rReplacement
.insertElement(it
->first
,it
->second
);
512 m_aChangedData
.removeElement(it
->first
);
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();
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();
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
);
597 pAddNode
->setReplacing();
599 pSetChange
->addChange(pNewChange
);
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
);
614 // collect removed or replaced element
616 _rRemovedElements
.push_back( pOriginal
->tree
);
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();
637 rtl::OUString
aElementName(it
->getNodeName());
639 ElementTreeData
* pOriginal
= getStoredElement(aElementName
);
641 if (ElementTreeData
* pNewElement
= m_aChangedData
.getElement(aElementName
))
643 ElementTreeData aOriginal
;
646 aOriginal
= *pOriginal
;
647 OSL_ASSERT(aOriginal
.isValid());
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
);
669 SetNodeImpl::insertElement(aElementName
,*pNewElement
);
671 this->rebuildElement(aElementName
,*pNewElement
);
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
);
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
);
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();
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");
752 (*pNewElement
)->takeTreeBack(aAddedTree
);
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
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");
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();
804 rtl::OUString
aElementName(it
->getNodeName());
806 ElementTreeData
* pOriginal
= getStoredElement(aElementName
);
808 if (ElementTreeData
* pNewElement
= m_aChangedData
.getElement(aElementName
))
810 ElementTreeData aOriginal
;
813 aOriginal
= *pOriginal
;
814 OSL_ASSERT(aOriginal
.isValid());
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");
838 if (aOriginal
.isValid())
839 SetNodeImpl::replaceElement(aElementName
,*pNewElement
);
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
);
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
);
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
);
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
);
909 // put the new element into the changed set
910 ElementTreeData
* pAddedElement
= m_aChangedData
.getElement(aName
);
913 OSL_ENSURE(!pAddedElement
->isValid(),"WARNING: Element being inserted was already there - replacing");
914 detach(m_aChangedData
.replaceElement(aName
,aNewElement
));
918 m_aChangedData
.insertElement(aName
, aNewElement
);
923 catch (std::exception
&)
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
);
937 OSL_ENSURE(pAddedElement
->isValid(),"WARNING: Element being removed was already removed");
938 detach(m_aChangedData
.replaceElement(aName
, ElementTreeData()));
944 m_aChangedData
.insertElement(aName
, ElementTreeData());
947 // now check the original one
948 ElementTreeData
* pOldElement
= getStoredElement(aName
);
951 OSL_ASSERT(pOldElement
->isValid());
952 detach(*pOldElement
);
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
);
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" );
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
);
1004 // already removed locally - should be notified by different route (if applicable)
1010 return SetNodeImpl::doAdjustChangedElement( rLocalChanges
,aName
,aChange
);
1013 //-----------------------------------------------------------------------------
1015 SetElementChangeImpl
* DeferredSetNodeImpl::doAdjustToAddedElement(rtl::OUString
const& aName
, AddNode
const& aAddNodeChange
, ElementTreeData
const& aNewElement
)
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
);
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
);
1049 return SetNodeImpl::implAdjustToAddedElement(aName
,aNewElement
,aAddNodeChange
.isReplacing());
1052 //-----------------------------------------------------------------------------
1054 SetElementChangeImpl
* DeferredSetNodeImpl::doAdjustToRemovedElement(rtl::OUString
const& aName
, RemoveNode
const& /*aRemoveNodeChange*/)
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
1079 return SetNodeImpl::implAdjustToRemovedElement(aName
);
1082 //-----------------------------------------------------------------------------
1084 void DeferredSetNodeImpl::doDifferenceToDefaultState(SubtreeChange
& _rChangeToDefault
, ISubtree
& _rDefaultTree
)
1088 implDifferenceToDefaultState(_rChangeToDefault
,_rDefaultTree
);
1090 ElementSet::Data::const_iterator it
= m_aChangedData
.beginNative();
1091 ElementSet::Data::const_iterator
const stop
= m_aChangedData
.endNative();
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
);
1139 addNode
->setReplacing();
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();
1155 // change already done locally
1156 _rChangeToDefault
.removeChange(aName
);
1158 // TODO: mark local removal as to-default
1163 //-----------------------------------------------------------------------------