wiki:FdoSchemaDeepCopy

Version 2 (modified by gregboone, 17 years ago) ( diff )

--

FDO Schema DeepCopy Support

Overview

As a result of further integrating the FDO API into the Autodesk Map and Autodesk MapGuide Enterprise product lines, an request was generated senior developers which would see the FDO community implement DeepCopy or Clone support directly into the FDO API class definitions. The lack of such support was seen as a deficiency in FDO that forced users of the API to write such functionality themselves.

The following sections outline how this new functionality will be implemented.

Definitions

The following changes will be made to the FDO API in order to support the process of deep copying or cloning FDO schema and data types.

FdoSchemaCopyContext Class

An FdoSchemaCopyContext class will be added to the FDO Schema API

FdoSchemaCopyContext is context class that will be used to assist in process of cloning schemas and their associated elements. FdoSchemaCopyContext is designed to contain a schema element map which will store instances of previously copied schema elements. Since FDO schema objects are often associated to one another, and a deep cloning process by design must copy the entire schema object, it is necessary to know if the associated objects have been previously copied. Implementing a mapping for the copied schema elements will avoid creating duplicate objects when cloning an FDO schema.

The FdoSchemaCopyContext class will have the following definition:

/// \brief
/// A Map that will allow copied schema elements to be tracked  
/// and will prevent duplicate elements from being copied.
typedef std::map <FdoSchemaElement*, FdoSchemaElement*> FdoSchemaElementMap;

/// \brief
/// A Map pair that will allow copied schema elements to identified and stored
/// in a FdoSchemaElementMap.
typedef std::pair <FdoSchemaElement*, FdoSchemaElement*> FdoSchemaElementPair;

/// \brief
/// A Map iterator that will allow iteration over a FdoSchemaElementMap.
typedef FdoSchemaElementMap::const_iterator FdoSchemaElementMapIterator;

/// \brief
/// A schema context class that is used to assist in process 
/// of cloning schema elemts. The schema element map contained 
/// by this class assists the DeepCopy process in avoiding duplicate 
/// schema element objects from being copied.
class FdoSchemaCopyContext : public FdoDisposable
{
public:
    /// \brief
    /// Creates a new instance of an FdoSchemaCopyContext
    /// 
    /// \param identifiers
    /// An optional set of identifiers that will constrain 
    /// the class indentifiers to copy. Use this collection to 
    /// copy a potion of an FDO class definition
    /// 
    /// \return
    /// Returns a new instance of FdoSchemaCopyContext
    /// 
    static FdoSchemaCopyContext* Create( FdoIdentifierCollection *identifiers = NULL );

public:
    /// \brief
    /// Gets the element map containing the copied elements 
    /// referenced by the copy context
    /// 
    /// \return
    /// Returns the element map containing the copied elements
    /// 
    const FdoSchemaElementMap * GetSchemaElementMap();

    /// \brief
    /// Inserts a source/copied pair into the element map 
    /// 
    /// \sourceElement
    /// The source element from which the element was copied
    /// 
    /// \copiedElement
    /// The copied element created from the source element
    /// 
    void InsertSchemaElement( FdoSchemaElement* sourceElement, 
                              FdoSchemaElement* copiedElement );

    /// \brief
    /// Sets the FDO identifier list that will constrain the 
    /// list of class properties to be copied
    /// 
    /// \param identifiers
    /// An optional set of identifiers that will constrain 
    /// the class indentifiers to copy. Use this collection to 
    /// copy a potion of an FDO class definition
    /// 
    void SetIdentifierConstraints( FdoIdentifierCollection* identifiers );

    /// \brief
    /// Find a copied element in the schema element 
    /// map based on it's source object
    /// 
    /// \param element 
    /// Input the element to search for in the element map
    /// 
    /// \return
    /// Returns the previously copied schema element 
    /// if found in the collection, otherwise NULL
    /// 
    template <typename T> T* FindSchemaElement( T* element )
    {
        if (m_schemaMap == NULL) {
            throw FdoException::Create(
                FdoException::NLSGetMessage(FDO_NLSID(FDO_4_UNREADY)));
        }

        T* retElem = NULL;

        FdoSchemaElementMapIterator elementIterator = m_schemaMap->find(element);
        if (elementIterator != m_schemaMap->end()) {
            retElem = dynamic_cast<T*>(elementIterator->second);
            if (retElem == NULL) {
                throw FdoException::Create(
                    FdoException::NLSGetMessage(FDO_NLSID(CLNT_3_NULLPOINTER)));
            }
        }

        return FDO_SAFE_ADDREF(retElem);
    }

protected:
    /// \brief
    /// Default Constructor
    FdoCommonSchemaCopyContext( void );

    /// \brief
    /// Destructor (Virtual)
    virtual ~FdoCommonSchemaCopyContext();

    /// \brief
    /// The Disposal method for this object. Dispose is called 
    /// when the objects RefCount == 0. Dispose will in turn 
    /// invoke the objects destructor
    virtual void Dispose();

private:
    /// \brief
    /// The std::map containing references to the copied schema elements
    FdoSchemaElementMap * m_schemaMap;

    /// \brief
    /// The identifier collection that will contrain the class properties
    /// to be copied.
    FdoPtr<FdoIdentifierCollection> m_identifierConstraints;
};

/// \brief
/// FdoSchemaCopyContextP is a FdoPtr on FdoSchemaCopyContext. Provided for convenience.
typedef FdoPtr<FdoSchemaCopyContext> FdoSchemaCopyContextP;
Note: See TracWiki for help on using the wiki.