MAK RTIspy API Documentation for HLA Evolved
spyXmlBlock.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  ** Copyright (c) 2006 MaK Technologies, Inc.
00003  ** All rights reserved.
00004  *********************************************************************/
00005 /*******************************************************************************
00006  ** $RCSfile: spyXmlBlock.h,v $ $Revision: 1.8 $ $State: Exp $
00007  *******************************************************************************/
00008 #ifndef DtSpyXmlBlock_H_
00009 #define DtSpyXmlBlock_H_
00010 
00011 #include <rtiMsConfig.h>
00012 #include <mtl/env.h>
00013 #include "spyXmlBlockElements.h"
00014 #include <vlutil/vlSmartPointers.h>
00015 #include <vlutil/vlString.h>
00016 #include <iosfwd>
00017 #include <set>
00018 
00019 // Forward Declarations
00020 class DtSpyXmlBlock;
00021 template< typename Key, typename Product, typename ProductCreatorParameter > class DtPluggableFactory;
00022 
00023 typedef DtBoost::shared_ptr<DtSpyXmlBlock> DtSpyXmlBlockSP;
00024 typedef DtBoost::weak_ptr<DtSpyXmlBlock>   DtSpyXmlBlockWP;
00025 typedef std::set< DtSpyXmlBlockSP >        DtSpyXmlBlockSet;
00026 typedef DtSpyXmlBlockSP (*DtSpyXmlBlockCreator)(MAKRti::DtEnvValueSP node);
00027 
00028 
00033 class DT_DLL_WWW DtSpyXmlBlock
00034 {
00035 public:
00036    // TODO: Create a real exception class
00037    typedef MAKRti::DtString DtXMLParseError;
00038 
00039    // XmlSpyBlocks should register themselves with the factory, with a creator
00040    // which takes a pointer to their XML node and the creating parent's node (if any)
00041    typedef std::pair< MAKRti::DtEnvValueSP, MAKRti::DtEnvValueSP > DtNodeAndParentPair;
00042 
00043 
00044    // Create a new DtSpyXmlBlock from its XML representation
00045    static DtSpyXmlBlockSP create( MAKRti::DtEnvValueSP node, MAKRti::DtEnvValueSP parent );
00046 
00047    // Is this node of a type with a registered factory creator?
00048    static bool isCreatable( MAKRti::DtEnvValueSP node );
00049 
00050 public:
00051 
00052    // Construct a basic container block
00053    // (must create a derived block if block has attributes)
00054    DtSpyXmlBlock( const MAKRti::DtString& name, const MAKRti::DtString& type, MAKRti::DtEnvValueSP parent );
00055    DtSpyXmlBlock( const DtSpyXmlBlock& orig );
00056 
00057    // Unless this node type is not registered with the factory, caller should
00058    // use the factory creator method when constructing from XML
00059    DtSpyXmlBlock( MAKRti::DtEnvValueSP node, MAKRti::DtEnvValueSP parent );
00060 
00061    // Assignment operator
00062    DtSpyXmlBlock& operator=( const DtSpyXmlBlock& orig );
00063 
00064    // Destructor
00065    virtual ~DtSpyXmlBlock();
00066 
00067    // Get the block name
00068    inline const MAKRti::DtString& name() const;
00069 
00070    // Get the block type
00071    inline const MAKRti::DtString& type() const;
00072 
00073    // Get a pointer to the Node's XML rep.
00074    inline MAKRti::DtEnvValueSP objectNode() const;
00075 
00076    // Add a pointer to a new child block keyed by its specific type
00077    inline void addChild( DtSpyXmlBlockSP child );
00078 
00079    // Remove all pointers to a child block
00080    inline void removeChild( DtSpyXmlBlockSP child );
00081 
00082    // Get a list of all child blocks
00083    inline const DtSpyXmlBlockSet& children() const;
00084    inline DtSpyXmlBlockSet& children();
00085 
00086    // Get a list of all child blocks by type (may be slow - creates a new sub-list)
00087    virtual DtSpyXmlBlockSet childrenByType( const MAKRti::DtString& type ) const;
00088 
00089    // Get a specific child by name and type
00090    virtual DtSpyXmlBlockSP lookupChild( const MAKRti::DtString& name, const MAKRti::DtString& type ) const;
00091 
00092    // Get a list of elements contained by the block
00093    // (ie - the block's xml attributes and simple (non-block) sub-elements)
00094    inline const DtSpyXmlBlockElementsSet& subElements() const;
00095    inline DtSpyXmlBlockElementsSet& subElements();
00096 
00097    // Output
00098    virtual std::ostream& print( std::ostream& ostr ) const;
00099 
00100 public:
00101    
00102    // Helper method to get children of a specific type
00103    template< typename SpyXmlBlockType >
00104    static std::set< DtBoost::shared_ptr<SpyXmlBlockType> > getChildrenOfType(
00105       const MAKRti::DtString& type, const DtSpyXmlBlock& block );
00106 
00107    // Helper method to lookup a child of a specific type by name
00108    template< typename SpyXmlBlockType >
00109    DtBoost::shared_ptr<SpyXmlBlockType> getChildByName( const MAKRti::DtString& name,
00110       const MAKRti::DtString& type, const DtSpyXmlBlock& block );
00111 
00112 protected:
00113 
00114    // Output
00115    virtual std::ostream& printAttributes( std::ostream& ostr ) const;
00116    virtual std::ostream& printElements( std::ostream& ostr ) const;
00117 
00118 protected:
00119 
00120    // IMPORTANT: The following functions must not be made virtual.  They 
00121    //            are used in initializer lists of derived blocks.
00122 
00123    // Add a new sub-element 
00124    // NOTE: generally it is best to make sub-elements members of derived blocks
00125    inline void addSubElement( DtSpyXmlBlockElements* element );
00126 
00127    // Remove a sub-element
00128    // NOTE: only use this for sub-elements added using add above
00129    inline void removeSubElement( DtSpyXmlBlockElements* element );
00130 
00131    // Reads the block's contained xml at construct time and populates the list of children
00132    void createChildren();
00133 
00134    // Direct access to the XML environment:
00135    // Note: sub-elements cannot have names or attributes otherwise they should be full children
00136    MAKRti::DtEnvValueSP findElement( const MAKRti::DtString& type );
00137    MAKRti::DtEnvValueSP findAttribute(  const MAKRti::DtString& name );
00138    MAKRti::DtEnvValueSP addElement( const MAKRti::DtString& type, const MAKRti::DtString& initialValue );
00139    MAKRti::DtEnvValueSP addAttribute(  const MAKRti::DtString& name, const MAKRti::DtString& initialValue );
00140    MAKRti::DtEnvValueSP removeElement( const MAKRti::DtString& type );
00141    MAKRti::DtEnvValueSP removeAttribute(  const MAKRti::DtString& name );
00142    MAKRti::DtEnvValueSP addComment(  const MAKRti::DtString& comment );
00143 
00144 protected:
00145 
00146    // The DtFactory is a helper class that allows callers
00147    // to construct DtSpyXmlBlocks by name from their XML representation
00148    // 
00149    // USE: Sub-class DtSpyXmlBlocks should derive from DtPluggableFactoryProduct
00150    //      ex. class DtDerivedXmlSpyBlock : public 
00151    //             DtPluggableFactoryProduct< DtSpyXmlBlock, DtDerivedXmlSpyBlock >
00152    //      This will ensure that the sub-class blocks are registered with the factory.
00153    typedef DtPluggableFactory< MAKRti::DtString, DtSpyXmlBlock, DtNodeAndParentPair > DtFactory; 
00154 
00155 protected:
00156 
00157    friend class DtSpyXmlBlockElements;
00158 
00159    MAKRti::DtString          myName;
00160    MAKRti::DtString          myType;
00161    MAKRti::DtEnvValueSP      myObjectNode; 
00162    MAKRti::DtEnvValueSP      myParentNode;
00163    DtSpyXmlBlockSet          myChildren;
00164    DtSpyXmlBlockElementsSet  myXmlElements;
00165 
00166    // Local xml env is rooted at the parent node, must be mutable
00167    // since environment has local settings that may change (myEnvironment
00168    // is stored only for convenience rather than creating it locally every time)
00169    mutable MAKRti::DtEnvironment myEnvironment;
00170 };
00171 
00172 
00173 inline std::ostream& operator<<( std::ostream& ostr, const DtSpyXmlBlock& block )
00174 {
00175    return block.print( ostr );
00176 }
00177 
00178 const MAKRti::DtString& DtSpyXmlBlock::name() const
00179 {
00180    return myName;
00181 }
00182 
00183 const MAKRti::DtString& DtSpyXmlBlock::type() const
00184 {
00185    return myType;
00186 }
00187 
00188 MAKRti::DtEnvValueSP DtSpyXmlBlock::objectNode() const
00189 {
00190    return myObjectNode;
00191 }
00192 
00193 void DtSpyXmlBlock::addChild( DtSpyXmlBlockSP child )
00194 {
00195    // Need to re-parent to the child node if it is currently rooted to a different parent
00196    MAKRti::DtEnvValueSP childNode = child->objectNode();
00197    if ( childNode->parent() != myObjectNode )
00198    {
00199       myEnvironment.reparent( childNode, myObjectNode );
00200    }
00201 
00202    myChildren.insert( child );
00203 }
00204 
00205 void DtSpyXmlBlock::removeChild( DtSpyXmlBlockSP child )
00206 {
00207    myChildren.erase( child );
00208    myEnvironment.remove( child->objectNode() );
00209 }
00210 
00211 const DtSpyXmlBlockSet& DtSpyXmlBlock::children() const
00212 {
00213    return myChildren;
00214 }
00215 
00216 DtSpyXmlBlockSet& DtSpyXmlBlock::children()
00217 {
00218    return myChildren;
00219 }
00220 
00221 void DtSpyXmlBlock::addSubElement( DtSpyXmlBlockElements* element )
00222 {
00223    myXmlElements.insert( element );
00224 }
00225 
00226 void DtSpyXmlBlock::removeSubElement( DtSpyXmlBlockElements* element )
00227 {
00228    myXmlElements.erase( element );
00229    myEnvironment.remove( element->xmlNode() );
00230 }
00231 
00232 const DtSpyXmlBlockElementsSet& DtSpyXmlBlock::subElements() const
00233 {
00234    return myXmlElements;
00235 }
00236 
00237 DtSpyXmlBlockElementsSet& DtSpyXmlBlock::subElements()
00238 {
00239    return myXmlElements;
00240 }
00241 
00242 template< typename SpyXmlBlockType >
00243 std::set< DtBoost::shared_ptr<SpyXmlBlockType> > DtSpyXmlBlock::getChildrenOfType(
00244    const MAKRti::DtString& type, const DtSpyXmlBlock& block )
00245 {
00246    std::set< DtBoost::shared_ptr<SpyXmlBlockType> > childrenOfType;
00247    DtSpyXmlBlockSet::const_iterator iter   = block.children().begin();
00248    DtSpyXmlBlockSet::const_iterator theEnd = block.children().end();
00249    for ( iter; iter != theEnd; ++iter )
00250    {
00251       if ( (*iter)->type() == type )
00252       {
00253          DtBoost::shared_ptr< SpyXmlBlockType > child =
00254             DtBoost::dynamic_pointer_cast<SpyXmlBlockType>( *iter );
00255          if ( child )
00256          {
00257             childrenOfType.insert( child );
00258          }
00259       }
00260    }
00261    return childrenOfType;
00262 }
00263 
00264 template< typename SpyXmlBlockType >
00265 DtBoost::shared_ptr<SpyXmlBlockType> DtSpyXmlBlock::getChildByName(
00266    const MAKRti::DtString& name, const MAKRti::DtString& type, const DtSpyXmlBlock& block )
00267 {
00268    DtBoost::shared_ptr<SpyXmlBlockType> child;
00269    DtSpyXmlBlockSet::const_iterator iter   = block.children().begin();
00270    DtSpyXmlBlockSet::const_iterator theEnd = block.children().end();
00271    for ( iter; iter != theEnd; ++iter )
00272    {
00273       if ( (*iter)->name() == name  && (*iter)->type() == type )
00274       {
00275          child = DtBoost::dynamic_pointer_cast<SpyXmlBlockType>( *iter );
00276          break;
00277       }
00278    }
00279    return child;
00280 }
00281 
00282 
00283 #endif // DtSpyXmlBlock_H_
00284 
00285 

Document ID: Generated on Thu Jun 14 14:15:04 EDT 2012 from SVN revision 116116
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)