summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/LifeCycle_Service/Factory_Trader.cpp
blob: 9fd155d917965d24804979cc645151cae3441802 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// $Id$

// ============================================================================
//
// = LIBRARY
//
// = FILENAME
//   Factory_Trader.cpp
//
// = DESCRIPTION
//   A colocated instance of the Trading Service, only part of
//   the functionality provided is used. This class serves
//   as Wrapper around the Trading Service and provides
//   smaller interfaces.
//   TRADER_AVAILABLE is defined via compiler switch in the Makefile
//
// = AUTHOR
//   Michael Kircher  (mk1@cs.wustl.edu)
//
// ============================================================================

#include "Factory_Trader.h"
#include "orbsvcs/orbsvcs/CosTradingC.h"

ACE_RCSID (LifeCycle_Service, 
           Factory_Trader, 
           "$Id$")

// This const char * is used for adding a new type to the service repository
// the added types will be subclasses of this.
const char * Factory_Trader::GENERIC_FACTORY_INTERFACE_REPOSITORY_ID =
  "IDL:omg.org/CosLifeCycle/GenericFactory:1.0";


Factory_Trader::Factory_Trader (int debug_level)
  : trader_ptr_(0),
    trading_Components_ptr_ (0),
    support_Attributes_ptr_(0),
    debug_level_ (debug_level)
{
  ACE_TRY_NEW_ENV
    {
      int argc = 0;
      // create the trader
      this->trader_ptr_ = TAO_Trader_Factory::create_trader (argc, 0);
      this->support_Attributes_ptr_ = &(trader_ptr_->support_attributes ());
      // this pointer is deleted when the trader_ptr is deleted
      this->trading_Components_ptr_ = &(trader_ptr_->trading_components ());
      // this pointer is deleted when the trader_ptr is deleted

      // Set the service type repository
      support_Attributes_ptr_->type_repos
                     (this->repository_._this (ACE_ENV_SINGLE_ARG_PARAMETER));
      ACE_TRY_CHECK;

      // Add the "Factory" type to the repository
      this->add_type ();
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
                           "LifeCycle Server: (Factory_Trader::Factory_Trader) Failed adding a new type.\n");
    }
  ACE_ENDTRY;
  // @@ ACE_CHECK?  No way to pass back any exceptions.
}

Factory_Trader::~Factory_Trader ()
{
  delete this->trader_ptr_;
}


void
Factory_Trader::add_type ()
{
  ACE_TRY_NEW_ENV
    {
      // define the new type
      CosTradingRepos::ServiceTypeRepository::PropStruct propStruct_name;
      propStruct_name.name = CORBA::string_dup ("name");
      propStruct_name.value_type = CORBA::_tc_string;
      propStruct_name.mode =  CosTradingRepos::ServiceTypeRepository::PROP_MANDATORY;

      CosTradingRepos::ServiceTypeRepository::PropStruct propStruct_location;
      propStruct_location.name  = CORBA::string_dup ("location");
      propStruct_location.value_type = CORBA::_tc_string;
      propStruct_location.mode =  CosTradingRepos::ServiceTypeRepository::PROP_NORMAL;

      CosTradingRepos::ServiceTypeRepository::PropStruct propStruct_description;
      propStruct_description.name = CORBA::string_dup ("description");
      propStruct_description.value_type = CORBA::_tc_string;
      propStruct_description.mode =  CosTradingRepos::ServiceTypeRepository::PROP_NORMAL;

      CosTradingRepos::ServiceTypeRepository::PropStructSeq propStructSeq(3);
      propStructSeq.length (3);
      propStructSeq[0] = propStruct_name;
      propStructSeq[1] = propStruct_location;
      propStructSeq[2] = propStruct_description;

      CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq superTypeSeq;

      // Add the new type
      this->repository_.add_type (CORBA::string_dup("GenericFactory"),
                                  GENERIC_FACTORY_INTERFACE_REPOSITORY_ID,
                                  propStructSeq,
                                  superTypeSeq
                                  ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
                           "LifeCycle Server: (Factory_Trader::init).\n");
    }
  ACE_ENDTRY;
  // @@ ACE_CHECK
}


