summaryrefslogtreecommitdiff
path: root/CIAO/RACE/Input_Adapters/PlanGenerator/PlanGenerator.cpp
blob: eb761275c6e2cbbcebc7dc27542c6133c323c847 (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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
/* -*- C++ -*- */

//========================================================================
/*
 *  file  Plan_Generator.cpp
 *
 * $Id$
 *
 *  This file contains the implementation of the PackageConfiguration
 *  Visitor class Plan_Generator which derives from PCVisitorBase. Each
 *  Visit function focuses on the functionality necessary to process
 *  the PackageConfiguration element which is passed to it as an argument
 *  and on dispatching the next sequence of calls in the correct order!
 *
 *  This implementation takes a PackageConfiguration and tries to grow
 *  a DeploymentPlan out of it by expanding the latter in width and depth
 *  simultaneously. At each level of the PackageConfiguration the
 *  Plan_Generator first expands the DeploymentPlan vertically at the
 *  corrsponding level and then dispatches the children of the current
 *  PackageConfiguration element. This in turn might and most probably
 *  will cause another vertical expansion of the DeploymentPlan, however
 *  for a different element. This effect is produced due to the flattened
 *  structure of the DeploymentPlan.
 *
 *  author Stoyan Paunov <spaunov@isis.vanderbilt.edu
 */
//========================================================================

#include "PCVisitorBase.h"
#include "PlanGenerator.h"

#include "ace/OS_Memory.h"         //for ACE_NEW* macros
#include "ace/SString.h"           //for ACE_CString

#include "ciao/DeploymentC.h"
#include "ciao/Deployment_DataC.h"
#include "ciao/Packaging_DataC.h"

#include "Config_Handlers/DnC_Dump.h"

#include <iostream>
using namespace std;

  //Constructor
  Plan_Generator::Plan_Generator (Deployment::DeploymentPlan &plan,
                        Deployment::PackageConfiguration &pc)
    : PCVisitorBase (),
      plan_ (plan),
      pc_ (pc),
      last_cad_ (0)
  {
  }

  //entry point for the protected visitor to get it do start
  //the visitation process
  void Plan_Generator::Visit ()
  {
    Accept (*this, this->pc_);
  }

  // A whole slew of overloaded routines for different IDL
  // data types part of the PackageConfiguration.


  void Plan_Generator::Visit (Deployment::PackageConfiguration &pc)
  {

    //visit the ComponentPackageDescription
    if (pc.basePackage.length ())
    {
      //currently no support for that anywhere
      //for (size_t r = 0; r = pc.selectRequirement.length (); ++r);

      Accept (*this, pc.basePackage);
    }
    else
      ACE_DEBUG ((LM_WARNING,
                 "[Plan_Generator - PackageConfiguration] We currently "
                 "do NOT support package references, specializedConfigs",
                 "or imports!\n"));
  }

  //!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!

  //ComponentPackageDescription descendents

  void Plan_Generator::Visit (Deployment::ComponentPackageDescription &cpd)
  {
    Accept (*this, cpd.realizes);
    //for (size_t impl = 0; impl < cpd.implementation.length (); ++impl)
    Accept (*this, cpd.implementation[0]);
  }


  void Plan_Generator::Visit (Deployment::ComponentInterfaceDescription &cid)
  {
    //Might want to populate this too once PICML starts supporting it
  }


  void Plan_Generator::Visit (Deployment::PackagedComponentImplementation &pci)
  {
    Accept (*this, pci.referencedImplementation);

    size_t plan_impl_len = plan_.implementation.length ();
    size_t plan_inst_len = plan_.instance.length ();

    //NOTE: order here matters. Need to populate the
    //MonolithicDeploymentDescription and the
    //InstanceDeploymentDescription first,
    //then call the update_configProperty
    if (plan_impl_len > 0 && plan_inst_len > 0)
       update_configProperty (pci,
                    plan_.implementation[plan_impl_len - 1],
                    plan_.instance[plan_inst_len - 1]);
  }


  void Plan_Generator::Visit (Deployment::ComponentImplementationDescription &cid)
  {
    if (cid.assemblyImpl.length ())
       Accept (*this, cid.assemblyImpl);
    else
       //;//Do nothing - monolithic component deployment not supported
       Accept (*this, cid.monolithicImpl);
  }


  void Plan_Generator::Visit (Deployment::ComponentAssemblyDescription &cad)
  {
    //NOTE: order matters for these calls. We need to populate
    //the instances before we try to polulate the connections

    //set the last ComponentAssemblyDescription
    this->last_cad_ = &cad;

    //visit the SubcomponentInstantiationDescription
    Accept (*this, cad.instance);
    //visit the connections
    Accept (*this, cad.connection);

    //reset the last ComponentAssemblyDescription
    this->last_cad_ = NULL;
  }


  void Plan_Generator::Visit (Deployment::SubcomponentInstantiationDescription &sid)
  {
    //visit the ComponentPackageDescription (again)
    if (sid.basePackage.length ())
    {
      size_t inst_len = plan_.instance.length ();
      plan_.instance.length (inst_len + 1);

      update_configProperty (sid, plan_.instance[inst_len]);

      plan_.instance[inst_len].name = sid.name;
      size_t impl_len = plan_.implementation.length ();
      plan_.implementation.length (impl_len + 1);

      ACE_CString mdname (plan_.instance[inst_len].name);
      mdname += "-mdd";
      plan_.implementation[impl_len].name = mdname.c_str ();

      plan_.instance[inst_len].implementationRef = impl_len;

      Accept (*this, sid.basePackage);
    }
    else
      ACE_DEBUG ((LM_WARNING,
                  "[Plan_Generator - SubcomponentInstantiationDescription] ",
                  "We currently do NOT support package references, ",
                  "specializedConfigs or imports!\n"));
  }


  void Plan_Generator::Visit (Deployment::MonolithicImplementationDescription &mid)
  {
    //NOTE: There are usually 3 NamedImplementationArtifacts per
    //MonolithicImplementationDescription *_stub, *_svnt & *_exec

    //visit the NamedImplementationArtifacts
    Accept (*this, mid.primaryArtifact);
  }


  void Plan_Generator::Visit (Deployment::NamedImplementationArtifact &nia)
  {
    //increase the artifact length by one
    size_t arti_len = plan_.artifact.length ();
    plan_.artifact.length (arti_len + 1);
    plan_.artifact[arti_len].name = nia.name;

    //increase the artifactRef length by one and
    //update the reference

    //get the index of the last MonolithicDeploymentDescription
    size_t last_mdd = plan_.implementation.length () - 1;
    Deployment::MonolithicDeploymentDescription& mdd = plan_.implementation[last_mdd];
    size_t ref_len = mdd.artifactRef.length ();
    mdd.artifactRef.length (ref_len + 1);
    mdd.artifactRef[ref_len] = arti_len;

    //visit the actual ImplementationArtifactDescriptor
    Accept (*this, nia.referencedArtifact);
  }


  void Plan_Generator::Visit (Deployment::ImplementationArtifactDescription &iad)
  {

    size_t last_arti = plan_.artifact.length ();
    size_t plan_loc_len = plan_.artifact[last_arti - 1].location.length ();
    size_t num_loc = iad.location.length ();
    for (size_t i = 0; i < num_loc; ++i)
    {
      Deployment::ArtifactDeploymentDescription& add = plan_.artifact[last_arti - 1];
      add.location.length (plan_loc_len + 1);
      add.location[plan_loc_len] = iad.location[i];
      ++plan_loc_len;

    //update execParameter
      update_execParameter (iad, add);
    }
  }

  //!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!

  //ComponentPackageReference descendents

  void Plan_Generator::Visit (Deployment::ComponentPackageReference &cpr)
  {
    //not implemented
  }

  //!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!

  //properties

  void Plan_Generator::Visit (Deployment::AssemblyPropertyMapping &apm)
  {

  }


  void Plan_Generator::Visit (Deployment::Property &property)
  {

  }


  //requirements & capabilities

  void Plan_Generator::Visit (Deployment::Requirement &requirement)
  {

  }


  void Plan_Generator::Visit (Deployment::Capability &capability)
  {

  }


  void Plan_Generator::Visit (Deployment::ImplementationRequirement &ir)
  {

  }


  void Plan_Generator::Visit (Deployment::ImplementationDependency &id)
  {

  }

  //ports and connections

  void Plan_Generator::Visit (Deployment::AssemblyConnectionDescription &acd)
  {
    if (!this->last_cad_)
      return;

    Deployment::ComponentAssemblyDescription& cad = *(this->last_cad_);

    size_t plan_conn_len = plan_.connection.length ();
    plan_.connection.length (plan_conn_len + 1);
    plan_.connection[plan_conn_len].name = acd.name;

    size_t iep_len = acd.internalEndpoint.length ();
    size_t plan_iep_len =
           plan_.connection[plan_conn_len].internalEndpoint.length ();

    //cout << "==> " << acd.name << " has " << iep_len << " and "
    //     << acd.externalEndpoint.length () << endl << endl ;

    plan_.connection[plan_conn_len].internalEndpoint.length (plan_iep_len + iep_len);

    for (size_t i = 0; i < iep_len; ++i)
    {
      plan_.connection[plan_conn_len]
           .internalEndpoint[plan_iep_len + i].portName =
                       acd.internalEndpoint[i].portName;

      size_t inst_ref = acd.internalEndpoint[i].instanceRef;
      const char* inst_name = cad.instance[inst_ref].name;
      size_t plan_inst_len = plan_.instance.length ();

      for (size_t j = 0; j < plan_inst_len; ++j)
      {
        const char* plan_inst_name = plan_.instance[j].name;
        if (ACE_OS::strcmp (plan_inst_name, inst_name) == 0)
        {
          plan_.connection[plan_conn_len]
               .internalEndpoint[plan_iep_len + i].instanceRef = j;
          break;
        }
      }

      //Now traverse the interface

      //NOTE: move these up and refactor!
      Deployment::SubcomponentInstantiationDescription& scid =
          cad.instance[inst_ref];
      Deployment::PlanSubcomponentPortEndpoint& pspe =
                  plan_.connection[plan_conn_len]
                       .internalEndpoint[plan_iep_len + i];

      size_t pkg_len = scid.basePackage.length ();
      for (size_t k = 0; k < pkg_len; ++k)
      {
        Deployment::ComponentPackageDescription& package = scid.basePackage[k];

        //empty unfortunately
        Deployment::ComponentInterfaceDescription cid = package.realizes;
        //cid = package.implementation[0].referencedImplementation.implements;

        size_t port_len = cid.port.length ();
        for (size_t p = 0; p < port_len; ++p)
        {
          const char* cid_pname = cid.port[p].name;
          const char* pspe_pname = pspe.portName;
          //cout << "CMP: " << pspe_pname << " <=> " << cid_pname << endl;
          if (ACE_OS::strcmp (cid_pname, pspe_pname) == 0)
          {
            pspe.kind = cid.port[p].kind;

            //cout << "-->" << pspe_pname << " Port kind is "
            //     << pspe.kind << endl;

            goto interface_end;
            break; // ???
          }
        }
      }

interface_end:
    //cout << endl;
    ;

    }

  }


  void Plan_Generator::Visit (Deployment::SubcomponentPortEndpoint &spe)
  {

  }


  void Plan_Generator::Visit (Deployment::ComponentExternalPortEndpoint &cepe)
  {

  }

//several helper functions

  void Plan_Generator::
  update_execParameter (Deployment::ImplementationArtifactDescription& iad,
                        Deployment::ArtifactDeploymentDescription& add)
  {
    //update execParameters
    size_t num_execP = iad.execParameter.length ();
    for (size_t j = 0; j < num_execP; ++j)
    {
      size_t execP_len = add.execParameter.length ();
      add.execParameter.length (execP_len + 1);
      add.execParameter[execP_len] = iad.execParameter[j];
      ++execP_len;
    }
  }

  void Plan_Generator::
  update_configProperty (Deployment::SubcomponentInstantiationDescription &scid,
                         Deployment::InstanceDeploymentDescription &idd)
  {
    size_t scid_plen =
    scid.configProperty.length ();

    size_t idd_plen = idd.configProperty.length ();
    idd.configProperty.length (idd_plen + scid_plen);

    for (size_t i = 0; i < scid_plen; ++i)
         idd.configProperty[idd_plen + i] =
                   scid.configProperty[i];

  }

  void Plan_Generator::
  update_configProperty (Deployment::PackagedComponentImplementation& pcid,
                         Deployment::MonolithicDeploymentDescription& mid,
                         Deployment::InstanceDeploymentDescription& idd)
  {
    bool update;
    size_t pcid_plen = pcid.referencedImplementation
                           .configProperty.length ();

    size_t mid_eplen = mid.execParameter.length ();
    mid.execParameter.length (mid_eplen + pcid_plen);

    for (size_t i = 0; i < pcid_plen; ++i)
    {
      update = true;
      mid.execParameter[mid_eplen + i] = pcid.referencedImplementation
                                             .configProperty[i];

      const char* pname = pcid.referencedImplementation
                              .configProperty[i].name;

      size_t idd_plen = idd.configProperty.length ();

      for (size_t j = 0; j < idd_plen; ++j)
      {
        const char* idd_pname = idd.configProperty[j].name;
        if (ACE_OS::strcmp (idd_pname, pname) == 0)
        {
          update = false;
          break;
        }
      }

      if (update)
      {
        idd.configProperty.length (idd_plen + 1);
        idd.configProperty[idd_plen] =
            pcid.referencedImplementation.configProperty[i];
      }
    }
  }