b311480e |
1 | // Created on: 2003-03-04 |
2 | // Created by: Pavel TELKOV |
3 | // Copyright (c) 2003-2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
7fd59977 |
20 | // The original implementation copyright (c) RINA S.p.A. |
21 | |
22 | #include <Message_Algorithm.ixx> |
23 | |
24 | #include <Message.hxx> |
25 | #include <Message_Msg.hxx> |
26 | #include <Message_MsgFile.hxx> |
27 | #include <Message_Messenger.hxx> |
28 | #include <Standard_AncestorIterator.hxx> |
29 | #include <TCollection_AsciiString.hxx> |
30 | #include <TColStd_SequenceOfInteger.hxx> |
31 | #include <TColStd_HSequenceOfInteger.hxx> |
32 | #include <TColStd_HSequenceOfHExtendedString.hxx> |
33 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
34 | |
35 | //======================================================================= |
36 | //function : SetMessenger |
37 | //purpose : |
38 | //======================================================================= |
39 | |
40 | Message_Algorithm::Message_Algorithm () |
41 | { |
42 | myMessenger = Message::DefaultMessenger(); |
43 | } |
44 | |
45 | //======================================================================= |
46 | //function : SetMessenger |
47 | //purpose : |
48 | //======================================================================= |
49 | |
50 | void Message_Algorithm::SetMessenger (const Handle(Message_Messenger)& theMsgr) |
51 | { |
52 | if ( theMsgr.IsNull() ) |
53 | myMessenger = Message::DefaultMessenger(); |
54 | else |
55 | myMessenger = theMsgr; |
56 | } |
57 | |
58 | //======================================================================= |
59 | //function : SetStatus |
60 | //purpose : |
61 | //======================================================================= |
62 | |
63 | void Message_Algorithm::SetStatus(const Message_Status& theStat) |
64 | { |
65 | myStatus.Set( theStat ); |
66 | } |
67 | |
68 | //======================================================================= |
69 | //function : SetStatus |
70 | //purpose : |
71 | //======================================================================= |
72 | |
73 | void Message_Algorithm::SetStatus (const Message_Status& theStat, |
74 | const Standard_Integer theInt) |
75 | { |
76 | // Set status flag |
77 | SetStatus ( theStat ); |
78 | |
79 | // Find index of bit corresponding to that flag |
80 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat); |
81 | if ( !aFlagIndex ) return; |
82 | |
83 | // Create map of integer parameters for a given flag, if not yet done |
84 | if ( myReportIntegers.IsNull() ) |
85 | myReportIntegers = new TColStd_HArray1OfTransient (Message_ExecStatus::FirstStatus, |
86 | Message_ExecStatus::LastStatus); |
87 | Handle(Standard_Transient)& aData = |
88 | myReportIntegers->ChangeValue(aFlagIndex); |
89 | if ( aData.IsNull() ) |
90 | aData = new TColStd_HPackedMapOfInteger; |
91 | |
92 | // add integer parameter for the status |
93 | Handle(TColStd_HPackedMapOfInteger)::DownCast(aData)->ChangeMap().Add(theInt); |
94 | } |
95 | |
96 | //======================================================================= |
97 | //function : SetStatus |
98 | //purpose : |
99 | //======================================================================= |
100 | |
101 | void Message_Algorithm::SetStatus (const Message_Status& theStat, |
102 | const Handle(TCollection_HExtendedString) &theStr, |
103 | const Standard_Boolean noRepetitions) |
104 | { |
105 | // Set status flag |
106 | SetStatus ( theStat ); |
107 | if ( theStr.IsNull() ) |
108 | return; |
109 | |
110 | // Find index of bit corresponding to that flag |
111 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat); |
112 | if ( !aFlagIndex ) return; |
113 | |
114 | // Create sequence of string parameters for a given flag, if not yet done |
115 | if ( myReportStrings.IsNull() ) |
116 | myReportStrings = new TColStd_HArray1OfTransient (Message_ExecStatus::FirstStatus, |
117 | Message_ExecStatus::LastStatus); |
118 | Handle(Standard_Transient)& aData = |
119 | myReportStrings->ChangeValue(aFlagIndex); |
120 | if ( aData.IsNull() ) |
121 | aData = new TColStd_HSequenceOfHExtendedString; |
122 | |
123 | // Add string parameter |
124 | Handle(TColStd_HSequenceOfHExtendedString) aReportSeq = |
125 | Handle(TColStd_HSequenceOfHExtendedString)::DownCast(aData); |
126 | if ( aReportSeq.IsNull() ) |
127 | return; |
128 | if ( noRepetitions ) |
129 | { |
130 | // if the provided string has been already registered, just do nothing |
131 | for ( Standard_Integer i=1; i <= aReportSeq->Length(); i++ ) |
132 | if ( aReportSeq->Value(i)->String().IsEqual( theStr->String() ) ) |
133 | return; |
134 | } |
135 | |
136 | aReportSeq->Append ( theStr ); |
137 | } |
138 | |
139 | //======================================================================= |
140 | //function : ClearStatus |
141 | //purpose : |
142 | //======================================================================= |
143 | |
144 | void Message_Algorithm::ClearStatus() |
145 | { |
146 | myStatus.Clear(); |
147 | myReportIntegers.Nullify(); |
148 | myReportStrings.Nullify(); |
149 | } |
150 | |
151 | //======================================================================= |
152 | //function : SendStatusMessages |
153 | //purpose : |
154 | //======================================================================= |
155 | |
156 | void Message_Algorithm::SendStatusMessages (const Message_ExecStatus& theStatus, |
157 | const Message_Gravity theTraceLevel, |
158 | const Standard_Integer theMaxCount) const |
159 | { |
160 | Handle(Message_Messenger) aMsgr = GetMessenger(); |
161 | if (aMsgr.IsNull()) return; |
162 | |
163 | TCollection_AsciiString aClassName ( DynamicType()->Name() ); |
164 | |
165 | // Iterate on all set flags in the specified range |
166 | for ( Standard_Integer i = Message_ExecStatus::FirstStatus; |
167 | i <= Message_ExecStatus::LastStatus; i++ ) |
168 | { |
169 | Message_Status stat = Message_ExecStatus::StatusByIndex( i ); |
170 | if ( !theStatus.IsSet( stat ) || !myStatus.IsSet( stat ) ) |
171 | continue; |
172 | |
173 | // construct message suffix |
174 | TCollection_AsciiString aSuffix; |
175 | switch( Message_ExecStatus::TypeOfStatus( stat ) ) |
176 | { |
177 | case Message_DONE: aSuffix.AssignCat( ".Done" ); break; |
178 | case Message_WARN: aSuffix.AssignCat( ".Warn" ); break; |
179 | case Message_ALARM: aSuffix.AssignCat( ".Alarm"); break; |
180 | case Message_FAIL: aSuffix.AssignCat( ".Fail" ); break; |
181 | default: continue; |
182 | } |
183 | aSuffix.AssignCat( Message_ExecStatus::LocalStatusIndex( stat ) ); |
184 | |
185 | // find message, iterating by base classes if necessary |
186 | TCollection_AsciiString aMsgName = aClassName + aSuffix; |
187 | Handle(Standard_Type) aType = DynamicType(); |
188 | while (Message_MsgFile::Msg(aMsgName).Length() == 0 && !aType.IsNull()) |
189 | { |
190 | Standard_AncestorIterator it(aType); |
191 | aType.Nullify(); |
192 | for (; it.More(); it.Next()) |
193 | { |
194 | aType = it.Value(); |
195 | TCollection_AsciiString aClassName1 (aType->Name()); |
196 | TCollection_AsciiString aMsgName1 = aClassName1 + aSuffix; |
197 | if (Message_MsgFile::Msg(aMsgName1).Length() != 0) |
198 | { |
199 | aMsgName = aMsgName1; |
200 | break; |
201 | } |
202 | } |
203 | } |
204 | |
205 | // create a message |
206 | Message_Msg aMsg ( aMsgName ); |
207 | |
208 | // if additional parameters are defined for a given status flag, |
209 | // try to feed them into the message |
210 | if ( ! myReportIntegers.IsNull() ) |
211 | { |
212 | Handle(TColStd_HPackedMapOfInteger) aMapErrors = |
213 | Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(i)); |
214 | if (!aMapErrors.IsNull() ) |
215 | aMsg << PrepareReport ( aMapErrors, theMaxCount ); |
216 | } |
217 | if ( ! myReportStrings.IsNull() && ! myReportStrings->Value(i).IsNull() ) |
218 | { |
219 | Handle(TColStd_HSequenceOfHExtendedString) aReportSeq = |
220 | Handle(TColStd_HSequenceOfHExtendedString)::DownCast ( myReportStrings->Value(i) ); |
221 | if ( ! aReportSeq.IsNull() ) |
222 | aMsg << PrepareReport ( aReportSeq->Sequence(), theMaxCount ); |
223 | } |
224 | |
225 | // output the message |
226 | aMsgr->Send(aMsg, theTraceLevel); |
227 | } |
228 | } |
229 | |
230 | //======================================================================= |
231 | //function : SendMessages |
232 | //purpose : |
233 | //======================================================================= |
234 | |
235 | void Message_Algorithm::SendMessages (const Message_Gravity theTraceLevel, |
236 | const Standard_Integer theMaxCount) const |
237 | { |
238 | Message_ExecStatus aStat; |
239 | aStat.SetAllWarn(); |
240 | aStat.SetAllAlarm(); |
241 | aStat.SetAllFail(); |
242 | SendStatusMessages( aStat, theTraceLevel, theMaxCount ); |
243 | } |
244 | |
245 | //======================================================================= |
246 | //function : AddStatus |
247 | //purpose : |
248 | //======================================================================= |
249 | |
250 | void Message_Algorithm::AddStatus |
251 | (const Handle(Message_Algorithm)& theOtherAlgo) |
252 | { |
253 | AddStatus( theOtherAlgo->GetStatus(), theOtherAlgo ); |
254 | } |
255 | |
256 | //======================================================================= |
257 | //function : AddStatus |
258 | //purpose : |
259 | //======================================================================= |
260 | |
261 | void Message_Algorithm::AddStatus |
262 | (const Message_ExecStatus& theAllowedStatus, |
263 | const Handle(Message_Algorithm)& theOtherAlgo) |
264 | { |
265 | // Iterate on all set flags in the specified range |
266 | const Message_ExecStatus& aStatusOfAlgo = theOtherAlgo->GetStatus(); |
267 | for ( Standard_Integer i = Message_ExecStatus::FirstStatus; |
268 | i <= Message_ExecStatus::LastStatus; i++ ) |
269 | { |
270 | Message_Status stat = Message_ExecStatus::StatusByIndex( i ); |
271 | if ( ! theAllowedStatus.IsSet( stat ) || ! aStatusOfAlgo.IsSet( stat ) ) |
272 | continue; |
273 | |
274 | SetStatus ( stat ); |
275 | |
276 | // if additional parameters are defined for a given status flag, |
277 | // move them to <this> algorithm |
278 | // a) numbers |
279 | Handle(TColStd_HPackedMapOfInteger) aNumsOther = |
280 | theOtherAlgo->GetMessageNumbers (stat); |
281 | if ( ! aNumsOther.IsNull() ) |
282 | { |
283 | // Create sequence of integer parameters for a given flag, if not yet done |
284 | if ( myReportIntegers.IsNull() ) |
285 | myReportIntegers = |
286 | new TColStd_HArray1OfTransient(Message_ExecStatus::FirstStatus, |
287 | Message_ExecStatus::LastStatus); |
288 | Handle(Standard_Transient)& aData = |
289 | myReportIntegers->ChangeValue(i); |
290 | if ( aData.IsNull() ) |
291 | aData = new TColStd_HPackedMapOfInteger; |
292 | |
293 | // add integer parameter for the status |
294 | Handle(TColStd_HPackedMapOfInteger)::DownCast(aData) |
295 | ->ChangeMap().Unite(aNumsOther->Map()); |
296 | } |
297 | // b) strings |
298 | Handle(TColStd_HSequenceOfHExtendedString) aStrsOther = |
299 | theOtherAlgo->GetMessageStrings (stat); |
300 | if ( ! aStrsOther.IsNull() ) |
301 | { |
302 | for (Standard_Integer n=1; n < aStrsOther->Length(); n++ ) |
303 | SetStatus (stat, aStrsOther->Value(n)); |
304 | } |
305 | } |
306 | } |
307 | |
308 | //======================================================================= |
309 | //function : GetMessageNumbers |
310 | //purpose : |
311 | //======================================================================= |
312 | |
313 | Handle(TColStd_HPackedMapOfInteger) Message_Algorithm::GetMessageNumbers |
314 | (const Message_Status& theStatus) const |
315 | { |
316 | if ( myReportIntegers.IsNull() ) |
317 | return 0; |
318 | |
319 | // Find index of bit corresponding to that flag |
320 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus); |
321 | if ( ! aFlagIndex ) return 0; |
322 | |
323 | return Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(aFlagIndex)); |
324 | } |
325 | |
326 | //======================================================================= |
327 | //function : GetMessageStrings |
328 | //purpose : |
329 | //======================================================================= |
330 | |
331 | Handle(TColStd_HSequenceOfHExtendedString) Message_Algorithm::GetMessageStrings |
332 | (const Message_Status& theStatus) const |
333 | { |
334 | if ( myReportStrings.IsNull() ) |
335 | return 0; |
336 | |
337 | // Find index of bit corresponding to that flag |
338 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus); |
339 | if ( ! aFlagIndex ) return 0; |
340 | |
341 | return Handle(TColStd_HSequenceOfHExtendedString)::DownCast(myReportStrings->Value(aFlagIndex)); |
342 | } |
343 | |
344 | //======================================================================= |
345 | //function : PrepareReport |
346 | //purpose : static method |
347 | //======================================================================= |
348 | |
349 | TCollection_ExtendedString Message_Algorithm::PrepareReport |
350 | (const Handle(TColStd_HPackedMapOfInteger)& theMapError, |
351 | const Standard_Integer theMaxCount) |
352 | { |
353 | TCollection_ExtendedString aNewReport; |
354 | TColStd_MapIteratorOfPackedMapOfInteger anIt(theMapError->Map()); |
355 | Standard_Integer nb = 1; |
356 | for (; anIt.More() && nb <= theMaxCount; anIt.Next(), nb++ ) |
357 | { |
358 | if ( nb > 1 ) |
359 | aNewReport += " "; |
360 | aNewReport += anIt.Key(); |
361 | } |
362 | |
363 | if ( anIt.More() ) |
364 | { |
365 | aNewReport += " ... (total "; |
366 | aNewReport += theMapError->Map().Extent(); |
367 | aNewReport += ")"; |
368 | } |
369 | return aNewReport; |
370 | } |
371 | |
372 | //======================================================================= |
373 | //function : PrepareReport |
374 | //purpose : static method |
375 | //======================================================================= |
376 | |
377 | TCollection_ExtendedString Message_Algorithm::PrepareReport |
378 | (const TColStd_SequenceOfHExtendedString& theReportSeq, |
379 | const Standard_Integer theMaxCount) |
380 | { |
381 | TCollection_ExtendedString aNewReport; |
382 | Standard_Integer nb = 1; |
383 | for ( ; nb <= theReportSeq.Length() && nb <= theMaxCount; nb++) |
384 | { |
385 | aNewReport += (Standard_CString)( nb > 1 ? ", \'" : "\'" ); |
386 | aNewReport += theReportSeq.Value(nb)->String(); |
387 | aNewReport += "\'"; |
388 | } |
389 | |
390 | if (theReportSeq.Length() > theMaxCount ) |
391 | { |
392 | aNewReport += " ... (total "; |
393 | aNewReport += theReportSeq.Length(); |
394 | aNewReport += ") "; |
395 | } |
396 | return aNewReport; |
397 | } |