diff options
author | Jörg Barfurth <jb@openoffice.org> | 2001-02-13 16:20:54 +0000 |
---|---|---|
committer | Jörg Barfurth <jb@openoffice.org> | 2001-02-13 16:20:54 +0000 |
commit | 60445aa07009ac5c7c522a41c9610bcd78d8e73d (patch) | |
tree | 13857c9f4b2227932ea4c81afc8505714193aa2e /configmgr/source/treemgr/nodeimpl.cxx | |
parent | 43f4ea27c39bd97dc2454b0fae7fa68bf04f8c07 (diff) |
Set element initialization is now deferred; External changes are intergrated as NodeChangeInformation
Diffstat (limited to 'configmgr/source/treemgr/nodeimpl.cxx')
-rw-r--r-- | configmgr/source/treemgr/nodeimpl.cxx | 286 |
1 files changed, 248 insertions, 38 deletions
diff --git a/configmgr/source/treemgr/nodeimpl.cxx b/configmgr/source/treemgr/nodeimpl.cxx index 82cc2f3b59..eeaa83fdbc 100644 --- a/configmgr/source/treemgr/nodeimpl.cxx +++ b/configmgr/source/treemgr/nodeimpl.cxx @@ -2,9 +2,9 @@ * * $RCSfile: nodeimpl.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: jb $ $Date: 2000-12-07 14:48:18 $ + * last change: $Author: jb $ $Date: 2001-02-13 17:20:54 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -64,7 +64,9 @@ #include "treeimpl.hxx" #include "nodechange.hxx" #include "nodechangeimpl.hxx" +#include "nodechangeinfo.hxx" #include "change.hxx" +#include "collectchanges.hxx" #include "cmtreemodel.hxx" @@ -107,6 +109,17 @@ void NodeImpl::makeIndirect(NodeImplHolder& aThis,bool bIndirect) } } +// helper for derived classes +//----------------------------------------------------------------------------- + +void NodeImpl::addLocalChangeHelper( NodeChangesInformation& rLocalChanges_, NodeChange const& aChange_) +{ + NodeChangeInformation aThisInfo; + if (aChange_.getChangeInfo(aThisInfo)) + rLocalChanges_.push_back( aThisInfo ); +} + + // Specific types of nodes //----------------------------------------------------------------------------- @@ -126,25 +139,25 @@ GroupNodeImpl::GroupNodeImpl(GroupNodeImpl& rOriginal) } //----------------------------------------------------------------------------- -NodeType::Enum GroupNodeImpl::getType() const +NodeType::Enum GroupNodeImpl::doGetType() const { return NodeType::eGROUP; } //----------------------------------------------------------------------------- -void GroupNodeImpl::getNodeInfo(NodeInfo& rInfo) const +void GroupNodeImpl::doGetNodeInfo(NodeInfo& rInfo) const { fetchInfo(rInfo,m_rOriginal); } //----------------------------------------------------------------------------- -void GroupNodeImpl::setNodeName(Name const& aName) +void GroupNodeImpl::doSetNodeName(Name const& aName) { m_rOriginal.setName(aName.toString()); } //----------------------------------------------------------------------------- -void GroupNodeImpl::dispatch(INodeHandler& rHandler) +void GroupNodeImpl::doDispatch(INodeHandler& rHandler) { rHandler.handle(*this); } @@ -159,8 +172,30 @@ SetEntry::SetEntry(ElementTreeImpl* pTree_) OSL_ENSURE(pTree_ == 0 || pTree_->isValidNode(pTree_->root()), "INTERNAL ERROR: Invalid empty tree used for SetEntry "); } + +//----------------------------------------------------------------------------- +// struct SetNodeImpl::InitHelper //----------------------------------------------------------------------------- +struct SetNodeImpl::InitHelper +{ + TemplateProvider aTemplateProvider; + TreeDepth nLoadDepth; + + InitHelper() + : aTemplateProvider() + , nLoadDepth(0) + { + } + + InitHelper(TemplateProvider const& aTP_, TreeDepth nDepth_) + : aTemplateProvider(aTP_) + , nLoadDepth(nDepth_) + { + OSL_ASSERT(nDepth_ > 0 || !aTP_.isValid()); + } +}; + //----------------------------------------------------------------------------- // class SetNodeImpl //----------------------------------------------------------------------------- @@ -170,6 +205,7 @@ SetNodeImpl::SetNodeImpl(ISubtree& rOriginal,Template* pTemplate) ,m_aTemplate(pTemplate) ,m_pParentTree(0) ,m_nContextPos(0) +,m_pInit(new InitHelper()) { } //----------------------------------------------------------------------------- @@ -179,11 +215,18 @@ SetNodeImpl::SetNodeImpl(SetNodeImpl& rOriginal) ,m_aTemplate(rOriginal.m_aTemplate) ,m_pParentTree(rOriginal.m_pParentTree) ,m_nContextPos(rOriginal.m_nContextPos) +,m_pInit(rOriginal.m_pInit) { // unbind the original rOriginal.m_aTemplate.unbind(); rOriginal.m_pParentTree = 0; rOriginal.m_nContextPos = 0; + +} +//----------------------------------------------------------------------------- + +SetNodeImpl::~SetNodeImpl() +{ } //----------------------------------------------------------------------------- @@ -201,32 +244,121 @@ NodeOffset SetNodeImpl::getContextOffset() const } //----------------------------------------------------------------------------- -void SetNodeImpl::getNodeInfo(NodeInfo& rInfo) const +bool SetNodeImpl::isEmpty() +{ + return !implLoadElements() || doIsEmpty(); +} +//----------------------------------------------------------------------------- + +SetEntry SetNodeImpl::findElement(Name const& aName) +{ + implEnsureElementsLoaded(); + return doFindElement(aName); +}; +//----------------------------------------------------------------------------- + +SetEntry SetNodeImpl::findAvailableElement(Name const& aName) +{ + if (implLoadElements()) + return doFindElement(aName); + else + return SetEntry(0); +}; +//----------------------------------------------------------------------------- + +void SetNodeImpl::insertElement(Name const& aName, SetEntry const& aNewEntry) +{ + // cannot insert, if we cannot check for collisions + implEnsureElementsLoaded(); + doInsertElement(aName,aNewEntry); +} +//----------------------------------------------------------------------------- + +void SetNodeImpl::removeElement(Name const& aName) +{ + // cannot remove, if we cannot check for existance + implEnsureElementsLoaded(); + doRemoveElement(aName); +} +//----------------------------------------------------------------------------- + +SetNodeVisitor::Result SetNodeImpl::dispatchToElements(SetNodeVisitor& aVisitor) +{ + if (implLoadElements()) + return doDispatchToElements(aVisitor); + + else + return SetNodeVisitor::CONTINUE; +} +//----------------------------------------------------------------------------- + +void SetNodeImpl::doGetNodeInfo(NodeInfo& rInfo) const { fetchInfo(rInfo,m_rOriginal); } //----------------------------------------------------------------------------- -void SetNodeImpl::setNodeName(Name const& aName) +void SetNodeImpl::doSetNodeName(Name const& aName) { m_rOriginal.setName(aName.toString()); } -//----------------------------------------------------------------------------- -NodeType::Enum SetNodeImpl::getType() const +//----------------------------------------------------------------------------- +NodeType::Enum SetNodeImpl::doGetType() const { return NodeType::eSET; } //----------------------------------------------------------------------------- - -void SetNodeImpl::dispatch(INodeHandler& rHandler) +void SetNodeImpl::doDispatch(INodeHandler& rHandler) { rHandler.handle(*this); } //----------------------------------------------------------------------------- +bool SetNodeImpl::implHasLoadedElements() const +{ + return m_pInit.get() == 0; // cannot check whether init was called though ... +} + +//----------------------------------------------------------------------------- +bool SetNodeImpl::implLoadElements() +{ + if (m_pInit.get() != 0 && m_pInit->nLoadDepth > 0) + { + implInitElements(*m_pInit); + m_pInit.reset(); + } + OSL_ASSERT(implHasLoadedElements() || m_pInit->nLoadDepth == 0); + + return m_pInit.get() == 0; +} + +//----------------------------------------------------------------------------- +void SetNodeImpl::implEnsureElementsLoaded() +{ + if (!implLoadElements()) + throw ConstraintViolation("Trying to access set elements beyond the loaded nestíng level"); +} + +//----------------------------------------------------------------------------- +bool SetNodeImpl::implInitElements(InitHelper const& aInit) +{ + TreeDepth nDepth = aInit.nLoadDepth; + if (nDepth > 0) + { + OSL_ENSURE(m_aTemplate.isEmpty() || m_aTemplate->isInstanceTypeKnown(),"ERROR: Need a type-validated template to fill a set"); + OSL_ENSURE(aInit.aTemplateProvider.isValid() || m_aTemplate->isInstanceValue(), "ERROR: Need a template provider to fill a non-primitive set"); + + doInitElements(aInit.aTemplateProvider,m_rOriginal,childDepth(nDepth)); + return true; + } + else + return false; +} + +//----------------------------------------------------------------------------- void SetNodeImpl::initElements(TemplateProvider const& aTemplateProvider,TreeImpl& rParentTree,NodeOffset nPos,TreeDepth nDepth) { OSL_ENSURE(m_pParentTree == 0 || m_pParentTree == &rParentTree, "WARNING: Set Node: Changing parent"); @@ -234,13 +366,11 @@ void SetNodeImpl::initElements(TemplateProvider const& aTemplateProvider,TreeImp m_pParentTree = &rParentTree; m_nContextPos = nPos; + OSL_ENSURE(!implHasLoadedElements(),"ERROR: Reinitializing set"); //doClearElements(); OSL_ASSERT(doIsEmpty()); //doClearElements(); - if (nDepth > 0) - { - OSL_ENSURE(m_aTemplate.isEmpty() || m_aTemplate->isInstanceTypeKnown(),"ERROR: Need a type-validated template to fill a set"); - doInitElements(aTemplateProvider,m_rOriginal,childDepth(nDepth)); - } + if (nDepth > 0) + m_pInit.reset( new InitHelper(aTemplateProvider,nDepth) ); } //----------------------------------------------------------------------------- @@ -301,26 +431,26 @@ void ValueNodeImpl::setDefault() } //----------------------------------------------------------------------------- -void ValueNodeImpl::getNodeInfo(NodeInfo& rInfo) const +void ValueNodeImpl::doGetNodeInfo(NodeInfo& rInfo) const { fetchInfo(rInfo,m_rOriginal); rInfo.aAttributes.bDefaultable = m_rOriginal.hasDefault(); } //----------------------------------------------------------------------------- -void ValueNodeImpl::setNodeName(Name const& aName) +void ValueNodeImpl::doSetNodeName(Name const& aName) { m_rOriginal.setName(aName.toString()); } //----------------------------------------------------------------------------- -NodeType::Enum ValueNodeImpl::getType() const +NodeType::Enum ValueNodeImpl::doGetType() const { return NodeType::eVALUE; } //----------------------------------------------------------------------------- -void ValueNodeImpl::dispatch(INodeHandler& rHandler) +void ValueNodeImpl::doDispatch(INodeHandler& rHandler) { rHandler.handle(*this); } @@ -330,14 +460,53 @@ void ValueNodeImpl::dispatch(INodeHandler& rHandler) // legacy commit //----------------------------------------------------------------------------- -std::auto_ptr<SubtreeChange> SetNodeImpl::preCommitChanges() +std::auto_ptr<SubtreeChange> SetNodeImpl::preCommitChanges() +{ + // cannot have changes if elements not yet loaded + if (implHasLoadedElements()) + { + return doPreCommitChanges(); + } + else + { + OSL_ENSURE(!hasChanges(),"ERROR: Cannot have changes if elements haven't been loaded yet"); + return std::auto_ptr<SubtreeChange>(); + } +} +//----------------------------------------------------------------------------- + +void SetNodeImpl::finishCommit(SubtreeChange& rChanges) +{ + // cannot have changes if elements not yet loaded + OSL_ENSURE(implHasLoadedElements(),"ERROR: Cannot have provided changes to be finished - set not yet loaded"); + doFinishCommit(rChanges); +} +//----------------------------------------------------------------------------- + +void SetNodeImpl::revertCommit(SubtreeChange& rChanges) +{ + // cannot have changes if elements not yet loaded + OSL_ENSURE(implHasLoadedElements(),"ERROR: Cannot have provided changes to be reverted - set not yet loaded"); + doRevertCommit(rChanges); +} +//----------------------------------------------------------------------------- + +void SetNodeImpl::failedCommit(SubtreeChange& rChanges) +{ + // cannot have changes if elements not yet loaded + OSL_ENSURE(implHasLoadedElements(),"ERROR: Cannot have provided changes that failed - set not yet loaded"); + doFailedCommit(rChanges); +} +//----------------------------------------------------------------------------- + +std::auto_ptr<SubtreeChange> SetNodeImpl::doPreCommitChanges() { OSL_ENSURE(!hasChanges(),"ERROR: Committing to an old changes tree is not supported on this node"); return std::auto_ptr<SubtreeChange>(); } //----------------------------------------------------------------------------- -void SetNodeImpl::finishCommit(SubtreeChange& rChange) +void SetNodeImpl::doFinishCommit(SubtreeChange& rChange) { OSL_ENSURE(rChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); OSL_ENSURE( rChange.getChildTemplateName() == getElementTemplate()->getPath().toString(), @@ -347,7 +516,7 @@ void SetNodeImpl::finishCommit(SubtreeChange& rChange) } //----------------------------------------------------------------------------- -void SetNodeImpl::revertCommit(SubtreeChange& rChange) +void SetNodeImpl::doRevertCommit(SubtreeChange& rChange) { OSL_ENSURE(rChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); OSL_ENSURE( rChange.getChildTemplateName() == getElementTemplate()->getPath().toString(), @@ -357,7 +526,7 @@ void SetNodeImpl::revertCommit(SubtreeChange& rChange) } //----------------------------------------------------------------------------- -void SetNodeImpl::failedCommit(SubtreeChange& rChange) +void SetNodeImpl::doFailedCommit(SubtreeChange& rChange) { OSL_ENSURE(rChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); OSL_ENSURE( rChange.getChildTemplateName() == getElementTemplate()->getPath().toString(), @@ -376,40 +545,76 @@ void SetNodeImpl::doCollectChangesWithTarget(NodeChanges& rChanges, TreeImpl* pP } //----------------------------------------------------------------------------- -void SetNodeImpl::adjustToChanges(NodeChanges& rLocalChanges, SubtreeChange const& rExternalChange, TemplateProvider const& aTemplateProvider, TreeDepth nDepth) +void SetNodeImpl::adjustToChanges(NodeChangesInformation& rLocalChanges, SubtreeChange const& rExternalChange, TemplateProvider const& aTemplateProvider, TreeDepth nDepth) { if (nDepth > 0) { OSL_ASSERT( aTemplateProvider.isValid() ); + + if (implHasLoadedElements()) + { + doAdjustToChanges(rLocalChanges, rExternalChange, aTemplateProvider, childDepth(nDepth)); + } + else + { + OSL_ENSURE( !hasChanges(),"Cannot have changes to consider when no elements are loaded"); - doAdjustToChanges(rLocalChanges, rExternalChange, aTemplateProvider, childDepth(nDepth)); + implCollectChanges( rLocalChanges, rExternalChange, nDepth); + } } } //----------------------------------------------------------------------------- +void SetNodeImpl::implCollectChanges(NodeChangesInformation& rLocalChanges, SubtreeChange const& rExternalChange, + TreeDepth nDepth) +{ + OSL_ASSERT(nDepth > 0); + + if (TreeImpl* pParentTree = this->getParentTree()) + { + NodeOffset nNode = getContextOffset(); + + OSL_ENSURE(pParentTree->isValidNode(nNode), "Invalid context node in Set"); + OSL_ENSURE(&pParentTree->node(nNode)->setImpl() == this, "Wrong context node in Set"); + + CollectChanges aCollector(rLocalChanges, *pParentTree, nNode, nDepth); + + aCollector.collectFrom(rExternalChange); + } + else + OSL_ENSURE(false, "Missing context tree in Set"); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +std::auto_ptr<SubtreeChange> GroupNodeImpl::preCommitChanges() +{ + return doPreCommitChanges(); +} //----------------------------------------------------------------------------- -std::auto_ptr<SubtreeChange> GroupNodeImpl::preCommitChanges() + +std::auto_ptr<SubtreeChange> GroupNodeImpl::doPreCommitChanges() { OSL_ENSURE(!hasChanges(),"ERROR: Committing to an old changes tree is not supported on this node"); return std::auto_ptr<SubtreeChange>(); } //----------------------------------------------------------------------------- -void GroupNodeImpl::finishCommit(SubtreeChange& rChange) +void GroupNodeImpl::doFinishCommit(SubtreeChange& rChange) { OSL_ENSURE(!rChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes are lost"); } //----------------------------------------------------------------------------- -void GroupNodeImpl::revertCommit(SubtreeChange& rChange) +void GroupNodeImpl::doRevertCommit(SubtreeChange& rChange) { OSL_ENSURE(!rChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes not restored"); } //----------------------------------------------------------------------------- -void GroupNodeImpl::failedCommit(SubtreeChange& rChange) +void GroupNodeImpl::doFailedCommit(SubtreeChange& rChange) { OSL_ENSURE(!rChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes not recovered"); @@ -423,26 +628,32 @@ void GroupNodeImpl::doCollectChangesWithTarget(NodeChanges& , TreeImpl* , NodeOf //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -std::auto_ptr<ValueChange> ValueNodeImpl::preCommitChange() +std::auto_ptr<ValueChange> ValueNodeImpl::preCommitChange() +{ + return doPreCommitChange(); +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ValueChange> ValueNodeImpl::doPreCommitChange() { OSL_ENSURE(!hasChanges(),"ERROR: Committing to an old changes tree is not supported on this node"); return std::auto_ptr<ValueChange>(); } //----------------------------------------------------------------------------- -void ValueNodeImpl::finishCommit(ValueChange& ) +void ValueNodeImpl::doFinishCommit(ValueChange& ) { OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes are lost"); } //----------------------------------------------------------------------------- -void ValueNodeImpl::revertCommit(ValueChange& ) +void ValueNodeImpl::doRevertCommit(ValueChange& ) { OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes not restored"); } //----------------------------------------------------------------------------- -void ValueNodeImpl::failedCommit(ValueChange& ) +void ValueNodeImpl::doFailedCommit(ValueChange& ) { OSL_ENSURE(!hasChanges(),"ERROR: Old-style commit not supported: changes not recovered"); } @@ -467,13 +678,12 @@ NodeChangeImpl* ValueNodeImpl::doCollectChange() const //----------------------------------------------------------------------------- -void ValueNodeImpl::adjustToChange(NodeChanges& rLocalChanges, ValueChange const& rExternalChange, TreeImpl& rParentTree, NodeOffset nPos) +void ValueNodeImpl::adjustToChange(NodeChangesInformation& rLocalChanges, ValueChange const& rExternalChange, TreeImpl& rParentTree, NodeOffset nPos) { if (NodeChangeImpl* pThisChange = doAdjustToChange(rExternalChange)) { pThisChange->setTarget(&rParentTree,nPos); - - rLocalChanges.add( NodeChange(pThisChange) ); + addLocalChangeHelper(rLocalChanges, NodeChange(pThisChange)); } else OSL_TRACE("WARNING: Configuration: derived class hides an external value change from listeners"); |