ModelServices.h

Go to the documentation of this file.
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

Software Development Kit - Opticks 4.9.0 Build 16218