//
// System.ComponentModel.Design.Serialization.DebugContext
//
// (C) 2007 Ivan N. Zlatev
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_2_0
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
namespace Mono.Design
{
internal class DebugContext
{
// This DebugContext is designed to work in terms of a linear execution
// model. It does support branching, but UnifyTraceContext has to be called
// after the branching has taken place and finished in order for all Error
// backtraces to continue to update.
private Trace _trace;
private List<Error> _errors;
private bool _errorOccurred;
public DebugContext ()
{
_errorOccurred = false;
_errors = new List<Error> ();
}
public bool ErrorOccurred {
get { return _errorOccurred; }
}
public Trace TraceContext {
get { return _trace; }
}
public void RaiseError (string message, string description)
{
Error r = new Error (message, description);
_errors.Add (r);
_trace = r.BackTrace;
_errorOccurred = true;
}
public void UnifyTraceContext ()
{
if (_errors.Count > 1) {
_trace = new Trace ();
foreach (Error error in _errors)
error.BackTrace.Parent = _trace;
}
}
public void ReportErrors (IDesignerSerializationManager manager)
{
foreach (Error error in _errors)
ReportError (manager, error.Message, error.FullText);
_errors.Clear ();
_errorOccurred = false;
}
public static void ReportError (IDesignerSerializationManager manager, string message)
{
ReportError (manager, message, "");
}
public static void ReportError (IDesignerSerializationManager manager, string message, string details)
{
try {
throw new Exception (message);
} catch (Exception e) {
e.Data["Details"] = details;
manager.ReportError (e);
}
}
}
internal class Error
{
private string _message;
private string _description;
private Trace _trace;
public Error (string errorMessage, string errorDescription)
{
_message = errorMessage;
_description = errorDescription;
_trace = new Trace ();
}
public string Message {
get { return _message; }
}
public string Description {
get { return _description; }
}
public Trace BackTrace {
get { return _trace; }
}
public string FullText {
get { return this.ToString(); }
}
public override string ToString ()
{
return _message + System.Environment.NewLine +
_description + System.Environment.NewLine + System.Environment.NewLine +
"--- TRACE ---" + System.Environment.NewLine + _trace;
}
}
internal class Trace
{
//
// Unlike e.g exception backtraces this one is actually stored in human readable order form :-)
//
// Element 1
// Element 2
// Element 3
//
private Trace _parent;
private Queue<string> _trace;
public Trace () : this (null)
{
}
public Trace (Trace parent)
{
_parent = parent;
_trace = new Queue<string> ();
}
public void Push (string info)
{
_trace.Enqueue (info);
}
public string Text {
get { return this.ToString (); }
}
internal Trace Parent {
set { _parent = value; }
}
public override string ToString ()
{
StringBuilder sb = new StringBuilder ();
foreach (string info in _trace)
sb.AppendLine (info);
if (_parent != null)
sb.Append (_parent.ToString ());
return sb.ToString ();
}
}
}
#endif