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 DATADESCRIPTOR_H 00011 #define DATADESCRIPTOR_H 00012 00013 #include "Subject.h" 00014 #include "Serializable.h" 00015 #include "TypesFile.h" 00016 00017 #include <string> 00018 #include <vector> 00019 00020 class Classification; 00021 class DataElement; 00022 class DynamicObject; 00023 class FileDescriptor; 00024 class Message; 00025 00026 /** 00027 * Describes a data element. 00028 * 00029 * A data descriptor contains all ancillary data for a DataElement that is 00030 * not part of the raw data. ModelServices stores elements based on a key 00031 * that is comprised of a name, type, and parent element, which are all stored 00032 * here. For this reason, the data descriptor must be created by calling 00033 * ModelServices::createDataDescriptor() passing in the name, type, and parent 00034 * element. 00035 * 00036 * After the data descriptor is created the name, type, and parent element 00037 * cannot be set directly on the data descriptor object to preserve the 00038 * integrity of the identifying key in ModelServices. After the data 00039 * descriptor is created call ModelServices::setElementName() to change the 00040 * name and ModelServices::setElementParent() to change the parent. 00041 * 00042 * The data descriptor also contains the element classification and metadata, 00043 * a processing location value that indicates how the data was imported and 00044 * where it is accessed, and a FileDescriptor indicating how the data is 00045 * stored in a file on disk. 00046 * 00047 * The file descriptor is intended to indicate how a data element was imported 00048 * and therefore is typically set only by importers and not as a result of 00049 * creating a new data element or exporting an existing data element. The file 00050 * descriptor is owned by the data descriptor class. 00051 * 00052 * This subclass of Subject will notify upon the following conditions: 00053 * - The following methods are called: setClassification(), setMetadata(), 00054 * setProcessingLocation(), setFileDescriptor(), and clone(). 00055 * - The descriptor is renamed. 00056 * - The descriptor's parent data element is changed. 00057 * - All notifications documented in Subject. 00058 * 00059 * @see DataElement, FileDescriptor 00060 */ 00061 class DataDescriptor : public Subject, public Serializable 00062 { 00063 public: 00064 /** 00065 * Emitted when the descriptor name changes with boost::any<std::string> 00066 * containing the new name. 00067 */ 00068 SIGNAL_METHOD(DataDescriptor, Renamed) 00069 00070 /** 00071 * Emitted when the parent data element changes with 00072 * boost::any<\link DataElement\endlink*> containing a pointer to the new 00073 * parent element. 00074 */ 00075 SIGNAL_METHOD(DataDescriptor, ParentChanged) 00076 00077 /** 00078 * Emitted when the processing location changes with 00079 * boost::any<\link ::ProcessingLocation ProcessingLocation\endlink> 00080 * containing the new processing location. 00081 * 00082 * @see setProcessingLocation() 00083 */ 00084 SIGNAL_METHOD(DataDescriptor, ProcessingLocationChanged) 00085 00086 /** 00087 * Returns the name for the data. 00088 * 00089 * This method returns the name that is used along with the type and parent 00090 * element to uniquely identify a DataElement in ModelServices. To set the 00091 * name after the data descriptor is created, call 00092 * ModelServices::setElementName(). 00093 * 00094 * @return The data name. 00095 */ 00096 virtual const std::string& getName() const = 0; 00097 00098 /** 00099 * Returns the type of the data. 00100 * 00101 * The type is used by ModelServices to determine the kind of element to 00102 * create and is used along with the name and parent element to uniquely 00103 * identify a DataElement. This method returns the type that was specified 00104 * in ModelServices::createDataDescriptor(). 00105 * 00106 * @return The data type. 00107 */ 00108 virtual const std::string& getType() const = 0; 00109 00110 /** 00111 * Returns the parent element. 00112 * 00113 * The parent element is typically the data set to which the element is 00114 * associated. This method returns the parent element that is used along 00115 * with the name and type to uniquely identify a DataElement in 00116 * ModelServices. To set the parent after the data descriptor is created, 00117 * call ModelServices::setElementParent(). 00118 * 00119 * @return The element's associated parent element. \b NULL is returned 00120 * if the element does not have a parent. 00121 */ 00122 virtual DataElement* getParent() const = 0; 00123 00124 /** 00125 * Returns the parent element designator. 00126 * 00127 * The parent element designator is a vector of strings such that the first 00128 * string is the name of a top level element, the second is the name of a child 00129 * of that element, and so on. This designator identifies the parent element. 00130 * 00131 * @return A parent element designator 00132 * 00133 * @see getParent(), ModelServices::createDataDescriptor(const std::string&,const std::string&, const std::vector<std::string>&) const 00134 */ 00135 virtual std::vector<std::string> getParentDesignator() const = 0; 00136 00137 /** 00138 * Sets the element's classification object. 00139 * 00140 * The classification object documents how the data in element is to be 00141 * handled and/or restricted. 00142 * 00143 * This method performs a deep copy of the given classification object, so 00144 * it is the responsibility of the calling object to delete the 00145 * classification object when necessary. 00146 * 00147 * @param pClassification 00148 * The classification for the element. A deep copy is performed 00149 * so it is the responsibility of the calling object to delete 00150 * the given classifcation object when necessary. This method 00151 * does nothing if \b NULL is passed in. 00152 * 00153 * @notify This method notifies Subject::signalModified if the given 00154 * classification is non-NULL and is different than the current 00155 * classification. 00156 * 00157 * @see Classification 00158 */ 00159 virtual void setClassification(const Classification* pClassification) = 0; 00160 00161 /** 00162 * Returns access to the element's classification object. 00163 * 00164 * The classification object documents how the data in element is to be 00165 * handled and/or restricted. 00166 * 00167 * @return A pointer to the element's classification object. 00168 * 00169 * @see Classification 00170 */ 00171 virtual Classification* getClassification() = 0; 00172 00173 /** 00174 * Returns read-only access to the element's classification object. 00175 * 00176 * The classification object documents how the data in element is to be 00177 * handled and/or restricted. 00178 * 00179 * @return A const pointer to the element's classification object. The 00180 * classification represented by the returned pointer should not 00181 * be modified. To modify the values, use the non-const version 00182 * of this method. 00183 * 00184 * @see Classification 00185 */ 00186 virtual const Classification* getClassification() const = 0; 00187 00188 /** 00189 * Sets the element's metadata. 00190 * 00191 * This method performs a deep copy of the given metadata dynamic object, 00192 * so it is the responsibility of the calling object to delete the metadata 00193 * object when necessary. 00194 * 00195 * @param pMetadata 00196 * The element metadata. Passing in \b NULL will clear all 00197 * existing metadata. A deep copy is performed so it is the 00198 * responsibility of the calling object to delete the given 00199 * metadata object when necessary. 00200 * 00201 * @notify This method notifies Subject::signalModified if the given 00202 * metadata object is different than the current metadata object. 00203 */ 00204 virtual void setMetadata(const DynamicObject* pMetadata) = 0; 00205 00206 /** 00207 * Returns a pointer to the element's metadata values. 00208 * Please see \ref specialmetadata for details on 00209 * special entries in the metadata that the application will 00210 * attempt to use. 00211 * 00212 * @return A pointer to the element's metadata as a DynamicObject. 00213 */ 00214 virtual DynamicObject* getMetadata() = 0; 00215 00216 /** 00217 * Returns read-only access to the element's metadata values. 00218 * Please see \ref specialmetadata for details on 00219 * special entries in the metadata that the application will 00220 * attempt to use. 00221 * 00222 * @return A const pointer to the element's metadata as a DynamicObject. 00223 * The metadata represented by the returned pointer should not be 00224 * modified. To modify the values, call the non-const version of 00225 * getMetadata(). 00226 */ 00227 virtual const DynamicObject* getMetadata() const = 0; 00228 00229 /** 00230 * Specifies the location from where the element data will be accessed. 00231 * 00232 * The processing location specifies how the element data should imported 00233 * and how it will be accessed after importing. This allows for processing 00234 * large data sets that cannot be loaded entirely into memory. The default 00235 * location is \link ProcessingLocation::IN_MEMORY IN_MEMORY\endlink. 00236 * 00237 * @param processingLocation 00238 * The processing location for the element data. 00239 * 00240 * @notify This method notifies signalProcessingLocationChanged() if the 00241 * given processing location is different than the current 00242 * processing location. 00243 */ 00244 virtual void setProcessingLocation(ProcessingLocation processingLocation) = 0; 00245 00246 /** 00247 * Returns the location for where the element data is processed. 00248 * 00249 * @return The processing location of the element data. 00250 * 00251 * @see setProcessingLocation() 00252 */ 00253 virtual ProcessingLocation getProcessingLocation() const = 0; 00254 00255 /** 00256 * Sets a file descriptor to indicate how the data is stored on disk. 00257 * 00258 * By default, the data descriptor contains a \b NULL file descriptor, 00259 * which indicates that the data element was not created as a result of an 00260 * import. By calling this method with a non-NULL value, the data element 00261 * is marked as having a corresponding file on disk from which the data 00262 * was imported. 00263 * 00264 * The file descriptor is intended to indicate how a data element was 00265 * imported and therefore this method should typically be called only by 00266 * importers and not as a result of creating a new data element or 00267 * exporting an existing data element. 00268 * 00269 * This method performs a deep copy of the given file descriptor, so it is 00270 * the responsibility of the calling object to delete the file descriptor 00271 * when necessary. 00272 * 00273 * @param pFileDescriptor 00274 * The file descriptor describing how the data is stored on disk. 00275 * A deep copy is performed so the calling object is responsible 00276 * for deleting the given file descriptor when necessary. Passing 00277 * in \b NULL indicates that the data element was not created as a 00278 * result of an import. 00279 * 00280 * @notify This method notifies Subject::signalModified if the given 00281 * file descriptor is different than the current file descriptor. 00282 */ 00283 virtual void setFileDescriptor(const FileDescriptor* pFileDescriptor) = 0; 00284 00285 /** 00286 * Returns the file descriptor indicating how the data is stored on disk. 00287 * 00288 * @return A pointer to the file descriptor describing how the data is 00289 * stored on disk. Do not delete this pointer since it's owned by 00290 * the data descriptor which will handle its deletion. 00291 * If \b NULL is returned, this indicates that the data element 00292 * was not created as a result of an import. 00293 * 00294 * @see setFileDescriptor() 00295 */ 00296 virtual FileDescriptor* getFileDescriptor() = 0; 00297 00298 /** 00299 * Returns read-only access to the file descriptor indicating how the data 00300 * is stored on disk. 00301 * 00302 * @return The file descriptor describing how the data is stored on disk. 00303 * The file descriptor represented by the returned pointer should 00304 * not be modified. To modify the values, call the non-const 00305 * version of getFileDescriptor(). Do not delete this pointer 00306 * since it's owned by the data descriptor which will handle its 00307 * deletion. If \b NULL is returned, this indicates that the data 00308 * element was not created as a result of an import. 00309 * 00310 * @see setFileDescriptor() 00311 */ 00312 virtual const FileDescriptor* getFileDescriptor() const = 0; 00313 00314 /** 00315 * Creates a duplicate data descriptor based on this data descriptor. 00316 * 00317 * This is typically used to deep copy a data descriptor when a non-shared 00318 * copy is required. If the data element for this data descriptor already 00319 * exists, the created data descriptor should not be used to create a new 00320 * data element as the element already exists. 00321 * 00322 * @return A duplicate copy of this data descriptor or \c NULL if there was 00323 * an error. The returned data descriptor contains the same 00324 * classification settings as this data descriptor. 00325 * 00326 * @see copy(const std::string&, DataElement*) const, 00327 * copy(const std::string&, const std::vector<std::string>&) const, 00328 * clone() 00329 */ 00330 virtual DataDescriptor* copy() const = 0; 00331 00332 /** 00333 * Creates a new data descriptor based on this data descriptor. 00334 * 00335 * This method creates a new data descriptor by calling 00336 * ModelServices::createDataDescriptor() and sets the values of the created 00337 * descriptor to this object's values. Because ModelServices uses the 00338 * name and parent element as unique identifiers, a new name and/or 00339 * parent should be passed into this method for the call to 00340 * ModelServices::createDataDescriptor() to succeed. The type of this 00341 * descriptor is used as the type for the new descriptor. 00342 * 00343 * @param name 00344 * The name for the new element that would be created with the 00345 * returned data descriptor. 00346 * @param pParent 00347 * The parent element for the new element that would be created 00348 * with the returned data descriptor. 00349 * 00350 * @return The new data descriptor containing values identical to the 00351 * values in this data descriptor except for the given name and 00352 * parent element. This method will return a valid data 00353 * descriptor even if a subsequent call to 00354 * ModelServices::createElement() would fail because an element 00355 * already exists with the same name, type, and parent as the 00356 * created data descriptor. The returned data descriptor will have 00357 * the same classification settings as this data descriptor and not 00358 * the classification settings of the given parent element. 00359 * 00360 * @see copy() const, 00361 * copy(const std::string&, const std::vector<std::string>&) const, 00362 * clone() 00363 */ 00364 virtual DataDescriptor* copy(const std::string& name, DataElement* pParent) const = 0; 00365 00366 /** 00367 * Creates a new data descriptor based on this data descriptor. 00368 * 00369 * This method creates a new data descriptor by calling 00370 * ModelServices::createDataDescriptor() and sets the values of the created 00371 * descriptor to this object's values. Because ModelServices uses the 00372 * name and parent element as unique identifiers, a new name and/or 00373 * parent designator should be passed into this method for the call to 00374 * ModelServices::createDataDescriptor() to succeed. The type of this 00375 * descriptor is used as the type for the new descriptor. 00376 * 00377 * @param name 00378 * The name for the new element that would be created with the 00379 * returned data descriptor. 00380 * @param parent 00381 * The designator that identifies the parent element for the 00382 * created data descriptor. The designator is a vector of element 00383 * names such that the first name is a top level element, the 00384 * second name is a child of that element, and so on. 00385 * 00386 * @return The new data descriptor containing values identical to the 00387 * values in this data descriptor except for the given name and 00388 * parent element. This method will return a valid data 00389 * descriptor even if a subsequent call to 00390 * ModelServices::createElement() would fail because an element 00391 * already exists with the same name, type, and parent as the 00392 * created data descriptor. The returned data descriptor will have 00393 * the same classification settings as this data descriptor and not 00394 * the classification settings of the element represented by the 00395 * given parent designator. 00396 * 00397 * @see copy() const, copy(const std::string&, DataElement*) const, 00398 * clone(), getParentDesignator() 00399 */ 00400 virtual DataDescriptor* copy(const std::string& name, const std::vector<std::string>& parent) const = 0; 00401 00402 /** 00403 * Sets all values in this data descriptor to those of another data 00404 * descriptor. 00405 * 00406 * @warning The type of given data descriptor must match the type of this 00407 * data descriptor. 00408 * 00409 * @param pDescriptor 00410 * The data descriptor from which to set all data values in this 00411 * data descriptor. No signal/slot attachments currently defined 00412 * in \em pDescriptor are set into this descriptor. This method 00413 * does nothing and returns \c false if \c NULL is passed in. 00414 * 00415 * @return Returns \c true if all values in this data descriptor were 00416 * successfully set to the values in the given data descriptor; 00417 * otherwise returns \c false. Returns \c false if the type of the 00418 * given data descriptor does not match the type of this data 00419 * descriptor. 00420 * 00421 * @notify This method notifies one or more signals defined in this class 00422 * or its subclasses based on data values that are actually 00423 * changed. 00424 * 00425 * @see copy(), getType() 00426 */ 00427 virtual bool clone(const DataDescriptor* pDescriptor) = 0; 00428 00429 /** 00430 * Adds the current values in this data descriptor to a given message. 00431 * 00432 * This convenience method adds the values in this data descriptor as 00433 * properties to the given message in a message log. 00434 * 00435 * @param pMessage 00436 * The message in the message log for which to add this data 00437 * descriptor's values. 00438 */ 00439 virtual void addToMessageLog(Message* pMessage) const = 0; 00440 00441 protected: 00442 /** 00443 * This should be destroyed by calling ModelServices::destroyDataDescriptor. 00444 */ 00445 virtual ~DataDescriptor() {} 00446 }; 00447 00448 #endif