void
Factory_Trader::_cxx_export (const char * name,
                             const char * location,
                             const char * description,
                             const CORBA::Object_ptr object_ptr)
{
  ACE_TRY_NEW_ENV
    {
      if (CORBA::is_nil(object_ptr))
        {
          ACE_ERROR ((LM_ERROR, "LifeCycle Server (Factory_Trader::export): "
                                "Object pointer is nil, cannot export!\n"));
          return;
        }

      CosTrading::PropertySeq propertySeq(3);
      propertySeq.length (3);
      propertySeq[0].name = CORBA::string_dup("name");
      propertySeq[0].value <<= CORBA::string_dup (name);
      propertySeq[1].name =  CORBA::string_dup("location");
      propertySeq[1].value <<= CORBA::string_dup (location);
      propertySeq[2].name =  CORBA::string_dup("description");
      propertySeq[2].value <<= CORBA::string_dup (description);

      // get the register interface
      CosTrading::Register_ptr register_ptr = this->trading_Components_ptr_->register_if ();
      // this pointer is deleted when the trader_ptr is deleted

      // invoke the export method on the Register interface of the Trading Service
      register_ptr->_cxx_export (CORBA::Object::_duplicate (object_ptr),
                                 CORBA::string_dup("GenericFactory"),
                                 propertySeq
                                 ACE_ENV_ARG_PARAMETER);

      ACE_TRY_CHECK;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
                           "LifeCycle Server (Factory_Trader::export): "
                           "Failed to export factory.\n");
    }
  ACE_ENDTRY;
  // @@ ACE_CHECK*
}


CORBA::Object_ptr
Factory_Trader::query (const char* constraint)
{
  ACE_TRY_NEW_ENV
    {
      CosTrading::Lookup::SpecifiedProps specifiedProps;
      specifiedProps._d(CosTrading::Lookup::all);

      // Get some pointers for the out parameters of the call.
      CosTrading::OfferSeq *offerSeq_ptr =  0;
      CosTrading::OfferIterator_ptr offerIterator_ptr = 0;
      CosTrading::PolicyNameSeq *policyNameSeq_ptr = 0;

      // An empty policy sequence
      CosTrading::PolicySeq policySeq;

      // Get a reference to the lookup interface
      CosTrading::Lookup_ptr lookup_ptr = this->trading_Components_ptr_->lookup_if ();
      // this pointer is deleted when the trader_ptr is deleted

      // Invoke the query method on the Lookup Interface.
      lookup_ptr->query ("GenericFactory",  // Type name
                         constraint,        // Constraint, very important
                         "",                // Preferences
                         policySeq,         // Policy
                         specifiedProps,    // Specified Properties
                         1,                 // Number of wanted results
                         CosTrading::OfferSeq_out(offerSeq_ptr),               // results
                         CosTrading::OfferIterator_out(offerIterator_ptr),     // more results
                         CosTrading::PolicyNameSeq_out(policyNameSeq_ptr)      // Policies
                         ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      // Initialize
      CORBA::Object_ptr object_ptr = 0;

      // Check if an offer was made
      if (offerSeq_ptr != 0)
        {
          // Insert the pointer into the out class
          CosTrading::OfferSeq_var offerSeq_var(offerSeq_ptr);

          // We need at least one offer.
          if (offerSeq_var->length() >= 1)
            {
              // now we are all set to read from the sequence the result
              object_ptr = CORBA::Object::_duplicate (offerSeq_var[0u].reference.in());

              if (CORBA::is_nil (object_ptr))
                ACE_ERROR_RETURN ((LM_ERROR,"Factory_Trader::query: Object reference is nil.\n"), 0);
              else
                if (this->debug_level_ >= 2)
                  ACE_DEBUG ((LM_DEBUG, "Factory_Trader::query: Received a proper object reference.\n"));
            }
          else
            ACE_ERROR ((LM_ERROR, "Factory_Trader::query: OfferSequence.length is smaller than 1.\n"));
        }
      return object_ptr;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Factory_Trader::query: Failed.\n");
    }
  ACE_ENDTRY;
  // @@ ACE_CHECK_RETURN (?)
  return 0;
}