summaryrefslogtreecommitdiff
path: root/configmgr/source/treemgr/nodeimpl.cxx
diff options
context:
space:
mode:
authorJörg Barfurth <jb@openoffice.org>2001-02-13 16:20:54 +0000
committerJörg Barfurth <jb@openoffice.org>2001-02-13 16:20:54 +0000
commit60445aa07009ac5c7c522a41c9610bcd78d8e73d (patch)
tree13857c9f4b2227932ea4c81afc8505714193aa2e /configmgr/source/treemgr/nodeimpl.cxx
parent43f4ea27c39bd97dc2454b0fae7fa68bf04f8c07 (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.cxx286
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");