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 MESSAGE_LOG_H 00011 #define MESSAGE_LOG_H 00012 00013 #include "EnumWrapper.h" 00014 #include "Int64.h" 00015 #include "Serializable.h" 00016 #include "Subject.h" 00017 #include "UInt64.h" 00018 00019 #include <string> 00020 #include <vector> 00021 00022 class DateTime; 00023 class DynamicObject; 00024 class Filename; 00025 class MessageLog; 00026 class Message; 00027 class Step; 00028 00029 /** 00030 * \ingroup ServiceModule 00031 * This class provides an interface to the message logging system. 00032 * A message log is displayed as a tab in the message log window and 00033 * saved to a file of the same name. New messages and steps can be 00034 * added with this interface. This interface can also be attached to receive 00035 * Subject/Observer messages as data is added to the message log. 00036 * 00037 * This subclass of Subject will notify upon the following conditions: 00038 * - The following methods are called: createMessage(), createStep(). 00039 * - A new Message is added to the log; data = any<Message*>. 00040 * - A new property is added to a Message: signalMessageModified with data = any<Message*>. 00041 * - A Message is finalized with data = any<Message*>. 00042 * - A Message is detached or deleted with data = any<Message*>. 00043 * - The MessageLog is deleted. This is called after all cleanup has occured. 00044 * - Everything else documented in Subject. 00045 */ 00046 class MessageLog : public Subject 00047 { 00048 public: // types 00049 /** 00050 * An STL iterator type. Has the semantics of an std::vector 00051 */ 00052 typedef std::vector<Message*>::iterator iterator; 00053 00054 /** 00055 * An STL iterator type. Has the semantics of an std::vector 00056 */ 00057 typedef std::vector<Message*>::const_iterator const_iterator; 00058 00059 /** 00060 * A type representing sizes and indices 00061 */ 00062 typedef ::size_t size_t; 00063 00064 public: // methods 00065 /** 00066 * Emitted with any<Message*> when a message is added to the log. 00067 */ 00068 SIGNAL_METHOD(MessageLog, MessageAdded) 00069 /** 00070 * Emitted with any<Message*> when a message in the log changes. 00071 */ 00072 SIGNAL_METHOD(MessageLog, MessageModified) 00073 /** 00074 * Emitted with any<Message*> when a message in the log is finalized. 00075 */ 00076 SIGNAL_METHOD(MessageLog, MessageHidden) 00077 /** 00078 * Emitted with any<Message*> when a message is deleted from the log. 00079 */ 00080 SIGNAL_METHOD(MessageLog, MessageDeleted) 00081 /** 00082 * Emitted with any<Message*> when a message is detached from the log. 00083 */ 00084 SIGNAL_METHOD(MessageLog, MessageDetached) 00085 00086 /** 00087 * Creates a new message to be added to a log. 00088 * 00089 * %Properties can be added to the message until it is finalized. 00090 * Messages should be used to log information 00091 * that is not necessary to repeat a process, but is informative only. This could 00092 * include intermediate results from an algorithm or detailed information about 00093 * a failure. A component and key must be provided to uniquely 00094 * identify a message. The purpose of the component and key is to allow 00095 * messages to be uniquely identified between versions of the software, so that 00096 * any code that may subscribe to messages or parses the message log does 00097 * not need to be regularly updated. 00098 * 00099 * @param action 00100 * A string describing the nature of the event that triggered the message. 00101 * @param component 00102 * A string specifying the component that is requesting a message 00103 * be created, for example the name of the plug-in suite logging the message. 00104 * @param key 00105 * A string that specifies a identifier for this message being 00106 * created. The key combined with the component shall uniquely 00107 * identify a message. 00108 * @param finalizeOnCreate 00109 * If this is \c true, the Message will be automatically finalized. 00110 * @param recurse 00111 * If this is \c true, steps are recursed and the Message 00112 * is added to the deepest un-finalized step. 00113 * 00114 * @return A pointer to the message created. This pointer will be valid until it 00115 * is finalized. 00116 * 00117 * @notify This method will notify signalMessageAdded() with 00118 * boost::any<\link Message \endlink*>. 00119 * 00120 * @see Message::finalize() 00121 */ 00122 virtual Message* createMessage(const std::string& action, const std::string& component, const std::string& key, 00123 bool finalizeOnCreate = false, bool recurse = true) = 0; 00124 00125 /** 00126 * Creates a new 'step' message to be added to a log. 00127 * 00128 * %Properties can be added to the message until it is finalized. 'Step' 00129 * messages should be used to log information that is necessary to repeat 00130 * a process. Steps can have sub-steps. After creating a 'step' message, 00131 * all properties necessary to duplicate that step should be added to the 00132 * message. A component and key must be provided to uniquely 00133 * identify a step. The purpose of the component and key is to allow 00134 * steps to be uniquely identified between versions of the software, so that 00135 * any code that may subscribe to steps or parses the message log does 00136 * not need to be regularly updated. 00137 * 00138 * @param action 00139 * A string describing the nature of the event that triggered the message. 00140 * @param component 00141 * A string specifying the component that is requesting a step 00142 * be created, for example the name of the plug-in suite logging the step. 00143 * @param key 00144 * A string that specifies a identifier for this step being 00145 * created. The key combined with the component shall uniquely 00146 * identify a step. 00147 * @param recurse 00148 * If this is \c true, steps are recursed and the new Step 00149 * is added to the deepest un-finalized step. 00150 * 00151 * @return A pointer to the message created. This pointer will be valid until it 00152 * is finalized. 00153 * 00154 * @notify This method will notify signalMessageAdded() with 00155 * boost::any<\link Message \endlink*>. 00156 * 00157 * @see Step::finalize() 00158 */ 00159 virtual Step* createStep(const std::string& action, const std::string& component, const std::string& key, 00160 bool recurse = true) = 0; 00161 00162 /** 00163 * Get the name of this message log 00164 * 00165 * @return The name of this log 00166 */ 00167 virtual const std::string& getLogName() const = 0; 00168 00169 /** 00170 * Obtain the count of Messages in this %MessageLog. 00171 * 00172 * @return the number of Messages 00173 */ 00174 virtual MessageLog::size_t size() const = 0; 00175 00176 /** 00177 * Obtain an STL iterator over Messages in this %MessageLog 00178 * starting at the begining of the vector. 00179 * 00180 * This iterator has the behavior of a std::vector::iterator 00181 * 00182 * @return an iterator over the %MessageLog's Messages 00183 */ 00184 virtual MessageLog::iterator begin() = 0; 00185 00186 /** 00187 * Obtain an STL const_iterator over Messages in this %MessageLog 00188 * starting at the begining of the vector. 00189 * 00190 * This iterator has the behavior of a std::vector::const_iterator 00191 * 00192 * @return a const_iterator over the %MessageLog's Messages 00193 */ 00194 virtual MessageLog::const_iterator begin() const = 0; 00195 00196 /** 00197 * Obtain an STL iterator over Messages in this %MessageLog 00198 * starting at the end of the vector. 00199 * 00200 * This iterator has the behavior of a std::vector::iterator 00201 * 00202 * @return an iterator over the %MessageLog's Messages 00203 */ 00204 virtual MessageLog::iterator end() = 0; 00205 00206 /** 00207 * Obtain an STL const_iterator over Messages in this %MessageLog 00208 * starting at the end of the vector. 00209 * 00210 * This iterator has the behavior of a std::vector::const_iterator 00211 * 00212 * @return a const_iterator over the %MessageLog's Messages 00213 */ 00214 virtual MessageLog::const_iterator end() const = 0; 00215 00216 /** 00217 * Get the %Message at index \a i. 00218 * 00219 * This function has the same semantics as std::vector::operator[]. It 00220 * does not ensure that \a i is a valid index. 00221 * 00222 * @param i The index to return. 00223 * 00224 * @return The %Message requested 00225 */ 00226 virtual Message *operator[](MessageLog::size_t i) = 0; 00227 virtual const Message *operator[](MessageLog::size_t i) const = 0; 00228 00229 protected: 00230 /** 00231 * This will be cleaned up during application close. Plug-ins do not 00232 * need to destroy it. 00233 */ 00234 virtual ~MessageLog() {} 00235 }; 00236 00237 /** 00238 * This interface represents an individual message in a message log. 00239 * These messages can contain properties which describe the message in 00240 * greater detail or provide useful parameters associated with a message. 00241 * 00242 * Message is a subclass of Subject It will notify upon the following conditions: 00243 * - The following methods are called: addProperty(), addBooleanProperty(), 00244 * finalize(), 00245 * - Everything else documented in Subject. 00246 */ 00247 class Message : public Serializable, public Subject 00248 { 00249 public: // types 00250 /** 00251 * Specifies the result state of a step 00252 */ 00253 enum ResultEnum 00254 { 00255 Success, /**< The step completed successfully. */ 00256 Failure, /**< The step failed to complete. */ 00257 Abort, /**< The step was aborted by the user. */ 00258 Unresolved /**< The step has not yet completed. */ 00259 }; 00260 00261 /** 00262 * @EnumWrapper Message::ResultEnum. 00263 */ 00264 typedef EnumWrapper<ResultEnum> Result; 00265 00266 public: // methods 00267 /** 00268 * Emitted with any<Message*> when a property is added to the message. 00269 */ 00270 SIGNAL_METHOD(Message, MessageModified) 00271 /** 00272 * Emitted with any<Message*> when a message is finalized. 00273 */ 00274 SIGNAL_METHOD(Message, Hidden) 00275 00276 /** 00277 * Adds a property to a message. Any number of properties can be added 00278 * to a message. 00279 * 00280 * @param name 00281 * A string naming the property being added. These must be unique 00282 * within a single message. 00283 * @param value 00284 * The value of the property being added. This will be converted to 00285 * a textual equivalent and recorded in the log. 00286 * 00287 * @return true if the property was successfully added; false otherwise. 00288 * 00289 * @notify This method will notify signalMessageModified with any<Message*>. 00290 * 00291 * @see DynamicObject::set 00292 */ 00293 virtual bool addProperty(const std::string &name, const char *value) = 0; 00294 virtual bool addProperty(const std::string &name, char value) = 0; 00295 virtual bool addProperty(const std::string &name, unsigned char value) = 0; 00296 virtual bool addProperty(const std::string &name, short value) = 0; 00297 virtual bool addProperty(const std::string &name, unsigned short value) = 0; 00298 virtual bool addProperty(const std::string &name, int value) = 0; 00299 virtual bool addProperty(const std::string &name, unsigned int value) = 0; 00300 virtual bool addProperty(const std::string &name, long value) = 0; 00301 virtual bool addProperty(const std::string &name, unsigned long value) = 0; 00302 virtual bool addProperty(const std::string &name, Int64 value) = 0; 00303 virtual bool addProperty(const std::string &name, UInt64 value) = 0; 00304 virtual bool addProperty(const std::string &name, float value) = 0; 00305 virtual bool addProperty(const std::string &name, double value) = 0; 00306 virtual bool addProperty(const std::string &name, const std::string &value) = 0; 00307 virtual bool addProperty(const std::string &name, const Filename *value) = 0; 00308 virtual bool addProperty(const std::string &name, const DateTime *value) = 0; 00309 virtual bool addProperty(const std::string &name, const std::vector<char>& value) = 0; 00310 virtual bool addProperty(const std::string &name, const std::vector<unsigned char>& value) = 0; 00311 virtual bool addProperty(const std::string &name, const std::vector<short>& value) = 0; 00312 virtual bool addProperty(const std::string &name, const std::vector<unsigned short>& value) = 0; 00313 virtual bool addProperty(const std::string &name, const std::vector<int>& value) = 0; 00314 virtual bool addProperty(const std::string &name, const std::vector<unsigned int>& value) = 0; 00315 virtual bool addProperty(const std::string &name, const std::vector<long>& value) = 0; 00316 virtual bool addProperty(const std::string &name, const std::vector<unsigned long>& value) = 0; 00317 virtual bool addProperty(const std::string &name, const std::vector<Int64>& value) = 0; 00318 virtual bool addProperty(const std::string &name, const std::vector<UInt64>& value) = 0; 00319 virtual bool addProperty(const std::string &name, const std::vector<float>& value) = 0; 00320 virtual bool addProperty(const std::string &name, const std::vector<double>& value) = 0; 00321 virtual bool addProperty(const std::string &name, const std::vector<bool>& value) = 0; 00322 virtual bool addProperty(const std::string &name, const std::vector<std::string>& value) = 0; 00323 virtual bool addProperty(const std::string &name, const std::vector<const Filename*>& value) = 0; 00324 00325 /** 00326 * Adds a property to a message. Any number of properties can be added 00327 * to a message. This method has a different name from the others 00328 * because if C++ cannot find a proper overload for the addProperty 00329 * method, it will implicitly convert it to a bool. If this method 00330 * was called addProperty, it would be implicitly called by C++, without 00331 * displaying a warning of any type during compilation. 00332 * 00333 * @param name 00334 * A string naming the property being added. These must be unique 00335 * within a single message. 00336 * @param value 00337 * The value of the property being added. This will be converted to 00338 * a textual equivalent and recorded in the log. 00339 * 00340 * @return true if the property was successfully added; false otherwise. 00341 * 00342 * @notify This method will notify signalMessageModified with any<Message*>. 00343 * 00344 * @see DynamicObject::set 00345 */ 00346 virtual bool addBooleanProperty(const std::string &name, bool value) = 0; 00347 00348 /** 00349 * If the message is a top level message, it is written to the log. If it is a 00350 * sub-message, it is closed to further modification. No properties can 00351 * be added to the message or any submessages after finalization. The 00352 * message pointer is no longer a valid pointer and must not be 00353 * de-referenced. Upon finalization of a message, the log will notify all 00354 * of its observers, passing the message to them. 00355 * 00356 * @return true if successfully closed or written; false otherwise. 00357 * 00358 * @notify This method will notify signalHidden() with any<Message*>. 00359 */ 00360 virtual bool finalize() = 0; 00361 00362 /** 00363 * Returns whether the message has been finalized by calling the finalize() method. 00364 * 00365 * @return true if the message has been finalized; false otherwise. 00366 */ 00367 virtual bool isFinalized() const = 0; 00368 00369 /** 00370 * Returns the name of the component that created this Message. 00371 * 00372 * @return the name of the component that created this Message. 00373 */ 00374 virtual std::string getComponent() const = 0; 00375 00376 /** 00377 * Returns the name of the key associated with this Message. 00378 * 00379 * The component and key of this Message should uniquely 00380 * identify this particular message instance, even between 00381 * new versions of the software. 00382 * 00383 * @return the name of the key associated with this Message. 00384 */ 00385 virtual std::string getKey() const = 0; 00386 00387 /** 00388 * Get reference to the properties. 00389 * 00390 * @return A reference to the property vector 00391 */ 00392 virtual const DynamicObject *getProperties() const = 0; 00393 00394 /** 00395 * Returns the string that was passed to the original createMessage or 00396 * createStep call. 00397 * 00398 * @return The action string that the message was created with. 00399 */ 00400 virtual std::string getAction() const = 0; 00401 00402 /** 00403 * Convert a property of an arbitrary (but valid) type to a string. 00404 * 00405 * @param type 00406 * the type of pValue 00407 * @param pValue 00408 * pointer to the value 00409 * @return a string representation of pValue 00410 * 00411 * @see addProperty 00412 */ 00413 virtual std::string propertyToString(const std::string &type, void *pValue) const = 0; 00414 00415 /** 00416 * Return a string representation of the ID number of this Message. 00417 * 00418 * An ID number is a serious of point separated numbers such that 00419 * sub-messages of Step 1 are numbered 1.1, 1.2, etc. and sub-messages 00420 * of Step 1.3 are numbered 1.3.1, 1.3.2, etc. 00421 * 00422 * @return a string representation of the ID 00423 */ 00424 virtual std::string getStringId() = 0; 00425 00426 /** 00427 * Returns a string reprsentation of the date and time associated with this Message 00428 * 00429 * @param date 00430 * output parameter which will hold the date string 00431 * @param time 00432 * output parameter which will hold the time string 00433 */ 00434 virtual void serializeDate(std::string &date, std::string &time) const = 0; 00435 00436 protected: 00437 /** 00438 * This will be cleaned up during application close. Plug-ins do not 00439 * need to destroy it. 00440 */ 00441 virtual ~Message() {} 00442 }; 00443 00444 /** 00445 * This interface represents a type of message log Message. Steps represent 00446 * individual algorithmic steps. Each can contain properties and substeps 00447 * which break the algorithm down further. 00448 * 00449 * Step is a subclass of Subject. It will notify upon the following conditions: 00450 * - The following methods are called: addStep(), addMessage(), 00451 * - A sub-Step or Message notifies. An unfinalized Step will forward any 00452 * notification. pValue will be forwarded, containing a Message* of the 00453 * originally notifying Message. 00454 * - Everything else documented in Message. 00455 */ 00456 class Step : public Message 00457 { 00458 public: // types 00459 /** 00460 * An STL iterator type. Has the semantics of an std::vector 00461 */ 00462 typedef std::vector<Message*>::iterator iterator; 00463 00464 /** 00465 * An STL iterator type. Has the semantics of an std::vector 00466 */ 00467 typedef std::vector<Message*>::const_iterator const_iterator; 00468 00469 /** 00470 * A type representing sizes and indices 00471 */ 00472 typedef ::size_t size_t; 00473 00474 public: // methods 00475 /** 00476 * Emitted with any<Message*> when a message is added to the step. 00477 */ 00478 SIGNAL_METHOD(Step, MessageAdded) 00479 /** 00480 * Emitted with any<Message*> when a message in the step is finalized. 00481 */ 00482 SIGNAL_METHOD(Step, MessageHidden) 00483 /** 00484 * Emitted with any<Message*> when a message is deleted from the step. 00485 */ 00486 SIGNAL_METHOD(Step, MessageDeleted) 00487 /** 00488 * Emitted with any<Message*> when a message is detached from the step. 00489 */ 00490 SIGNAL_METHOD(Step, MessageDetached) 00491 00492 /** 00493 * Creates a new sub-step. 00494 * 00495 * @param action 00496 * A string describing the nature of the event that triggered the message. 00497 * @param component 00498 * A string specifying the component that is requesting a step 00499 * be created, for example the name of the plug-in suite logging the step. 00500 * @param key 00501 * A string that specifies a identifier for this step being 00502 * created. The key combined with the component shall uniquely 00503 * identify a step. 00504 * @param recurse 00505 * If this is true, steps are recursed and the new Step 00506 * is added to the deepest un-finalized step. 00507 * 00508 * @return A pointer to the message created. This pointer will be valid until it 00509 * or a parent message is finalized. This will return NULL if the parent 00510 * Message object isn't a step. 00511 * 00512 * @notify This method will notify signalMessageAdded with any<Message*>. 00513 */ 00514 virtual Step *addStep(const std::string &action, 00515 const std::string &component, 00516 const std::string &key, 00517 bool recurse = true) = 0; 00518 00519 /** 00520 * Adds a sub-message to a step. 00521 * 00522 * @param action 00523 * A string describing the nature of the event that triggered the message. 00524 * @param component 00525 * A string specifying the component that is requesting a message 00526 * be created, for example the name of the plug-in suite logging the message. 00527 * @param key 00528 * A string that specifies a identifier for this message being 00529 * created. The key combined with the component shall uniquely 00530 * identify a message. 00531 * @param finalizeOnCreate 00532 * If this is true, the Message will be automatically finalize()'d 00533 * @param recurse 00534 * If this is true, steps are recursed and the Message 00535 * is added to the deepest un-finalized step. 00536 * 00537 * @return A pointer to the message created. This pointer will be valid until it 00538 * or a parent message is finalized. 00539 * 00540 * @notify This method will notify signalMessageAdded with any<Message*>. 00541 */ 00542 virtual Message *addMessage(const std::string &action, 00543 const std::string &component, 00544 const std::string &key, 00545 bool finalizeOnCreate = false, 00546 bool recurse = true) = 0; 00547 00548 /** 00549 * If the step is a top-level step (i.e. not a sub-step), this method 00550 * writes the message and any submessages to the log. No properties can 00551 * be added to the message or any submessages after finalization. The 00552 * message pointer and pointers to all of its sub-messages are no longer 00553 * valid pointers and must not be de-referenced. 00554 * This will recursively call finalize on all sub-steps and sub-messages, 00555 * passing a Result of Success to the sub-steps. 00556 * Calling finalize on a sub-step or sub-message closes the message 00557 * or step and all sub-messages or sub-steps to modification, but does not 00558 * cause the sub-step or sub-message to be written to disk. Serialize only 00559 * actually writes to disk when called on a top-level step or message. 00560 * Upon finalization of a message, the log will notify all of its observers. 00561 * 00562 * @param result 00563 * An indication of the cause of the completion of the step. 00564 * 00565 * @param failureReason 00566 * An message that indicates the reason for step failure. This 00567 * should ony be used to provided details in the case of 00568 * message failure. 00569 * 00570 * @return true if successfully closed or written; false otherwise. 00571 */ 00572 virtual bool finalize(Result result, const std::string& failureReason = "") = 0; 00573 00574 /** 00575 * This method finalizes the current Step with the result being \link Message::Success\endlink 00576 * and an empty failure reason string. 00577 * 00578 * @return \c true if the step is successfully closed or written; otherwise returns \c false. 00579 */ 00580 virtual bool finalize() = 0; 00581 00582 /** 00583 * This method returns the failure message passed to the finalize 00584 * method or an string of length zero if no failure message was 00585 * provided. 00586 * 00587 * @return the failure message provided to the finalize method. 00588 * 00589 * @see Step::finalize 00590 */ 00591 virtual const std::string& getFailureMessage() const = 0; 00592 00593 /** 00594 * Get the result associated with this Step 00595 * 00596 * @return The Result of this Step. 00597 */ 00598 virtual Result getResult() const = 0; 00599 00600 /** 00601 * Obtain the count of Messages in this %Step. 00602 * 00603 * @return the number of Messages 00604 */ 00605 virtual Step::size_t size() const = 0; 00606 00607 /** 00608 * Obtain an STL iterator over Messages in this %Step 00609 * starting at the begining of the vector. 00610 * 00611 * This iterator has the behavior of a std::vector::iterator 00612 * 00613 * @return an iterator over the %Step's Messages 00614 */ 00615 virtual Step::iterator begin() = 0; 00616 00617 /** 00618 * Obtain an STL const_iterator over Messages in this %Step 00619 * starting at the begining of the vector. 00620 * 00621 * This iterator has the behavior of a std::vector::const_iterator 00622 * 00623 * @return a const_iterator over the %Step's Messages 00624 */ 00625 virtual Step::const_iterator begin() const = 0; 00626 00627 /** 00628 * Obtain an STL iterator over Messages in this %Step 00629 * starting at the end of the vector. 00630 * 00631 * This iterator has the behavior of a std::vector::iterator 00632 * 00633 * @return an iterator over the %Step's Messages 00634 */ 00635 virtual Step::iterator end() = 0; 00636 00637 /** 00638 * Obtain an STL const_iterator over Messages in this %Step 00639 * starting at the end of the vector. 00640 * 00641 * This iterator has the behavior of a std::vector::const_iterator 00642 * 00643 * @return a const_iterator over the %Step's Messages 00644 */ 00645 virtual Step::const_iterator end() const = 0; 00646 00647 /** 00648 * Get the %Message at index \a i. 00649 * 00650 * This function has the same semantics as std::vector::operator[]. It 00651 * does not ensure that \a i is a valid index. 00652 * 00653 * @param i The index to return. 00654 * 00655 * @return The %Message requested 00656 */ 00657 virtual Message *operator[](Step::size_t i) = 0; 00658 virtual const Message *operator[](Step::size_t i) const = 0; 00659 00660 protected: 00661 /** 00662 * This will be cleaned up during application close. Plug-ins do not 00663 * need to destroy it. 00664 */ 00665 virtual ~Step() {} 00666 }; 00667 00668 #endif