1 // Created on: 2003-03-04
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 // The original implementation copyright (c) RINA S.p.A.
18 #include <Message.hxx>
19 #include <Message_Algorithm.hxx>
20 #include <Message_Messenger.hxx>
21 #include <Message_Msg.hxx>
22 #include <Message_MsgFile.hxx>
23 #include <Standard_Type.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TCollection_ExtendedString.hxx>
26 #include <TCollection_HAsciiString.hxx>
27 #include <TCollection_HExtendedString.hxx>
28 #include <TColStd_HPackedMapOfInteger.hxx>
29 #include <TColStd_HSequenceOfHExtendedString.hxx>
30 #include <TColStd_HSequenceOfInteger.hxx>
31 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
32 #include <TColStd_SequenceOfInteger.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(Message_Algorithm,Standard_Transient)
36 //=======================================================================
37 //function : Message_Algorithm
39 //=======================================================================
40 Message_Algorithm::Message_Algorithm ()
42 myMessenger = Message::DefaultMessenger();
45 //=======================================================================
46 //function : SetMessenger
48 //=======================================================================
50 void Message_Algorithm::SetMessenger (const Handle(Message_Messenger)& theMsgr)
52 if ( theMsgr.IsNull() )
53 myMessenger = Message::DefaultMessenger();
55 myMessenger = theMsgr;
58 //=======================================================================
59 //function : SetStatus
61 //=======================================================================
63 void Message_Algorithm::SetStatus(const Message_Status& theStat)
65 myStatus.Set( theStat );
68 //=======================================================================
69 //function : SetStatus
71 //=======================================================================
73 void Message_Algorithm::SetStatus (const Message_Status& theStat,
74 const Standard_Integer theInt)
77 SetStatus ( theStat );
79 // Find index of bit corresponding to that flag
80 Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat);
81 if ( !aFlagIndex ) return;
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);
90 aData = new TColStd_HPackedMapOfInteger;
92 // add integer parameter for the status
93 Handle(TColStd_HPackedMapOfInteger)::DownCast(aData)->ChangeMap().Add(theInt);
96 //=======================================================================
97 //function : SetStatus
99 //=======================================================================
101 void Message_Algorithm::SetStatus (const Message_Status& theStat,
102 const Handle(TCollection_HExtendedString) &theStr,
103 const Standard_Boolean noRepetitions)
106 SetStatus ( theStat );
107 if ( theStr.IsNull() )
110 // Find index of bit corresponding to that flag
111 Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat);
112 if ( !aFlagIndex ) return;
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;
123 // Add string parameter
124 Handle(TColStd_HSequenceOfHExtendedString) aReportSeq =
125 Handle(TColStd_HSequenceOfHExtendedString)::DownCast(aData);
126 if ( aReportSeq.IsNull() )
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() ) )
136 aReportSeq->Append ( theStr );
139 //=======================================================================
140 //function : SetStatus
142 //=======================================================================
144 void Message_Algorithm::SetStatus (const Message_Status& theStat,
145 const Message_Msg& theMsg)
150 // Find index of bit corresponding to that flag
151 Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex (theStat);
157 // Create sequence of messages for a given flag, if not yet done
158 if (myReportMessages.IsNull())
160 myReportMessages = new Message_ArrayOfMsg (Message_ExecStatus::FirstStatus, Message_ExecStatus::LastStatus);
163 myReportMessages->ChangeValue (aFlagIndex) = new Message_Msg (theMsg);
166 //=======================================================================
167 //function : ClearStatus
169 //=======================================================================
171 void Message_Algorithm::ClearStatus()
174 myReportIntegers.Nullify();
175 myReportStrings.Nullify();
176 myReportMessages.Nullify();
179 //=======================================================================
180 //function : SendStatusMessages
182 //=======================================================================
184 void Message_Algorithm::SendStatusMessages (const Message_ExecStatus& theStatus,
185 const Message_Gravity theTraceLevel,
186 const Standard_Integer theMaxCount) const
188 Handle(Message_Messenger) aMsgr = GetMessenger();
194 // Iterate on all set flags in the specified range
195 for ( Standard_Integer i = Message_ExecStatus::FirstStatus;
196 i <= Message_ExecStatus::LastStatus; i++ )
198 Message_Status stat = Message_ExecStatus::StatusByIndex( i );
199 if (!theStatus.IsSet (stat) || !myStatus.IsSet (stat))
204 NCollection_Handle<Message_Msg> aMsgCustom;
205 if (! myReportMessages.IsNull())
206 aMsgCustom = myReportMessages->Value (i);
207 if (!aMsgCustom.IsNull())
209 // print custom message
210 aMsgr->Send (*aMsgCustom, theTraceLevel);
214 // construct message suffix
215 TCollection_AsciiString aSuffix;
216 switch( Message_ExecStatus::TypeOfStatus( stat ) )
218 case Message_DONE: aSuffix.AssignCat( ".Done" ); break;
219 case Message_WARN: aSuffix.AssignCat( ".Warn" ); break;
220 case Message_ALARM: aSuffix.AssignCat( ".Alarm"); break;
221 case Message_FAIL: aSuffix.AssignCat( ".Fail" ); break;
224 aSuffix.AssignCat( Message_ExecStatus::LocalStatusIndex( stat ) );
226 // find message, prefixed by class type name, iterating by base classes if necessary
227 TCollection_AsciiString aMsgName;
228 for (Handle(Standard_Type) aType = DynamicType(); ! aType.IsNull(); aType = aType->Parent())
230 aMsgName = aType->Name();
232 if (Message_MsgFile::HasMsg(aMsgName))
237 Message_Msg aMsg ( aMsgName );
239 // if additional parameters are defined for a given status flag,
240 // try to feed them into the message
241 if (!myReportIntegers.IsNull())
243 Handle(TColStd_HPackedMapOfInteger) aMapErrors =
244 Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(i));
245 if (!aMapErrors.IsNull())
247 aMsg << PrepareReport (aMapErrors, theMaxCount);
250 if (!myReportStrings.IsNull()
251 && !myReportStrings->Value (i).IsNull())
253 Handle(TColStd_HSequenceOfHExtendedString) aReportSeq =
254 Handle(TColStd_HSequenceOfHExtendedString)::DownCast (myReportStrings->Value(i));
255 if (!aReportSeq.IsNull())
257 aMsg << PrepareReport (aReportSeq->Sequence(), theMaxCount);
261 // output the message
262 aMsgr->Send(aMsg, theTraceLevel);
266 //=======================================================================
267 //function : SendMessages
269 //=======================================================================
271 void Message_Algorithm::SendMessages (const Message_Gravity theTraceLevel,
272 const Standard_Integer theMaxCount) const
274 Message_ExecStatus aStat;
278 SendStatusMessages( aStat, theTraceLevel, theMaxCount );
281 //=======================================================================
282 //function : AddStatus
284 //=======================================================================
286 void Message_Algorithm::AddStatus
287 (const Handle(Message_Algorithm)& theOtherAlgo)
289 AddStatus( theOtherAlgo->GetStatus(), theOtherAlgo );
292 //=======================================================================
293 //function : AddStatus
295 //=======================================================================
297 void Message_Algorithm::AddStatus
298 (const Message_ExecStatus& theAllowedStatus,
299 const Handle(Message_Algorithm)& theOtherAlgo)
301 // Iterate on all set flags in the specified range
302 const Message_ExecStatus& aStatusOfAlgo = theOtherAlgo->GetStatus();
303 for ( Standard_Integer i = Message_ExecStatus::FirstStatus;
304 i <= Message_ExecStatus::LastStatus; i++ )
306 Message_Status stat = Message_ExecStatus::StatusByIndex( i );
307 if ( ! theAllowedStatus.IsSet( stat ) || ! aStatusOfAlgo.IsSet( stat ) )
312 // if additional parameters are defined for a given status flag,
313 // move them to <this> algorithm
315 Handle(TColStd_HPackedMapOfInteger) aNumsOther =
316 theOtherAlgo->GetMessageNumbers (stat);
317 if ( ! aNumsOther.IsNull() )
319 // Create sequence of integer parameters for a given flag, if not yet done
320 if ( myReportIntegers.IsNull() )
322 new TColStd_HArray1OfTransient(Message_ExecStatus::FirstStatus,
323 Message_ExecStatus::LastStatus);
324 Handle(Standard_Transient)& aData =
325 myReportIntegers->ChangeValue(i);
326 if ( aData.IsNull() )
327 aData = new TColStd_HPackedMapOfInteger;
329 // add integer parameter for the status
330 Handle(TColStd_HPackedMapOfInteger)::DownCast(aData)
331 ->ChangeMap().Unite(aNumsOther->Map());
334 Handle(TColStd_HSequenceOfHExtendedString) aStrsOther =
335 theOtherAlgo->GetMessageStrings (stat);
336 if ( ! aStrsOther.IsNull() )
338 for (Standard_Integer n=1; n < aStrsOther->Length(); n++ )
339 SetStatus (stat, aStrsOther->Value(n));
344 //=======================================================================
345 //function : GetMessageNumbers
347 //=======================================================================
349 Handle(TColStd_HPackedMapOfInteger) Message_Algorithm::GetMessageNumbers
350 (const Message_Status& theStatus) const
352 if ( myReportIntegers.IsNull() )
355 // Find index of bit corresponding to that flag
356 Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus);
357 if ( ! aFlagIndex ) return 0;
359 return Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(aFlagIndex));
362 //=======================================================================
363 //function : GetMessageStrings
365 //=======================================================================
367 Handle(TColStd_HSequenceOfHExtendedString) Message_Algorithm::GetMessageStrings
368 (const Message_Status& theStatus) const
370 if ( myReportStrings.IsNull() )
373 // Find index of bit corresponding to that flag
374 Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus);
375 if ( ! aFlagIndex ) return 0;
377 return Handle(TColStd_HSequenceOfHExtendedString)::DownCast(myReportStrings->Value(aFlagIndex));
380 //=======================================================================
381 //function : PrepareReport
382 //purpose : static method
383 //=======================================================================
385 TCollection_ExtendedString Message_Algorithm::PrepareReport
386 (const Handle(TColStd_HPackedMapOfInteger)& theMapError,
387 const Standard_Integer theMaxCount)
389 TCollection_ExtendedString aNewReport;
390 TColStd_MapIteratorOfPackedMapOfInteger anIt(theMapError->Map());
391 Standard_Integer nb = 1;
392 for (; anIt.More() && nb <= theMaxCount; anIt.Next(), nb++ )
396 aNewReport += anIt.Key();
401 aNewReport += " ... (total ";
402 aNewReport += theMapError->Map().Extent();
408 //=======================================================================
409 //function : PrepareReport
410 //purpose : static method
411 //=======================================================================
413 TCollection_ExtendedString Message_Algorithm::PrepareReport
414 (const TColStd_SequenceOfHExtendedString& theReportSeq,
415 const Standard_Integer theMaxCount)
417 TCollection_ExtendedString aNewReport;
418 Standard_Integer nb = 1;
419 for ( ; nb <= theReportSeq.Length() && nb <= theMaxCount; nb++)
421 aNewReport += (Standard_CString)( nb > 1 ? ", \'" : "\'" );
422 aNewReport += theReportSeq.Value(nb)->String();
426 if (theReportSeq.Length() > theMaxCount )
428 aNewReport += " ... (total ";
429 aNewReport += theReportSeq.Length();