Environment.cpp

Go to the documentation of this file.
00001 #include "tao/Environment.h"
00002 #include "tao/ORB_Core.h"
00003 #include "tao/SystemException.h"
00004 #include "tao/default_environment.h"
00005 
00006 #include "ace/OS_NS_string.h"
00007 
00008 #if !defined (__ACE_INLINE__)
00009 # include "tao/Environment.inl"
00010 #endif /* __ACE_INLINE__ */
00011 
00012 
00013 ACE_RCSID (tao,
00014            Environment,
00015            "$Id: Environment.cpp 76551 2007-01-24 13:42:44Z johnnyw $")
00016 
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 CORBA::Environment::Environment (void)
00021   : exception_ (0)
00022   , previous_ (0)
00023 {
00024 }
00025 
00026 CORBA::Environment::Environment (const CORBA::Environment& rhs)
00027   : exception_ (0)
00028   , previous_ (0)
00029 {
00030   if (rhs.exception_)
00031     this->exception_ = rhs.exception_->_tao_duplicate ();
00032 }
00033 
00034 CORBA::Environment::Environment (TAO_ORB_Core* orb_core)
00035   : exception_ (0)
00036   , previous_ (orb_core->default_environment ())
00037 {
00038   orb_core->default_environment (this);
00039 }
00040 
00041 CORBA::Environment&
00042 CORBA::Environment::operator= (const CORBA::Environment& rhs)
00043 {
00044   CORBA::Environment tmp (rhs);
00045   {
00046     CORBA::Exception *tmp_ex = this->exception_;
00047     this->exception_ = tmp.exception_;
00048     tmp.exception_ = tmp_ex;
00049   }
00050   {
00051     CORBA::Environment *tmp_env = this->previous_;
00052     this->previous_ = rhs.previous_;
00053     tmp.previous_ = tmp_env;
00054   }
00055   return *this;
00056 }
00057 
00058 CORBA::Environment::~Environment (void)
00059 {
00060   this->clear ();
00061 
00062   // If previous is 0 then this is the first Environment, allocated
00063   // with the ORB, it shouldn't try to pop because the ORB is beign
00064   // destroyed also.
00065   if (this->previous_ != 0)
00066     TAO_ORB_Core_instance ()->default_environment (this->previous_);
00067 }
00068 
00069 void
00070 CORBA::Environment::exception (CORBA::Exception *ex)
00071 {
00072   // @@ This does not look right, setting the exception to the
00073   //    contained exception is a bug,  the application is only
00074   //    supposed to pass in a pointer to an exception that it (the
00075   //    application) owns, however, if we contain the exception then
00076   //    *WE* own it.
00077   //    Normally I (coryan) would remove code like this, but I feel
00078   //    that it is a typical example of defensive programming for the
00079   //    *BAD*, i.e. we are not helping the application to get better
00080   //    and only making the ORB bigger and slower.
00081 #if 0
00082   if (ex != this->exception_)
00083     {
00084       this->clear ();
00085     }
00086 #else
00087   ACE_ASSERT (ex != this->exception_);
00088   this->clear ();
00089 #endif /* 0 */
00090 
00091   this->exception_ = ex;
00092 
00093   if (this->exception_ != 0)
00094     this->exception_->_raise ();
00095 }
00096 
00097 void
00098 CORBA::Environment::clear (void)
00099 {
00100   delete this->exception_;
00101   this->exception_ = 0;
00102 }
00103 
00104 CORBA::Environment&
00105 CORBA::Environment::default_environment ()
00106 {
00107   //
00108   // If we are using native C++ exceptions the user is *not* supposed
00109   // to clear the environment every time she calls into TAO.  In fact
00110   // the user is not supposed to use the environment at all!
00111   //
00112   // But TAO is using the default environment internally, thus
00113   // somebody has to clear it. Since TAO passes the environment around
00114   // this function should only be called when going from the user code
00115   // into TAO's code.
00116   //
00117   // This is not an issue when using the alternative C++ mapping (with
00118   // the Environment argument) because then the user is supposed to
00119   // clear the environment before calling into the ORB.
00120   //
00121   TAO_ORB_Core_instance ()->default_environment ()->clear ();
00122 
00123   return TAO_default_environment ();;
00124 }
00125 
00126 // Convenience -- say if the exception is a system exception or not.
00127 
00128 int
00129 CORBA::Environment::exception_type (void) const
00130 {
00131   // @@ Carlos, is this stuff that's properly "transformed" for EBCDIC
00132   //    platforms?!
00133   // @@ Doug: Yes, they are used to compare against the _id() of the
00134   //    exception, which should have been mappend to the native
00135   //    codeset.  Notice the "should" we haven't tried that stuff yet,
00136   //    and i find it hard to keep track of all the transformations
00137   //    going on, specially for the TypeCodes that are generated by
00138   //    the IDL compiler vs. the ones hard-coded in
00139   //    $TAO_ROOT/tao/Typecode_Constants.cpp
00140 
00141   static char sysex_prefix [] = "IDL:omg.org/CORBA/";
00142   static char typecode_extra [] = "TypeCode/";
00143 
00144   if (!this->exception_)
00145     {
00146       return CORBA::NO_EXCEPTION;
00147     }
00148 
00149   // All exceptions currently (CORBA 2.0) defined in the CORBA scope
00150   // are system exceptions ... except for a couple that are related to
00151   // TypeCodes.
00152 
00153   const char *id = this->exception_->_rep_id ();
00154 
00155   if ((ACE_OS::strncmp (id,
00156                         sysex_prefix,
00157                         sizeof sysex_prefix - 1) == 0
00158        && ACE_OS::strncmp (id + sizeof sysex_prefix - 1,
00159                            typecode_extra,
00160                            sizeof typecode_extra - 1) != 0))
00161     return CORBA::SYSTEM_EXCEPTION;
00162   else
00163     return CORBA::USER_EXCEPTION;
00164 }
00165 
00166 const char*
00167 CORBA::Environment::exception_id (void) const
00168 {
00169   if (this->exception_ == 0)
00170     return 0;
00171 
00172   return this->exception_->_rep_id ();
00173 }
00174 
00175 // Diagnostic utility routine: describe the exception onto the
00176 // standard I/O stream passed as a parameter.
00177 
00178 void
00179 CORBA::Environment::print_exception (const char *info,
00180                                      FILE *) const
00181 {
00182   if (this->exception_)
00183     {
00184       const char *id = this->exception_->_rep_id ();
00185 
00186       ACE_ERROR ((LM_ERROR,
00187                   ACE_TEXT ("TAO: (%P|%t) EXCEPTION, %s\n"),
00188                   ACE_TEXT_CHAR_TO_TCHAR (info)));
00189 
00190       CORBA::SystemException *x2 =
00191         CORBA::SystemException::_downcast (this->exception_);
00192 
00193       if (x2 != 0)
00194         x2->_tao_print_system_exception ();
00195       else
00196         // @@ we can use the exception's typecode to dump all the data
00197         // held within it ...
00198 
00199         ACE_ERROR ((LM_ERROR,
00200                     ACE_TEXT ("TAO: (%P|%t) user exception, ID '%s'\n"),
00201                     ACE_TEXT_CHAR_TO_TCHAR (id)));
00202     }
00203   else
00204     ACE_ERROR ((LM_ERROR,
00205                 ACE_TEXT ("TAO: (%P|%t) no exception, %s\n"), ACE_TEXT_CHAR_TO_TCHAR (info)));
00206 }
00207 
00208 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:51 2010 for TAO by  doxygen 1.4.7