casa
$Rev:20696$
|
00001 //# LoggerHolder.h: Class holding a hierarchy of loggers 00002 //# Copyright (C) 2001,2003 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# 00027 //# $Id: LoggerHolder.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $ 00028 00029 #ifndef TABLES_LOGGERHOLDER_H 00030 #define TABLES_LOGGERHOLDER_H 00031 00032 //# Includes 00033 #include <casa/Logging/LogIO.h> 00034 #include <casa/Containers/Block.h> 00035 #include <casa/Utilities/CountedPtr.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 //# Forward Declarations 00040 class LoggerHolderRep; 00041 class LoggerHolderIterator; 00042 class TableLogSink; 00043 00044 // <summary> 00045 // Class holding a hierarchy of loggers. 00046 // </summary> 00047 00048 // <use visibility=export> 00049 00050 // <reviewed reviewer="" date="" tests="tLoggerHolder.cc" demos=""> 00051 // </reviewed> 00052 00053 // <prerequisite> 00054 // <li> <linkto class="LogIO">LogIO</linkto> <li> 00055 // </prerequisite> 00056 00057 // <synopsis> 00058 // The LoggerHolder class implements a hierarchy of loggers. 00059 // It has a log sink of its own and can have multiple parent LoggerHolder 00060 // objects representing the log info of parent objects. 00061 // It is used by class 00062 // <linkto class=ImageInterface>ImageInterface</linkto>, but could also 00063 // be used elsewhere. 00064 // 00065 // The sink of a LoggerHolder can be different depending on the type of image. 00066 // E.g. for a transient image it can be a 00067 // <linkto class=MemoryLogSink>MemoryLogSink</linkto>, while for a persistent 00068 // image it will be a <linkto class=TableLogSink>TableLogSink</linkto>. 00069 // <br>An important feature is that an LoggerHolder can have zero or more 00070 // parent LoggerHolder objects. In that way the log of the parent object 00071 // of an image object can be made part of the log of the image object itself, 00072 // without having to copy the log. 00073 // 00074 // To iterate through all messages in a LoggerHolder (including all parents), 00075 // the <linkto class=LoggerHolderIterator>LoggerHolderIterator</linkto> can 00076 // be used. This is an STL-style const_iterator object. 00077 // 00078 // LoggerHolder uses reference counting 00079 // (of class <linkto class=LoggerHolderRep>LoggerHolderRep</linkto>) 00080 // to be able to retain 00081 // the object after the (ImageInterface) object containing it is gone. 00082 // Otherwise classes like SubImage would lose their log info. 00083 // </synopsis> 00084 00085 // <example> 00086 // <srcblock> 00087 // LoggerHolder logger ("tLoggerHolder_tmp.log", True); 00088 // logger.logio() << "test1" << LogIO::POST; 00089 // logger.logio() << "test2" << LogIO::POST; 00090 // for (LoggerHolder::const_iterator iter = logger.begin(); 00091 // iter != logger.end(); 00092 // iter++) { 00093 // cout << iter->time() << ' ' << iter->message() << endl; 00094 // } 00095 // </srcblock> 00096 // This example shows the construction of an LoggerHolder with a 00097 // TableLogSink sink. Thereafter some messages are written. 00098 // The latter part shows how to iterate through all messages. 00099 // 00100 // <srcblock> 00101 // LoggerHolder logger (False); 00102 // logger.addParent (parent.logger()); 00103 // logger.logio() << "test1" << LogIO::POST; 00104 // logger.logio() << "test2" << LogIO::POST; 00105 // </srcblock> 00106 // This example shows the construction of an LoggerHolder with a 00107 // MemoryLogSink sink (e.g. for a SubImage). Thereafter the logger of 00108 // the parent image is added to it. 00109 // Finally some messages are written. 00110 // </example> 00111 00112 // <motivation> 00113 // This class simplifies and unifies all Image logging activities. 00114 // </motivation> 00115 00116 //# <todo asof="2001/06/14"> 00117 //# </todo> 00118 00119 class LoggerHolder 00120 { 00121 public: 00122 // Create with a NullSink or MemoryLogSink (default). 00123 explicit LoggerHolder (Bool nullSink = False); 00124 00125 // Create with a TableLogSink. 00126 LoggerHolder (const String& logTableName, Bool isWritable); 00127 00128 // Copy constructor (reference sematics). 00129 LoggerHolder (const LoggerHolder&); 00130 00131 ~LoggerHolder(); 00132 00133 // Assignment (reference semantics). 00134 LoggerHolder& operator= (const LoggerHolder&); 00135 00136 // Add a logger from a parent. 00137 void addParent (const LoggerHolder&); 00138 00139 // Append the entries of the other logger to this one. 00140 void append (const LoggerHolder& other); 00141 00142 // Reopen a readonly logtable for read/write (if needed). 00143 void reopenRW(); 00144 00145 // Reopen the log table if needed (after a tempClose). 00146 void reopen(); 00147 00148 // Temporarily close all log tables. 00149 // By default the possible parent log tables are also closed. 00150 void tempClose (Bool closeParents = True) const; 00151 00152 // Unlock the log table. 00153 void unlock(); 00154 00155 // Flush the log table. 00156 void flush(); 00157 00158 // Resync the log table (if needed). 00159 void resync(); 00160 00161 // Is the log table temporarily closed? 00162 Bool isTempClosed() const; 00163 00164 // Get access to the logger. 00165 // It assumes that it will be used to post a message, so it reopens 00166 // the log table for read/write if needed). 00167 LogIO& logio(); 00168 00169 // Get access to the log sink (reopen the log table if needed). 00170 // It is not assumed you want to write. If you want to do that, 00171 // you should first call reopenRW() to ensure you can write. 00172 // <group> 00173 LogSink& sink(); 00174 const LogSink& sink() const; 00175 // </group> 00176 00177 // Clear the log. 00178 // It removes the parents and removes all messages from the sink. 00179 void clear(); 00180 00181 // Remove all parents. 00182 void removeParents(); 00183 00184 // Return the block of parents. 00185 const Block<LoggerHolder>& parents() const; 00186 00187 // Define the STL-style iterators. 00188 // Only a const forward iterator is available. 00189 // It makes it possible to iterate through all messages in the logger. 00190 // <srcblock> 00191 // LoggerHolder logger("log.name", False) 00192 // for (LoggerHolder::const_iterator iter=arr.begin(); 00193 // iter!=arr.end(); iter++) { 00194 // cout << iter.message() << endl; 00195 // } 00196 // </srcblock> 00197 // <group name=STL-iterator> 00198 // STL-style typedefs. 00199 typedef LoggerHolderIterator const_iterator; 00200 // Get the begin and end iterator object. 00201 const_iterator begin() const; 00202 const_iterator end() const; 00203 // </group> 00204 00205 00206 private: 00207 CountedPtr<LoggerHolderRep> itsRep; 00208 }; 00209 00210 00211 00212 00213 // <summary> 00214 // Representation of the class holding a hierarchy of loggers. 00215 // </summary> 00216 00217 // <use visibility=local> 00218 00219 // <reviewed reviewer="" date="" tests="tLoggerHolder.cc" demos=""> 00220 // </reviewed> 00221 00222 // <prerequisite> 00223 // <li> <linkto class="LogIO">LogIO</linkto> <li> 00224 // </prerequisite> 00225 00226 // <synopsis> 00227 // The LoggerHolderRep class is the reference counted implementation 00228 // of <linkto class=LoggerHolder>LoggerHolder</linkto>. 00229 // See that class for more information. 00230 // </synopsis> 00231 00232 // <motivation> 00233 // Reference counting was needed to be able to keep a LoggerHolder 00234 // object after the (ImageInterface) object containing it is gone. 00235 // </motivation> 00236 00237 //# <todo asof="2001/06/14"> 00238 //# </todo> 00239 00240 class LoggerHolderRep 00241 { 00242 public: 00243 // Create with a NullSink or MemoryLogSink (default). 00244 LoggerHolderRep (Bool nullSink); 00245 00246 // Create with a TableLogSink. 00247 LoggerHolderRep (const String& logTableName, Bool isWritable); 00248 00249 // Copy constructor. 00250 LoggerHolderRep (const LoggerHolderRep&); 00251 00252 ~LoggerHolderRep(); 00253 00254 // Assignment. 00255 // It removes the current parents. 00256 LoggerHolderRep& operator= (const LoggerHolderRep&); 00257 00258 // Add a logger from a parent. 00259 void addParent (const LoggerHolder&); 00260 00261 // Append the entries of the other logger to this one. 00262 void append (const LoggerHolder& other); 00263 00264 // Reopen a readonly logtable for read/write (if needed). 00265 void reopenRW(); 00266 00267 // Reopen the log table if needed (after a tempClose). 00268 void reopen() 00269 { if (itsIsClosed) doReopen(); } 00270 00271 // Temporarily close all log tables. 00272 // By default the possible parent log tables are also closed. 00273 void tempClose (Bool closeParents = True); 00274 00275 // Unlock the log table. 00276 void unlock(); 00277 00278 // Flush the log table. 00279 void flush(); 00280 00281 // Resync the log table (if needed). 00282 void resync(); 00283 00284 // Is the log table temporarily closed? 00285 Bool isTempClosed() const 00286 { return itsIsClosed; } 00287 00288 // Get access to the logger. 00289 // It assumes that it will be used to post a message, so it reopens 00290 // the log table for read/write if needed). 00291 LogIO& logio(); 00292 00293 // Get access to the log sink (reopen the log table if needed). 00294 // It is not assumed you want to write. If you want to do that, 00295 // you should first call reopenRW() to ensure you can write. 00296 LogSink& sink(); 00297 00298 // Clear the log. 00299 // It removes the parents and removes all messages from the sink. 00300 void clear(); 00301 00302 // Remove all parents. 00303 void removeParents(); 00304 00305 // Return the block of parents. 00306 const Block<LoggerHolder>& parents() const 00307 { return itsParents; } 00308 00309 // Define the STL-style iterators. 00310 // Only a const forward iterator is available. 00311 // It makes it possible to iterate through all messages in the logger. 00312 // <srcblock> 00313 // LoggerHolder logger("log.name", False) 00314 // for (LoggerHolder::const_iterator iter=arr.begin(); 00315 // iter!=arr.end(); iter++) { 00316 // cout << iter.message() << endl; 00317 // } 00318 // </srcblock> 00319 // <group name=STL-iterator> 00320 // STL-style typedefs. 00321 typedef LoggerHolderIterator const_iterator; 00322 // Get the begin and end iterator object. 00323 const_iterator begin() const; 00324 const_iterator end() const; 00325 // </group> 00326 00327 00328 private: 00329 // Do the actual reopen. 00330 void doReopen(); 00331 00332 00333 Block<LoggerHolder> itsParents; 00334 LogSink itsSink; 00335 LogIO itsLogger; 00336 String itsTableName; 00337 TableLogSink* itsTablePtr; 00338 Bool itsIsWritable; 00339 Bool itsIsClosed; 00340 }; 00341 00342 00343 00344 00345 // <summary> 00346 // Class representing an entry in a LoggerHolder. 00347 // </summary> 00348 00349 // <use visibility=local> 00350 00351 // <reviewed reviewer="" date="" tests="tLoggerHolder.cc" demos=""> 00352 // </reviewed> 00353 00354 // <prerequisite> 00355 // <li> <linkto class="LoggerHolder">LoggerHolder</linkto> <li> 00356 // </prerequisite> 00357 00358 // <synopsis> 00359 // This class makes it possible to use the iterator in the STL-style. 00360 // It only contains a 'pointer' to the current entry in the current logger. 00361 // Function like <src>time()</src> can be used to retrieve the message parts. 00362 // </synopsis> 00363 00364 class LogHolderIterEntry 00365 { 00366 public: 00367 LogHolderIterEntry() 00368 : itsSink(0), itsIndex(0) {} 00369 00370 LogHolderIterEntry (const LogSink* sink, uInt index) 00371 : itsSink(sink), itsIndex(index) {} 00372 00373 LogHolderIterEntry (const LogHolderIterEntry& that) 00374 : itsSink(that.itsSink), itsIndex(that.itsIndex) {} 00375 00376 ~LogHolderIterEntry() 00377 {} 00378 00379 LogHolderIterEntry& operator= (const LogHolderIterEntry& that) 00380 { itsSink=that.itsSink; itsIndex=that.itsIndex; return *this; } 00381 00382 // Get the message parts. 00383 // <group> 00384 Double time() const 00385 { return itsSink->getTime(itsIndex); } 00386 String message() const 00387 { return itsSink->getMessage(itsIndex); } 00388 String priority() const 00389 { return itsSink->getPriority(itsIndex); } 00390 String location() const 00391 { return itsSink->getLocation(itsIndex); } 00392 String objectID() const 00393 { return itsSink->getObjectID(itsIndex); } 00394 // </group> 00395 00396 private: 00397 const LogSink* itsSink; 00398 uInt itsIndex; 00399 }; 00400 00401 00402 00403 00404 // <summary> 00405 // Class doing the actual iteration through an LoggerHolder. 00406 // </summary> 00407 00408 // <use visibility=local> 00409 00410 // <reviewed reviewer="" date="" tests="tLoggerHolder.cc" demos=""> 00411 // </reviewed> 00412 00413 // <prerequisite> 00414 // <li> <linkto class="LoggerHolder">LoggerHolder</linkto> <li> 00415 // </prerequisite> 00416 00417 // <synopsis> 00418 // This class makes it possible to use the iterator in the STL-style. 00419 // It is used by 00420 //<linkto class=LoggerHolderIterator>LoggerHolderIterator</linkto> 00421 // which is the class as seen by the user. 00422 // LogHolderIter makes it easier to make the first entry available on 00423 // construction of an LoggerHolderIterator. 00424 // </synopsis> 00425 00426 class LogHolderIter 00427 { 00428 public: 00429 // Construct the iterator on the given LoggerHolderRep. 00430 LogHolderIter (const LoggerHolder*); 00431 00432 ~LogHolderIter(); 00433 00434 // Increment to next message. 00435 // Returns False if at the end. 00436 Bool next(); 00437 00438 // Get the entry. 00439 const LogHolderIterEntry& getEntry() const 00440 { return itsEntry; } 00441 00442 const LoggerHolder& logger() const 00443 { return *itsLogger; } 00444 00445 private: 00446 // Copy constructor is not needed, thus forbidden. 00447 LogHolderIter (const LogHolderIter&); 00448 00449 // Assignment is not needed, thus forbidden. 00450 LogHolderIter& operator= (const LogHolderIter&); 00451 00452 00453 const LoggerHolder* itsLogger; 00454 Bool itsTempClosed; 00455 LogHolderIter* itsParentIter; 00456 uInt itsCounter; 00457 LogHolderIterEntry itsEntry; 00458 }; 00459 00460 00461 00462 // <summary> 00463 // Class to iterate through an LoggerHolder. 00464 // </summary> 00465 00466 // <use visibility=export> 00467 00468 // <reviewed reviewer="" date="" tests="tLoggerHolder.cc" demos=""> 00469 // </reviewed> 00470 00471 // <prerequisite> 00472 // <li> <linkto class="LoggerHolder">LoggerHolder</linkto> <li> 00473 // </prerequisite> 00474 00475 // <synopsis> 00476 // This class makes it possible to iterate in the STL-style through all 00477 // entries of an LoggerHolder object. If the logger has parent LoggerHolder 00478 // objects, it first iterates through all parents (recursively) and 00479 // finally through all entries in the LoggerHolder object itself. 00480 // </synopsis> 00481 00482 // <example> 00483 // <srcblock> 00484 // LoggerHolder logger ("tLoggerHolder_tmp.log", True); 00485 // logger.logio() << "test1" << LogIO::POST; 00486 // logger.logio() << "test2" << LogIO::POST; 00487 // for (LoggerHolder::const_iterator iter = logger.begin(); 00488 // iter != logger.end(); 00489 // iter++) { 00490 // cout << iter->time() << ' ' << iter->message() << endl; 00491 // } 00492 // </srcblock> 00493 // </example> 00494 00495 class LoggerHolderIterator 00496 { 00497 public: 00498 LoggerHolderIterator() 00499 : itsIter(0), itsNotAtEnd(False) {} 00500 00501 LoggerHolderIterator (const LoggerHolder*); 00502 00503 LoggerHolderIterator (const LoggerHolderIterator&); 00504 00505 ~LoggerHolderIterator() 00506 { delete itsIter; } 00507 00508 LoggerHolderIterator& operator= (const LoggerHolderIterator&); 00509 00510 // Increment to next message. 00511 // <group> 00512 void operator++() 00513 { next(); } 00514 void operator++ (int) 00515 { next(); } 00516 // </group> 00517 00518 // Is the iterator not at the end yet? 00519 Bool operator!= (const LoggerHolderIterator&) 00520 { return itsNotAtEnd; } 00521 00522 // Get the entry. 00523 // <group> 00524 const LogHolderIterEntry& operator*() const 00525 { return itsIter->getEntry(); } 00526 const LogHolderIterEntry* operator->() const 00527 { return &(itsIter->getEntry()); } 00528 // </group> 00529 00530 const LoggerHolder& logger() const 00531 { return itsIter->logger(); } 00532 00533 private: 00534 // Get the next entry (if available). 00535 void next() 00536 { itsNotAtEnd = itsIter->next(); } 00537 00538 00539 LogHolderIter* itsIter; 00540 Bool itsNotAtEnd; 00541 }; 00542 00543 00544 00545 inline void LoggerHolder::reopen() 00546 { 00547 itsRep->reopen(); 00548 } 00549 inline Bool LoggerHolder::isTempClosed() const 00550 { 00551 return itsRep->isTempClosed(); 00552 } 00553 inline LogIO& LoggerHolder::logio() 00554 { 00555 return itsRep->logio(); 00556 } 00557 inline LogSink& LoggerHolder::sink() 00558 { 00559 return itsRep->sink(); 00560 } 00561 inline const LogSink& LoggerHolder::sink() const 00562 { 00563 return itsRep->sink(); 00564 } 00565 inline const Block<LoggerHolder>& LoggerHolder::parents() const 00566 { 00567 return itsRep->parents(); 00568 } 00569 inline LoggerHolder::const_iterator LoggerHolder::begin() const 00570 { 00571 return LoggerHolderIterator (this); 00572 } 00573 inline LoggerHolder::const_iterator LoggerHolder::end() const 00574 { 00575 return LoggerHolderIterator(); 00576 } 00577 00578 00579 00580 00581 } //# NAMESPACE CASA - END 00582 00583 #endif