00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef MODELSERVICES_H 00011 #define MODELSERVICES_H 00012 00013 #include "Any.h" 00014 #include "AnyData.h" 00015 #include "ComplexData.h" 00016 #include "Service.h" 00017 #include "Subject.h" 00018 #include "switchOnEncoding.h" 00019 #include "TypesFile.h" 00020 00021 #include <map> 00022 #include <string> 00023 #include <vector> 00024 00025 class DataDescriptor; 00026 class DataElement; 00027 class ImportDescriptor; 00028 00029 /** 00030 * \ingroup ServiceModule 00031 * Provides access for storing and managing data. 00032 * 00033 * This interface allows for creation and manipulation of data, including 00034 * access to a session within the application. Data is stored in elements 00035 * that contain descriptor classes to provide information related to the data. 00036 * 00037 * Each element is stored internally according to a key that is comprised of 00038 * a name, type, and a parent element. The combination of these three 00039 * identifiers must be unique when creating a new element, renaming an 00040 * existing element, or reparenting an existing element. 00041 * 00042 * The parent element allows for different elements of different types to 00043 * be associated with each other. For example, a common parent/child pair 00044 * is an AoiElement element that has a RasterElement parent to indicate that 00045 * the area of interest relates to a specific data set. 00046 * 00047 * If an element has a non-\b NULL parent element, the element will be 00048 * destroyed when its parent is destroyed. 00049 * 00050 * This subclass of Subject will notify upon the following conditions: 00051 * - The following methods are called: createElement(), destroyElement(), 00052 * setElementParent(), and clear(). 00053 * - Everything else documented in Subject. 00054 */ 00055 class ModelServices : public Subject 00056 { 00057 public: 00058 /** 00059 * Emitted with boost::any<DataElement*> when a DataElement is created. 00060 */ 00061 SIGNAL_METHOD(ModelServices, ElementCreated) 00062 00063 /** 00064 * Emitted with boost::any<DataElement*> when a DataElement is destroyed. 00065 */ 00066 SIGNAL_METHOD(ModelServices, ElementDestroyed) 00067 00068 /** 00069 * Emitted with boost::any<DataElement*> when the parent of a DataElement 00070 * changes. 00071 */ 00072 SIGNAL_METHOD(ModelServices, ElementReparented) 00073 00074 /** 00075 * Creates an empty data descriptor. 00076 * 00077 * This method creates an empty data descriptor that can be populated so 00078 * that a data element can be created. The memory for the data is 00079 * allocated by the studio but owned by the plug-in, so plug-in must 00080 * destroy the data descriptor by calling the destroyDataDescriptor() 00081 * method. 00082 * 00083 * @param name 00084 * The name for the data element. 00085 * @param type 00086 * The type of the data element, which is used to determine the 00087 * kind of element to create when createElement() is called. To 00088 * create a data element from the returned data descriptor, the 00089 * type string must be one of the valid element types returned 00090 * from getValidElementTypes(). For raster data types, a 00091 * RasterDataDescriptor is created. For all other types, a 00092 * DataDescriptor is created. 00093 * @param pParent 00094 * An optional parent element to which the new element will be 00095 * associated. Passing in \c NULL indicates that the new element 00096 * is not associated with another element. If the parent is 00097 * non-\b NULL, the returned element is automatically destroyed 00098 * when the parent element is destroyed. The new DataDescriptor 00099 * inherits the parent's classification unless the parent is \c NULL, 00100 * in which case the classification will be set to the system's 00101 * highest level of classification. 00102 * 00103 * @return Returns a pointer to the newly created data descriptor. 00104 * 00105 * @see createElement() 00106 */ 00107 virtual DataDescriptor* createDataDescriptor(const std::string& name, const std::string& type, 00108 DataElement* pParent) const = 0; 00109 00110 /** 00111 * Creates an empty data descriptor. 00112 * 00113 * This method creates a DataDescriptor with a parent specified as a vector of strings. 00114 * It should not be called if the parent data element already exists. It is to be used when the 00115 * parent has not yet been created. Since the parent should not exist, the classification will 00116 * be set to the highest level of the system. It is the responsibility of the caller to set 00117 * the proper classification settings. 00118 * 00119 * @param name 00120 * The name for the data element. 00121 * @param type 00122 * The type of the data element, which is used to determine the 00123 * kind of element to create when createElement() is called. To 00124 * create a data element from the returned data descriptor, the 00125 * type string must be one of the valid element types returned 00126 * from getValidElementTypes(). For raster data types, a 00127 * RasterDataDescriptor is created. For all other types, a 00128 * DataDescriptor is created. 00129 * @param parent 00130 * A parent element to which the new element will be associated. 00131 * This parent is specified as a vector of names of elements. The 00132 * first name in the vector is the top-level element, the next name 00133 * is a child of that element, and so on. Passing an empty vector 00134 * will create a top-level element. 00135 * 00136 * @return Returns a pointer to the newly created data descriptor. 00137 * 00138 * @see createElement() 00139 */ 00140 virtual DataDescriptor* createDataDescriptor(const std::string& name, const std::string& type, 00141 const std::vector<std::string> &parent) const = 0; 00142 00143 /** 00144 * Destroys a data descriptor. 00145 * 00146 * This destroys a data descriptor that was created with the 00147 * createDataDescriptor() method. 00148 * 00149 * @param pDescriptor 00150 * The data descriptor to destroy. 00151 */ 00152 virtual void destroyDataDescriptor(DataDescriptor* pDescriptor) const = 0; 00153 00154 /** 00155 * Creates an import descriptor. 00156 * 00157 * This method creates an import descriptor that contains a data descriptor 00158 * that can be populated so that a data element can be imported. Ownership 00159 * of the import descriptor is transferred to the caller, so the 00160 * destroyImportDescriptor() method should be called to destroy the object. 00161 * The import descriptor maintains ownership of the created data 00162 * descriptor. 00163 * 00164 * @param name 00165 * The name for the data element. 00166 * @param type 00167 * The type of the data element, which is used to determine the 00168 * kind of element to create when createElement() is called. To 00169 * create a data element from the returned data descriptor, the 00170 * type string must be one of the valid element types returned 00171 * from getValidElementTypes(). For raster data types, a 00172 * RasterDataDescriptor is created. For all other types, a 00173 * DataDescriptor is created. 00174 * @param pParent 00175 * An optional parent element to which the new element will be 00176 * associated. Passing in \c NULL indicates that the new element 00177 * is not associated with another element. If the parent is 00178 * non-\c NULL, the returned element is automatically destroyed 00179 * when the parent element is destroyed. The created data descriptor 00180 * in the new import descriptor inherits the parent's classification 00181 * unless the parent is \c NULL, in which case the classification 00182 * will be set to the system's highest level of classification. 00183 * @param bImported 00184 * Set this parameter to \c true to import the element or to 00185 * \c false to not create the data element on import. 00186 * 00187 * @return Returns a pointer to the newly created import descriptor. 00188 * 00189 * @see createImportDescriptor(DataDescriptor*, bool) const 00190 */ 00191 virtual ImportDescriptor* createImportDescriptor(const std::string& name, const std::string& type, 00192 DataElement* pParent, bool bImported = true) const = 0; 00193 00194 /** 00195 * Creates an import descriptor. 00196 * 00197 * This method creates an import descriptor whose parent is specified as a vector of names. 00198 * It should not be called if the parent data element already exists. It is to be used when the 00199 * parent has not yet been created, e.g., in an importer to display the hierarchy of data elements 00200 * to be imported in the import options widget. Since the parent should not exist, the classification 00201 * will be set to the highest level of the system. It is the responsibility of the caller to set the 00202 * proper classification settings. 00203 * 00204 * @param name 00205 * The name for the data element. 00206 * @param type 00207 * The type of the data element, which is used to determine the 00208 * kind of element to create when createElement() is called. To 00209 * create a data element from the returned data descriptor, the 00210 * type string must be one of the valid element types returned 00211 * from getValidElementTypes(). For raster data types, a 00212 * RasterDataDescriptor is created. For all other types, a 00213 * DataDescriptor is created. 00214 * @param parent 00215 * A parent element to which the new element will be associated. 00216 * This parent is specified as a vector of names of elements. The 00217 * first name in the vector is the top-level element, the next name 00218 * is a child of that element, and so on. Passing an empty vector will 00219 * create a top-level element. 00220 * @param bImported 00221 * Set this parameter to \c true to import the element or to 00222 * \c false to not create the data element on import. 00223 * 00224 * @return Returns a pointer to the newly created import descriptor. 00225 * 00226 * @see createImportDescriptor(DataDescriptor*, bool) const, 00227 * createDataDescriptor(const std::string& name, const std::string& type, const std::vector<std::string> &parent) const 00228 */ 00229 virtual ImportDescriptor* createImportDescriptor(const std::string& name, const std::string& type, 00230 const std::vector<std::string> &parent, bool bImported = true) const = 0; 00231 00232 /** 00233 * Creates an import descriptor. 00234 * 00235 * This method creates an import descriptor that contains a given data 00236 * descriptor so that a data element can be imported. Ownership of the 00237 * import descriptor is transferred to the caller, so the 00238 * destroyImportDescriptor() method should be called to destroy the object. 00239 * Ownership of the given data descriptor is transferred to the created 00240 * import descriptor. 00241 * 00242 * @param pDescriptor 00243 * The data descriptor with which to create the data element on 00244 * import. 00245 * @param bImported 00246 * Set this parameter to \c true to create the data element and 00247 * load the data on import or to \c false to not create the data 00248 * element on import. 00249 * 00250 * @return Returns a pointer to the newly created import descriptor. 00251 * 00252 * @see createImportDescriptor(const std::string&, const std::string&, DataElement*, bool) const 00253 */ 00254 virtual ImportDescriptor* createImportDescriptor(DataDescriptor* pDescriptor, bool bImported = true) const = 0; 00255 00256 /** 00257 * Destroys an import descriptor. 00258 * 00259 * This destroys an import descriptor that was created with the 00260 * createImportDescriptor() method. 00261 * 00262 * @param pImportDescriptor 00263 * The import descriptor to destroy. 00264 */ 00265 virtual void destroyImportDescriptor(ImportDescriptor* pImportDescriptor) const = 0; 00266 00267 /** 00268 * Adds a new element type to the list of valid types. 00269 * 00270 * This method adds a new element type to the list of valid types and also 00271 * adds the new type as a valid plug-in arg type in PlugInManagerServices. 00272 * 00273 * New element types are added to distinguish between multiple custom data 00274 * types stored in an Any element. A new plug-in arg type is automatically 00275 * registered with PlugInManagerServices, and when creating an arg with the 00276 * new element type, the arg value must be set to the Any element and not 00277 * the AnyData object contained in the Any element. 00278 * 00279 * @warning If the new element type is going to be used as the type in a 00280 * PlugInArg, this method should be called before setting the arg 00281 * type in Executable::getInputSpecification() or 00282 * Executable::getOutputSpecification(). 00283 * 00284 * @param elementType 00285 * The new element type. 00286 * 00287 * @return Returns \b true if the element type was successfully added to 00288 * the valid types list. Returns \b false if the element type 00289 * already exists in the list, or if an empty string is passed in. 00290 * 00291 * @see getValidElementTypes() 00292 */ 00293 virtual bool addElementType(const std::string& elementType) = 0; 00294 00295 /** 00296 * Queries whether a given type is a valid element type. 00297 * 00298 * @param elementType 00299 * The type to query whether it is a valid element type. 00300 * 00301 * @return Returns \b true if the given type is a valid element type; 00302 * otherwise returns \b false. 00303 * 00304 * @see getValidElementTypes() 00305 */ 00306 virtual bool hasElementType(const std::string& elementType) const = 0; 00307 00308 /** 00309 * Returns the valid element types. 00310 * 00311 * This method returns the names of each recognized element type. Custom 00312 * element types can be added to the list by calling the addElementType() 00313 * method. When a element with a custom type is created, an Any element 00314 * is created. 00315 * 00316 * The default element types are as follows: 00317 * - AnnotationElement 00318 * - Any 00319 * - AoiElement 00320 * - DataElement 00321 * - DataElementGroup 00322 * - GcpList 00323 * - RasterElement 00324 * - Signature 00325 * - SignatureSet 00326 * - TiePointList 00327 * 00328 * @return A vector of strings specifying the name of each valid element 00329 * type. 00330 */ 00331 virtual const std::vector<std::string>& getValidElementTypes() const = 0; 00332 00333 /** 00334 * Creates multiple data elements as a batch, ensuring proper parentage. 00335 * 00336 * This method creates a data element for each DataDescriptor. When created, 00337 * each element will have the parentage specified in the DataDescriptor. The 00338 * group will be created in an order that guarantees a new element's parent exists 00339 * before it is created as long as that parent exists before the call to createElements() 00340 * or is part of the group of new elements. If a new element requests a parent that does 00341 * not already exist and is not in the vector of DataDescriptors, that element will not be created. 00342 * 00343 * @param descriptors 00344 * A vector of DataDescriptors describing the elements to be created. 00345 * 00346 * @return A vector of the new elements. If one or more elements can not be created, this method will 00347 * not fail fast. A partial error can be detected by comparing the size of the return value 00348 * with the size of descriptors. Only successfully created elements will be returned. If an element 00349 * can not be created and has children in descriptors, those children will also fail to be created. 00350 * 00351 * @see createElement(const DataDescriptor*) 00352 */ 00353 virtual std::vector<DataElement*> createElements(const std::vector<DataDescriptor*> &descriptors) = 0; 00354 00355 /** 00356 * Creates an empty data element with no data. 00357 * 00358 * This method creates an element based on the given data descriptor. The 00359 * type in the data descriptor must be one of the valid element types 00360 * returned from getValidElementTypes(). 00361 * 00362 * The memory for the element is created and maintained by the studio. A 00363 * deep copy of the given data descriptor is made so the calling object 00364 * should destroy the data descriptor after calling this method. The new 00365 * element inherits the classification settings of the passed in data descriptor. 00366 * 00367 * @param pDescriptor 00368 * The data descriptor from which to create the data element. The 00369 * type in the data descriptor is used to determine the kind of 00370 * element to create and must be one of the types returned from 00371 * getValidElementTypes(). If a valid custom type is specified, 00372 * an Any element is created. This method does nothing if \c NULL 00373 * is passed in. 00374 * 00375 * @return This method returns a pointer to the newly created data 00376 * element. \c NULL is returned in the following conditions: 00377 * - The type in the data descriptor is not a valid element type 00378 * returned from getValidElementTypes(). 00379 * - The parent element specified by the parent designator in the 00380 * data descriptor (see DataDescriptor::getParentDesignator()) 00381 * does not exist. 00382 * - The element could not be created (i.e. the element already 00383 * exists). 00384 * - The element type is RasterElement with a processing location of \link ProcessingLocation::IN_MEMORY IN_MEMORY \endlink 00385 * and the required amount of memory could not be allocated. 00386 * 00387 * @warning For data element type RasterElement with a processing location of \link ProcessingLocation::ON_DISK ON_DISK \endlink 00388 * or \link ProcessingLocation::ON_DISK_READ_ONLY ON_DISK_READ_ONLY \endlink, this method will return a non-\c NULL pointer 00389 * even if the temporary file required for the element can't be created. This behavior is necessary 00390 * to prevent performance problems with importers. If you use this method to create an 00391 * \link ProcessingLocation::ON_DISK ON_DISK \endlink or \link ProcessingLocation::ON_DISK_READ_ONLY ON_DISK_READ_ONLY \endlink 00392 * raster element, a \c NULL check on the return from this method will not insure that the 00393 * returned data element is usable. A better way is to check the return from a call to 00394 * RasterElement::createDefaultPager() which will return \c false if the associated temporary file 00395 * can not be created. For an even simpler approach, use RasterUtilities::createRasterElement() instead of 00396 * this method to create the data element. RasterUtilities::createRasterElement() will return \c NULL 00397 * if either the memory can't be allocated or the temporary file can't be created. 00398 * 00399 * @notify This method will notify signalElementCreated() with 00400 * boost::any<DataElement*>. 00401 * 00402 * @see createElement(const std::string&, const std::string&, DataElement*), 00403 * RasterUtilities::createRasterElement() 00404 */ 00405 virtual DataElement* createElement(const DataDescriptor* pDescriptor) = 0; 00406 00407 /** 00408 * Creates an empty data element with no data. 00409 * 00410 * This is a convenience method that creates a data element without needing 00411 * to first create a data descriptor and then destroy the data descriptor 00412 * after the element is created. It is typically used to create simple 00413 * data elements such as AOIs and GCP lists. The new element inherits the classification 00414 * settings of the parent element unless the parent is \c NULL, in which case 00415 * the new element's classification will be set to the system's highest level. 00416 * 00417 * @param name 00418 * The string name for the data element to create. 00419 * @param type 00420 * The string name corresponding to the type of the data element 00421 * to create. The types must be one of the valid element types 00422 * returned from getValidElementTypes(). If a valid custom type 00423 * is passed in, an Any element is created. 00424 * @param pParent 00425 * The parent element of the element to create. Passing in 00426 * \b NULL indicates that the element is not associated with 00427 * another element. If the parent is non-\b NULL, the returned 00428 * element is automatically destroyed when the parent element is 00429 * destroyed. 00430 * 00431 * @return This method returns a pointer to the newly created data 00432 * element. \b NULL is returned if the given type is not a valid 00433 * element type returned from getValidElementTypes() or if the 00434 * element could not be created (i.e. the element already exists). 00435 * 00436 * @notify This method will notify signalElementCreated with any<DataElement*>. 00437 * 00438 * @see createElement(const DataDescriptor*) 00439 */ 00440 virtual DataElement* createElement(const std::string& name, const std::string& type, DataElement* pParent) = 0; 00441 00442 /** 00443 * Retrieves a data element. 00444 * 00445 * @param name 00446 * The string name for the data element to retrieve. 00447 * @param type 00448 * The string name corresponding to the type of the data element 00449 * to retrieve. If this is an empty string, an element of any type is retrieved. 00450 * @param pParent 00451 * The parent element of the element to get. Passing in 00452 * \b NULL indicates that the element is not associated with 00453 * another element. 00454 * 00455 * @return This method returns a pointer to the data element with the 00456 * given parameters. If no element is found where all of the 00457 * parameters match, \b NULL is returned. 00458 * 00459 * @see model_cast() 00460 */ 00461 virtual DataElement* getElement(const std::string& name, const std::string& type, 00462 const DataElement* pParent) const = 0; 00463 00464 /** 00465 * Retrieves a data element. 00466 * 00467 * @param designator 00468 * The element designator for the data element to retrieve. 00469 * @param type 00470 * The string name corresponding to the type of the data element 00471 * to retrieve. If this is an empty string, an element of any type is retrieved. 00472 * @return This method returns a pointer to the data element with the 00473 * given parameters. If no element is found where all of the 00474 * parameters match, \b NULL is returned. 00475 * 00476 * @see model_cast(), DataElement::getParentDesignator() 00477 */ 00478 virtual DataElement* getElement(const std::vector<std::string>& designator, const std::string& type) const = 0; 00479 00480 /** 00481 * Retrieves elements of a given type. 00482 * 00483 * @param type 00484 * The string name corresponding to the element type to retrieve. 00485 * If an empty string is passed in, all elements in the model are 00486 * retrieved. 00487 * 00488 * @return A vector containing pointers to the data elements of the given 00489 * type. 00490 * 00491 * @see getElements(const DataElement*, const std::string&) const, 00492 * getElements(const std::string&, const std::string&) const 00493 */ 00494 virtual std::vector<DataElement*> getElements(const std::string& type) const = 0; 00495 00496 /** 00497 * Retrieves elements with a given parent. 00498 * 00499 * @param pParent 00500 * The parent element for which all child elements should be 00501 * retrieved. Passing in \b NULL retrieves all top-level 00502 * elements. 00503 * @param type 00504 * An optional type string for retreiving elements of a particular 00505 * type from the given parent. If an empty string is passed in, 00506 * all elements with the given parent are retrieved. 00507 * 00508 * @return A vector containing pointers to the data elements with the 00509 * given parent. 00510 * 00511 * @see getElements(const std::string&) const, 00512 * getElements(const std::string&, const std::string&) const 00513 */ 00514 virtual std::vector<DataElement*> getElements(const DataElement* pParent, const std::string& type) const = 0; 00515 00516 /** 00517 * Retrieves elements with a given file. 00518 * 00519 * @param filename 00520 * The filename for which all elements with the same filename 00521 * should be retrieved. Passing in an empty string retrieves 00522 * all elements that have no associated file. 00523 * @param type 00524 * An optional type string for retreiving elements of a particular 00525 * type within the given file. If an empty string is passed in, 00526 * all elements within the given file are retrieved. 00527 * 00528 * @return A vector containing pointers to the data elements within the 00529 * given file. 00530 * 00531 * @see getElements(const std::string&) const, 00532 * getElements(const DataElement*, const std::string&) const 00533 */ 00534 virtual std::vector<DataElement*> getElements(const std::string& filename, const std::string& type) const = 0; 00535 00536 /** 00537 * Retrieves the names of elements of a given type. 00538 * 00539 * @param type 00540 * The string name corresponding to the element type for which to 00541 * retrieve the names. If an empty string is passed in, the names 00542 * of all elements in the model are retrieved. 00543 * 00544 * @return A vector containing the names of the data elements of the given 00545 * type. 00546 * 00547 * @see getElementNames(const DataElement*, const std::string&) const, 00548 * getElementNames(const std::string&, const std::string&) const 00549 */ 00550 virtual std::vector<std::string> getElementNames(const std::string& type) const = 0; 00551 00552 /** 00553 * Retrieves the names of elements with a given parent. 00554 * 00555 * @param pParent 00556 * The parent element for which the names of all child elements 00557 * should be retrieved. Passing in \b NULL retrieves the names 00558 * of all top-level elements. 00559 * @param type 00560 * An optional type string for retreiving the names of elements 00561 * of a particular type from the given parent. If an empty 00562 * string is passed in, the names of all elements with the given 00563 * parent are retrieved. 00564 * 00565 * @return A vector containing the names of the data elements with the 00566 * given parent. 00567 * 00568 * @see getElementNames(const std::string&) const, 00569 * getElementNames(const std::string&, const std::string&) const 00570 */ 00571 virtual std::vector<std::string> getElementNames(const DataElement* pParent, const std::string& type) const = 0; 00572 00573 /** 00574 * Retrieves the names of elements with a given file. 00575 * 00576 * @param filename 00577 * The filename for which the names of all elements with the same 00578 * filename should be retrieved. Passing in an empty string 00579 * retrieves the name of all elements that have no associated file. 00580 * @param type 00581 * An optional type string for retreiving the names of elements of 00582 * a particular type within the given file. If an empty string is 00583 * passed in, the names of all elements within the given file are 00584 * retrieved. 00585 * 00586 * @return A vector containing the names of the data elements with the 00587 * given file. 00588 * 00589 * @see getElementNames(const std::string&) const, 00590 * getElementNames(const DataElement*, const std::string&) const 00591 */ 00592 virtual std::vector<std::string> getElementNames(const std::string& filename, const std::string& type) const = 0; 00593 00594 /** 00595 * Renames a data element. 00596 * 00597 * @param pElement 00598 * The existing element in the session to rename. This method 00599 * does nothing if \b NULL is passed in. 00600 * @param name 00601 * The new name for the element. If an empty string is passed in, 00602 * the element is not renamed. 00603 * 00604 * @return True if the rename was successful, false otherwise. This 00605 * operation will fail if a DataElement already exists with the new 00606 * name, type, and parent as this element. 00607 */ 00608 virtual bool setElementName(DataElement* pElement, const std::string& name) = 0; 00609 00610 /** 00611 * Reparents a data element. The classification settings of the reparented 00612 * element will not be changed, i.e., they will not be set to the new parent's settings. 00613 * 00614 * @param pElement 00615 * The existing element in the session to reparent. This method 00616 * does nothing if \b NULL is passed in. 00617 * @param pParent 00618 * The new parent for the element. 00619 * 00620 * @return Returns \b true if the reparent was successful, otherwise 00621 * returns \b false. This operation will fail if the given parent 00622 * element already contains a child element with the same name and 00623 * type as the given element. 00624 * 00625 * @notify This method will notify signalElementReparented() with 00626 * boost::any<DataElement*> if the element is successfully 00627 * reparented. 00628 */ 00629 virtual bool setElementParent(DataElement* pElement, DataElement *pParent) = 0; 00630 00631 /** 00632 * Removes a data element from the session. 00633 * 00634 * This method removes a data element from the session but does not 00635 * delete it. To remove and delete the element, call the destroyElement() 00636 * method instead. 00637 * 00638 * @param pElement 00639 * The data element to be removed. 00640 * 00641 * @return Returns \b true if element was successfully removed; otherwise 00642 * returns \b false. 00643 */ 00644 virtual bool removeElement(const DataElement* pElement) = 0; 00645 00646 /** 00647 * Removes a data element from the session and deletes it. 00648 * 00649 * This method removes a data element from the session and deletes it and 00650 * all of its child elements. To remove the element without deleting it 00651 * and its children, call the removeElement() method instead. 00652 * 00653 * @param pElement 00654 * The element to remove and delete, along with its child 00655 * elements. This method does nothing if \b NULL is passed in. 00656 * 00657 * @return Returns \b true if the element was successfully removed and 00658 * deleted; otherwise returns \b false. 00659 * 00660 * @notify This method will notify signalElementDestroyed with 00661 * any<DataElement*>. The DataElement pointer is still valid at 00662 * the time of notification. 00663 */ 00664 virtual bool destroyElement(DataElement* pElement) = 0; 00665 00666 /** 00667 * Removes and destroys all elements in the session. 00668 * 00669 * @notify This method will notify signalElementDestroyed with 00670 * any<DataElement*> for each element destroyed. The DataElement 00671 * pointer is still valid at the time of notification. 00672 */ 00673 virtual void clear() = 0; 00674 00675 /** 00676 * Allocates a large block of memory. 00677 * 00678 * This method allocates a contiguous block of memory of a given size and 00679 * returns a pointer to the memory block. This method can be used to 00680 * create space for a dataset in the studio's memory space that it can be 00681 * accessed when a plug-in has been unloaded. 00682 * 00683 * NOTE: On a 64-bit platform, the maximum available bytes to allocate is 00684 * 2^64, which is well over 18 million GB. On a 32-bit platform, the 00685 * maximum available bytes to allocate is 4 GB. 00686 * 00687 * @param size 00688 * The size in bytes of the requested memory block. 00689 * @return A pointer to the new memory block. \b NULL is returned if 00690 * a contiguous block of memory of the given size cannot be 00691 * allocated. On Windows systems, \b NULL may be returned 00692 * even if the amount of free memory is greater than <em>size</em> 00693 * if the location of any system DLLs fragments the memory space 00694 * so that a contiguous block is not available. 00695 * 00696 * @see deleteMemoryBlock() 00697 */ 00698 virtual char* getMemoryBlock(size_t size) = 0; 00699 00700 /** 00701 * Deletes a block of memory allocated by the studio. 00702 * 00703 * This method is used to delete a block of memory created by the 00704 * getMemoryBlock() method. 00705 * 00706 * @param memory 00707 * A pointer to the memory block to be deleted. 00708 */ 00709 virtual void deleteMemoryBlock(char* memory) = 0; 00710 00711 /** 00712 * This static method retrieves an individual data value from a block of memory. 00713 * 00714 * @param type 00715 * The data type of the memory block. 00716 * @param pData 00717 * A pointer to the block of memory from which to get the data 00718 * value. 00719 * @param iIndex 00720 * The index into the memory block for the data value. 00721 * 00722 * @return The data value. A value of 0.0 is returned if the given type 00723 * is not recognized. 00724 */ 00725 static double getDataValue(EncodingType type, const void* pData, int iIndex) 00726 { 00727 return getDataValue(type, pData, COMPLEX_MAGNITUDE, iIndex); 00728 } 00729 00730 /** 00731 * This static method retrieves an individual data value from a block of memory. 00732 * 00733 * @param type 00734 * The data type of the memory block. 00735 * @param pData 00736 * A pointer to the block of memory from which to get the data 00737 * value. 00738 * @param component 00739 * For complex data, this specifies the component of the complex 00740 * data that should be returned. For non-complex data, this 00741 * value is ignored. 00742 * @param iIndex 00743 * The index into the memory block for the data value. 00744 * 00745 * @return The data value. A value of 0.0 is returned if the given type 00746 * is not recognized. 00747 * 00748 * @see ComplexComponent 00749 */ 00750 static double getDataValue(EncodingType type, const void* pData, ComplexComponent component, int iIndex) 00751 { 00752 double dValue = 0.0; 00753 switchOnComplexEncoding(type, ModelServices::getDataValue, pData, component, iIndex, dValue); 00754 return dValue; 00755 } 00756 00757 /** 00758 * Retrieves an individual data value from a block of memory independent 00759 * of the data type. 00760 * 00761 * This static method provides the same functionality as the corresponding 00762 * virtual method, but can be used inside of other template methods. This 00763 * can provide a significant performance improvement if getting numerous 00764 * data values. 00765 * 00766 * @param pData 00767 * A pointer to the block of memory from which to get the data 00768 * value. 00769 * @param component 00770 * For complex data, this specifies the component of the complex 00771 * data that should be returned. For non-complex data, this value 00772 * is ignored. 00773 * @param iIndex 00774 * The index into the memory block for the data value. 00775 * @param dValue 00776 * Populated with the data value. 00777 */ 00778 template<class T> 00779 static inline void getDataValue(const T* pData, ComplexComponent component, int iIndex, double& dValue) 00780 { 00781 if (pData != NULL) 00782 { 00783 dValue = ModelServices::getDataValue(pData[iIndex], component); 00784 } 00785 } 00786 00787 /** 00788 * Provided for convenience for template methods, this method simply returns the given value. 00789 * 00790 * @param data 00791 * The data value from which to extract the complex component value. 00792 * @param component 00793 * This value is ignored since the given data value is non-complex. 00794 * 00795 * @return The given data value. 00796 */ 00797 static inline unsigned char getDataValue(const unsigned char& data, ComplexComponent component) 00798 { 00799 return data; 00800 } 00801 00802 /** 00803 * Provided for convenience for template methods, this method simply returns the given value. 00804 * 00805 * @param data 00806 * The data value from which to extract the complex component value. 00807 * @param component 00808 * This value is ignored since the given data value is non-complex. 00809 * 00810 * @return The given data value. 00811 */ 00812 static inline signed char getDataValue(const signed char& data, ComplexComponent component) 00813 { 00814 return data; 00815 } 00816 00817 /** 00818 * Provided for convenience for template methods, this method simply returns the given value. 00819 * 00820 * @param data 00821 * The data value from which to extract the complex component value. 00822 * @param component 00823 * This value is ignored since the given data value is non-complex. 00824 * 00825 * @return The given data value. 00826 */ 00827 static inline unsigned short getDataValue(const unsigned short& data, ComplexComponent component) 00828 { 00829 return data; 00830 } 00831 00832 /** 00833 * Provided for convenience for template methods, this method simply returns the given value. 00834 * 00835 * @param data 00836 * The data value from which to extract the complex component value. 00837 * @param component 00838 * This value is ignored since the given data value is non-complex. 00839 * 00840 * @return The given data value. 00841 */ 00842 static inline signed short getDataValue(const signed short& data, ComplexComponent component) 00843 { 00844 return data; 00845 } 00846 00847 /** 00848 * Returns a data value according to a given complex data component. 00849 * 00850 * @param data 00851 * The data value from which to extract the complex component value. 00852 * @param component 00853 * For complex data, this specifies the component of the complex data whose 00854 * value should be returned. 00855 * 00856 * @return The data value corresponding to the given complex data component. 00857 */ 00858 static inline double getDataValue(const IntegerComplex& data, ComplexComponent component) 00859 { 00860 return data[component]; 00861 } 00862 00863 /** 00864 * Provided for convenience for template methods, this method simply returns the given value. 00865 * 00866 * @param data 00867 * The data value from which to extract the complex component value. 00868 * @param component 00869 * This value is ignored since the given data value is non-complex. 00870 * 00871 * @return The given data value. 00872 */ 00873 static inline unsigned int getDataValue(const unsigned int& data, ComplexComponent component) 00874 { 00875 return data; 00876 } 00877 00878 /** 00879 * Provided for convenience for template methods, this method simply returns the given value. 00880 * 00881 * @param data 00882 * The data value from which to extract the complex component value. 00883 * @param component 00884 * This value is ignored since the given data value is non-complex. 00885 * 00886 * @return The given data value. 00887 */ 00888 static inline signed int getDataValue(const signed int& data, ComplexComponent component) 00889 { 00890 return data; 00891 } 00892 00893 /** 00894 * Provided for convenience for template methods, this method simply returns the given value. 00895 * 00896 * @param data 00897 * The data value from which to extract the complex component value. 00898 * @param component 00899 * This value is ignored since the given data value is non-complex. 00900 * 00901 * @return The given data value. 00902 */ 00903 static inline float getDataValue(const float& data, ComplexComponent component) 00904 { 00905 return data; 00906 } 00907 00908 /** 00909 * Returns a data value according to a given complex data component. 00910 * 00911 * @param data 00912 * The data value from which to extract the complex component value. 00913 * @param component 00914 * For complex data, this specifies the component of the complex data whose 00915 * value should be returned. 00916 * 00917 * @return The data value corresponding to the given complex data component. 00918 */ 00919 static inline double getDataValue(const FloatComplex& data, ComplexComponent component) 00920 { 00921 return data[component]; 00922 } 00923 00924 /** 00925 * Provided for convenience for template methods, this method simply returns the given value. 00926 * 00927 * @param data 00928 * The data value from which to extract the complex component value. 00929 * @param component 00930 * This value is ignored since the given data value is non-complex. 00931 * 00932 * @return The given data value. 00933 */ 00934 static inline double getDataValue(const double& data, ComplexComponent component) 00935 { 00936 return data; 00937 } 00938 00939 /** 00940 * Queries a element to see if it is a kind of another element. 00941 * 00942 * This method check type compatibility between two data elements. This 00943 * functionality is different than TypeAwareObject::isKindOf() in that only 00944 * DataElement-derived classes are checked. 00945 * 00946 * @param className 00947 * The name of the DataElement-derived class to query. 00948 * @param elementName 00949 * The DataElement-derived class name to check type compatibility. 00950 * 00951 * @return Returns true if the given element name is a kind of the given class 00952 * name, otherwise false. 00953 */ 00954 virtual bool isKindOfElement(const std::string& className, const std::string& elementName) const = 0; 00955 00956 /** 00957 * Returns a list of inherited data element class names for a given class name. 00958 * 00959 * This method populates a vector with the class names of all inherited DataElement 00960 * class types. The given class name is used as the initial class for populating the 00961 * vector. For example, passing in "RasterElement" as a class name populates a 00962 * vector with the "RasterElement" and "DataElement" 00963 * strings. 00964 * 00965 * @param className 00966 * The data element class name for which to get all inherited element types. 00967 * @param classList 00968 * This vector is populated with the class names of all inherited data 00969 * element classes and the given class name. 00970 */ 00971 virtual void getElementTypes(const std::string& className, std::vector<std::string>& classList) const = 0; 00972 00973 /** 00974 * Queries a data descriptor to see if it is a kind of another data descriptor. 00975 * 00976 * This method check type compatibility between two data descriptors. This 00977 * functionality is different than TypeAwareObject::isKindOf() in that only 00978 * DataDescriptor-derived classes are checked. 00979 * 00980 * @param className 00981 * The name of the DataDescriptor-derived class to query. 00982 * @param descriptorName 00983 * The DataDescriptor-derived class name to check type compatibility. 00984 * 00985 * @return Returns true if the given data descriptor name is a kind of the 00986 * given class name, otherwise false. 00987 */ 00988 virtual bool isKindOfDataDescriptor(const std::string& className, const std::string& descriptorName) const = 0; 00989 00990 /** 00991 * Returns a list of inherited data descriptor class names for a given class name. 00992 * 00993 * This method populates a vector with the class names of all inherited DataDescriptor 00994 * class types. The given class name is used as the initial class for populating the 00995 * vector. For example, passing in "RasterDataDescriptor" as a class name populates a 00996 * vector with the "RasterDataDescriptor" and "DataDescriptor" strings. 00997 * 00998 * @param className 00999 * The data descriptor class name for which to get all inherited descriptor types. 01000 * @param classList 01001 * This vector is populated with the class names of all inherited data 01002 * descriptor classes and the given class name. 01003 */ 01004 virtual void getDataDescriptorTypes(const std::string& className, std::vector<std::string>& classList) const = 0; 01005 01006 /** 01007 * Queries a file descriptor to see if it is a kind of another file descriptor. 01008 * 01009 * This method check type compatibility between two file descriptors. This 01010 * functionality is different than TypeAwareObject::isKindOf() in that only 01011 * FileDescriptor-derived classes are checked. 01012 * 01013 * @param className 01014 * The name of the FileDescriptor-derived class to query. 01015 * @param descriptorName 01016 * The FileDescriptor-derived class name to check type compatibility. 01017 * 01018 * @return Returns true if the given file descriptor name is a kind of the 01019 * given class name, otherwise false. 01020 */ 01021 virtual bool isKindOfFileDescriptor(const std::string& className, const std::string& descriptorName) const = 0; 01022 01023 /** 01024 * Returns a list of inherited file descriptor class names for a given class name. 01025 * 01026 * This method populates a vector with the class names of all inherited FileDescriptor 01027 * class types. The given class name is used as the initial class for populating the 01028 * vector. For example, passing in "RasterFileDescriptor" as a class name 01029 * populates a vector with the "RasterFileDescriptor" and "FileDescriptor", strings. 01030 * 01031 * @param className 01032 * The file descriptor class name for which to get all inherited descriptor types. 01033 * @param classList 01034 * This vector is populated with the class names of all inherited file 01035 * descriptor classes and the given class name. 01036 */ 01037 virtual void getFileDescriptorTypes(const std::string& className, std::vector<std::string>& classList) const = 0; 01038 01039 protected: 01040 /** 01041 * This will be cleaned up during application close. Plug-ins do not 01042 * need to destroy it. 01043 */ 01044 virtual ~ModelServices() {} 01045 }; 01046 01047 /** 01048 * Converts a pointer of one type to a pointer of another type. 01049 * 01050 * This cast is provided as a convenience to directly cast from a DataElement 01051 * as returned by ModelServices::getElement() to the custom AnyData object 01052 * stored in an Any element. If the requested type is registered with 01053 * ModelServices::addElementType() and stored in an Any element, this cast 01054 * returns a pointer to the custom data type; otherwise this cast is simply 01055 * a wrapper around a dynamic_cast. 01056 * 01057 * @param pSourcePtr 01058 * The pointer to convert to a pointer of the requested type. 01059 * 01060 * @return A pointer of the requested type. \b NULL is returned if the 01061 * given pointer cannot be dynamic_cast to the requested type or if 01062 * the given Any element pointer does not contain data of the 01063 * requested type. 01064 * 01065 * @see DataElement::isKindOf() 01066 * 01067 * @relates ModelServices 01068 */ 01069 template<typename Destination, typename Source> 01070 Destination model_cast(Source pSourcePtr) 01071 { 01072 if (pSourcePtr == NULL) 01073 { 01074 return NULL; 01075 } 01076 01077 Destination pDestPtr = dynamic_cast<Destination>(pSourcePtr); 01078 if (pDestPtr == NULL) 01079 { 01080 Any* pAny = dynamic_cast<Any*>(pSourcePtr); 01081 if (pAny != NULL) 01082 { 01083 return dynamic_cast<Destination>(pAny->getData()); 01084 } 01085 } 01086 01087 return pDestPtr; 01088 } 01089 01090 #endif