casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LoggerHolder.h
Go to the documentation of this file.
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