mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0030773: Application Framework - To allow to inherit existing attributes to reuse persistence mechanisms
Added possibility to inherit existing attributes if the same persistent fields are used. All methods that allow controlling the data model changes or getting some callbacks may be overridden in successor. They may have same GUIDs as a base class or new ones. Special macros IMPLEMENT_DERIVED_ATTRIBUTE and IMPLEMENT_DERIVED_ATTRIBUTE_WITH_TYPE must be used instead of standard Handle macro definition IMPLEMENT_STANDARD_RTTIEXT to register new derived attributes. Using this improvement several existing attributes from TDataStd, TDataXtd and XCAFDoc packages become inherited from other base attribute-classes. XML and Bin drivers of these attributes are removed. New base attribute classes are added: TDataStd_GenericEmpty and TDataStd_GenericExtString. This improvement does not change both present formats Bin and XML documents. The obsolete Standard scheme is not changed at all.
This commit is contained in:
@@ -12,3 +12,5 @@ XmlMDF_ReferenceDriver.hxx
|
||||
XmlMDF_TagSourceDriver.cxx
|
||||
XmlMDF_TagSourceDriver.hxx
|
||||
XmlMDF_TypeADriverMap.hxx
|
||||
XmlMDF_DerivedDriver.cxx
|
||||
XmlMDF_DerivedDriver.hxx
|
||||
|
@@ -86,9 +86,6 @@ Standard_Integer XmlMDF::WriteSubTree
|
||||
// create element "label"
|
||||
XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
|
||||
|
||||
// Extraction of the driver subset.
|
||||
const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
|
||||
|
||||
// write attributes
|
||||
Standard_Integer count = 0;
|
||||
TDF_AttributeIterator itr1 (theLabel);
|
||||
@@ -96,9 +93,9 @@ Standard_Integer XmlMDF::WriteSubTree
|
||||
{
|
||||
const Handle(TDF_Attribute)& tAtt = itr1.Value();
|
||||
const Handle(Standard_Type)& aType = tAtt->DynamicType();
|
||||
if (aDriverMap.IsBound (aType))
|
||||
Handle(XmlMDF_ADriver) aDriver;
|
||||
if (theDrivers->GetDriver(aType, aDriver))
|
||||
{
|
||||
const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
|
||||
count++;
|
||||
|
||||
// Add source to relocation table
|
||||
@@ -165,7 +162,7 @@ Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
|
||||
{
|
||||
TDF_Label aRootLab = theData->Root();
|
||||
XmlMDF_MapOfDriver aDriverMap;
|
||||
CreateDrvMap (theDrivers, aDriverMap);
|
||||
theDrivers->CreateDrvMap (aDriverMap);
|
||||
|
||||
Standard_Integer count = 0;
|
||||
|
||||
@@ -340,26 +337,3 @@ void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
|
||||
aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
|
||||
aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CreateDrvMap
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
|
||||
XmlMDF_MapOfDriver& theAsciiDriverMap)
|
||||
{
|
||||
const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
|
||||
XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
|
||||
while (anIter.More()) {
|
||||
const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
|
||||
const TCollection_AsciiString aTypeName = aDriver -> TypeName();
|
||||
if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
|
||||
theAsciiDriverMap.Bind (aTypeName, aDriver);
|
||||
else
|
||||
aDriver -> myMessageDriver->Send
|
||||
(TCollection_ExtendedString ("Warning: skipped driver name: \"")
|
||||
+ aTypeName + '\"', Message_Warning);
|
||||
anIter.Next();
|
||||
}
|
||||
}
|
||||
|
@@ -31,7 +31,8 @@ IMPLEMENT_STANDARD_RTTIEXT(XmlMDF_ADriver,Standard_Transient)
|
||||
XmlMDF_ADriver::XmlMDF_ADriver (const Handle(Message_Messenger)& theMsgDriver,
|
||||
const Standard_CString theNS,
|
||||
const Standard_CString theName)
|
||||
: myMessageDriver (theMsgDriver)
|
||||
: myNamespace(theNS == NULL ? "" : theNS),
|
||||
myMessageDriver (theMsgDriver)
|
||||
{
|
||||
if (theNS != NULL)
|
||||
if (theNS[0] != '\0') {
|
||||
@@ -73,4 +74,4 @@ const TCollection_AsciiString& XmlMDF_ADriver::TypeName () const
|
||||
if (myTypeName.Length() == 0 || aString [myTypeName.Length() - 1] == ':')
|
||||
(TCollection_AsciiString&)myTypeName += SourceType() -> Name();
|
||||
return myTypeName;
|
||||
}
|
||||
}
|
||||
|
@@ -53,11 +53,14 @@ public:
|
||||
|
||||
//! Returns the type of source object,
|
||||
//! inheriting from Attribute from TDF.
|
||||
Standard_EXPORT Handle(Standard_Type) SourceType() const;
|
||||
Standard_EXPORT virtual Handle(Standard_Type) SourceType() const;
|
||||
|
||||
//! Returns the full XML tag name (including NS prefix)
|
||||
Standard_EXPORT const TCollection_AsciiString& TypeName() const;
|
||||
|
||||
|
||||
//! Returns the namespace string
|
||||
const TCollection_AsciiString& Namespace() const { return myNamespace; }
|
||||
|
||||
//! Translate the contents of <aSource> and put it
|
||||
//! into <aTarget>, using the relocation table
|
||||
//! <aRelocTable> to keep the sharings.
|
||||
@@ -68,6 +71,9 @@ public:
|
||||
//! <aRelocTable> to keep the sharings.
|
||||
Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& aSource, XmlObjMgt_Persistent& aTarget, XmlObjMgt_SRelocationTable& aRelocTable) const = 0;
|
||||
|
||||
//! Returns the current message driver of this driver
|
||||
const Handle(Message_Messenger)& MessageDriver() const { return myMessageDriver; }
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(XmlMDF_ADriver,Standard_Transient)
|
||||
|
||||
protected:
|
||||
@@ -75,7 +81,7 @@ protected:
|
||||
Standard_EXPORT XmlMDF_ADriver(const Handle(Message_Messenger)& theMessageDriver, const Standard_CString theNamespace, const Standard_CString theName = NULL);
|
||||
|
||||
TCollection_AsciiString myTypeName;
|
||||
|
||||
TCollection_AsciiString myNamespace;
|
||||
Handle(Message_Messenger) myMessageDriver;
|
||||
|
||||
private:
|
||||
|
@@ -13,11 +13,14 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <Standard_Type.hxx>
|
||||
#include <XmlMDF_ADriver.hxx>
|
||||
#include <XmlMDF_ADriverTable.hxx>
|
||||
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <TDF_DerivedAttribute.hxx>
|
||||
#include <TDF_AttributeList.hxx>
|
||||
#include <XmlMDF_ADriver.hxx>
|
||||
#include <XmlMDF_DerivedDriver.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(XmlMDF_ADriverTable,Standard_Transient)
|
||||
|
||||
//=======================================================================
|
||||
@@ -42,12 +45,39 @@ void XmlMDF_ADriverTable::AddDriver (const Handle(XmlMDF_ADriver)& anHDriver)
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetDrivers
|
||||
//purpose :
|
||||
//function : AddDerivedDriver
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
const XmlMDF_TypeADriverMap& XmlMDF_ADriverTable::GetDrivers() const
|
||||
void XmlMDF_ADriverTable::AddDerivedDriver (const Handle(TDF_Attribute)& theInstance)
|
||||
{
|
||||
return myMap;
|
||||
const Handle(Standard_Type)& anInstanceType = theInstance->DynamicType();
|
||||
if (!myMap.IsBound (anInstanceType)) // no direct driver, use a derived one
|
||||
{
|
||||
for (Handle(Standard_Type) aType = anInstanceType->Parent(); !aType.IsNull(); aType = aType->Parent())
|
||||
{
|
||||
if (myMap.IsBound (aType))
|
||||
{
|
||||
Handle(XmlMDF_ADriver) aDriver = new XmlMDF_DerivedDriver (theInstance, myMap (aType));
|
||||
myMap.Bind (anInstanceType, aDriver);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddDerivedDriver
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
const Handle(Standard_Type)& XmlMDF_ADriverTable::AddDerivedDriver (Standard_CString theDerivedType)
|
||||
{
|
||||
if (Handle(TDF_Attribute) anInstance = TDF_DerivedAttribute::Attribute (theDerivedType))
|
||||
{
|
||||
AddDerivedDriver (anInstance);
|
||||
return anInstance->DynamicType();
|
||||
}
|
||||
static const Handle(Standard_Type) aNullType;
|
||||
return aNullType;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -56,8 +86,12 @@ const XmlMDF_TypeADriverMap& XmlMDF_ADriverTable::GetDrivers() const
|
||||
//=======================================================================
|
||||
Standard_Boolean XmlMDF_ADriverTable::GetDriver
|
||||
(const Handle(Standard_Type)& aType,
|
||||
Handle(XmlMDF_ADriver)& anHDriver) const
|
||||
Handle(XmlMDF_ADriver)& anHDriver)
|
||||
{
|
||||
if (!myMap.IsBound (aType)) // try to assign driver for derived type
|
||||
{
|
||||
AddDerivedDriver (aType->Name());
|
||||
}
|
||||
if (myMap.IsBound(aType))
|
||||
{
|
||||
anHDriver = myMap.Find(aType);
|
||||
@@ -65,3 +99,37 @@ Standard_Boolean XmlMDF_ADriverTable::GetDriver
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CreateDrvMap
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void XmlMDF_ADriverTable::CreateDrvMap (XmlMDF_MapOfDriver& theDriverMap)
|
||||
{
|
||||
// add derived drivers not yet registered in the map
|
||||
TDF_AttributeList aDerived;
|
||||
TDF_DerivedAttribute::Attributes (aDerived);
|
||||
for (TDF_AttributeList::Iterator aDerIter (aDerived); aDerIter.More(); aDerIter.Next())
|
||||
{
|
||||
if (!myMap.IsBound (aDerIter.Value()->DynamicType()))
|
||||
{
|
||||
AddDerivedDriver (aDerIter.Value());
|
||||
}
|
||||
}
|
||||
|
||||
// put everything to the map
|
||||
for (XmlMDF_DataMapIteratorOfTypeADriverMap anIter (myMap); anIter.More(); anIter.Next())
|
||||
{
|
||||
const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
|
||||
const TCollection_AsciiString aTypeName = aDriver->TypeName();
|
||||
if (!theDriverMap.IsBound (aTypeName))
|
||||
{
|
||||
theDriverMap.Bind (aTypeName, aDriver);
|
||||
}
|
||||
else
|
||||
{
|
||||
aDriver->MessageDriver()->Send (TCollection_AsciiString ("Warning: skipped driver name: \"")
|
||||
+ aTypeName + "\"", Message_Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <XmlMDF_MapOfDriver.hxx>
|
||||
class XmlMDF_ADriver;
|
||||
|
||||
|
||||
@@ -45,16 +46,23 @@ public:
|
||||
|
||||
//! Sets a translation driver: <aDriver>.
|
||||
Standard_EXPORT void AddDriver (const Handle(XmlMDF_ADriver)& anHDriver);
|
||||
|
||||
//! Gets a map of drivers.
|
||||
Standard_EXPORT const XmlMDF_TypeADriverMap& GetDrivers() const;
|
||||
|
||||
|
||||
//! Adds a translation driver for the derived attribute. The base driver must be already added.
|
||||
//! @param theInstance is newly created attribute, detached from any label
|
||||
Standard_EXPORT void AddDerivedDriver (const Handle(TDF_Attribute)& theInstance);
|
||||
|
||||
//! Adds a translation driver for the derived attribute. The base driver must be already added.
|
||||
//! @param theDerivedType is registered attribute type using IMPLEMENT_DERIVED_ATTRIBUTE macro
|
||||
Standard_EXPORT const Handle(Standard_Type)& AddDerivedDriver (Standard_CString theDerivedType);
|
||||
|
||||
//! Fills the map by all registered drivers.
|
||||
Standard_EXPORT void CreateDrvMap (XmlMDF_MapOfDriver& theDriverMap);
|
||||
|
||||
//! Gets a driver <aDriver> according to <aType>
|
||||
//!
|
||||
//! Returns True if a driver is found; false otherwise.
|
||||
Standard_EXPORT Standard_Boolean GetDriver (const Handle(Standard_Type)& aType, Handle(XmlMDF_ADriver)& anHDriver) const;
|
||||
|
||||
|
||||
Standard_EXPORT Standard_Boolean GetDriver (const Handle(Standard_Type)& theType,
|
||||
Handle(XmlMDF_ADriver)& theDriver);
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(XmlMDF_ADriverTable,Standard_Transient)
|
||||
|
16
src/XmlMDF/XmlMDF_DerivedDriver.cxx
Normal file
16
src/XmlMDF/XmlMDF_DerivedDriver.cxx
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2020 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <XmlMDF_DerivedDriver.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(XmlMDF_DerivedDriver, XmlMDF_ADriver)
|
72
src/XmlMDF/XmlMDF_DerivedDriver.hxx
Normal file
72
src/XmlMDF/XmlMDF_DerivedDriver.hxx
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright (c) 2020 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _XmlMDF_DerivedDriver_HeaderFile
|
||||
#define _XmlMDF_DerivedDriver_HeaderFile
|
||||
|
||||
#include <XmlMDF_ADriver.hxx>
|
||||
#include <TDF_DerivedAttribute.hxx>
|
||||
|
||||
//! A universal driver for the attribute that inherits another attribute with
|
||||
//! ready to used persistence mechanism implemented (already has a driver to store/retrieve).
|
||||
class XmlMDF_DerivedDriver : public XmlMDF_ADriver
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(XmlMDF_DerivedDriver, XmlMDF_ADriver)
|
||||
public:
|
||||
//! Creates a derivative persistence driver for theDerivative attribute by reusage of theBaseDriver
|
||||
//! @param theDerivative an instance of the attribute, just created, detached from any label
|
||||
//! @param theBaseDriver a driver of the base attribute, called by Paste methods
|
||||
XmlMDF_DerivedDriver (const Handle(TDF_Attribute)& theDerivative,
|
||||
const Handle(XmlMDF_ADriver)& theBaseDriver)
|
||||
: XmlMDF_ADriver (theBaseDriver->MessageDriver(), theBaseDriver->Namespace().ToCString()),
|
||||
myDerivative (theDerivative),
|
||||
myBaseDirver(theBaseDriver) {}
|
||||
|
||||
//! Creates a new instance of the derivative attribute
|
||||
virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE { return myDerivative->NewEmpty(); }
|
||||
|
||||
//! Returns the full XML tag name (including NS prefix)
|
||||
const TCollection_AsciiString& TypeName() const
|
||||
{
|
||||
const TCollection_AsciiString& aRegistered = TDF_DerivedAttribute::TypeName (myDerivative->DynamicType()->Name());
|
||||
if (aRegistered.IsEmpty())
|
||||
{
|
||||
return XmlMDF_ADriver::TypeName();
|
||||
}
|
||||
return aRegistered;
|
||||
}
|
||||
|
||||
//! Reuses the base driver to read the base fields
|
||||
virtual Standard_Boolean Paste (const XmlObjMgt_Persistent& theSource,
|
||||
const Handle(TDF_Attribute)& theTarget,
|
||||
XmlObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE
|
||||
{
|
||||
Standard_Boolean aResult = myBaseDirver->Paste (theSource, theTarget, theRelocTable);
|
||||
theTarget->AfterRetrieval(); // to allow synchronization of the derived attribute with the base content
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//! Reuses the base driver to store the base fields
|
||||
virtual void Paste (const Handle(TDF_Attribute)& theSource,
|
||||
XmlObjMgt_Persistent& theTarget,
|
||||
XmlObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE
|
||||
{
|
||||
myBaseDirver->Paste (theSource, theTarget, theRelocTable);
|
||||
}
|
||||
|
||||
protected:
|
||||
Handle(TDF_Attribute) myDerivative; //!< the derivative attribute that inherits the base
|
||||
Handle(XmlMDF_ADriver) myBaseDirver; //!< the base attribute driver to be reused here
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user