Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / engine / LinkInfo.cxx
1 #include "LinkInfo.hxx"
2 #include "ComposedNode.hxx"
3
4 #include <sstream>
5
6 using namespace std;
7 using namespace YACS::ENGINE;
8
9 static const char GLOBAL_MESSAGE1[]="Global report  : \n";
10
11 static const char LINK_REPR[]="link";
12
13 LinkInfo::LinkInfo(unsigned char level):_levelOfInfo(level),_level(0)
14 {
15 }
16
17 void LinkInfo::clearAll()
18 {
19   _level=0;
20   _unsetInPort.clear();
21   _onlyBackDefined.clear();
22   _uselessLinks.clear();
23   _infos.clear();
24   _collapse.clear();
25   _errors.clear();
26 }
27
28 void LinkInfo::startCollapseTransac()
29 {
30   _level++;
31 }
32
33 void LinkInfo::endCollapseTransac() throw(Exception)
34 {
35   if(--_level==0)
36     {
37       if(_levelOfInfo==ALL_STOP_ASAP or _levelOfInfo==ERR_ONLY_DONT_STOP)
38         throw Exception(getErrRepr());
39       if(_levelOfInfo==ALL_STOP_ASAP)
40         throw Exception(getWarnRepr());
41     }
42 }
43
44 void LinkInfo::setPointOfView(ComposedNode *pov)
45 {
46   _pov=pov;
47 }
48
49 void LinkInfo::pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
50 {
51   _infos[reason].push_back(pair<OutPort *, InPort *>(semStart,end));
52 }
53
54 void LinkInfo::pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason)
55 {
56   if(_collapse[reason].empty())
57     _collapse[reason].push_back(vector< pair<OutPort *,InPort *> >());
58   else
59     if(_collapse[reason].back()[0].second!=end)
60       _collapse[reason].push_back(vector< pair<OutPort *,InPort *> >());
61   _collapse[reason].back().push_back(pair<OutPort *,InPort *>(semStart,end));
62 }
63
64 void LinkInfo::pushErrLink(OutPort *semStart, InPort *end, ErrReason reason) throw(Exception)
65 {
66   if(reason==E_NEVER_SET_INPUTPORT)
67     _unsetInPort.push_back(end);
68   else if(reason==E_ONLY_BACKWARD_DEFINED)
69     _onlyBackDefined.push_back(end);
70   else
71     _errors[reason].push_back(pair<OutPort *, InPort *>(semStart,end));
72   if(_level==0)
73     if(_levelOfInfo==ALL_STOP_ASAP or _levelOfInfo==ERR_ONLY_DONT_STOP)
74       throw Exception(getErrRepr());
75 }
76
77 void LinkInfo::pushUselessCFLink(Node *start, Node *end)
78 {
79   _uselessLinks.insert(pair<Node *,Node *>(start,end));
80 }
81
82 void LinkInfo::takeDecision() const throw(Exception)
83 {
84   if(!_errors.empty())
85     throw Exception(getErrRepr());
86 }
87
88 std::string LinkInfo::getGlobalRepr() const
89 {
90   ostringstream retS; retS << GLOBAL_MESSAGE1;
91   retS << printThereIsAre(getNumberOfErrLinks(E_ALL),"error") << ".\n";
92   retS << printThereIsAre(getNumberOfWarnLinksGrp(W_ALL),"warning") << ".\n";
93   retS << printThereIsAre(getNumberOfInfoLinks(I_ALL),"info") << ".\n";
94   if(getNumberOfErrLinks(E_ALL)>0)
95     {
96       retS << "****** ERRORS ******" << endl;
97       retS << getErrRepr() << endl;
98     }
99   if(getNumberOfWarnLinksGrp(W_ALL)>0)
100     {
101       retS << "****** WARNINGS ******" << endl;
102       retS << getWarnRepr() << endl;
103     }
104   if(getNumberOfInfoLinks(I_ALL)>0)
105     {
106       retS << "****** INFO ******" << endl;
107       retS << getInfoRepr() << endl;
108     }
109   return retS.str();
110 }
111
112 std::string LinkInfo::getInfoRepr() const
113 {
114   map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter;
115   ostringstream stream;
116   for(iter=_infos.begin();iter!=_infos.end();iter++)
117     {
118       for(vector< pair<OutPort *,InPort *> >::const_iterator iter2=(*iter).second.begin();iter2!=(*iter).second.end();iter2++)
119         {
120           stream << getStringReprOfI((*iter).first) << " between \"" << _pov->getOutPortName((*iter2).first);
121           stream << "\" and \"" << _pov->getInPortName((*iter2).second) << "\"." << endl;
122         }
123     }
124   set< pair<Node *, Node *> >::const_iterator iter3;
125   for(iter3=_uselessLinks.begin();iter3!=_uselessLinks.end();iter3++)
126     {
127       stream << getStringReprOfI(I_USELESS) << " between \"" << _pov->getChildName((*iter3).first);
128       stream << "\" and \"" << _pov->getChildName((*iter3).second) << "\"." << endl;
129     }
130   return stream.str();
131 }
132
133 std::string LinkInfo::getWarnRepr() const
134 {
135   map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter;
136   ostringstream stream;
137   unsigned i=0;
138   for(iter=_collapse.begin();iter!=_collapse.end();iter++)
139     {
140       stream << getStringReprOfW((*iter).first) << " for group containing following group links: ";
141       vector< vector< pair<OutPort *,InPort *> > >::const_iterator iter2=(*iter).second.begin();
142       for(;iter2!=(*iter).second.end();iter2++)
143         {
144           stream << "    Group # " << i++ << " : " << endl;
145           for(vector< pair<OutPort *,InPort *> >::const_iterator iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
146             stream << "          \"" << _pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl;
147         }
148     }
149   return stream.str();
150 }
151
152 std::string LinkInfo::getErrRepr() const
153 {
154   vector<InPort *>::const_iterator iter;
155   ostringstream stream;
156   for(iter=_unsetInPort.begin();iter!=_unsetInPort.end();iter++)
157     stream << getStringReprOfE(E_NEVER_SET_INPUTPORT) << "\"" << _pov->getInPortName(*iter) << "\"." << endl;
158   for(iter=_onlyBackDefined.begin();iter!=_onlyBackDefined.end();iter++)
159     stream << getStringReprOfE(E_ONLY_BACKWARD_DEFINED) << "\"" << _pov->getInPortName(*iter) << "\"." << endl;
160   map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter2;
161   for(iter2=_errors.begin();iter2!=_errors.end();iter2++)
162     for(vector< pair<OutPort *,InPort *> >::const_iterator iter3=(*iter2).second.begin();iter3!=(*iter2).second.end();iter3++)
163       stream << getStringReprOfE((*iter2).first) << " between \"" <<_pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl;
164   return stream.str();
165 }
166
167 /*!
168  * If 'reason'==I_ALL returns nummmber of types of links info whereas it returns number of info per type.
169  */
170 unsigned LinkInfo::getNumberOfInfoLinks(InfoReason reason) const
171 {
172   if(reason==I_ALL)
173     return _infos.size()+_uselessLinks.size();
174   if(reason==I_CF_USELESS)
175     return _uselessLinks.size();
176   else
177     {
178       map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_infos.find(reason);
179       if(iter!=_infos.end())
180         return (*iter).second.size();
181       else
182         return 0;
183     }
184 }
185
186 unsigned LinkInfo::getNumberOfWarnLinksGrp(WarnReason reason) const
187 {
188   unsigned ret=0;
189   map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter;
190   if(reason==W_ALL)
191     {
192       for(iter=_collapse.begin();iter!=_collapse.end();iter++)
193         ret+=(*iter).second.size();
194       return ret;
195     }
196   map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter2=_collapse.find(reason);
197   if(iter2!=_collapse.end())
198     return (*iter2).second.size();
199   else
200     return 0;
201 }
202
203 unsigned LinkInfo::getNumberOfErrLinks(ErrReason reason) const
204 {
205   if(reason==E_ALL)
206     return _errors.size()+_onlyBackDefined.size()+_unsetInPort.size();
207   else if(reason==E_NEVER_SET_INPUTPORT)
208     return _unsetInPort.size();
209   else if(reason==E_ONLY_BACKWARD_DEFINED)
210     return _onlyBackDefined.size();
211   else
212     {
213       map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_errors.find(reason);
214       if(iter!=_errors.end())
215         return (*iter).second.size();
216       else
217         return 0;
218     }
219 }
220
221 std::set< std::pair<Node *, Node *> > LinkInfo::getInfoUselessLinks() const
222 {
223   return _uselessLinks;
224 }
225
226 std::pair<OutPort *, InPort *> LinkInfo::getInfoLink(unsigned id, InfoReason reason) const
227 {
228   if(reason==I_CF_USELESS)
229     return pair<OutPort *, InPort *>();
230   map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_infos.find(reason);
231   if(iter!=_infos.end())
232     return (*iter).second[id];
233   else
234     return pair<OutPort *, InPort *>(0,0);
235 }
236
237 std::vector< std::pair<OutPort *, InPort *> > LinkInfo::getWarnLink(unsigned id, WarnReason reason) const
238 {
239   map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter=_collapse.find(reason);
240   if(iter!=_collapse.end())
241     return (*iter).second[id];
242   else
243     return vector< pair<OutPort *, InPort *> >();
244 }
245
246 std::pair<OutPort *, InPort *> LinkInfo::getErrLink(unsigned id, ErrReason reason) const
247 {
248   if(reason==E_NEVER_SET_INPUTPORT)
249     return pair<OutPort *, InPort *>(0,_unsetInPort[id]);
250   else if(reason==E_ONLY_BACKWARD_DEFINED)
251     return pair<OutPort *, InPort *>(0,_onlyBackDefined[id]);
252   else
253     {
254       map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_errors.find(reason);
255       if(iter!=_errors.end())
256         return (*iter).second[id];
257       else
258         return pair<OutPort *, InPort *>(0,0);
259     }
260 }
261
262 std::string LinkInfo::getStringReprOfI(InfoReason reason)
263 {
264   string ret;
265   switch(reason)
266     {
267     case I_USELESS:
268       ret="Useless CF";
269       break;
270     case I_BACK:
271       ret="Back";
272       break;
273     case I_BACK_USELESS:
274       ret="Back and useless";
275       break;
276     case I_BACK_CRAZY:
277       ret+="Crazy back";
278       break;
279     case I_DFDS:
280       ret+="DF/DS";
281     }
282   ret+=" "; ret+=LINK_REPR;
283   return ret;
284 }
285
286 std::string LinkInfo::getStringReprOfW(WarnReason reason)
287 {
288   string ret;
289   switch(reason)
290     {
291     case W_COLLAPSE:
292       ret="Collapse";
293       break;
294     case W_COLLAPSE_AND_USELESS:
295       ret="Collapse and useless";
296       break;
297     case W_COLLAPSE_EL:
298       ret="Collapse on ElementaryNode";
299       break;
300     case W_COLLAPSE_EL_AND_USELESS:
301       ret+="Collapse on ElementaryNode and useless";
302       break;
303     case W_BACK_COLLAPSE:
304       ret+="Back collapse";
305       break;
306     case W_BACK_COLLAPSE_AND_USELESS:
307       ret+="Back collapse and useless";
308       break;
309     case W_BACK_COLLAPSE_EL:
310       ret+="Back collapse on ElementaryNode";
311       break;
312     case W_BACK_COLLAPSE_EL_AND_USELESS:
313       ret+="Back collapse and useless on ElementaryNode";
314     }
315   ret+=" "; ret+=LINK_REPR;
316   return ret;
317 }
318
319 std::string LinkInfo::getStringReprOfE(ErrReason reason)
320 {
321   string ret;
322   if(reason==E_NEVER_SET_INPUTPORT)
323     return "Never set InPort ";
324   if(reason==E_ONLY_BACKWARD_DEFINED)
325     return "Never set InPort only back defined ";
326   switch(reason)
327     {
328     case E_DS_LINK_UNESTABLISHABLE:
329       ret="DS unestablishable";
330       break;
331     case E_COLLAPSE_DFDS:
332       ret="DF/DS collapse";
333       break;
334     case E_COLLAPSE_DS:
335       ret="Inter DS collapse";
336       break;
337     case E_UNPREDICTABLE_FED:
338       ret="Unpredictable fed";
339     }
340   ret+=" "; ret+=LINK_REPR;
341   return ret;
342 }
343
344 std::string LinkInfo::printThereIsAre(unsigned val, const std::string& other)
345 {
346   ostringstream ret;
347   ret << "There ";
348   if(val==0)
349     ret << "are no";
350   else if(val==1)
351     ret << "is one";
352   else
353     ret << "are " << val;
354   ret << " " << other;
355   if(val==0 || val>1)
356     ret << "s";
357   return ret.str();
358 }