![]() |
MAK RTIspy API Documentation for HLA 1.3
|
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