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 SIGNATURE_H 00011 #define SIGNATURE_H 00012 00013 #include "DataElement.h" 00014 #include "DataVariant.h" 00015 00016 #include <set> 00017 #include <string> 00018 #include <vector> 00019 00020 class Units; 00021 00022 /** 00023 * Signature with identifying attributes 00024 * 00025 * A signature is an object that essentially consists of a map of data sets, along with a map of 00026 * optional Units objects. Each data set is referred to as a component of the signature. 00027 * The unique name associated with each data set is called its component name and is the key for 00028 * the map of data sets. The optional Units object associated with a data set is stored in a map using the 00029 * data set component name as the key. 00030 * 00031 * This subclass of Subject will notify upon the following conditions: 00032 * - The following method is called: setData(). 00033 * - Everything else documented in DataElement. 00034 * 00035 * @see DataElement, Units 00036 */ 00037 class Signature : public DataElement 00038 { 00039 public: 00040 /** 00041 * Emitted with any<std::pair<string,DataVariant> > when an attribute is added or changed. 00042 */ 00043 SIGNAL_METHOD(Signature, DataChanged) 00044 00045 /** 00046 * Gets a data set from the signature. 00047 * 00048 * This method returns a data set from the signature in the form of a 00049 * DataVariant. 00050 * 00051 * @param name 00052 * The name of the data set, as provided when the data set was 00053 * added to the Signature. 00054 * 00055 * @return A DataVariant containing the requested data set. If no data 00056 * set exists in the signature with the specified name, it will 00057 * return an invalid DataVariant. 00058 * 00059 * @see DataVariant::isValid() 00060 */ 00061 virtual const DataVariant& getData(const std::string& name) const = 0; 00062 00063 /** 00064 * Adds a data set to the signature. 00065 * 00066 * This method adds a data set to the signature. A deep copy of the 00067 * value will be performed. If a data set already exists in the 00068 * Signature with the name specified, it will be replaced with the new 00069 * value. 00070 * 00071 * This method is preferred to adoptData() unless 00072 * you are passing an already constructed DataVariant in 00073 * which case, adoptData() will be faster because 00074 * it avoids a deep copy. 00075 * 00076 * @param name 00077 * The name of the data set to be added to the signature. 00078 * 00079 * @param data 00080 * The data set to be added to the Signature. For example: 00081 * 00082 * @code 00083 * bool populateSignature(Signature *pSig, 00084 * const vector<double> &wavelengths, 00085 * const vector<double> &reflectances) 00086 * { 00087 * if (pSig == NULL) return false; 00088 * pSig->setData("wavelengths", wavelengths); 00089 * pSig->setData("reflectances", reflectances); 00090 * return true; 00091 * } 00092 * @endcode 00093 * 00094 * @notify This method will notify signalDataChanged with 00095 * any<std::pair<string,DataVariant> > after the 00096 * data set is added to the Signature. 00097 */ 00098 template<typename T> 00099 void setData(const std::string& name, const T& data) 00100 { 00101 DataVariant temp(data); 00102 adoptData(name, temp); 00103 } 00104 00105 /** 00106 * Adds a data set to the signature. 00107 * 00108 * This method adds a data set to the signature. A deep copy of the 00109 * value will be performed. If a data set already exists in the 00110 * Signature with the name specified, it will be replaced with the new 00111 * value. 00112 * 00113 * This method should not be used; generally setData() is 00114 * preferred. This method and setData() have identical 00115 * performance characteristics and setData() is easier to 00116 * call. This method is faster than setData() though if 00117 * you have an already constructed DataVariant and is 00118 * preferred to setData() in this case. 00119 * 00120 * @param name 00121 * The name of the data set to be added to the signature. 00122 * 00123 * @param data 00124 * The data set to be added to the Signature. On return, this 00125 * will contain the value previously stored. If the value did 00126 * not previously exist, then this will contain an invalid 00127 * DataVariant. 00128 * 00129 * @notify This method will notify signalDataChanged with 00130 * any<std::pair<string,DataVariant> > after the 00131 * data set is added to the Signature. 00132 */ 00133 virtual void adoptData(const std::string& name, DataVariant& data) = 0; 00134 00135 00136 /** 00137 * A convenience method that returns the Units object returned from calling 00138 * SignatureDataDescriptor::getUnits. 00139 * 00140 * @param name 00141 * The component name of the Units object to get from the signature. 00142 * 00143 * @return A pointer to the Units object with the specified component name. \c NULL 00144 * will be returned if no Units object exists with the specified 00145 * name. 00146 * 00147 * @note This pointer should not be stored. It may become invalid at a later time. 00148 */ 00149 virtual const Units* getUnits(const std::string& name) const = 0; 00150 00151 /** 00152 * Gets the names associated with data in this Signature. 00153 * 00154 * @return set of names 00155 */ 00156 virtual std::set<std::string> getDataNames() const = 0; 00157 00158 /** 00159 * Gets the names associated with units in this Signature. 00160 * 00161 * @return set of names 00162 */ 00163 virtual std::set<std::string> getUnitNames() const = 0; 00164 00165 protected: 00166 /** 00167 * This should be destroyed by calling ModelServices::destroyElement. 00168 */ 00169 virtual ~Signature() {} 00170 }; 00171 00172 #endif // SIGNATURE_H