ifr_adding_visitor_exception.cpp

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 // ifr_adding_visitor_exception.cpp,v 1.21 2006/02/09 16:48:01 parsons Exp
00003 
00004 #include "ast_enum.h"
00005 #include "ast_exception.h"
00006 #include "ast_expression.h"
00007 #include "ast_field.h"
00008 #include "ast_union.h"
00009 #include "utl_identifier.h"
00010 
00011 #include "ifr_adding_visitor_exception.h"
00012 #include "ifr_adding_visitor_structure.h"
00013 #include "ifr_adding_visitor_union.h"
00014 
00015 ACE_RCSID (IFR_Service,
00016            ifr_adding_visitor_exception,
00017            "ifr_adding_visitor_exception.cpp,v 1.21 2006/02/09 16:48:01 parsons Exp")
00018 
00019 ifr_adding_visitor_exception::ifr_adding_visitor_exception (
00020     AST_Decl *scope,
00021     CORBA::Boolean in_reopened
00022   )
00023   : ifr_adding_visitor (scope,
00024                         in_reopened)
00025 {
00026 }
00027 
00028 ifr_adding_visitor_exception::~ifr_adding_visitor_exception (void)
00029 {
00030 }
00031 
00032 // Specialized visit_scope method for exceptions only.
00033 int
00034 ifr_adding_visitor_exception::visit_scope (UTL_Scope *node)
00035 {
00036   // If the exception has members that are scopes but not exceptions,
00037   // the regular visit_scope method should be called instead.
00038   if (node->scope_node_type () != AST_Decl::NT_except)
00039     {
00040       return ifr_adding_visitor::visit_scope (node);
00041     }
00042 
00043   AST_Exception *e = AST_Exception::narrow_from_scope (node);
00044 
00045   CORBA::ULong nfields = static_cast<CORBA::ULong> (e->nfields ());
00046 
00047   this->members_.length (nfields);
00048 
00049   AST_Field **f = 0;
00050 
00051   ACE_DECLARE_NEW_CORBA_ENV;
00052   ACE_TRY
00053     {
00054       // Visit each field.
00055       for (CORBA::ULong i = 0; i < nfields; ++i)
00056         {
00057           if (e->field (f, i) != 0)
00058             {
00059               ACE_ERROR_RETURN ((
00060                   LM_ERROR,
00061                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00062                   ACE_TEXT ("visit_scope -")
00063                   ACE_TEXT (" field node access failed\n")
00064                 ),
00065                 -1
00066               );
00067             }
00068 
00069           AST_Type *ft = (*f)->field_type ();
00070 
00071           bool defined_here = ft->is_child (this->scope_);
00072 
00073           // If the struct member is defined in the struct, we have to
00074           // do some visiting - otherwise we can just look up the entry.
00075           if (defined_here)
00076             {
00077               if (ft->ast_accept (this) == -1)
00078                 {
00079                   ACE_ERROR_RETURN ((
00080                       LM_ERROR,
00081                       ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00082                       ACE_TEXT ("visit_scope -")
00083                       ACE_TEXT (" failed to accept visitor\n")
00084                     ),
00085                     -1
00086                   );
00087                 }
00088             }
00089           else
00090             {
00091               // Updates ir_current_.
00092               this->get_referenced_type (ft ACE_ENV_ARG_PARAMETER);
00093               ACE_TRY_CHECK;
00094             }
00095 
00096           this->members_[i].name =
00097             CORBA::string_dup ((*f)->local_name ()->get_string ());
00098 
00099           // IfR method create_exception does not use this - it just needs
00100           // to be non-zero for marshaling.
00101           this->members_[i].type =
00102             CORBA::TypeCode::_duplicate (CORBA::_tc_void);
00103 
00104           this->members_[i].type_def =
00105             CORBA::IDLType::_duplicate (this->ir_current_.in ());
00106         }
00107     }
00108   ACE_CATCHANY
00109     {
00110       ACE_PRINT_EXCEPTION (
00111           ACE_ANY_EXCEPTION,
00112           ACE_TEXT ("ifr_adding_visitor_structure::visit_scope")
00113         );
00114 
00115       return -1;
00116     }
00117   ACE_ENDTRY;
00118 
00119   return 0;
00120 }
00121 
00122 int
00123 ifr_adding_visitor_exception::visit_structure (AST_Structure *node)
00124 {
00125   ACE_DECLARE_NEW_CORBA_ENV;
00126   ACE_TRY
00127     {
00128       // Is this union already in the respository?
00129       CORBA::Contained_var prev_def =
00130         be_global->repository ()->lookup_id (node->repoID ()
00131                                              ACE_ENV_ARG_PARAMETER);
00132       ACE_TRY_CHECK;
00133 
00134       // If not, create a new entry.
00135       if (CORBA::is_nil (prev_def.in ()))
00136         {
00137           ifr_adding_visitor_structure visitor (node,
00138                                                 1);
00139 
00140           int retval = visitor.visit_structure (node);
00141 
00142           if (retval == 0)
00143             {
00144               // Get the result of the visit.
00145               this->ir_current_ =
00146                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00147 
00148               CORBA::Contained_ptr tmp =
00149                 CORBA::Contained::_narrow (visitor.ir_current ()
00150                                            ACE_ENV_ARG_PARAMETER);
00151               ACE_TRY_CHECK;
00152 
00153               // Since the enclosing ExceptionDef hasn't been created
00154               // yet, we don't have a scope, so this nested StructDef
00155               // (which was created at global scope) goes on the
00156               // queue to be moved later.
00157               this->move_queue_.enqueue_tail (tmp);
00158             }
00159 
00160           return retval;
00161         }
00162       else
00163         {
00164           // If the line below is true, we are clobbering a previous
00165           // entry (from another IDL file) of another type. In that
00166           // case we do what other ORB vendors do, and destroy the
00167           // original entry, create the new one, and let the user beware.
00168           if (node->ifr_added () == 0)
00169             {
00170               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00171               ACE_TRY_CHECK;
00172 
00173               // This call will take the other branch.
00174               return this->visit_structure (node);
00175             }
00176 
00177           this->ir_current_ =
00178             CORBA::IDLType::_narrow (prev_def.in ()
00179                                     ACE_ENV_ARG_PARAMETER);
00180           ACE_TRY_CHECK;
00181         }
00182     }
00183   ACE_CATCHANY
00184     {
00185       ACE_PRINT_EXCEPTION (
00186           ACE_ANY_EXCEPTION,
00187           ACE_TEXT ("ifr_adding_visitor_exception::visit_structure")
00188         );
00189 
00190       return -1;
00191     }
00192   ACE_ENDTRY;
00193 
00194   return 0;
00195 }
00196 
00197 int
00198 ifr_adding_visitor_exception::visit_exception (AST_Exception *node)
00199 {
00200   ACE_DECLARE_NEW_CORBA_ENV;
00201   ACE_TRY
00202     {
00203       CORBA::Contained_var prev_def =
00204         be_global->repository ()->lookup_id (node->repoID ()
00205                                              ACE_ENV_ARG_PARAMETER);
00206       ACE_TRY_CHECK;
00207 
00208       if (!CORBA::is_nil (prev_def.in ()))
00209         {
00210           // If we and our enclosing module are both already in the
00211           // repository, we are probably processing the same IDL file
00212           // a second time. If it is just a name clash, there is no
00213           // way to detect it.
00214           if (this->in_reopened_ == 1)
00215             {
00216               return 0;
00217             }
00218 
00219           // If the line below is true, we are clobbering a previous
00220           // entry (from another IDL file) of another type. In that
00221           // case we do what other ORB vendors do, and destroy the
00222           // original entry, create the new one, and let the user beware.
00223           if (node->ifr_added () == 0)
00224             {
00225               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00226               ACE_TRY_CHECK;
00227 
00228               // This call will create a new ExceptionDef entry.
00229               return this->visit_exception (node);
00230             }
00231           else
00232             {
00233               // The node is being referenced in an operation, no action.
00234               return 0;
00235             }
00236         }
00237 
00238       if (this->visit_scope (node) == -1)
00239         {
00240           ACE_ERROR_RETURN ((
00241               LM_ERROR,
00242               ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00243               ACE_TEXT ("visit_exception -")
00244               ACE_TEXT (" visit_scope failed\n")
00245             ),
00246             -1
00247           );
00248         }
00249 
00250       CORBA::Container_ptr current_scope =
00251         CORBA::Container::_nil ();
00252 
00253       if (be_global->ifr_scopes ().top (current_scope) != 0)
00254         {
00255           ACE_ERROR_RETURN ((
00256               LM_ERROR,
00257               ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00258               ACE_TEXT ("visit_exception -")
00259               ACE_TEXT (" scope stack is empty\n")
00260             ),
00261             -1
00262           );
00263         }
00264 
00265       CORBA::ExceptionDef_var new_def =
00266         current_scope->create_exception (node->repoID (),
00267                                          node->local_name ()->get_string (),
00268                                          node->version (),
00269                                          this->members_
00270                                          ACE_ENV_ARG_PARAMETER);
00271 
00272       ACE_TRY_CHECK;
00273 
00274       size_t size = this->move_queue_.size ();
00275 
00276       if (size > 0)
00277         {
00278           CORBA::Contained_var traveller;
00279 
00280           CORBA::Container_var new_container =
00281             CORBA::Container::_narrow (new_def.in ()
00282                                       ACE_ENV_ARG_PARAMETER);
00283           ACE_TRY_CHECK;
00284 
00285           for (size_t i = 0; i < size; ++i)
00286             {
00287               this->move_queue_.dequeue_head (traveller);
00288 
00289               CORBA::String_var name =
00290                 traveller->name (ACE_ENV_SINGLE_ARG_PARAMETER);
00291               ACE_TRY_CHECK;
00292 
00293               CORBA::String_var version =
00294                 traveller->version (ACE_ENV_SINGLE_ARG_PARAMETER);
00295               ACE_TRY_CHECK;
00296 
00297               traveller->move (new_container.in (),
00298                                name.in (),
00299                                version.in ()
00300                                ACE_ENV_ARG_PARAMETER);
00301               ACE_TRY_CHECK;
00302             }
00303         }
00304 
00305       node->ifr_added (1);
00306     }
00307   ACE_CATCHANY
00308     {
00309       ACE_PRINT_EXCEPTION (
00310           ACE_ANY_EXCEPTION,
00311           ACE_TEXT ("ifr_adding_visitor_exception::visit_exception")
00312         );
00313 
00314       return -1;
00315     }
00316   ACE_ENDTRY;
00317 
00318   return 0;
00319 }
00320 
00321 int
00322 ifr_adding_visitor_exception::visit_enum (AST_Enum *node)
00323 {
00324   ACE_DECLARE_NEW_CORBA_ENV;
00325   ACE_TRY
00326     {
00327       // Is this enum already in the respository?
00328       CORBA::Contained_var prev_def =
00329         be_global->repository ()->lookup_id (node->repoID ()
00330                                              ACE_ENV_ARG_PARAMETER);
00331       ACE_TRY_CHECK;
00332 
00333       // If not, create a new entry.
00334       if (CORBA::is_nil (prev_def.in ()))
00335         {
00336           CORBA::ULong member_count = static_cast<CORBA::ULong> (node->member_count ());
00337 
00338           CORBA::EnumMemberSeq members (member_count);
00339           members.length (member_count);
00340 
00341           UTL_ScopedName *member_name = 0;
00342 
00343           // Get a list of the member names.
00344           for (CORBA::ULong i = 0; i < member_count; ++i)
00345             {
00346               member_name = node->value_to_name (i);
00347 
00348               members[i] =
00349                 CORBA::string_dup (
00350                     member_name->last_component ()->get_string ()
00351                   );
00352             }
00353 
00354           this->ir_current_ =
00355             be_global->repository ()->create_enum (
00356                                           node->repoID (),
00357                                           node->local_name ()->get_string (),
00358                                           node->version (),
00359                                           members
00360                                           ACE_ENV_ARG_PARAMETER
00361                                         );
00362           ACE_TRY_CHECK;
00363 
00364           CORBA::Contained_ptr tmp =
00365             CORBA::Contained::_narrow (this->ir_current_.in ()
00366                                       ACE_ENV_ARG_PARAMETER);
00367           ACE_TRY_CHECK;
00368 
00369           this->move_queue_.enqueue_tail (tmp);
00370 
00371           node->ifr_added (1);
00372         }
00373       else
00374         {
00375           // If the line below is true, we are clobbering a previous
00376           // entry (from another IDL file) of another type. In that
00377           // case we do what other ORB vendors do, and destroy the
00378           // original entry, create the new one, and let the user beware.
00379           if (node->ifr_added () == 0)
00380             {
00381               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00382               ACE_TRY_CHECK;
00383 
00384               // This call will take the other branch.
00385               return this->visit_enum (node);
00386             }
00387 
00388           this->ir_current_ =
00389             CORBA::IDLType::_narrow (prev_def.in ()
00390                                     ACE_ENV_ARG_PARAMETER);
00391           ACE_TRY_CHECK;
00392         }
00393     }
00394   ACE_CATCHANY
00395     {
00396       ACE_PRINT_EXCEPTION (
00397           ACE_ANY_EXCEPTION,
00398           ACE_TEXT ("ifr_adding_visitor_exception::visit_enum")
00399         );
00400 
00401       return -1;
00402     }
00403   ACE_ENDTRY;
00404 
00405   return 0;
00406 }
00407 
00408 int
00409 ifr_adding_visitor_exception::visit_union (AST_Union *node)
00410 {
00411   ACE_DECLARE_NEW_CORBA_ENV;
00412   ACE_TRY
00413     {
00414       // Is this union already in the respository?
00415       CORBA::Contained_var prev_def =
00416         be_global->repository ()->lookup_id (node->repoID ()
00417                                              ACE_ENV_ARG_PARAMETER);
00418       ACE_TRY_CHECK;
00419 
00420       // If not, create a new entry.
00421       if (CORBA::is_nil (prev_def.in ()))
00422         {
00423           ifr_adding_visitor_union visitor (node,
00424                                             1);
00425 
00426           int retval = visitor.visit_union (node);
00427 
00428           if (retval == 0)
00429             {
00430               // Get the result of the visit.
00431               this->ir_current_ =
00432                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00433 
00434               CORBA::Contained_ptr tmp =
00435                 CORBA::Contained::_narrow (visitor.ir_current ()
00436                                           ACE_ENV_ARG_PARAMETER);
00437               ACE_TRY_CHECK;
00438 
00439               // Since the enclosing ExceptionDef hasn't been created
00440               // yet, we don't have a scope, so this nested UnionDef
00441               // (which was created at global scope) goes on the
00442               // queue to be moved later.
00443               this->move_queue_.enqueue_tail (tmp);
00444             }
00445 
00446           return retval;
00447         }
00448       else
00449         {
00450           // If the line below is true, we are clobbering a previous
00451           // entry (from another IDL file) of another type. In that
00452           // case we do what other ORB vendors do, and destroy the
00453           // original entry, create the new one, and let the user beware.
00454           if (node->ifr_added () == 0)
00455             {
00456               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00457               ACE_TRY_CHECK;
00458 
00459               // This call will take the other branch.
00460               return this->visit_union (node);
00461             }
00462 
00463           this->ir_current_ =
00464             CORBA::IDLType::_narrow (prev_def.in ()
00465                                     ACE_ENV_ARG_PARAMETER);
00466           ACE_TRY_CHECK;
00467         }
00468     }
00469   ACE_CATCHANY
00470     {
00471       ACE_PRINT_EXCEPTION (
00472           ACE_ANY_EXCEPTION,
00473           ACE_TEXT ("ifr_adding_visitor_exception::visit_union")
00474         );
00475 
00476       return -1;
00477     }
00478   ACE_ENDTRY;
00479 
00480   return 0;
00481 }
00482 
00483 CORBA::IDLType_ptr
00484 ifr_adding_visitor_exception::ir_current (void) const
00485 {
00486   return this->ir_current_.in ();
00487 }

Generated on Thu Nov 9 14:11:50 2006 for TAO_IFR by doxygen 1.3.6