Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / XslException.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XslException.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
7
8 using System.CodeDom.Compiler;
9 using System.Diagnostics;
10 using System.Globalization;
11 using System.Resources;
12 using System.Runtime.Serialization;
13 using System.Security.Permissions;
14 using System.Text;
15
16 namespace System.Xml.Xsl {
17     using Res = System.Xml.Utils.Res;
18
19     [Serializable]
20     internal class XslTransformException : XsltException {
21
22         protected XslTransformException(SerializationInfo info, StreamingContext context)
23             : base(info, context) {}
24
25         public XslTransformException(Exception inner, string res, params string[] args)
26             : base(CreateMessage(res, args), inner) {}
27
28         public XslTransformException(string message)
29             : base(CreateMessage(message, null), null) {}
30
31         internal XslTransformException(string res, params string[] args)
32             : this(null, res, args) {}
33
34         internal static string CreateMessage(string res, params string[] args) {
35             string message = null;
36
37             try {
38                 message = Res.GetString(res, args);
39             }
40             catch (MissingManifestResourceException) {
41             }
42
43             if (message != null) {
44                 return message;
45             }
46
47             StringBuilder sb = new StringBuilder(res);
48             if (args != null && args.Length > 0) {
49                 Debug.Fail("Resource string '" + res + "' was not found");
50                 sb.Append('(');
51                 sb.Append(args[0]);
52                 for (int idx = 1; idx < args.Length; idx++) {
53                     sb.Append(", ");
54                     sb.Append(args[idx]);
55                 }
56                 sb.Append(')');
57             }
58             return sb.ToString();
59         }
60
61         internal virtual string FormatDetailedMessage() {
62             return Message;
63         }
64
65         public override string ToString() {
66             string result = this.GetType().FullName;
67             string info = FormatDetailedMessage();
68             if (info != null && info.Length > 0) {
69                 result += ": " + info;
70             }
71             if (InnerException != null) {
72                 result += " ---> " + InnerException.ToString() + Environment.NewLine + "   " + CreateMessage(Res.Xml_EndOfInnerExceptionStack);
73             }
74             if (StackTrace != null) {
75                 result += Environment.NewLine + StackTrace;
76             }
77             return result;
78         }
79     }
80
81     [Serializable]
82     internal class XslLoadException : XslTransformException {
83         ISourceLineInfo lineInfo;
84
85         protected XslLoadException (SerializationInfo info, StreamingContext context)
86             : base(info, context)
87         {
88             bool hasLineInfo = (bool) info.GetValue("hasLineInfo", typeof(bool));
89
90             if (hasLineInfo) {
91                 string  uriString;
92                 int     startLine, startPos, endLine, endPos;
93
94                 uriString   = (string)   info.GetValue("Uri"        , typeof(string ));
95                 startLine   = (int)      info.GetValue("StartLine"  , typeof(int    ));
96                 startPos    = (int)      info.GetValue("StartPos"   , typeof(int    ));
97                 endLine     = (int)      info.GetValue("EndLine"    , typeof(int    ));
98                 endPos      = (int)      info.GetValue("EndPos"     , typeof(int    ));
99
100                 lineInfo = new SourceLineInfo(uriString, startLine, startPos, endLine, endPos);
101             }
102         }
103
104         [SecurityPermissionAttribute(SecurityAction.LinkDemand, SerializationFormatter=true)]
105         public override void GetObjectData(SerializationInfo info, StreamingContext context) {
106             base.GetObjectData(info, context);
107             info.AddValue("hasLineInfo"  , lineInfo != null);
108
109             if (lineInfo != null) {
110                 info.AddValue("Uri"      , lineInfo.Uri);
111                 info.AddValue("StartLine", lineInfo.Start.Line);
112                 info.AddValue("StartPos" , lineInfo.Start.Pos );
113                 info.AddValue("EndLine"  , lineInfo.End.Line);
114                 info.AddValue("EndPos"   , lineInfo.End.Pos );
115             }
116         }
117
118         internal XslLoadException(string res, params string[] args)
119             : base(null, res, args) {}
120
121         internal XslLoadException(Exception inner, ISourceLineInfo lineInfo)
122             : base(inner, Res.Xslt_CompileError2, null)
123         {
124             SetSourceLineInfo(lineInfo);
125         }
126
127 #if !DISABLE_XSLT_SCRIPT
128         internal XslLoadException(CompilerError error)
129             : base(Res.Xml_UserException, new string[] { error.ErrorText })
130         {
131             int errorLine = error.Line;
132             int errorColumn = error.Column;
133
134             if (errorLine == 0) {
135                 // If the compiler reported error on Line 0 - ignore columns, 
136                 //   0 means it doesn't know where the error was and our SourceLineInfo
137                 //   expects either all zeroes or all non-zeroes
138                 errorColumn = 0;
139             }
140             else {
141                 if (errorColumn == 0) {
142                     // In this situation the compiler returned for example Line 10, Column 0.
143                     // This means that the compiler knows the line of the error, but it doesn't
144                     //   know (or support) the column part of the location.
145                     // Since we don't allow column 0 (as it's invalid), let's turn it into 1 (the begining of the line)
146                     errorColumn = 1;
147                 }
148             }
149
150             SetSourceLineInfo(new SourceLineInfo(error.FileName, errorLine, errorColumn, errorLine, errorColumn));
151         }
152 #endif
153
154         internal void SetSourceLineInfo(ISourceLineInfo lineInfo) {
155             Debug.Assert(lineInfo == null || lineInfo.Uri != null);
156             this.lineInfo = lineInfo;
157         }
158
159         public override string SourceUri {
160             get { return lineInfo != null ? lineInfo.Uri : null; }
161         }
162
163         public override int LineNumber {
164             get { return lineInfo != null ? lineInfo.Start.Line : 0; }
165         }
166
167         public override int LinePosition {
168             get { return lineInfo != null ? lineInfo.Start.Pos : 0; }
169         }
170
171         private static string AppendLineInfoMessage(string message, ISourceLineInfo lineInfo) {
172             if (lineInfo != null) {
173                 string fileName = SourceLineInfo.GetFileName(lineInfo.Uri);
174                 string lineInfoMessage = CreateMessage(Res.Xml_ErrorFilePosition, fileName, lineInfo.Start.Line.ToString(CultureInfo.InvariantCulture), lineInfo.Start.Pos.ToString(CultureInfo.InvariantCulture));
175                 if (lineInfoMessage != null && lineInfoMessage.Length > 0) {
176                     if (message.Length > 0 && !XmlCharType.Instance.IsWhiteSpace(message[message.Length - 1])) {
177                         message += " ";
178                     }
179                     message += lineInfoMessage;
180                 }
181             }
182             return message;
183         }
184
185         internal static string CreateMessage(ISourceLineInfo lineInfo, string res, params string[] args) {
186             return AppendLineInfoMessage(CreateMessage(res, args), lineInfo);
187         }
188
189         internal override string FormatDetailedMessage() {
190             return AppendLineInfoMessage(Message, lineInfo);
191         }
192     }
193 }