#include <Draw.hxx>
#include <Draw_Interpretor.hxx>
+#include <Message.hxx>
#include <TDocStd_Document.hxx>
#include <TDF_Label.hxx>
#include <TCollection_AsciiString.hxx>
#include <TDF_ListIteratorOfAttributeDeltaList.hxx>
#include <Standard_DomainError.hxx>
+#include <XmlDrivers_MessageReportStorage.hxx>
//=======================================================================
return 1;
}
+//=======================================================================
+//function : DDocStd_WriteReport
+//=======================================================================
+
+static Standard_Integer DDocStd_WriteReport(Draw_Interpretor& di,Standard_Integer n, const char** a)
+{
+ if (n < 2)
+ {
+ di << "DDocStd_WriteReport : Error not enough argument\n";
+ return 1;
+ }
+ TCollection_ExtendedString aPath (a[1]);
+ MESSAGE_STORE_XML_REPORT (aPath);
+
+ return 0;
+}
//=======================================================================
//function : ModificationCommands
"DumpCommand (DOC)",
__FILE__, DDocStd_DumpCommand, g);
+ theCommands.Add ("WriteReport",
+ "WriteReport path",
+ __FILE__, DDocStd_WriteReport, g);
+
}
#include <Draw_ProgressIndicator.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
+#include <Message_Report.hxx>
#include <OSD.hxx>
#include <OSD_Chronometer.hxx>
#include <OSD_Environment.hxx>
return 0;
}
+//==============================================================================
+//function : dsetreportprinter
+//purpose :
+//==============================================================================
+static Message_SequenceOfPrinters MyDeactivatedPrinters;
+
+static Standard_Integer dsetreportprinter(Draw_Interpretor&, Standard_Integer n, const char** a)
+{
+ if (n != 2)
+ {
+ std::cout << "Enable or disable report printer: " << a[0] << " {on|off}" << std::endl;
+ return 1;
+ }
+
+ const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
+ const Handle(Message_Messenger)& aMessenger = Message::DefaultMessenger();
+ if (! strcmp (a[1], "on") && n == 2)
+ {
+ if (aReport->IsActiveInMessenger (aMessenger))
+ {
+ std::cout << "Error: report printer has been already activated." << std::endl;
+ return 1;
+ }
+ // store current printers in cache to restore them by deactivation current printer
+ MyDeactivatedPrinters = aMessenger->Printers();
+ aMessenger->ChangePrinters().Clear();
+
+ aReport->ActivateInMessenger (Standard_True);
+ }
+ else if (! strcmp (a[1], "off") && n == 2)
+ {
+ if (!aReport->IsActiveInMessenger())
+ {
+ std::cout << "Report printer was not activated." << std::endl;
+ return 1;
+ }
+ aReport->ActivateInMessenger (Standard_False);
+
+ aMessenger->ChangePrinters().Assign (MyDeactivatedPrinters);
+ }
+ else
+ {
+ std::cout << "Unrecognized option(s): " << a[1] << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+//==============================================================================
+//function : dsetreportmetric
+//purpose :
+//==============================================================================
+static Standard_Integer dsetreportmetric(Draw_Interpretor&, Standard_Integer n, const char** a)
+{
+ if (n < 1)
+ {
+ std::cout << "Report metric activation: " << a[0] << " [metric_1 metric_2 ...]" << std::endl;
+ return 1;
+ }
+
+ const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
+ if (aReport.IsNull())
+ return 1;
+
+ aReport->ClearMetrics();
+ for (int i = 1; i < n; i++)
+ {
+ Standard_Integer aMetricId = Draw::Atoi (a [i]);
+ if (aMetricId < Message_MetricType_UserTimeCPU || aMetricId > Message_MetricType_MemHeapUsage)
+ {
+ std::cout << "Unrecognized message metric: " << aMetricId << std::endl;
+ return 1;
+ }
+ aReport->SetActiveMetric ((Message_MetricType)aMetricId, Standard_True);
+ }
+
+ return 0;
+}
+
+//==============================================================================
+//function : dprintreport
+//purpose :
+//==============================================================================
+static Standard_Integer dprintreport(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+ if (n < 1)
+ {
+ std::cout << "Report metric activation: " << a[0] << " [messenger]" << std::endl;
+ return 1;
+ }
+
+ const Handle(Message_Report)& aReport = Message::DefaultReport (Standard_True);
+ if (aReport.IsNull())
+ return 1;
+
+ if (n > 1) // default messenger
+ {
+ aReport->SendMessages (Message::DefaultMessenger());
+ }
+ else // stream
+ {
+ Standard_SStream aSStream;
+ aReport->Dump (aSStream);
+ di << aSStream;
+ }
+
+ return 0;
+}
+
//==============================================================================
//function : dtracelevel
//purpose :
__FILE__,dperf,g);
theCommands.Add("dsetsignal","dsetsignal [{asis|set|unhandled|unset}=set] [{0|1|default=$CSF_FPE}]\n -- set OSD signal handler, with FPE option if argument is given",
__FILE__,dsetsignal,g);
+ theCommands.Add("dsetreportprinter", "manage logging of messenger into default report",
+ __FILE__,dsetreportprinter,g);
+ theCommands.Add("dsetreportmetric", "dsetreportmetric [metric...] \n Activate report metrics, deactivate all if there are no parameters.\n",
+ __FILE__,dsetreportmetric,g);
+ theCommands.Add("dprintreport", "dprintreport [messenger] \n Send report content to default messenger or stream (if parameter is absent).\n",
+ __FILE__,dprintreport,g);
theCommands.Add("dparallel",
"dparallel [-occt {0|1}] [-nbThreads Count] [-nbDefThreads Count]"
Message.cxx
Message.hxx
+Message_Alert.cxx
+Message_Alert.hxx
+Message_AlertExtended.cxx
+Message_AlertExtended.hxx
Message_Algorithm.cxx
Message_Algorithm.hxx
Message_Algorithm.lxx
Message_ConsoleColor.hxx
+Message_Attribute.cxx
+Message_Attribute.hxx
+Message_AttributeMeter.cxx
+Message_AttributeMeter.hxx
+Message_AttributeObject.hxx
+Message_AttributeStream.cxx
+Message_AttributeStream.hxx
+Message_CompositeAlerts.cxx
+Message_CompositeAlerts.hxx
Message_ExecStatus.hxx
Message_Gravity.hxx
Message_HArrayOfMsg.hxx
+Message_Level.cxx
+Message_Level.hxx
Message_ListIteratorOfListOfMsg.hxx
Message_ListOfMsg.hxx
Message_Messenger.cxx
Message_Messenger.hxx
+Message_MetricType.hxx
Message_Msg.cxx
Message_Msg.hxx
Message_Msg.lxx
Message_PrinterOStream.hxx
Message_PrinterSystemLog.cxx
Message_PrinterSystemLog.hxx
+Message_PrinterToReport.cxx
+Message_PrinterToReport.hxx
Message_ProgressIndicator.cxx
Message_ProgressIndicator.hxx
Message_ProgressIndicator.lxx
Message_SequenceOfProgressScale.hxx
Message_Status.hxx
Message_StatusType.hxx
-Message_Alert.cxx
-Message_Alert.hxx
Message_ListOfAlert.hxx
Message_Report.cxx
Message_Report.hxx
#include <Message.hxx>
#include <Message_Messenger.hxx>
+#include <Message_Report.hxx>
#include <TCollection_AsciiString.hxx>
#include <stdio.h>
#include <string.h>
+
+static Handle(Message_Messenger) MyMessenger;
+
//=======================================================================
//function : DefaultMessenger
//purpose :
//=======================================================================
-const Handle(Message_Messenger)& Message::DefaultMessenger ()
+
+const Handle(Message_Messenger)& Message::DefaultMessenger()
+{
+ if (MyMessenger.IsNull())
+ MyMessenger = new Message_Messenger;
+ return MyMessenger;
+}
+
+//=======================================================================
+//function : SetDefaultMessenger
+//purpose :
+//=======================================================================
+
+void Message::SetDefaultMessenger (const Handle(Message_Messenger)& theMessenger)
+{
+ MyMessenger = theMessenger;
+}
+
+//=======================================================================
+//function : DefaultReport
+//purpose :
+//=======================================================================
+
+const Handle(Message_Report)& Message::DefaultReport(const Standard_Boolean theToCreate)
{
- static Handle(Message_Messenger) aMessenger = new Message_Messenger;
- return aMessenger;
+ static Handle(Message_Report) MyReport;
+
+ if (MyReport.IsNull() && theToCreate)
+ MyReport = new Message_Report();
+
+ return MyReport;
}
//=======================================================================
Sprintf (t, "%.2fs", second);
return TCollection_AsciiString (t);
}
+
+namespace
+{
+ static Standard_CString Message_Table_PrintMetricTypeEnum[10] =
+ {
+ "NONE", "UserTimeCPU", "SystemTimeInfo", "MemPrivate", "MemVirtual",
+ "MemWorkingSet", "MemWorkingSetPeak", "MemSwapUsage", "MemSwapUsagePeak", "MemHeapUsage"
+ };
+}
+
+//=======================================================================
+//function : MetricToString
+//purpose :
+//=======================================================================
+
+Standard_CString Message::MetricToString (const Message_MetricType theType)
+{
+ return Message_Table_PrintMetricTypeEnum[theType];
+}
+
+//=======================================================================
+//function : MetricFromString
+//purpose :
+//=======================================================================
+
+Standard_Boolean Message::MetricFromString (const Standard_CString theString,
+ Message_MetricType& theGravity)
+{
+ TCollection_AsciiString aName (theString);
+ for (Standard_Integer aMetricIter = 0; aMetricIter <= Message_MetricType_MemHeapUsage; ++aMetricIter)
+ {
+ Standard_CString aMetricName = Message_Table_PrintMetricTypeEnum[aMetricIter];
+ if (aName == aMetricName)
+ {
+ theGravity = Message_MetricType (aMetricIter);
+ return Standard_True;
+ }
+ }
+ return Standard_False;
+}
+
+// =======================================================================
+// function : ToOSDMetric
+// purpose :
+// =======================================================================
+Standard_Boolean Message::ToOSDMetric (const Message_MetricType theMetric, OSD_MemInfo::Counter& theMemInfo)
+{
+ switch (theMetric)
+ {
+ case Message_MetricType_MemPrivate: theMemInfo = OSD_MemInfo::MemPrivate; break;
+ case Message_MetricType_MemVirtual: theMemInfo = OSD_MemInfo::MemVirtual; break;
+ case Message_MetricType_MemWorkingSet: theMemInfo = OSD_MemInfo::MemWorkingSet; break;
+ case Message_MetricType_MemWorkingSetPeak: theMemInfo = OSD_MemInfo::MemWorkingSetPeak; break;
+ case Message_MetricType_MemSwapUsage: theMemInfo = OSD_MemInfo::MemSwapUsage; break;
+ case Message_MetricType_MemSwapUsagePeak: theMemInfo = OSD_MemInfo::MemSwapUsagePeak; break;
+ case Message_MetricType_MemHeapUsage: theMemInfo = OSD_MemInfo::MemHeapUsage; break;
+ }
+ return Standard_True;
+}
+
+// =======================================================================
+// function : ToMessageMetric
+// purpose :
+// =======================================================================
+Standard_Boolean Message::ToMessageMetric (const OSD_MemInfo::Counter theMemInfo, Message_MetricType& theMetric)
+{
+ switch (theMemInfo)
+ {
+ case OSD_MemInfo::MemPrivate: theMetric = Message_MetricType_MemPrivate; break;
+ case OSD_MemInfo::MemVirtual: theMetric = Message_MetricType_MemVirtual; break;
+ case OSD_MemInfo::MemWorkingSet: theMetric = Message_MetricType_MemWorkingSet; break;
+ case OSD_MemInfo::MemWorkingSetPeak: theMetric = Message_MetricType_MemWorkingSetPeak; break;
+ case OSD_MemInfo::MemSwapUsage: theMetric = Message_MetricType_MemSwapUsage; break;
+ case OSD_MemInfo::MemSwapUsagePeak: theMetric = Message_MetricType_MemSwapUsagePeak; break;
+ case OSD_MemInfo::MemHeapUsage: theMetric = Message_MetricType_MemHeapUsage; break;
+ default: return Standard_False;
+ }
+ return Standard_True;
+}
#ifndef _Message_HeaderFile
#define _Message_HeaderFile
+#include <Message_Gravity.hxx>
+#include <Message_MetricType.hxx>
+#include <NCollection_Vector.hxx>
+#include <OSD_MemInfo.hxx>
+
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Integer.hxx>
#include <Standard_Real.hxx>
+#include <TCollection_AsciiString.hxx>
+
class Message_Messenger;
-class TCollection_AsciiString;
class Message_Msg;
class Message_MsgFile;
class Message_Messenger;
class Message_ProgressIndicator;
class Message_ProgressScale;
class Message_ProgressSentry;
+class Message_Report;
//! Defines
//! By default, it contains single printer directed to std::cout.
//! It can be customized according to the application needs.
Standard_EXPORT static const Handle(Message_Messenger)& DefaultMessenger();
-
+
+ //! Sets default messenger.
+ Standard_EXPORT static void SetDefaultMessenger (const Handle(Message_Messenger)& theMessenger);
+
+ //! returns the only one instance of Report
+ //! When theToCreate is true - automatically creates message report when not exist.
+ //! that has been created.
+ Standard_EXPORT static const Handle(Message_Report)& DefaultReport (const Standard_Boolean theToCreate = Standard_False);
+
//! Returns the string filled with values of hours, minutes and seconds.
//! Example:
//! 1. (5, 12, 26.3345) returns "05h:12m:26.33s",
//! 3. (0, 0, 4.5 ) returns "4.50s"
Standard_EXPORT static TCollection_AsciiString FillTime (const Standard_Integer Hour, const Standard_Integer Minute, const Standard_Real Second);
-
-
+ //! Determines the metric from the given string identifier.
+ //! @param theString string identifier
+ //! @param theType detected type of metric
+ //! @return TRUE if string identifier is known
+ Standard_EXPORT static Standard_Boolean MetricFromString (const Standard_CString theString,
+ Message_MetricType& theType);
+
+ //! Returns the string name for a given metric type.
+ //! @param theType metric type
+ //! @return string identifier from the list of Message_MetricType
+ Standard_EXPORT static Standard_CString MetricToString (const Message_MetricType theType);
+
+ //! Returns the metric type from the given string identifier.
+ //! @param theString string identifier
+ //! @return metric type or Message_MetricType_None if string identifier is invalid
+ static Message_MetricType MetricFromString (const Standard_CString theString)
+ {
+ Message_MetricType aMetric = Message_MetricType_None;
+ MetricFromString (theString, aMetric);
+ return aMetric;
+ }
+
+ //! Converts message metric to OSD memory info type.
+ //! @param theMetric [in] message metric
+ //! @param theMemInfo [out] filled memory info type
+ //! @return true if converted
+ static Standard_EXPORT Standard_Boolean ToOSDMetric (const Message_MetricType theMetric, OSD_MemInfo::Counter& theMemInfo);
+
+ //! Converts OSD memory info type to message metric.
+ //! @param theMemInfo [int] memory info type
+ //! @param theMetric [out] filled message metric
+ //! @return true if converted
+ static Standard_EXPORT Standard_Boolean ToMessageMetric (const OSD_MemInfo::Counter theMemInfo, Message_MetricType& theMetric);
protected:
-
private:
//! Base implementation always returns true.
virtual Standard_EXPORT Standard_Boolean Merge (const Handle(Message_Alert)& theTarget);
- // OCCT RTTI
DEFINE_STANDARD_RTTIEXT(Message_Alert,Standard_Transient)
};
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_AlertExtended.hxx>
+#include <Message_Attribute.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_Report.hxx>
+
+#include <Precision.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AlertExtended,Message_Alert)
+
+//=======================================================================
+//function : GetMessageKey
+//purpose :
+//=======================================================================
+
+Standard_CString Message_AlertExtended::GetMessageKey () const
+{
+ if (myAttribute.IsNull())
+ return Message_Alert::GetMessageKey();
+
+ return myAttribute->GetMessageKey();
+}
+
+//=======================================================================
+//function : CompositeAlerts
+//purpose :
+//=======================================================================
+Handle(Message_CompositeAlerts) Message_AlertExtended::CompositeAlerts (const Standard_Boolean theToCreate)
+{
+ if (myCompositAlerts.IsNull() && theToCreate)
+ myCompositAlerts = new Message_CompositeAlerts();
+
+ return myCompositAlerts;
+}
+
+//=======================================================================
+//function : SupportsMerge
+//purpose :
+//=======================================================================
+Standard_Boolean Message_AlertExtended::SupportsMerge () const
+{
+ if (myCompositAlerts.IsNull())
+ return Standard_True;
+
+ // hierarchical alerts can not be merged
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
+ {
+ if (!myCompositAlerts->Alerts ((Message_Gravity)aGravIter).IsEmpty())
+ return Standard_False;
+ }
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : Merge
+//purpose :
+//=======================================================================
+Standard_Boolean Message_AlertExtended::Merge (const Handle(Message_Alert)& /*theTarget*/)
+{
+ // by default, merge trivially
+ return Standard_False;
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose :
+//=======================================================================
+Handle(Message_Alert) Message_AlertExtended::AddAlert (const Handle(Message_Report)& theReport,
+ const Handle(Message_Attribute)& theAttribute,
+ const Message_Gravity theGravity)
+{
+ Handle(Message_AlertExtended) anAlert = new Message_AlertExtended();
+ anAlert->SetAttribute (theAttribute);
+ theReport->AddAlert (theGravity, anAlert);
+
+ return anAlert;
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_AlertExtended_HeaderFile
+#define _Message_AlertExtended_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <Message_Gravity.hxx>
+#include <TCollection_AsciiString.hxx>
+
+class Message_Attribute;
+class Message_Report;
+
+DEFINE_STANDARD_HANDLE(Message_AlertExtended, Message_Alert)
+
+class Message_CompositeAlerts;
+
+//! Inherited class of Message_Alert with some additional information.
+//!
+//! It has Message_Attributes to provide the alert name, and other custom information
+//!
+//! It has a container of composite alerts, if the alert might provide
+//! sub-alerts collecting.
+//!
+class Message_AlertExtended : public Message_Alert
+{
+public:
+ //! Empty constructor
+ Standard_EXPORT Message_AlertExtended() : Message_Alert() {}
+
+ //! Return a C string to be used as a key for generating text user
+ //! messages describing this alert.
+ //! The messages are generated with help of Message_Msg class, in
+ //! Message_Report::Dump().
+ //! Base implementation returns dynamic type name of the instance.
+ Standard_EXPORT virtual Standard_CString GetMessageKey () const Standard_OVERRIDE;
+
+ //! Sets container of the alert attributes
+ //! @param theAttributes an attribute values
+ void SetAttribute (const Handle(Message_Attribute)& theAttribute) { myAttribute = theAttribute; }
+
+ //! Returns container of the alert attributes
+ //! @param theAttributes an attribute values
+ const Handle(Message_Attribute)& Attribute() const { return myAttribute; }
+
+ //! Returns class provided hierarchy of alerts if created or create if the parameter is true
+ //! @param isCreate if composite alert has not been created for this alert, it should be created
+ //! @return instance or NULL
+ Standard_EXPORT Handle(Message_CompositeAlerts) CompositeAlerts (const Standard_Boolean theToCreate = Standard_False);
+
+ //! Return true if this type of alert can be merged with other
+ //! of the same type to avoid duplication.
+ //! Hierarchical alerts can not be merged
+ //! Basis implementation returns true.
+ virtual Standard_EXPORT Standard_Boolean SupportsMerge() const Standard_OVERRIDE;
+
+ //! If possible, merge data contained in this alert to theTarget.
+ //! @return True if merged.
+ //! Base implementation always returns false.
+ virtual Standard_EXPORT Standard_Boolean Merge (const Handle(Message_Alert)& theTarget) Standard_OVERRIDE;
+
+ //! Creates new instance of the alert and put it into report with Message_Info gravity.
+ //! It does nothing if such kind of gravity is not active in the report
+ //! @param theReport the message report where new alert is placed
+ //! @param theAttribute container of additional values of the alert
+ //! @return created alert or NULL if Message_Info is not active in report
+ static Standard_EXPORT Handle(Message_Alert) AddAlert (const Handle(Message_Report)& theReport,
+ const Handle(Message_Attribute)& theAttribute,
+ const Message_Gravity theGravity);
+
+ DEFINE_STANDARD_RTTIEXT(Message_AlertExtended, Message_Alert)
+
+protected:
+
+ Handle(Message_CompositeAlerts) myCompositAlerts; //!< class provided hierarchical structure of alerts
+ Handle(Message_Attribute) myAttribute; //!< container of the alert attributes
+};
+
+#endif // _Message_Alert_HeaderFile
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_Attribute.hxx>
+
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_Attribute, Standard_Transient)
+
+//=======================================================================
+//function : GetMessageKey
+//purpose :
+//=======================================================================
+
+Standard_CString Message_Attribute::GetMessageKey () const
+{
+ return !myName.IsEmpty() ? myName.ToCString() : "";
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_Attribute_HeaderFile
+#define _Message_Attribute_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+
+DEFINE_STANDARD_HANDLE(Message_Attribute, Standard_Transient)
+
+//! Additional information of extended alert attribute
+//! To provide other custom attribute container, it might be redefined.
+class Message_Attribute : public Standard_Transient
+{
+public:
+ //! Empty constructor
+ Standard_EXPORT Message_Attribute (const TCollection_AsciiString& theName = TCollection_AsciiString())
+ : myName (theName) {}
+
+ //! Return a C string to be used as a key for generating text user
+ //! messages describing this alert.
+ //! The messages are generated with help of Message_Msg class, in
+ //! Message_Report::Dump().
+ //! Base implementation returns dynamic type name of the instance.
+ virtual Standard_EXPORT Standard_CString GetMessageKey () const;
+
+ //! Returns custom name of alert if it is set
+ //! @return alert name
+ const TCollection_AsciiString& GetName() const { return myName; }
+
+ //! Sets the custom name of alert
+ //! @param theName a name for the alert
+ void SetName (const TCollection_AsciiString& theName) { myName = theName; }
+
+ DEFINE_STANDARD_RTTIEXT(Message_Attribute, Standard_Transient)
+
+private:
+ TCollection_AsciiString myName; //!< alert name, if defined is used in GetMessageKey
+
+};
+
+#endif // _Message_Attribute_HeaderFile
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_AttributeMeter.hxx>
+
+#include <Precision.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AttributeMeter, Message_Attribute)
+
+//=======================================================================
+//function : SetValues
+//purpose :
+//=======================================================================
+Message_AttributeMeter::Message_AttributeMeter (const TCollection_AsciiString& theName)
+: Message_Attribute(theName)
+{
+}
+
+//=======================================================================
+//function : HasMetric
+//purpose :
+//=======================================================================
+Standard_Boolean Message_AttributeMeter::HasMetric (const Message_MetricType& theMetric) const
+{
+ return myMetrics.IsBound (theMetric);
+}
+
+//=======================================================================
+//function : IsMetricValid
+//purpose :
+//=======================================================================
+Standard_Boolean Message_AttributeMeter::IsMetricValid (const Message_MetricType& theMetric) const
+{
+ return Abs (StartValue (theMetric) - UndefinedMetricValue()) > Precision::Confusion() &&
+ Abs (StopValue (theMetric) - UndefinedMetricValue()) > Precision::Confusion();
+}
+
+//=======================================================================
+//function : StartValue
+//purpose :
+//=======================================================================
+Standard_Real Message_AttributeMeter::StartValue (const Message_MetricType& theMetric) const
+{
+ if (!HasMetric (theMetric))
+ return UndefinedMetricValue();
+
+ return myMetrics.Seek (theMetric)->first;
+}
+
+//=======================================================================
+//function : SetStartValue
+//purpose :
+//=======================================================================
+void Message_AttributeMeter::SetStartValue (const Message_MetricType& theMetric, const Standard_Real theValue)
+{
+ if (!HasMetric (theMetric))
+ {
+ myMetrics.Bind (theMetric, std::make_pair (theValue, UndefinedMetricValue()));
+ }
+ myMetrics.ChangeFind (theMetric).first = theValue;
+}
+
+//=======================================================================
+//function : StopValue
+//purpose :
+//=======================================================================
+Standard_Real Message_AttributeMeter::StopValue (const Message_MetricType& theMetric) const
+{
+ if (!HasMetric (theMetric))
+ return UndefinedMetricValue();
+
+ return myMetrics.Find (theMetric).second;
+}
+
+//=======================================================================
+//function : SetStopValue
+//purpose :
+//=======================================================================
+void Message_AttributeMeter::SetStopValue (const Message_MetricType& theMetric, const Standard_Real theValue)
+{
+ if (!HasMetric (theMetric))
+ {
+ // start value should be already set
+ return;
+ }
+ myMetrics.ChangeFind (theMetric).second = theValue;
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_AttributeMeter_HeaderFile
+#define _Message_AttributeMeter_HeaderFile
+
+#include <Message_Attribute.hxx>
+#include <Message_MetricType.hxx>
+
+#include <NCollection_DataMap.hxx>
+
+class Message_Alert;
+
+//! Alert object storing alert metrics values.
+//! Start and stop values for each metric.
+class Message_AttributeMeter : public Message_Attribute
+{
+public:
+
+ //! Returns default value of the metric when it is not defined
+ //! @return undefined value
+ static Standard_Real UndefinedMetricValue() { return -1.0; }
+
+public:
+
+ //! Constructor with string argument
+ Standard_EXPORT Message_AttributeMeter (const TCollection_AsciiString& theName = TCollection_AsciiString());
+
+ //! Checks whether the attribute has values for the metric
+ //! @param theMetric [in] metric type
+ //! @return true if the metric values exist in the attribute
+ Standard_EXPORT Standard_Boolean HasMetric (const Message_MetricType& theMetric) const;
+
+ //! Returns true when both values of the metric are set.
+ //! @param theMetric [in] metric type
+ //! @return true if metric values are valid
+ Standard_EXPORT Standard_Boolean IsMetricValid (const Message_MetricType& theMetric) const;
+
+ //! Returns start value for the metric
+ //! @param theMetric [in] metric type
+ //! @return real value
+ Standard_EXPORT Standard_Real StartValue (const Message_MetricType& theMetric) const;
+
+ //! Sets start values for the metric
+ //! @param theMetric [in] metric type
+ Standard_EXPORT void SetStartValue (const Message_MetricType& theMetric, const Standard_Real theValue);
+
+ //! Returns stop value for the metric
+ //! @param theMetric [in] metric type
+ //! @return real value
+ Standard_EXPORT Standard_Real StopValue (const Message_MetricType& theMetric) const;
+
+ //! Sets stop values for the metric
+ //! @param theMetric [in] metric type
+ Standard_EXPORT void SetStopValue (const Message_MetricType& theMetric, const Standard_Real theValue);
+
+ DEFINE_STANDARD_RTTIEXT(Message_AttributeMeter, Message_Attribute)
+
+private:
+
+ typedef std::pair<Standard_Real, Standard_Real> StartToStopValue;
+ NCollection_DataMap<Message_MetricType, StartToStopValue> myMetrics; //!< computed metrics
+};
+
+#endif // _Message_AttributeMeter_HeaderFile
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_AttributeObject_HeaderFile
+#define _Message_AttributeObject_HeaderFile
+
+#include <Message_Attribute.hxx>
+
+class Standard_Transient;
+
+//! Alert object storing a transient object
+class Message_AttributeObject : public Message_Attribute
+{
+public:
+ //! Constructor with string argument
+ Message_AttributeObject (const Handle(Standard_Transient)& theObject,
+ const TCollection_AsciiString& theName = TCollection_AsciiString())
+ : Message_Attribute (theName) { myObject = theObject; }
+
+ //! Returns object
+ //! @return the object instance
+ const Handle(Standard_Transient)& Object() { return myObject; }
+
+ //! Sets the object
+ //! @param theObject an instance
+ void SetObject (const Handle(Standard_Transient)& theObject) { myObject = theObject; }
+
+ DEFINE_STANDARD_RTTI_INLINE(Message_AttributeObject, Message_Attribute)
+
+private:
+ Handle(Standard_Transient) myObject; //!< alert object
+};
+
+#endif // _Message_AttributeObject_HeaderFile
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_AttributeStream.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_AttributeStream, Message_Attribute)
+
+//=======================================================================
+//function : SetValues
+//purpose :
+//=======================================================================
+Message_AttributeStream::Message_AttributeStream (const Standard_SStream& theStream,
+ const TCollection_AsciiString& theName)
+: Message_Attribute(theName)
+{
+ SetStream (theStream);
+}
+
+//=======================================================================
+//function : SetStream
+//purpose :
+//=======================================================================
+
+void Message_AttributeStream::SetStream (const Standard_SStream& theStream)
+{
+ myStream.str ("");
+
+ TCollection_AsciiString aStreamStr (theStream.str().c_str());
+ myStream << aStreamStr;
+}
+
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_AttributeStream_HeaderFile
+#define _Message_AttributeStream_HeaderFile
+
+#include <Message_Attribute.hxx>
+
+#include <NCollection_Vector.hxx>
+#include <Standard_SStream.hxx>
+
+//! Alert object storing stream values
+class Message_AttributeStream : public Message_Attribute
+{
+public:
+
+ //! Constructor with string argument
+ Standard_EXPORT Message_AttributeStream (const Standard_SStream& theStream,
+ const TCollection_AsciiString& theName = TCollection_AsciiString());
+
+ //! Returns stream value
+ const Standard_SStream& Stream() const { return myStream; }
+
+ //! Sets stream value
+ Standard_EXPORT void SetStream (const Standard_SStream& theStream);
+
+ DEFINE_STANDARD_RTTIEXT(Message_AttributeStream, Message_Attribute)
+
+private:
+ Standard_SStream myStream; //!< container of values
+};
+
+#endif // _Message_AttributeStream_HeaderFile
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_CompositeAlerts.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_CompositeAlerts, Standard_Transient)
+
+//=======================================================================
+//function : Alerts
+//purpose :
+//=======================================================================
+const Message_ListOfAlert& Message_CompositeAlerts::Alerts (const Message_Gravity theGravity) const
+{
+ static const Message_ListOfAlert anEmptyList;
+ Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
+ "Requesting alerts for gravity not in valid range", anEmptyList);
+
+ return myAlerts[theGravity];
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose :
+//=======================================================================
+Standard_Boolean Message_CompositeAlerts::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
+{
+ Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert", Standard_False);
+ Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
+ "Adding alert with gravity not in valid range", Standard_False);
+
+ Message_ListOfAlert& aList = myAlerts[theGravity];
+ if (theAlert->SupportsMerge() && ! aList.IsEmpty())
+ {
+ // merge is performed only for alerts of exactly same type
+ const Handle(Standard_Type)& aType = theAlert->DynamicType();
+ for (Message_ListOfAlert::Iterator anIt(aList); anIt.More(); anIt.Next())
+ {
+ // if merged successfully, just return
+ if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
+ return Standard_False;
+ }
+ }
+
+ // if not merged, just add to the list
+ aList.Append (theAlert);
+ return Standard_True;
+}
+
+//=======================================================================
+//function : RemoveAlert
+//purpose :
+//=======================================================================
+Standard_Boolean Message_CompositeAlerts::RemoveAlert (Message_Gravity theGravity,
+ const Handle(Message_Alert)& theAlert)
+{
+ Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert", Standard_False);
+ Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
+ "Adding alert with gravity not in valid range", Standard_False);
+
+ Message_ListOfAlert& anAlerts = myAlerts[theGravity];
+ if (!anAlerts.Contains (theAlert))
+ return Standard_False;
+
+ return anAlerts.Remove (theAlert);
+}
+
+//=======================================================================
+//function : HasAlerts
+//purpose :
+//=======================================================================
+
+Standard_Boolean Message_CompositeAlerts::HasAlert (const Handle(Message_Alert)& theAlert)
+{
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
+ {
+ const Message_ListOfAlert& anAlerts = Alerts ((Message_Gravity)aGravIter);
+ if (anAlerts.Contains (theAlert))
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+//=======================================================================
+//function : HasAlerts
+//purpose :
+//=======================================================================
+Standard_Boolean Message_CompositeAlerts::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
+{
+ Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
+ "Requesting alerts for gravity not in valid range", Standard_False);
+
+ for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
+ {
+ if (anIt.Value()->IsInstance(theType))
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void Message_CompositeAlerts::Clear ()
+{
+ for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
+ {
+ myAlerts[i].Clear();
+ }
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void Message_CompositeAlerts::Clear (Message_Gravity theGravity)
+{
+ Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
+ "Requesting alerts for gravity not in valid range", );
+ myAlerts[theGravity].Clear();
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void Message_CompositeAlerts::Clear (const Handle(Standard_Type)& theType)
+{
+ for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
+ {
+ for (Message_ListOfAlert::Iterator anIt (myAlerts[i]); anIt.More(); )
+ {
+ if (anIt.Value().IsNull() || anIt.Value()->IsInstance (theType))
+ {
+ myAlerts[i].Remove (anIt);
+ }
+ else
+ {
+ anIt.More();
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_CompositeAlerts_HeaderFile
+#define _Message_CompositeAlerts_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <Message_Gravity.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <Standard_Transient.hxx>
+
+class Message_CompositeAlerts;
+DEFINE_STANDARD_HANDLE(Message_CompositeAlerts, Standard_Transient)
+
+//! Class providing container of alerts
+class Message_CompositeAlerts : public Standard_Transient
+{
+public:
+ //! Empty constructor
+ Standard_EXPORT Message_CompositeAlerts() {}
+
+ //! Returns list of collected alerts with specified gravity
+ Standard_EXPORT const Message_ListOfAlert& Alerts (const Message_Gravity theGravity) const;
+
+ //! Add alert with specified gravity. If the alert supports merge it will be merged.
+ //! @param theGravity an alert gravity
+ //! @param theAlert an alert to be added as a child alert
+ //! @return true if the alert is added or merged
+ Standard_EXPORT Standard_Boolean AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert);
+
+ //! Removes alert with specified gravity.
+ //! @param theGravity an alert gravity
+ //! @param theAlert an alert to be removed from the children
+ //! @return true if the alert is removed
+ Standard_EXPORT Standard_Boolean RemoveAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert);
+
+ //! Returns true if the alert belong the list of the child alerts.
+ //! @param theAlert an alert to be checked as a child alert
+ //! @return true if the alert is found in a container of children
+ Standard_EXPORT Standard_Boolean HasAlert (const Handle(Message_Alert)& theAlert);
+
+ //! Returns true if specific type of alert is recorded with specified gravity
+ //! @param theType an alert type
+ //! @param theGravity an alert gravity
+ //! @return true if the alert is found in a container of children
+ Standard_EXPORT Standard_Boolean HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity);
+
+ //! Clears all collected alerts
+ Standard_EXPORT void Clear ();
+
+ //! Clears collected alerts with specified gravity
+ //! @param theGravity an alert gravity
+ Standard_EXPORT void Clear (Message_Gravity theGravity);
+
+ //! Clears collected alerts with specified type
+ //! @param theType an alert type
+ Standard_EXPORT void Clear (const Handle(Standard_Type)& theType);
+
+ DEFINE_STANDARD_RTTIEXT(Message_CompositeAlerts,Standard_Transient)
+
+protected:
+ // store messages in a lists sorted by gravity;
+ // here we rely on knowledge that Message_Fail is the last element of the enum
+ Message_ListOfAlert myAlerts[Message_Fail + 1]; //!< container of child alert for each type of gravity
+};
+
+#endif // _Message_CompositeAlerts_HeaderFile
--- /dev/null
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_Level.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_AttributeMeter.hxx>
+#include <Message_Messenger.hxx>
+#include <Message_Report.hxx>
+
+#include <OSD_Chronometer.hxx>
+#include <OSD_MemInfo.hxx>
+
+//=======================================================================
+//function : Message_Level
+//purpose :
+//=======================================================================
+Message_Level::Message_Level()
+{
+ const Handle(Message_Report)& aDefaultReport = Message::DefaultReport();
+ if (!aDefaultReport.IsNull() && aDefaultReport->IsActiveInMessenger())
+ aDefaultReport->AddLevel (this);
+}
+
+//=======================================================================
+//function : Destructor
+//purpose :
+//=======================================================================
+Message_Level::~Message_Level()
+{
+ Remove();
+}
+
+//=======================================================================
+//function : SetRootAlert
+//purpose :
+//=======================================================================
+void Message_Level::SetRootAlert (const Handle(Message_AlertExtended)& theAlert)
+{
+ myRootAlert = theAlert;
+ startAlert (myRootAlert);
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose :
+//=======================================================================
+Standard_Boolean Message_Level::AddAlert (const Message_Gravity theGravity,
+ const Handle(Message_Alert)& theAlert)
+{
+ Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+ if (anAlertExtended.IsNull())
+ return Standard_False;
+
+ if (myRootAlert.IsNull())
+ return Standard_False;
+
+ // looking for the parent of the parameter alert to release the previous alert
+ Handle(Message_AlertExtended) aRootAlert = myRootAlert;
+ Handle(Message_CompositeAlerts) aCompositeAlert = aRootAlert->CompositeAlerts (Standard_True);
+
+ // update metrics of the previous alert
+ stopAlert (myLastAlert);
+
+ myLastAlert = anAlertExtended;
+
+ // set start metrics of the new alert
+ startAlert (myLastAlert);
+
+ // add child alert
+ aCompositeAlert->AddAlert (theGravity, theAlert);
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : AddLevelAlert
+//purpose :
+//=======================================================================
+Standard_Boolean Message_Level::AddLevelAlert (const Message_Gravity theGravity,
+ const Handle(Message_Alert)& theAlert)
+{
+ Handle(Message_AlertExtended) aRootAlert = !myLastAlert.IsNull() ? myLastAlert : myRootAlert;
+ if (aRootAlert.IsNull())
+ return Standard_False;
+
+ Handle(Message_CompositeAlerts) aCompositeAlert = aRootAlert->CompositeAlerts (Standard_True);
+ // add child alert
+ aCompositeAlert->AddAlert (theGravity, theAlert);
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : Remove()
+//purpose :
+//=======================================================================
+void Message_Level::Remove()
+{
+ const Handle(Message_Report)& aDefaultReport = Message::DefaultReport();
+ if (aDefaultReport.IsNull() || !aDefaultReport->IsActiveInMessenger())
+ return;
+
+ stopAlert (myLastAlert);
+ stopAlert (myRootAlert);
+
+ if (!Message::DefaultReport().IsNull())
+ Message::DefaultReport()->RemoveLevel (this);
+}
+
+//=======================================================================
+//function : setAlertMetrics
+//purpose :
+//=======================================================================
+void Message_Level::setAlertMetrics (const Handle(Message_AlertExtended)& theAlert,
+ const Standard_Boolean theStartValue)
+{
+ if (theAlert.IsNull())
+ return;
+
+ Handle(Message_AttributeMeter) aMeterAttribute = Handle(Message_AttributeMeter)::DownCast (theAlert->Attribute());
+ if (aMeterAttribute.IsNull())
+ return;
+
+ Handle(Message_Report) aReport = Message::DefaultReport (Standard_True);
+ const NCollection_Map<Message_MetricType>& anActiveMetrics = aReport->ActiveMetrics();
+
+ // time metrics
+ if (anActiveMetrics.Contains (Message_MetricType_UserTimeCPU) ||
+ anActiveMetrics.Contains (Message_MetricType_SystemTimeInfo))
+ {
+ Standard_Real aUserSeconds, aSystemSeconds;
+ OSD_Chronometer::GetThreadCPU (aUserSeconds, aSystemSeconds);
+
+ if (anActiveMetrics.Contains (Message_MetricType_UserTimeCPU))
+ {
+ if (theStartValue)
+ aMeterAttribute->SetStartValue (Message_MetricType_UserTimeCPU, aUserSeconds);
+ else
+ aMeterAttribute->SetStopValue (Message_MetricType_UserTimeCPU, aUserSeconds);
+ }
+ if (anActiveMetrics.Contains (Message_MetricType_SystemTimeInfo))
+ {
+ if (theStartValue)
+ aMeterAttribute->SetStartValue (Message_MetricType_SystemTimeInfo, aSystemSeconds);
+ else
+ aMeterAttribute->SetStopValue (Message_MetricType_SystemTimeInfo, aSystemSeconds);
+ }
+ }
+ // memory metrics
+ NCollection_Map<OSD_MemInfo::Counter> aCounters;
+ for (NCollection_Map<Message_MetricType>::Iterator anIterator (anActiveMetrics); anIterator.More(); anIterator.Next())
+ {
+ OSD_MemInfo::Counter aMemInfo;
+ if (!Message::ToOSDMetric (anIterator.Value(), aMemInfo))
+ continue;
+
+ aCounters.Add (aMemInfo);
+ }
+ if (aCounters.IsEmpty())
+ return;
+
+ OSD_MemInfo aMemInfo (Standard_False);
+ //aMemInfo.SetActiveCounters (aCounters);
+ aMemInfo.Update ();
+ Message_MetricType aMetricType;
+ for (NCollection_Map<OSD_MemInfo::Counter>::Iterator anIterator (aCounters); anIterator.More(); anIterator.Next())
+ {
+ if (!Message::ToMessageMetric (anIterator.Value(), aMetricType))
+ continue;
+
+ if (theStartValue)
+ aMeterAttribute->SetStartValue (aMetricType, (Standard_Real)aMemInfo.ValuePreciseMiB (anIterator.Value()));
+ else
+ aMeterAttribute->SetStopValue (aMetricType, (Standard_Real)aMemInfo.ValuePreciseMiB (anIterator.Value()));
+ }
+}
--- /dev/null
+// Copyright (c) 2019 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_Level_HeaderFile
+#define _Message_Level_HeaderFile
+
+#include <Message_AlertExtended.hxx>
+#include <Message_Gravity.hxx>
+#include <Message_MetricType.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <Standard.hxx>
+
+//! This class is an instance of Sentry to create a level in a message report
+//! Constructor of the class add new (active) level in the report, destructor removes it
+//! While the level is active in the report, new alerts are added below the level root alert.
+//!
+//! The first added alert is a root alert, other are added below the root alert
+//!
+//! If alert has Message_AttributeMeter attribute, active metrics of the default report are stored in
+//! the attriute: start value of metric on adding alert, stop on adding another alert or closing (delete) the level
+//! in the report.
+//!
+//! Processing of this class is implemented in Message_Report, it is used only insided it.
+//! Levels using should be only through using MESSAGE_ADD_LEVEL_SENTRY only. No other code is required outside.
+class Message_Level
+{
+
+public:
+ //! Constructor. Append
+ //! One string key is used for all alert meters. The perf meter is not started automatically, it will be done in
+ //! AddAlert method
+ Standard_EXPORT Message_Level();
+
+ //! Assures stopping upon destruction
+ Standard_EXPORT ~Message_Level();
+
+ //! Returns root alert of the level
+ //! @return alert instance or NULL
+ const Handle(Message_AlertExtended)& RootAlert() const { return myRootAlert; }
+
+ //! Sets the root alert. Starts collects alert metrics if active.
+ //! @param theAlert an alert
+ Standard_EXPORT void SetRootAlert (const Handle(Message_AlertExtended)& theAlert);
+
+ //! Adds new alert on the level. Stops the last alert metric, appends the alert and starts the alert metrics collecting.
+ //! Sets root alert beforehead this method using, if the root is NULL, it does nothing.
+ //! @param theGravity an alert gravity
+ //! @param theAlert an alert
+ //! @return true if alert is added
+ Standard_EXPORT Standard_Boolean AddAlert (const Message_Gravity theGravity,
+ const Handle(Message_Alert)& theAlert);
+
+ //! Add new alert as a child of the last alert if exists or as a child of the root alert.
+ //! @param theGravity an alert gravity
+ //! @param theAlert an alert
+ //! @return true if alert is added
+ Standard_EXPORT Standard_Boolean AddLevelAlert (const Message_Gravity theGravity,
+ const Handle(Message_Alert)& theAlert);
+
+ //! Remove the current level from the report. It stops metric collecting for the last and the root alerts.
+ Standard_EXPORT void Remove();
+
+protected:
+ //! Sets start values of default report metrics into the alert
+ //! @param theAlert an alert
+ void startAlert (const Handle(Message_AlertExtended)& theAlert) { setAlertMetrics (theAlert, Standard_True); }
+
+ //! Sets stop values of default report metrics into the alert
+ //! @param theAlert an alert
+ void stopAlert (const Handle(Message_AlertExtended)& theAlert) { setAlertMetrics (theAlert, Standard_True); }
+
+ //! Sets current values of default report metrics into the alert.
+ //! Processed oly alert with Message_AttributeMeter attribute
+ //! @param theAlert an alert
+ //! @param theStartValue flag, if true, the start value is collected otherwise stop
+ Standard_EXPORT void setAlertMetrics (const Handle(Message_AlertExtended)& theAlert,
+ const Standard_Boolean theStartValue);
+
+protected:
+ Handle(Message_AlertExtended) myRootAlert; //!< root alert
+ Handle(Message_AlertExtended) myLastAlert; //!< last added alert on the root alert
+};
+
+//! @def MESSAGE_NEW_LEVEL
+//! Creates a new level instance of Sentry. This row should be inserted before messages using in the method.
+#define MESSAGE_ADD_LEVEL_SENTRY Message_Level aLevel;
+
+#endif // _Message_Level_HeaderFile
//purpose :
//=======================================================================
Message_Messenger::Message_Messenger ()
+: myOutputGravity (Message_Info)
{
AddPrinter ( new Message_PrinterOStream );
}
//=======================================================================
Message_Messenger::Message_Messenger (const Handle(Message_Printer)& thePrinter)
+: myOutputGravity (Message_Info)
{
AddPrinter (thePrinter);
}
}
}
}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+
+void Message_Messenger::Send (const Standard_SStream& theStream,
+ const Message_Gravity theGravity,
+ const Standard_Boolean putEndl) const
+{
+ for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next())
+ {
+ const Handle(Message_Printer)& aPrinter = aPrinterIter.Value();
+ if (!aPrinter.IsNull())
+ {
+ aPrinter->Send (theStream, theGravity, putEndl);
+ }
+ }
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+
+void Message_Messenger::Send (const Handle(Standard_Transient)& theObject,
+ const Message_Gravity theGravity,
+ const Standard_Boolean putEndl) const
+{
+ for (Message_SequenceOfPrinters::Iterator aPrinterIter (myPrinters); aPrinterIter.More(); aPrinterIter.Next())
+ {
+ const Handle(Message_Printer)& aPrinter = aPrinterIter.Value();
+ if (!aPrinter.IsNull())
+ {
+ aPrinter->Send (theObject, theGravity, putEndl);
+ }
+ }
+}
//! The sequence can be modified.
Message_SequenceOfPrinters& ChangePrinters() { return myPrinters; }
+ //! Returns the output gavity used in operator <<
+ Message_Gravity OuputGravity() const { return myOutputGravity; }
+
+ //! Sets the output gavity used in operator <<
+ void SetOuputGravity (const Message_Gravity theValue) { myOutputGravity = theValue; }
+
//! Dispatch a message to all the printers in the list.
//! Three versions of string representations are accepted for
//! convenience, by default all are converted to ExtendedString.
//! See above
Standard_EXPORT void Send (const TCollection_ExtendedString& theString, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const;
+ //! See above
+ Standard_EXPORT void Send (const Standard_SStream& theStream, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const;
+
+ //! See above
+ Standard_EXPORT void Send (const Handle(Standard_Transient)& theObject, const Message_Gravity theGravity = Message_Warning, const Standard_Boolean putEndl = Standard_True) const;
+
private:
Message_SequenceOfPrinters myPrinters;
-
+ Message_Gravity myOutputGravity; //!< gravity used in operator <<
};
// CString
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const Standard_CString theStr)
{
- theMessenger->Send (theStr, Message_Info, Standard_False);
+ theMessenger->Send (theStr, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const TCollection_AsciiString& theStr)
{
- theMessenger->Send (theStr, Message_Info, Standard_False);
+ theMessenger->Send (theStr, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const Handle(TCollection_HAsciiString)& theStr)
{
- theMessenger->Send (theStr->String(), Message_Info, Standard_False);
+ theMessenger->Send (theStr->String(), theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const TCollection_ExtendedString& theStr)
{
- theMessenger->Send (theStr, Message_Info, Standard_False);
+ theMessenger->Send (theStr, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const Handle(TCollection_HExtendedString)& theStr)
{
- theMessenger->Send (theStr->String(), Message_Info, Standard_False);
+ theMessenger->Send (theStr->String(), theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
const Standard_Integer theVal)
{
TCollection_AsciiString aStr (theVal);
- theMessenger->Send (aStr, Message_Info, Standard_False);
+ theMessenger->Send (aStr, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
const Standard_Real theVal)
{
TCollection_AsciiString aStr (theVal);
- theMessenger->Send (aStr, Message_Info, Standard_False);
+ theMessenger->Send (aStr, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
const Standard_SStream& theStream)
{
- theMessenger->Send (theStream.str().c_str(), Message_Info, Standard_False);
+ theMessenger->Send (theStream, theMessenger->OuputGravity(), Standard_False);
+ return theMessenger;
+}
+
+// AsciiString
+inline const Handle(Message_Messenger)& operator<< (const Handle(Message_Messenger)& theMessenger,
+ const Handle(Standard_Transient)& theObject)
+{
+ theMessenger->Send (theObject, theMessenger->OuputGravity(), Standard_False);
return theMessenger;
}
// Message_EndLine
inline const Handle(Message_Messenger)& Message_EndLine (const Handle(Message_Messenger)& theMessenger)
{
- theMessenger->Send ("", Message_Info, Standard_True);
+ theMessenger->Send ("", theMessenger->OuputGravity(), Standard_True);
return theMessenger;
}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_MetricType_HeaderFile
+#define _Message_MetricType_HeaderFile
+
+//! Specifies kind of report information to collect
+enum Message_MetricType
+{
+ Message_MetricType_None, //!< no computation
+ Message_MetricType_UserTimeCPU, //!< the current CPU user time in seconds
+ Message_MetricType_SystemTimeInfo, //!< the current CPU system time in seconds
+ Message_MetricType_MemPrivate, //!< OSD_MemInfo::MemPrivate
+ Message_MetricType_MemVirtual, //!< OSD_MemInfo::MemVirtual
+ Message_MetricType_MemWorkingSet, //!< OSD_MemInfo::MemWorkingSet
+ Message_MetricType_MemWorkingSetPeak, //!< OSD_MemInfo::MemWorkingSetPeak
+ Message_MetricType_MemSwapUsage, //!< OSD_MemInfo::MemSwapUsage
+ Message_MetricType_MemSwapUsagePeak, //!< OSD_MemInfo::MemSwapUsagePeak
+ Message_MetricType_MemHeapUsage //!< OSD_MemInfo::MemHeapUsage
+};
+
+#endif // _Message_MetricType_HeaderFile
#include <Message_Printer.hxx>
+#include <Standard_Dump.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
Send (TCollection_ExtendedString (theString), theGravity, theToOutEol);
}
}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+
+void Message_Printer::Send (const Standard_SStream& theStream,
+ const Message_Gravity theGravity,
+ const Standard_Boolean theToOutEol) const
+{
+ if (theGravity >= myTraceLevel)
+ {
+ Send (TCollection_ExtendedString (theStream.str().c_str()), theGravity, theToOutEol);
+ }
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void Message_Printer::Send (const Handle(Standard_Transient)& theObject,
+ const Message_Gravity theGravity,
+ const Standard_Boolean theToOutEol) const
+{
+ if (theObject.IsNull())
+ return;
+
+ if (theGravity >= myTraceLevel)
+ {
+ TCollection_ExtendedString aString = TCollection_ExtendedString (theObject->DynamicType()->Name())
+ + ": " + Standard_Dump::GetPointerInfo (theObject);
+ Send (aString, theGravity, theToOutEol);
+ }
+}
#include <Standard_Transient.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_CString.hxx>
+#include <Standard_SStream.hxx>
+
class TCollection_ExtendedString;
class TCollection_AsciiString;
//! Default implementation calls first method Send().
Standard_EXPORT virtual void Send (const TCollection_AsciiString& theString, const Message_Gravity theGravity, const Standard_Boolean theToPutEol) const;
+ //! Send a string message with specified trace level.
+ //! Stream is converted to string value.
+ //! The parameter theToPutEol specified whether end-of-line should be added to the end of the message.
+ //! Default implementation calls first method Send().
+ Standard_EXPORT virtual void Send (const Standard_SStream& theStream, const Message_Gravity theGravity, const Standard_Boolean theToPutEol) const;
+
+ //! Send a string message with specified trace level.
+ //! The object is converted to string in format: <object kind> : <object pointer>.
+ //! The parameter theToPutEol specified whether end-of-line should be added to the end of the message.
+ //! Default implementation calls first method Send().
+ Standard_EXPORT virtual void Send (const Handle(Standard_Transient)& theObject, const Message_Gravity theGravity, const Standard_Boolean theToPutEol) const;
+
protected:
//! Empty constructor with Message_Info trace level
--- /dev/null
+// Created on: 2001-01-06
+// Created by: OCC Team
+// Copyright (c) 2001-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_PrinterToReport.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_Attribute.hxx>
+#include <Message_AttributeMeter.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_Report.hxx>
+
+#include <Standard_Dump.hxx>
+#include <TCollection_ExtendedString.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_PrinterToReport, Message_Printer)
+
+//=======================================================================
+//function : Report
+//purpose :
+//=======================================================================
+const Handle(Message_Report)& Message_PrinterToReport::Report() const
+{
+ if (!myReport.IsNull())
+ return myReport;
+
+ return Message::DefaultReport (Standard_True);
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void Message_PrinterToReport::Send (const TCollection_ExtendedString& theString,
+ const Message_Gravity theGravity,
+ const Standard_Boolean putEndl) const
+{
+ TCollection_AsciiString aString (theString/*, myUseUtf8 ? Standard_Character(0) : '?'*/);
+
+ if (putEndl)
+ {
+ if (myValue.IsEmpty())
+ return;
+
+ const Handle(Message_Report)& aReport = Report();
+ if (!aReport->ActiveMetrics().IsEmpty())
+ {
+ sendMetricAlert (myValue, theGravity);
+ return;
+ }
+ Message_AlertExtended::AddAlert (aReport, new Message_Attribute (myValue), theGravity);
+ ((Message_PrinterToReport*)this)->Clear();
+ return;
+ }
+ ((Message_PrinterToReport*)this)->myValue += aString;
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void Message_PrinterToReport::Send (const Standard_SStream& theStream,
+ const Message_Gravity theGravity,
+ const Standard_Boolean /*putEndl*/) const
+{
+ const Handle(Message_Report)& aReport = Report();
+ if (!aReport->ActiveMetrics().IsEmpty())
+ {
+ sendMetricAlert (myValue, theGravity);
+ return;
+ }
+ Message_AlertExtended::AddAlert (aReport, new Message_AttributeStream (theStream, myValue), theGravity);
+ ((Message_PrinterToReport*)this)->Clear();
+
+ return;
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void Message_PrinterToReport::Send (const Handle(Standard_Transient)& theObject,
+ const Message_Gravity theGravity,
+ const Standard_Boolean /*putEndl*/) const
+{
+ const Handle(Message_Report)& aReport = Report();
+ if (!aReport->ActiveMetrics().IsEmpty())
+ {
+ sendMetricAlert (myValue, theGravity);
+ return;
+ }
+
+ Message_AlertExtended::AddAlert (aReport, new Message_AttributeObject (theObject, myValue), theGravity);
+ ((Message_PrinterToReport*)this)->Clear();
+}
+
+//=======================================================================
+//function : sendMetricAlert
+//purpose :
+//=======================================================================
+void Message_PrinterToReport::sendMetricAlert (const TCollection_AsciiString theValue,
+ const Message_Gravity theGravity) const
+{
+ Message_AlertExtended::AddAlert (Report(), new Message_AttributeMeter (theValue), theGravity);
+ ((Message_PrinterToReport*)this)->Clear();
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_PrinterToReport_HeaderFile
+#define _Message_PrinterToReport_HeaderFile
+
+#include <Message_Printer.hxx>
+#include <Standard_Address.hxx>
+#include <Standard_OStream.hxx>
+#include <TCollection_AsciiString.hxx>
+
+class Message_Report;
+
+class Message_PrinterToReport;
+DEFINE_STANDARD_HANDLE(Message_PrinterToReport, Message_Printer)
+
+//! Implementation of a message printer associated with Message_Report
+//! Send will create a new alert of the report. If string is sent, an alert is created by Eol only.
+//! The alerts are sent into set report or default report of Message.
+class Message_PrinterToReport : public Message_Printer
+{
+ DEFINE_STANDARD_RTTIEXT(Message_PrinterToReport, Message_Printer)
+
+public:
+ //! Create printer for redirecting messages into report.
+ Message_PrinterToReport() {}
+
+ ~Message_PrinterToReport() {}
+
+ //! Returns the current or default report
+ Standard_EXPORT const Handle(Message_Report)& Report() const;
+
+ //! Sets the printer report
+ //! @param theReport report for messages processing, if NULL, the default report is used
+ Standard_EXPORT void SetReport (const Handle(Message_Report)& theReport) { myReport = theReport; }
+
+ //!< Returns the first sent value
+ const TCollection_AsciiString& Value() { return myValue; }
+
+ //! Clears current values
+ Standard_EXPORT void Clear() { myValue.Clear(); }
+
+ //! Appends a new alert into message report if Endl is false or send a new extended alert with attribute on value
+ //! Use Message_EndLine to finalize the current alert
+ Standard_EXPORT virtual void Send (const TCollection_ExtendedString& theString,
+ const Message_Gravity theGravity,
+ const Standard_Boolean putEndl = Standard_True) const Standard_OVERRIDE;
+
+ //! Send a string message with specified trace level.
+ //! Stream is converted to string value.
+ //! The parameter theToPutEol specified whether end-of-line should be added to the end of the message.
+ //! Default implementation calls first method Send().
+ Standard_EXPORT virtual void Send (const Standard_SStream& theStream,
+ const Message_Gravity theGravity,
+ const Standard_Boolean theToPutEol) const Standard_OVERRIDE;
+
+ //! Send a string message with specified trace level.
+ //! The object is converted to string in format: <object kind> : <object pointer>.
+ //! The parameter theToPutEol specified whether end-of-line should be added to the end of the message.
+ //! Default implementation calls first method Send().
+ Standard_EXPORT virtual void Send (const Handle(Standard_Transient)& theObject,
+ const Message_Gravity theGravity,
+ const Standard_Boolean theToPutEol) const Standard_OVERRIDE;
+protected:
+
+ //! Send an alert with metrics active in the current report
+ Standard_EXPORT void sendMetricAlert (const TCollection_AsciiString theValue,
+ const Message_Gravity theGravity) const;
+
+private:
+ Handle(Message_Report) myReport; //!< the report for sending alerts
+ TCollection_AsciiString myValue; //!< the union of sent strings until Eol
+};
+
+#endif // _Message_PrinterToReport_HeaderFile
// commercial license or contractual agreement.
#include <Message_Report.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_CompositeAlerts.hxx>
#include <Message_Msg.hxx>
#include <Message_Messenger.hxx>
+#include <Message_PrinterToReport.hxx>
+
#include <NCollection_Map.hxx>
+#include <Precision.hxx>
+#include <Standard_Dump.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
//=======================================================================
Message_Report::Message_Report ()
+: myLimit (-1)
{
}
void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
{
- Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert",);
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Adding alert with gravity not in valid range",);
-
Standard_Mutex::Sentry aSentry (myMutex);
- // iterate by already recorded alerts and try to merge new one with one of those
- Message_ListOfAlert &aList = myAlerts[theGravity];
- if (theAlert->SupportsMerge() && ! aList.IsEmpty())
+ // alerts of the top level
+ if (myAlertLevels.IsEmpty())
{
- // merge is performed only for alerts of exactly same type
- const Handle(Standard_Type)& aType = theAlert->DynamicType();
- for (Message_ListOfAlert::Iterator anIt(aList); anIt.More(); anIt.Next())
+ Handle (Message_CompositeAlerts) aCompositeAlert = compositeAlerts (Standard_True);
+ if (aCompositeAlert->AddAlert (theGravity, theAlert))
+ return;
+
+ // remove alerts under the report only
+ const Message_ListOfAlert& anAlerts = aCompositeAlert->Alerts (theGravity);
+ if (anAlerts.Extent() > myLimit)
{
- // if merged successfully, just return
- if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
- return;
+ aCompositeAlert->RemoveAlert (theGravity, anAlerts.First());
}
+ return;
}
- // if not merged, just add to the list
- aList.Append (theAlert);
+ // if there are some levels of alerts
+ // iterate by already recorded alerts and try to merge new one with one of those
+ Message_Level* aLevel = myAlertLevels.Last();
+
+ // level has root alert, the new alert will be placed below the root
+ if (!aLevel->RootAlert().IsNull())
+ {
+ aLevel->AddAlert (theGravity, theAlert);
+ return;
+ }
+
+ Handle(Message_AlertExtended) anAlert = Handle(Message_AlertExtended)::DownCast (theAlert);
+ if (anAlert.IsNull())
+ return;
+ // place new alert as a root of the level, after place the level alert below the report or
+ // below the previous level
+ aLevel->SetRootAlert (anAlert);
+
+ if (myAlertLevels.Size() == 1) // this is the first level, so root alert should be pushed in the report composite of alerts
+ compositeAlerts (Standard_True)->AddAlert (theGravity, theAlert);
+ else
+ {
+ // root alert of next levels should be pushed under the previous level
+ Message_Level* aPrevLevel = myAlertLevels.Value (myAlertLevels.Size() - 1); // previous level
+ aPrevLevel->AddLevelAlert (theGravity, theAlert);
+ }
}
//=======================================================================
const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity) const
{
static const Message_ListOfAlert anEmptyList;
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Requesting alerts for gravity not in valid range", anEmptyList);
- return myAlerts[theGravity];
+ if (myCompositAlerts.IsNull())
+ return anEmptyList;
+
+ return myCompositAlerts->Alerts (theGravity);
}
//=======================================================================
Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType)
{
- for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
{
- if (HasAlert (theType, (Message_Gravity)iGravity))
+ if (HasAlert (theType, (Message_Gravity)aGravIter))
return Standard_True;
}
return Standard_False;
Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
{
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Requesting alerts for gravity not in valid range", Standard_False);
- for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
+ if (compositeAlerts().IsNull())
+ return Standard_False;
+
+ return compositeAlerts()->HasAlert (theType, theGravity);
+}
+
+//=======================================================================
+//function : IsActiveInMessenger
+//purpose :
+//=======================================================================
+
+Standard_Boolean Message_Report::IsActiveInMessenger (const Handle(Message_Messenger)& theMessenger) const
+{
+ Handle(Message_Messenger) aMessenger = theMessenger.IsNull() ? Message::DefaultMessenger() : theMessenger;
+ for (Message_SequenceOfPrinters::Iterator anIterator (aMessenger->Printers()); anIterator.More(); anIterator.Next())
{
- if (anIt.Value()->IsInstance(theType))
+ if (anIterator.Value()->IsKind(STANDARD_TYPE (Message_PrinterToReport)) &&
+ Handle(Message_PrinterToReport)::DownCast (anIterator.Value())->Report() == this)
return Standard_True;
}
return Standard_False;
}
//=======================================================================
-//function : Clear
+//function : ActivateInMessenger
//purpose :
//=======================================================================
-void Message_Report::Clear ()
+void Message_Report::ActivateInMessenger (const Standard_Boolean toActivate,
+ const Handle(Message_Messenger)& theMessenger) const
{
- for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
+ if (toActivate == IsActiveInMessenger())
+ return;
+
+ Handle(Message_Messenger) aMessenger = theMessenger.IsNull() ? Message::DefaultMessenger() : theMessenger;
+ if (toActivate)
{
- myAlerts[i].Clear();
+ Handle (Message_PrinterToReport) aPrinterToReport = new Message_PrinterToReport();
+ aPrinterToReport->SetReport (this);
+ aMessenger->AddPrinter (aPrinterToReport);
}
+ else // deactivate
+ {
+ Message_SequenceOfPrinters aPrintersToRemove;
+ for (Message_SequenceOfPrinters::Iterator anIterator (aMessenger->Printers()); anIterator.More(); anIterator.Next())
+ {
+ const Handle(Message_Printer) aPrinter = anIterator.Value();
+ if (aPrinter->IsKind(STANDARD_TYPE (Message_PrinterToReport)) &&
+ Handle(Message_PrinterToReport)::DownCast (aPrinter)->Report() == this)
+ aPrintersToRemove.Append (aPrinter);
+ }
+ for (Message_SequenceOfPrinters::Iterator anIterator (aPrintersToRemove); anIterator.More(); anIterator.Next())
+ {
+ aMessenger->RemovePrinter (anIterator.Value());
+ }
+ }
+}
+
+//=======================================================================
+//function : AddLevel
+//purpose :
+//=======================================================================
+
+void Message_Report::AddLevel (Message_Level* theLevel)
+{
+ myAlertLevels.Append (theLevel);
+}
+
+//=======================================================================
+//function : RemoveLevel
+//purpose :
+//=======================================================================
+
+void Message_Report::RemoveLevel (Message_Level* theLevel)
+{
+ for (int aLevelIndex = myAlertLevels.Size(); aLevelIndex >= 1; aLevelIndex--)
+ {
+ Message_Level* aLevel = myAlertLevels.Value (aLevelIndex);
+ myAlertLevels.Remove (aLevelIndex);
+
+ if (aLevel == theLevel)
+ return;
+ }
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+
+void Message_Report::Clear()
+{
+ if (compositeAlerts().IsNull())
+ return;
+
+ compositeAlerts()->Clear();
+ myAlertLevels.Clear();
}
//=======================================================================
void Message_Report::Clear (Message_Gravity theGravity)
{
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Requesting alerts for gravity not in valid range", );
- myAlerts[theGravity].Clear();
+ if (compositeAlerts().IsNull())
+ return;
+
+ compositeAlerts()->Clear (theGravity);
+ myAlertLevels.Clear();
}
//=======================================================================
void Message_Report::Clear (const Handle(Standard_Type)& theType)
{
- for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
- {
- for (Message_ListOfAlert::Iterator anIt (myAlerts[i]); anIt.More(); )
- {
- if (anIt.Value().IsNull() || anIt.Value()->IsInstance (theType))
- {
- myAlerts[i].Remove (anIt);
- }
- else
- {
- anIt.More();
- }
- }
- }
+ if (compositeAlerts().IsNull())
+ return;
+
+ compositeAlerts()->Clear (theType);
+ myAlertLevels.Clear();
+}
+
+//=======================================================================
+//function : SetActiveMetric
+//purpose :
+//=======================================================================
+
+void Message_Report::SetActiveMetric (const Message_MetricType theMetricType,
+ const Standard_Boolean theActivate)
+{
+ if (theActivate == myActiveMetrics.Contains (theMetricType))
+ return;
+
+ if (theActivate)
+ myActiveMetrics.Add (theMetricType);
+ else
+ myActiveMetrics.Remove (theMetricType);
}
//=======================================================================
void Message_Report::Dump (Standard_OStream& theOS)
{
- for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
{
- Dump (theOS, (Message_Gravity)iGravity);
+ Dump (theOS, (Message_Gravity)aGravIter);
}
}
void Message_Report::Dump (Standard_OStream& theOS, Message_Gravity theGravity)
{
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Requesting alerts for gravity not in valid range", );
+ if (compositeAlerts().IsNull())
+ return;
- // report each type of warning only once
- NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
- for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
- {
- if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
- {
- Message_Msg aMsg (anIt.Value()->GetMessageKey());
- theOS << aMsg.Original() << std::endl;
- }
- }
+ if (compositeAlerts().IsNull())
+ return;
+
+ dumpMessages (theOS, theGravity, compositeAlerts());
}
//=======================================================================
void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger)
{
- for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
{
- SendMessages (theMessenger, (Message_Gravity)iGravity);
+ SendMessages (theMessenger, (Message_Gravity)aGravIter);
}
}
void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity)
{
- Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
- "Requesting alerts for gravity not in valid range", );
+ if (compositeAlerts().IsNull())
+ return;
- // report each type of warning only once
- NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
- for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
- {
- if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
- {
- Message_Msg aMsg (anIt.Value()->GetMessageKey());
- theMessenger->Send (aMsg, theGravity);
- }
- }
+ sendMessages (theMessenger, theGravity, compositeAlerts());
}
//=======================================================================
void Message_Report::Merge (const Handle(Message_Report)& theOther)
{
- for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+ for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
{
- Merge (theOther, (Message_Gravity)iGravity);
+ Merge (theOther, (Message_Gravity)aGravIter);
}
}
AddAlert (theGravity, anIt.Value());
}
}
+
+//=======================================================================
+//function : ñompositeAlerts
+//purpose :
+//=======================================================================
+const Handle(Message_CompositeAlerts)& Message_Report::compositeAlerts (const Standard_Boolean isCreate)
+{
+ if (myCompositAlerts.IsNull() && isCreate)
+ myCompositAlerts = new Message_CompositeAlerts();
+
+ return myCompositAlerts;
+}
+
+//=======================================================================
+//function : sendMessages
+//purpose :
+//=======================================================================
+
+void Message_Report::sendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity,
+ const Handle(Message_CompositeAlerts)& theCompositeAlert)
+{
+ if (theCompositeAlert.IsNull())
+ return;
+
+ const Message_ListOfAlert& anAlerts = theCompositeAlert->Alerts (theGravity);
+ // report each type of warning only once
+ //NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
+ for (Message_ListOfAlert::Iterator anIt (anAlerts); anIt.More(); anIt.Next())
+ {
+ //if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
+ {
+ //Message_Msg aMsg (anIt.Value()->GetMessageKey());
+ //theMessenger->Send (aMsg, theGravity);
+ theMessenger->Send (anIt.Value()->GetMessageKey(), theGravity);
+ }
+ Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anIt.Value());
+ if (anExtendedAlert.IsNull())
+ continue;
+
+ Handle(Message_CompositeAlerts) aCompositeAlerts = anExtendedAlert->CompositeAlerts();
+ if (aCompositeAlerts.IsNull())
+ continue;
+
+ sendMessages (theMessenger, theGravity, aCompositeAlerts);
+ }
+}
+
+//=======================================================================
+//function : dumpMessages
+//purpose :
+//=======================================================================
+void Message_Report::dumpMessages (Standard_OStream& theOS, Message_Gravity theGravity,
+ const Handle(Message_CompositeAlerts)& theCompositeAlert)
+{
+ if (theCompositeAlert.IsNull())
+ return;
+
+ const Message_ListOfAlert& anAlerts = theCompositeAlert->Alerts (theGravity);
+ // report each type of war++ning only once
+ //NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
+ for (Message_ListOfAlert::Iterator anIt (anAlerts); anIt.More(); anIt.Next())
+ {
+ //if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
+ {
+ //Message_Msg aMsg (anIt.Value()->GetMessageKey());
+ //theOS << aMsg.Original() << std::endl;
+ theOS << anIt.Value()->GetMessageKey() << std::endl;
+ }
+
+ Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anIt.Value());
+ if (anExtendedAlert.IsNull())
+ continue;
+ dumpMessages (theOS, theGravity, anExtendedAlert->CompositeAlerts());
+ }
+}
#define _Message_Report_HeaderFile
#include <Message_Gravity.hxx>
+#include <Message_Level.hxx>
#include <Message_ListOfAlert.hxx>
+#include <Message_MetricType.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_Sequence.hxx>
#include <Standard_Mutex.hxx>
+class Message_CompositeAlerts;
class Message_Messenger;
-
class Message_Report;
-DEFINE_STANDARD_HANDLE(Message_Report, MMgt_TShared)
+
+DEFINE_STANDARD_HANDLE(Message_Report, Standard_Transient)
//! Container for alert messages, sorted according to their gravity.
//!
//! Dump() or in more advanced way, by iterating over lists returned by GetAlerts()
//!
//! - Report can be cleared by methods Clear() (usually after reporting)
+//!
+//! Message_PrinterToReport is a printer in Messenger to convert data sent to messenger into report
class Message_Report : public Standard_Transient
{
//! Returns true if specific type of alert is recorded with specified gravity
Standard_EXPORT Standard_Boolean HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity);
+ //! Returns true if a report printer for the current report is registered in the messenger
+ // @param theMessenger the messenger. If it's NULL, the default messenger is used
+ Standard_EXPORT Standard_Boolean IsActiveInMessenger (const Handle(Message_Messenger)& theMessenger = NULL) const;
+
+ //! Creates an instance of Message_PrinterToReport with the current report and register it in messenger
+ //! @param toActivate if true, activated else deactivated
+ // @param theMessenger the messenger. If it's NULL, the default messenger is used
+ Standard_EXPORT void ActivateInMessenger (const Standard_Boolean toActivate, const Handle(Message_Messenger)& theMessenger = NULL) const;
+
+ //! Add new level of alerts
+ //! @param theLevel a level
+ Standard_EXPORT void AddLevel (Message_Level* theLevel);
+
+ //! Remove level of alerts
+ Standard_EXPORT void RemoveLevel (Message_Level* theLevel);
+
//! Clears all collected alerts
Standard_EXPORT void Clear ();
//! Clears collected alerts with specified type
Standard_EXPORT void Clear (const Handle(Standard_Type)& theType);
+ //! Returns computed metrics when alerts are performed
+ const NCollection_Map<Message_MetricType>& ActiveMetrics() const { return myActiveMetrics; }
+
+ //! Sets metrics to compute when alerts are performed
+ //! @param theMetrics container of metrics
+ Standard_EXPORT void SetActiveMetric (const Message_MetricType theMetricType, const Standard_Boolean theActivate);
+
+ //! Removes all activated metrics
+ void ClearMetrics() { myActiveMetrics.Clear(); }
+
+ //! Returns maximum number of collecting alerts. If the limit is achieved,
+ //! first alert is removed, the new alert is added in the container.
+ //! @return the limit value
+ Standard_Integer Limit() const { return myLimit; }
+
+ //! Sets maximum number of collecting alerts.
+ //! @return theLimit limit value
+ void SetLimit(const Standard_Integer theLimit) { myLimit = theLimit; }
+
//! Dumps all collected alerts to stream
Standard_EXPORT void Dump (Standard_OStream& theOS);
//! Merges alerts with specified gravity from theOther report into this
Standard_EXPORT void Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity);
- // OCCT RTTI
DEFINE_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
+protected:
+ //! Returns class provided hierarchy of alerts if created or create if the parameter is true
+ //! @param isCreate if composite alert has not been created for this alert, it should be created
+ //! @return instance or NULL
+ Standard_EXPORT const Handle(Message_CompositeAlerts)& compositeAlerts (const Standard_Boolean isCreate = Standard_False);
+
+ //! Sends alerts to messenger
+ Standard_EXPORT void sendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity,
+ const Handle(Message_CompositeAlerts)& theCompositeAlert);
+
+ //! Dumps collected alerts with specified gravity to stream
+ Standard_EXPORT void dumpMessages (Standard_OStream& theOS, Message_Gravity theGravity,
+ const Handle(Message_CompositeAlerts)& theCompositeAlert);
+
protected:
Standard_Mutex myMutex;
- // store messages in a lists sorted by gravity;
- // here we rely on knowledge that Message_Fail is the last element of the enum
- Message_ListOfAlert myAlerts[Message_Fail + 1];
+ Handle(Message_CompositeAlerts) myCompositAlerts; //! container of alerts
+
+ NCollection_Sequence<Message_Level*> myAlertLevels; //! container of active levels, new alerts are added below the latest level
+ NCollection_Map<Message_MetricType> myActiveMetrics; //! metrics to compute on alerts
+
+ Standard_Integer myLimit; //! Maximum number of collected alerts on the top level
};
#endif // _Message_Report_HeaderFile
XmlDrivers_DocumentRetrievalDriver.hxx
XmlDrivers_DocumentStorageDriver.cxx
XmlDrivers_DocumentStorageDriver.hxx
+XmlDrivers_MessageReportStorage.cxx
+XmlDrivers_MessageReportStorage.hxx
--- /dev/null
+// Created on: 2018-06-10
+// Created by: Natalia Ermolaeva
+// Copyright (c) 2001-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <XmlDrivers_MessageReportStorage.hxx>
+
+#include <Message.hxx>
+#include <Message_AlertExtended.hxx>
+#include <Message_AttributeObject.hxx>
+#include <Message_AttributeStream.hxx>
+#include <Message_CompositeAlerts.hxx>
+#include <Message_Level.hxx>
+#include <Message_Report.hxx>
+
+#include <Standard_Dump.hxx>
+
+#include <TCollection.hxx>
+#include <TDataStd_AsciiString.hxx>
+#include <TDataStd_Comment.hxx>
+#include <TDataStd_Real.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_ExtStringArray.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDocStd_Application.hxx>
+#include <TDocStd_Document.hxx>
+
+#include <XmlDrivers.hxx>
+
+// =======================================================================
+// function : GetApplication
+// purpose :
+// =======================================================================
+
+const Handle(TDocStd_Application)& GetApplication()
+{
+ static Handle(TDocStd_Application) anApp;
+ if (anApp.IsNull())
+ {
+ anApp = new TDocStd_Application;
+ XmlDrivers::DefineFormat (anApp);
+ }
+ return anApp;
+}
+
+// =======================================================================
+// function : ExportReport
+// purpose :
+// =======================================================================
+
+void XmlDrivers_MessageReportStorage::ExportReport (const Handle(Message_Report)& theReport,
+ const TCollection_AsciiString& theFileName)
+{
+ if (theReport.IsNull())
+ return;
+
+ Handle(TDocStd_Document) aDocument;
+ GetApplication()->NewDocument (TCollection_ExtendedString ("XmlOcaf"), aDocument);
+
+ TDF_Label aMainLabel = aDocument->Main();
+
+ for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+ {
+ Message_Gravity aGravity = (Message_Gravity)aGravityId;
+
+ if (theReport->GetAlerts (aGravity).Size() == 0)
+ continue;
+ // Gravity Label
+ TDF_Label aGravityLabel = aMainLabel.NewChild();
+ // set gravity kind string
+ TCollection_ExtendedString aName (aGravity);
+ if (!aName.IsEmpty())
+ TDataStd_Name::Set (aGravityLabel, aName);
+
+ /// reserved label to store gravity information
+ //TDF_Label aFirstAlertLabel = aGravityLabel.NewChild();
+
+ // Alert Labels: labels are started from the second index
+ const Message_ListOfAlert& anAlerts = theReport->GetAlerts (aGravity);
+ for (Message_ListOfAlert::Iterator anAlertsIt (anAlerts); anAlertsIt.More(); anAlertsIt.Next())
+ {
+ exportAlert (anAlertsIt.Value(), aGravityLabel);
+ }
+ }
+ GetApplication()->SaveAs (aDocument, theFileName);
+ GetApplication()->Close (aDocument);
+}
+
+// =======================================================================
+// function : ImportReport
+// purpose :
+// =======================================================================
+
+Handle(Message_Report) XmlDrivers_MessageReportStorage::ImportReport (const TCollection_AsciiString& theFileName)
+{
+ Handle(TDocStd_Application) anApplication = GetApplication();
+ Standard_Integer aDocumentId = anApplication->IsInSession (theFileName);
+ if (aDocumentId > 0)
+ {
+ Handle(TDocStd_Document) aDocument;
+ anApplication->GetDocument (aDocumentId, aDocument);
+ anApplication->Close (aDocument);
+ }
+
+ Handle(TDocStd_Document) aDocument;
+ GetApplication()->Open (theFileName, aDocument);
+ if (aDocument.IsNull())
+ return Handle(Message_Report)();
+
+ TDF_Label aMainLabel = aDocument->Main();
+ if (aMainLabel.IsNull())
+ return Handle(Message_Report)();
+
+ TDF_Label aLabel;
+ Handle(Message_Report) aReport = new Message_Report();
+ for (TDF_ChildIterator aLabelsIt(aMainLabel); aLabelsIt.More(); aLabelsIt.Next())
+ {
+ TDF_Label aGravityLabel = aLabelsIt.Value();
+ if (aGravityLabel.IsNull())
+ continue;
+ Handle(TDF_Attribute) anAttribute;
+ if (!aGravityLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+ continue;
+ Handle(TDataStd_Name) aNameAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+ if (aNameAttribute.IsNull())
+ continue;
+
+ // get gravity type
+ const TCollection_ExtendedString& aGravityName = aNameAttribute->Get();
+ Message_Gravity aGravity = (Message_Gravity) (TCollection_AsciiString (aGravityName).IntegerValue());
+
+ /// reserved label to store gravity information
+ //TDF_Label aFirstAlertLabel = aGravityLabel.FindChild (1, Standard_False);
+
+ // find alerts information, add corresponded alerts to the report
+ for (TDF_ChildIterator anAlertLabelsIt (aGravityLabel); anAlertLabelsIt.More(); anAlertLabelsIt.Next())
+ {
+ TDF_Label anAlertLabel = anAlertLabelsIt.Value();
+ if (anAlertLabel.IsNull())
+ continue;
+
+ importAlert (anAlertLabel, aGravity, aReport, Handle(Message_Alert)());
+ }
+ }
+ return aReport;
+}
+
+// =======================================================================
+// function : exportAlert
+// purpose :
+// =======================================================================
+
+void XmlDrivers_MessageReportStorage::exportAlert (const Handle(Message_Alert)& theAlert, const TDF_Label& theParentLabel)
+{
+ TDF_Label anAlertLabel = theParentLabel.NewChild();
+ TDataStd_Name::Set (anAlertLabel, theAlert->DynamicType()->Name());
+
+ /// reserved label to store parameters of the current label
+ TDF_Label anAlertParmetersLabel = anAlertLabel.NewChild();
+ exportAlertParameters (theAlert, anAlertParmetersLabel);
+
+ for (int aGravityId = Message_Trace; aGravityId <= Message_Fail; aGravityId++)
+ {
+ // Gravity Label
+ TDF_Label aGravityLabel = anAlertLabel.NewChild();
+ // set gravity kind string
+ TDataStd_Name::Set (aGravityLabel, aGravityId);
+
+ Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+ if (anAlertExtended.IsNull())
+ continue;
+ Handle(Message_CompositeAlerts) aComposite = anAlertExtended->CompositeAlerts();
+ if (aComposite.IsNull())
+ continue;
+
+ const Message_ListOfAlert& anAlerts = aComposite->Alerts ((Message_Gravity)aGravityId);
+ for (Message_ListOfAlert::Iterator anAlertsIt (anAlerts); anAlertsIt.More(); anAlertsIt.Next())
+ exportAlert (anAlertsIt.Value(), aGravityLabel);
+ }
+}
+
+// =======================================================================
+// function : importAlert
+// purpose :
+// =======================================================================
+
+void XmlDrivers_MessageReportStorage::importAlert (const TDF_Label& theAlertLabel,
+ const Message_Gravity theGravity,
+ Handle(Message_Report)& theReport,
+ const Handle(Message_Alert)& theParentAlert)
+{
+ TDF_Label aParametersLabel = theAlertLabel.FindChild (1, Standard_False);
+ Handle(Message_Alert) anAlert = importAlertParameters (aParametersLabel);
+ if (anAlert.IsNull())
+ return;
+
+ TDF_Label aLabel;
+ TDF_ChildIterator aSubAlertsLabelsIt (theAlertLabel);
+ aSubAlertsLabelsIt.Next(); // do not processing the first (parameters) label
+ for (; aSubAlertsLabelsIt.More(); aSubAlertsLabelsIt.Next())
+ {
+ TDF_Label aGravityLabel = aSubAlertsLabelsIt.Value();
+ if (aGravityLabel.IsNull())
+ continue;
+ Handle(TDF_Attribute) anAttribute;
+ if (!aGravityLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+ continue;
+ Handle(TDataStd_Name) aNameAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+ if (aNameAttribute.IsNull())
+ continue;
+
+ // get gravity type
+ Message_Gravity aGravity = (Message_Gravity) (TCollection_AsciiString (aNameAttribute->Get()).IntegerValue());
+ // find alerts information, add corresponded alerts to the report
+ for (TDF_ChildIterator anAlertLabelsIt (aGravityLabel); anAlertLabelsIt.More(); anAlertLabelsIt.Next())
+ {
+ TDF_Label anAlertLabel = anAlertLabelsIt.Value();
+ if (anAlertLabel.IsNull())
+ continue;
+
+ importAlert (anAlertLabel, aGravity, theReport, anAlert);
+ }
+ }
+ if (theParentAlert.IsNull())
+ theReport->AddAlert (theGravity, anAlert);
+ else
+ {
+ MESSAGE_ADD_LEVEL_SENTRY
+ theReport->AddAlert (theGravity, anAlert);
+ }
+}
+
+// =======================================================================
+// function : exportAlertParameters
+// purpose :
+// =======================================================================
+void XmlDrivers_MessageReportStorage::exportAlertParameters (const Handle(Message_Alert)& theAlert, const TDF_Label& theAlertLabel)
+{
+ Handle(Message_AlertExtended) anAlertExtended = Handle(Message_AlertExtended)::DownCast (theAlert);
+ if (anAlertExtended.IsNull()) // name attribute is empty
+ return;
+
+ // store attribute time
+ Handle(Message_Attribute) anAttribute = anAlertExtended->Attribute();
+
+ TDataStd_Name::Set (theAlertLabel, anAttribute->DynamicType()->Name());
+ //TDataStd_Real::Set (theAlertLabel, anAlertExtended->CumulativeMetric());
+
+ TDataStd_AsciiString::Set (theAlertLabel, anAttribute->GetName());
+
+ Standard_CString aDynamicTypeName = anAttribute->DynamicType()->Name();
+ if (aDynamicTypeName == STANDARD_TYPE (Message_AttributeStream)->Name())
+ {
+ Handle(Message_AttributeStream) aValuesArrayAlert = Handle(Message_AttributeStream)::DownCast (anAttribute);
+ // store values
+ TCollection_AsciiString aStreamText = Standard_Dump::Text (aValuesArrayAlert->Stream());
+ if (aStreamText.IsEmpty())
+ return;
+ Handle(TDataStd_ExtStringArray) aListAttribute = TDataStd_ExtStringArray::Set (theAlertLabel, 0, 0);
+ aListAttribute->SetValue (0, aStreamText);
+ }
+}
+
+// =======================================================================
+// function : importAlertParameters
+// purpose :
+// =======================================================================
+Handle(Message_Alert) XmlDrivers_MessageReportStorage::importAlertParameters (const TDF_Label& aParametersLabel)
+{
+ Handle(TDF_Attribute) anAttribute;
+ if (!aParametersLabel.FindAttribute (TDataStd_Name::GetID(), anAttribute))
+ return Handle(Message_Alert)();
+
+ Handle(TDataStd_Name) aDynamicTypeAttribute = Handle(TDataStd_Name)::DownCast (anAttribute);
+ if (aDynamicTypeAttribute.IsNull())
+ return Handle(Message_Alert)();
+ const TCollection_ExtendedString& aDynamicTypeName = aDynamicTypeAttribute->Get();
+
+ Handle(Message_AlertExtended) anAlert = new Message_AlertExtended();
+ Handle(Message_Attribute) aMessageAttribute;
+ if (aDynamicTypeName == STANDARD_TYPE (Message_Attribute)->Name())
+ aMessageAttribute = new Message_Attribute();
+ else if (aDynamicTypeName == STANDARD_TYPE (Message_AttributeStream)->Name())
+ {
+ // values
+ NCollection_Vector<TCollection_AsciiString> anArrayValues;
+ if (!aParametersLabel.FindAttribute (TDataStd_ExtStringArray::GetID(), anAttribute))
+ return Handle(Message_Alert)();
+
+ Handle(TDataStd_ExtStringArray) aValuesAttribute = Handle(TDataStd_ExtStringArray)::DownCast (anAttribute);
+ if (aValuesAttribute.IsNull())
+ return Handle(Message_Alert)();
+
+ Standard_SStream aStream;
+ for (int aValueId = aValuesAttribute->Lower(); aValueId <= aValuesAttribute->Upper(); aValueId++)
+ {
+ aStream << aValuesAttribute->Value (aValueId);
+ }
+ aMessageAttribute = new Message_AttributeStream (aStream);
+ }
+
+ if (!aMessageAttribute.IsNull())
+ {
+ // name
+ if (!aParametersLabel.FindAttribute (TDataStd_AsciiString::GetID(), anAttribute))
+ return Handle(Message_Alert)();
+ Handle(TDataStd_AsciiString) aNameAttribute = Handle(TDataStd_AsciiString)::DownCast (anAttribute);
+ if (aNameAttribute.IsNull())
+ return Handle(Message_Alert)();
+
+ aMessageAttribute->SetName (aNameAttribute->Get());
+ anAlert->SetAttribute (aMessageAttribute);
+ }
+
+ // time
+ //Standard_Real aTime = -1;
+ //Handle(TDataStd_Real) aTimeAttribute;
+ //if (aParametersLabel.FindAttribute (TDataStd_Real::GetID(), aTimeAttribute))
+ // aTime = aTimeAttribute->Get();
+
+ //anAlert->SetCumulativeMetric (aTime);
+ return anAlert;
+}
--- /dev/null
+// Created on: 2018-06-10
+// Created by: Natalia Ermolaeva
+// Copyright (c) 2001-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _XmlDrivers_MessageReportStorage
+#define _XmlDrivers_MessageReportStorage
+
+#include <Standard_Handle.hxx>
+
+#include <Message_Report.hxx>
+#include <Message_Alert.hxx>
+#include <TDF_Label.hxx>
+
+//! Base class to store/restore Message_Report content in XML document
+class XmlDrivers_MessageReportStorage
+{
+public:
+ //! Create document for the report
+ //! \param theReport the source report
+ //! \param theFileName a file name
+ Standard_EXPORT static void ExportReport (const Handle(Message_Report)& theReport, const TCollection_AsciiString& theFileName);
+
+ //! Restores document file content into report instance
+ //! \param theFileName a file name
+ //! \return new report or NULL
+ Standard_EXPORT static Handle(Message_Report) ImportReport (const TCollection_AsciiString& theFileName);
+
+private:
+ //! Create labels/attributes for the alert and place it under the parent label.
+ //! It is recursive as alerts may contains other alerts
+ //! \param theAlert a source alert
+ //! \parm theParentLabel a label where alert label is placed
+ static void exportAlert (const Handle(Message_Alert)& theAlert, const TDF_Label& theParentLabel);
+
+ //! Creates a new alert by the label parameters
+ //! \param theAlertLabel a source document label
+ //! \param theGravity an alert gravity
+ //! \param theReport a container of alerts
+ //! \param theParentAlert a parent alert, if null, the parent is report
+ static void importAlert (const TDF_Label& theAlertLabel,
+ const Message_Gravity theGravity,
+ Handle(Message_Report)& theReport,
+ const Handle(Message_Alert)& theParentAlert);
+
+ //! Convert alert to a custom type and store parameters in child labels and attributes
+ //! \param theAlert a source alert
+ //! \parm theAlertLabel an alert label
+ static void exportAlertParameters (const Handle(Message_Alert)& theAlert,
+ const TDF_Label& theAlertLabel);
+
+ //! Creates alert by label type filled by the label content
+ //! \param theParametersLabel a label
+ //! \return new alert or NULL
+ static Handle(Message_Alert) importAlertParameters (const TDF_Label& aParametersLabel);
+};
+
+#define MESSAGE_STORE_XML_REPORT(FileName) \
+{ \
+ Handle(Message_Report) aReport = Message::DefaultReport (Standard_False); \
+ if (!aReport.IsNull()) XmlDrivers_MessageReportStorage::ExportReport (aReport, FileName); \
+}
+
+#endif // _XmlDrivers_MessageReportStorage