00001 #include "stdafx.h"
00002
00003 #include "BON.h"
00004 #include "BONImpl.h"
00005
00006
00007 #include "ConnJoint.h"
00008 #include "ConnectionRep.h"
00009 #include "logger.h"
00010 #include "ModelRep.h"
00011 #include "ReferenceRep.h"
00012 #include "Broker.h"
00013 #include "ConstraintRep.h"
00014 #include "Dumper.h"
00015
00016 #include "algorithm"
00017
00018 #include "globals.h"
00019 extern Globals global_vars;
00020
00021
00022 std::string ConnJoint::m_srcLabel = "src";
00023 std::string ConnJoint::m_dstLabel = "dst";
00024
00025
00026 ConnJoint::ConnJoint
00027 ( ConnectionRep * ptr,
00028 const SDList& op1,
00029 const SDList& op2,
00030 bool bidirect,
00031 std::string card1 ,
00032 std::string card2
00033 )
00034 : m_connPtr( ptr)
00035
00036 , m_oper1( op1)
00037 , m_oper2( op2)
00038
00039 , m_oper1TargetMap()
00040 , m_oper2TargetMap()
00041
00042 , m_bidirect( bidirect)
00043
00044 , m_oper1Card( card1)
00045 , m_oper2Card( card2)
00046 {
00047 }
00048
00049
00050 ConnJoint::ConnJoint( const ConnJoint& peer)
00051 : m_connPtr( peer.m_connPtr)
00052
00053 , m_oper1( peer.m_oper1)
00054 , m_oper2( peer.m_oper2)
00055
00056 , m_oper1TargetMap( peer.m_oper1TargetMap)
00057 , m_oper2TargetMap( peer.m_oper2TargetMap)
00058
00059 , m_bidirect( peer.m_bidirect)
00060
00061 , m_oper1Card( peer.m_oper1Card)
00062 , m_oper2Card( peer.m_oper2Card)
00063 {
00064 }
00065
00066
00067 const ConnJoint& ConnJoint::operator=( const ConnJoint& peer)
00068 {
00069 if ( this == &peer ) return *this;
00070 m_connPtr = peer.m_connPtr;
00071
00072 m_oper1 = peer.m_oper1;
00073 m_oper2 = peer.m_oper2;
00074
00075 m_oper1TargetMap = peer.m_oper1TargetMap;
00076 m_oper2TargetMap = peer.m_oper2TargetMap;
00077
00078 m_bidirect = peer.m_bidirect;
00079
00080 m_oper1Card = peer.m_oper1Card;
00081 m_oper2Card = peer.m_oper2Card;
00082
00083 return *this;
00084 }
00085
00086
00087 ConnJoint::~ConnJoint()
00088 {
00089 m_connPtr = 0;
00090
00091 m_oper1.clear();
00092 m_oper2.clear();
00093
00094 m_oper1TargetMap.clear();
00095 m_oper2TargetMap.clear();
00096 }
00097
00098
00099
00100 void ConnJoint::setConnectionPtr( ConnectionRep * conn_ptr)
00101 {
00102 m_connPtr = conn_ptr;
00103 }
00104
00105
00106 const ConnJoint::SDList& ConnJoint::getOp1() const { return m_oper1; }
00107 const ConnJoint::SDList& ConnJoint::getOp2() const { return m_oper2; }
00108
00109
00110 bool ConnJoint::isBidirect() const { return m_bidirect; }
00111
00112
00113 void ConnJoint::addTargetItem( int i, const ModelRep * model, const PointerItem & item)
00114 {
00115 PointerItemSeries * series;
00116 if (i==0) series = &m_oper1TargetMap[model];
00117 else series = &m_oper2TargetMap[model];
00118
00119 if ( std::find( series->begin(), series->end(), item)
00120 == series->end())
00121 series->push_back( item);
00122
00123
00124 }
00125
00126
00127 void ConnJoint::addTargetItem( int i, const ModelRep * model, const RoleRep & new_role)
00128 {
00129 PointerItem item = new_role.getSmartRoleName();
00130 addTargetItem( i, model, item);
00131 }
00132
00133
00134 void ConnJoint::addTargetItem( int i, const ModelRep * model, const RoleRep::RoleRepSeries & new_role_series)
00135 {
00136 RoleRep::RoleRepSeries_ConstIterator r_it = new_role_series.begin();
00137 for( ; r_it != new_role_series.end(); ++r_it)
00138 addTargetItem( i, model, *r_it);
00139 }
00140
00141
00142 void ConnJoint::intInherit( ModelRep * mod_ptr)
00143 {
00144 std::string con_name = m_connPtr->getName();
00145 std::string mod_name = mod_ptr->getName();
00146
00147 const int number_of_endpoints = 2;
00148 TargetMap * target_map[ number_of_endpoints] = { &m_oper1TargetMap, &m_oper2TargetMap };
00149
00150 std::vector<ModelRep*> inner_models1 = mod_ptr->getInnerModelsFinal();
00151
00152 std::vector< const ModelRep*> inner_models( inner_models1.size());
00153 std::copy( inner_models1.begin(), inner_models1.end(), inner_models.begin());
00154
00155 std::vector<ReferenceRep*> inner_modelreferences = mod_ptr->getInnerModelReferencesFinal();
00156 std::vector<ReferenceRep*>::iterator model_ref_it = inner_modelreferences.begin();
00157 for( ; model_ref_it != inner_modelreferences.end(); ++model_ref_it)
00158 {
00159 std::string m_r_n = (*model_ref_it)->getName();
00160 std::vector<const ModelRep *> models_ref_refers = (*model_ref_it)->getModelRefVector();
00161 std::vector<const ModelRep *>::iterator ref_model_it = models_ref_refers.begin();
00162 for( ; ref_model_it != models_ref_refers.end(); ++ref_model_it)
00163 {
00164 std::string r_m_n = (*ref_model_it)->getName();
00165 if ( std::find( inner_models.begin(), inner_models.end(), *ref_model_it) == inner_models.end())
00166 inner_models.push_back( *ref_model_it);
00167 }
00168 }
00169
00170
00171
00172
00173 SDList* targets[ number_of_endpoints] = { &m_oper1, &m_oper2 };
00174
00175 for( int i = 0; i < number_of_endpoints; ++i)
00176 {
00177 SDList_Iterator op_it = targets[i]->begin();
00178 for( ; op_it != targets[i]->end(); ++op_it)
00179 {
00180 FCO* target_ptr = *op_it;
00181
00182 std::vector<FCO*> descendants;
00183
00184
00185 target_ptr->getIntDescendants( descendants);
00186 descendants.push_back( target_ptr);
00187
00188 std::vector<FCO*>::reverse_iterator desc_it = descendants.rbegin();
00189
00190 for( ; desc_it != descendants.rend(); ++desc_it)
00191 {
00192 FCO * fco = *desc_it;
00193 std::string fco_name = fco->getName();
00194
00195
00196 if ( !fco->isAbstract() )
00197 {
00198
00199
00200 RoleRep::RoleRepSeries series;
00201 bool has_some = mod_ptr->getFinalRoles( fco, series);
00202 if ( has_some && !series.empty())
00203 {
00204
00205 this->addTargetItem( i, mod_ptr, series);
00206 }
00207
00208 std::vector<const ModelRep*>::iterator sub_mod_it = inner_models.begin();
00209 for(; sub_mod_it != inner_models.end(); ++sub_mod_it)
00210 {
00211 const ModelRep * sub_model = *sub_mod_it;
00212 std::string sm_name = sub_model->getName();
00213
00214 RoleRep::RoleRepSeries roles_in_sub_model;
00215 bool has_some = sub_model->getFinalRoles( fco, roles_in_sub_model);
00216 RoleRep::RoleRepSeries_ConstIterator r_it = roles_in_sub_model.begin();
00217 for( ; has_some && r_it != roles_in_sub_model.end(); ++r_it)
00218 {
00219 RoleRep sub_role = *r_it;
00220
00221 if ( sub_role.isPort())
00222 {
00223 if ( sub_model->getMyKind() == Any::MODEL && !sub_model->isAbstract())
00224 {
00225
00226 RoleRep::RoleRepSeries sub_model_roles_in_model;
00227 bool has_some_subm = mod_ptr->getFinalRoles( sub_model, sub_model_roles_in_model );
00228 RoleRep::RoleRepSeries_ConstIterator r_it_sm = sub_model_roles_in_model.begin();
00229 for( ; has_some_subm && r_it_sm != sub_model_roles_in_model.end(); ++r_it_sm )
00230 {
00231 std::string desc_sub_model_role_name = r_it_sm->getSmartRoleName();
00232 PointerItem item = desc_sub_model_role_name + " " + sub_role.getSmartRoleName();
00233 this->addTargetItem( i, mod_ptr, item);
00234 }
00235
00236 const FCO::ReferenceRepList &ref_list = sub_model->getTransitiveReferencesToMe();
00237 FCO::ReferenceRepList_ConstIterator ref_it = ref_list.begin();
00238 for( ; ref_it != ref_list.end(); ++ref_it)
00239 {
00240 if( !(*ref_it)->isAbstract() && (*ref_it)->amIPartOfFinal( mod_ptr) )
00241 {
00242 RoleRep::RoleRepSeries sub_ref_roles_in_model;
00243 bool ref_has_roles = mod_ptr->getFinalRoles( *ref_it, sub_ref_roles_in_model );
00244 RoleRep::RoleRepSeries_ConstIterator r_it_ref = sub_ref_roles_in_model.begin();
00245 for( ; ref_has_roles && r_it_ref != sub_ref_roles_in_model.end(); ++r_it_ref )
00246 {
00247 std::string desc_sub_ref_role_name = r_it_ref->getSmartRoleName();
00248 PointerItem item = desc_sub_ref_role_name + " " + sub_role.getSmartRoleName();
00249 this->addTargetItem( i, mod_ptr, item);
00250 }
00251
00252
00253 }
00254 }
00255 }
00256 }
00257 }
00258 }
00259 }
00260 }
00261 }
00262 }
00263 }
00264
00265
00266 bool ConnJoint::checkElements( std::string connection_name)
00267 {
00268 bool res = true;
00269 const int number_of_lists = 2;
00270 const int number_of_endpoints = 2;
00271
00272 const SDList* lists [ number_of_endpoints]=
00273 {
00274 &m_oper1, &m_oper2
00275 };
00276
00277 for( int i = 0; i < number_of_endpoints; ++i)
00278 {
00279 SDList_ConstIterator fco_it = lists[i]->begin();
00280
00281 for( ; fco_it != lists[i]->end(); ++fco_it)
00282 {
00283 FCO * member_ptr = *fco_it;
00284
00285 if ( !member_ptr->checkIsPartOfFinal() && !member_ptr->isAbstract())
00286 {
00287 global_vars.err << MSG_WARNING << "CHECK: \"" << member_ptr->getName() << "\" fco in connection \"" << connection_name << "\" is not contained by any model.\n";
00288 res = false;
00289 }
00290 }
00291 }
00292 return res;
00293 }
00294
00295
00296 std::string ConnJoint::dumpElements( FCO::ModelRepPtrList & model_list)
00297 {
00298 std::string mmm;
00299 std::string mmm_src = "";
00300 std::string mmm_dst = "";
00301
00302 PointerItemSeries src_dumper_list, dst_dumper_list;
00303
00304 FCO::ModelRepPtrList_ConstIterator mod_it = model_list.begin();
00305
00306 for( ; mod_it != model_list.end(); ++mod_it )
00307 {
00308 ModelRep * mod_ptr = *mod_it;
00309 PointerItemSeries_Iterator item_it = m_oper1TargetMap[ mod_ptr].begin();
00310 for( ; item_it != m_oper1TargetMap[ mod_ptr].end(); ++item_it)
00311 {
00312 if ( std::find( src_dumper_list.begin(), src_dumper_list.end(), *item_it) ==
00313 src_dumper_list.end())
00314 src_dumper_list.push_back( *item_it);
00315 else
00316 { }
00317 }
00318
00319 item_it = m_oper2TargetMap[ mod_ptr].begin();
00320 for( ; item_it != m_oper2TargetMap[ mod_ptr].end(); ++item_it)
00321 {
00322 if ( std::find( dst_dumper_list.begin(), dst_dumper_list.end(), *item_it) ==
00323 dst_dumper_list.end())
00324 dst_dumper_list.push_back( *item_it);
00325 else
00326 { }
00327 }
00328 }
00329
00330 mmm += indStr() + "<connjoint>\n";
00331 ++ind;
00332
00333 mmm += indStr() + "<pointerspec name = \"src\">\n";
00334 ++ind;
00335
00336 PointerItemLex lex;
00337 std::sort( src_dumper_list.begin(), src_dumper_list.end(), lex);
00338 std::sort( dst_dumper_list.begin(), dst_dumper_list.end(), lex);
00339
00340 PointerItemSeries_Iterator item_it = src_dumper_list.begin();
00341 for( ; item_it != src_dumper_list.end(); ++item_it)
00342 mmm_src += indStr() + "<pointeritem desc = \"" + item_it->name() + "\"></pointeritem>\n";
00343
00344 --ind;
00345 mmm += mmm_src + indStr() + "</pointerspec>\n";
00346 mmm += indStr() + "<pointerspec name = \"dst\">\n";
00347 ++ind;
00348
00349 item_it = dst_dumper_list.begin();
00350 for( ; item_it != dst_dumper_list.end(); ++item_it)
00351 mmm_dst += indStr() + "<pointeritem desc = \"" + item_it->name() + "\"></pointeritem>\n";
00352
00353 --ind;
00354 mmm += mmm_dst + indStr() + "</pointerspec>\n";
00355
00356 --ind;
00357 mmm += indStr() + "</connjoint>\n";
00358
00359
00360 if (m_bidirect)
00361 {
00362 mmm += indStr() + "<connjoint>\n";
00363 ++ind;
00364
00365 mmm += indStr() + "<pointerspec name = \"src\">\n";
00366
00367 mmm += mmm_dst + indStr() + "</pointerspec>\n";
00368
00369 mmm += indStr() + "<pointerspec name = \"dst\">\n";
00370
00371 mmm += mmm_src + indStr() + "</pointerspec>\n";
00372
00373 --ind;
00374 mmm += indStr() + "</connjoint>\n";
00375 }
00376 return mmm;
00377 }
00378
00379
00380 void ConnJoint::createConstraints( Sheet* s, const std::string& conn_name)
00381 {
00382 int cons_id1 = Broker::getNextConstraintId();
00383 int cons_id2 = Broker::getNextConstraintId();
00384
00385 char cons_id1_str[64], cons_id2_str[64];
00386
00387 sprintf( cons_id1_str, "%d", cons_id1);
00388 sprintf( cons_id2_str, "%d", cons_id2);
00389
00390 std::string src_cons_name, dst_cons_name;
00391 src_cons_name = "Valid" + conn_name + m_srcLabel + "Cardinality" + cons_id1_str;
00392 dst_cons_name = "Valid" + conn_name + m_dstLabel + "Cardinality" + cons_id2_str;
00393 std::string::size_type pos = 0;
00394 pos = src_cons_name.find( "::");
00395 if( pos != std::string::npos)
00396 src_cons_name.replace( pos, 2, 2, '_');
00397 pos = dst_cons_name.find( "::");
00398 if( pos != std::string::npos)
00399 dst_cons_name.replace( pos, 2, 2, '_');
00400
00401 int iEventMask = 0;
00402 char chMask[64];
00403 sprintf( chMask, "%x", iEventMask );
00404 std::string mask = chMask;
00405
00406
00407
00408 std::string src_expr_begin, dst_expr_begin;
00409 src_expr_begin = "let srcCount = self.attachingConnections( \"" + m_dstLabel + "\", meta::" + conn_name + " ) -> size in\n ";
00410 dst_expr_begin = "let dstCount = self.attachingConnections( \"" + m_srcLabel + "\", meta::" + conn_name + " ) -> size in\n ";
00411
00412 std::string src_expr_end, dst_expr_end;
00413 std::string src_card_context, dst_card_context;
00414
00415 src_card_context = "[connection] Connection: " + conn_name + ", Conn.Role: " + m_srcLabel;
00416 dst_card_context = "[connection] Connection: " + conn_name + ", Conn.Role: " + m_dstLabel;
00417
00418 if ( Dumper::doParseCardinality( this->m_oper1Card, "srcCount", src_card_context, src_expr_end))
00419 {
00420 global_vars.err << MSG_WARNING << "Ignoring invalid cardinality string in connection: " << m_connPtr->getPtr() << ". String: " << this->m_oper1Card << "\n";
00421 }
00422 if ( ! src_expr_end.empty() )
00423 {
00424
00425 SDList_Iterator it = m_oper2.begin();
00426 while ( it != m_oper2.end())
00427 {
00428 std::string src_desc;
00429 src_desc = "Multiplicity of objects, which are associated to " + (*it)->getName() +
00430 " as \"" + m_srcLabel + "\" over " + conn_name + ", has to match " + m_oper1Card + ".";
00431
00432 ConstraintRep * cr = s->createConstraintRep( BON::FCO());
00433 std::string s_b = src_expr_begin + src_expr_end;
00434 cr->init( src_cons_name, global_vars.genConstr.connect_mask, "1", global_vars.genConstr.priority, s_b, src_desc);
00435
00436 (*it)->addInitialConstraintRep( cr);
00437 cr->attachedTo();
00438 ++it;
00439 }
00440 }
00441 if ( Dumper::doParseCardinality( this->m_oper2Card, "dstCount", dst_card_context, dst_expr_end))
00442 {
00443 global_vars.err << MSG_WARNING << "Ignoring invalid cardinality string in connection: " << m_connPtr->getPtr() << ". String: " << this->m_oper2Card << "\n";
00444 }
00445 if ( ! dst_expr_end.empty() )
00446 {
00447
00448 SDList_Iterator it = m_oper1.begin();
00449 while ( it != m_oper1.end())
00450 {
00451 std::string dst_desc;
00452 dst_desc = "Multiplicity of objects, which are associated to " + (*it)->getName() +
00453 " as \"" + m_dstLabel + "\" over " + conn_name + ", has to match " + m_oper2Card + ".";
00454
00455 ConstraintRep * cr = s->createConstraintRep( BON::FCO());
00456 std::string d_b = dst_expr_begin + dst_expr_end;
00457 cr->init( dst_cons_name, global_vars.genConstr.connect_mask, "1", global_vars.genConstr.priority, d_b, dst_desc);
00458
00459 (*it)->addInitialConstraintRep( cr);
00460 cr->attachedTo();
00461 ++it;
00462 }
00463
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472 bool ConnJoint::descendantsOf( const ConnJoint& peer) const
00473 {
00474 bool res = true;
00475
00476 const SDList* mylists[] = { &m_oper1, &m_oper2 };
00477 const SDList* peerlists[] = { &peer.m_oper1, &peer.m_oper2 };
00478
00479 for( int i = 0; res && i < 2; ++i)
00480 {
00481 SDList_ConstIterator it = mylists[i]->begin();
00482 for( ; res && it != mylists[i]->end(); ++it)
00483 {
00484 bool current_found = false;
00485
00486 SDList_ConstIterator itp = peerlists[i]->begin();
00487 for( ; !current_found && itp != peerlists[i]->end(); ++itp)
00488 {
00489 std::vector<FCO*> descs;
00490 (*itp)->getIntDescendants( descs);
00491
00492 if ( std::find( descs.begin(), descs.end(), *it) != descs.end())
00493 current_found = true;
00494 }
00495 res = res && current_found;
00496 }
00497 }
00498 return res;
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532