1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include <QUrl>
41 
42 #include "qabstractmessagehandler.h"
43 
44 #include "qcommonnamespaces_p.h"
45 #include "qexpression_p.h"
46 
47 #include "qreportcontext_p.h"
48 
49 QT_BEGIN_NAMESPACE
50 
51 using namespace QPatternist;
52 
~ReportContext()53 ReportContext::~ReportContext()
54 {
55 }
56 
finalizeDescription(const QString & desc)57 QString ReportContext::finalizeDescription(const QString &desc)
58 {
59     return QLatin1String("<html xmlns='http://www.w3.org/1999/xhtml/'><body><p>")
60            + desc
61            + QLatin1String("</p></body></html>");
62 }
63 
warning(const QString & description,const QSourceLocation & sourceLocation)64 void ReportContext::warning(const QString &description,
65                             const QSourceLocation &sourceLocation)
66 {
67     messageHandler()->message(QtWarningMsg, finalizeDescription(description), QUrl(), sourceLocation);
68 }
69 
createError(const QString & description,const QtMsgType type,const QUrl & id,const QSourceLocation & sourceLocation) const70 void ReportContext::createError(const QString &description,
71                                 const QtMsgType type,
72                                 const QUrl &id,
73                                 const QSourceLocation &sourceLocation) const
74 {
75     messageHandler()->message(type, finalizeDescription(description), id, sourceLocation);
76     throw Exception(true);
77 }
78 
error(const QString & msg,const ErrorCode code,const QSourceLocation & sourceLocation)79 void ReportContext::error(const QString &msg,
80                           const ErrorCode code,
81                           const QSourceLocation &sourceLocation)
82 {
83     createError(msg, QtFatalMsg,
84                 QUrl(CommonNamespaces::XPERR + QLatin1Char('#') + codeToString(code)),
85                 sourceLocation);
86 }
87 
lookupSourceLocation(const SourceLocationReflection * const r) const88 QSourceLocation ReportContext::lookupSourceLocation(const SourceLocationReflection *const r) const
89 {
90     Q_ASSERT(r);
91     const SourceLocationReflection *const actual = r->actualReflection();
92     Q_ASSERT(actual);
93 
94     const QSourceLocation &sl = actual->sourceLocation();
95 
96     if(sl.isNull())
97     {
98         Q_ASSERT_X(!locationFor(actual).isNull(), Q_FUNC_INFO,
99                    qPrintable(QString::fromLatin1("No location is available for: %1").arg(actual->description())));
100         return locationFor(actual);
101     }
102     else
103         return sl;
104 }
105 
error(const QString & message,const ReportContext::ErrorCode errorCode,const SourceLocationReflection * const reflection)106 void ReportContext::error(const QString &message,
107                           const ReportContext::ErrorCode errorCode,
108                           const SourceLocationReflection *const reflection)
109 {
110     Q_ASSERT(reflection);
111     error(message, errorCode, lookupSourceLocation(reflection));
112 }
113 
error(const QString & msg,const QXmlName qname,const SourceLocationReflection * const reflection)114 void ReportContext::error(const QString &msg,
115                           const QXmlName qname,
116                           const SourceLocationReflection *const reflection)
117 {
118     Q_ASSERT(!qname.isNull());
119     createError(msg, QtFatalMsg,
120                 QUrl(namePool()->stringForNamespace(qname.namespaceURI()) + QLatin1Char('#') + namePool()->stringForLocalName(qname.localName())),
121                 lookupSourceLocation(reflection));
122 }
123 
codeFromURI(const QString & typeURI,QString & uri)124 QString ReportContext::codeFromURI(const QString &typeURI,
125                                    QString &uri)
126 {
127     /* Wouldn't surprise me if this can be done more efficiently. */
128     QUrl source(typeURI);
129 
130     const QString code(source.fragment());
131     source.setFragment(QString());
132     uri = source.toString();
133     return code;
134 }
135 
codeToString(const ReportContext::ErrorCode code)136 QString ReportContext::codeToString(const ReportContext::ErrorCode code)
137 {
138     const char *result = 0;
139 
140     switch(code)
141     {
142         /* Alphabetically. */
143         case FOAR0001: result = "FOAR0001"; break;
144         case FOAR0002: result = "FOAR0002"; break;
145         case FOCA0001: result = "FOCA0001"; break;
146         case FOCA0002: result = "FOCA0002"; break;
147         case FOCA0003: result = "FOCA0003"; break;
148         case FOCA0005: result = "FOCA0005"; break;
149         case FOCA0006: result = "FOCA0006"; break;
150         case FOCH0001: result = "FOCH0001"; break;
151         case FOCH0002: result = "FOCH0002"; break;
152         case FOCH0003: result = "FOCH0003"; break;
153         case FOCH0004: result = "FOCH0004"; break;
154         case FODC0001: result = "FODC0001"; break;
155         case FODC0002: result = "FODC0002"; break;
156         case FODC0003: result = "FODC0003"; break;
157         case FODC0004: result = "FODC0004"; break;
158         case FODC0005: result = "FODC0005"; break;
159         case FODT0001: result = "FODT0001"; break;
160         case FODT0002: result = "FODT0002"; break;
161         case FODT0003: result = "FODT0003"; break;
162         case FOER0000: result = "FOER0000"; break;
163         case FONS0004: result = "FONS0004"; break;
164         case FONS0005: result = "FONS0005"; break;
165         case FORG0001: result = "FORG0001"; break;
166         case FORG0002: result = "FORG0002"; break;
167         case FORG0003: result = "FORG0003"; break;
168         case FORG0004: result = "FORG0004"; break;
169         case FORG0005: result = "FORG0005"; break;
170         case FORG0006: result = "FORG0006"; break;
171         case FORG0008: result = "FORG0008"; break;
172         case FORG0009: result = "FORG0009"; break;
173         case FORX0001: result = "FORX0001"; break;
174         case FORX0002: result = "FORX0002"; break;
175         case FORX0003: result = "FORX0003"; break;
176         case FORX0004: result = "FORX0004"; break;
177         case FOTY0012: result = "FOTY0012"; break;
178         case SENR0001: result = "SENR0001"; break;
179         case SEPM0004: result = "SEPM0004"; break;
180         case SEPM0009: result = "SEPM0009"; break;
181         case SEPM0010: result = "SEPM0010"; break;
182         case SEPM0016: result = "SEPM0016"; break;
183         case SERE0003: result = "SERE0003"; break;
184         case SERE0005: result = "SERE0005"; break;
185         case SERE0006: result = "SERE0006"; break;
186         case SERE0008: result = "SERE0008"; break;
187         case SERE0012: result = "SERE0012"; break;
188         case SERE0014: result = "SERE0014"; break;
189         case SERE0015: result = "SERE0015"; break;
190         case SESU0007: result = "SESU0007"; break;
191         case SESU0011: result = "SESU0011"; break;
192         case SESU0013: result = "SESU0013"; break;
193         case XPDY0002: result = "XPDY0002"; break;
194         case XPDY0021: result = "XPDY0021"; break;
195         case XPDY0050: result = "XPDY0050"; break;
196         case XPST0001: result = "XPST0001"; break;
197         case XPST0003: result = "XPST0003"; break;
198         case XPST0005: result = "XPST0005"; break;
199         case XPST0008: result = "XPST0008"; break;
200         case XPST0010: result = "XPST0010"; break;
201         case XPST0017: result = "XPST0017"; break;
202         case XPST0051: result = "XPST0051"; break;
203         case XPST0080: result = "XPST0080"; break;
204         case XPST0081: result = "XPST0081"; break;
205         case XPST0083: result = "XPST0083"; break;
206         case XPTY0004: result = "XPTY0004"; break;
207         case XPTY0006: result = "XPTY0006"; break;
208         case XPTY0007: result = "XPTY0007"; break;
209         case XPTY0018: result = "XPTY0018"; break;
210         case XPTY0019: result = "XPTY0019"; break;
211         case XPTY0020: result = "XPTY0020"; break;
212         case XQDY0025: result = "XQDY0025"; break;
213         case XQDY0026: result = "XQDY0026"; break;
214         case XQDY0027: result = "XQDY0027"; break;
215         case XQDY0029: result = "XQDY0029"; break;
216         case XQDY0041: result = "XQDY0041"; break;
217         case XQDY0044: result = "XQDY0044"; break;
218         case XQDY0052: result = "XQDY0052"; break;
219         case XQDY0061: result = "XQDY0061"; break;
220         case XQDY0062: result = "XQDY0062"; break;
221         case XQDY0064: result = "XQDY0064"; break;
222         case XQDY0072: result = "XQDY0072"; break;
223         case XQDY0074: result = "XQDY0074"; break;
224         case XQDY0084: result = "XQDY0084"; break;
225         case XQDY0091: result = "XQDY0091"; break;
226         case XQDY0092: result = "XQDY0092"; break;
227         case XQST0009: result = "XQST0009"; break;
228         case XQST0012: result = "XQST0012"; break;
229         case XQST0013: result = "XQST0013"; break;
230         case XQST0014: result = "XQST0014"; break;
231         case XQST0015: result = "XQST0015"; break;
232         case XQST0016: result = "XQST0016"; break;
233         case XQST0022: result = "XQST0022"; break;
234         case XQST0031: result = "XQST0031"; break;
235         case XQST0032: result = "XQST0032"; break;
236         case XQST0033: result = "XQST0033"; break;
237         case XQST0034: result = "XQST0034"; break;
238         case XQST0035: result = "XQST0035"; break;
239         case XQST0036: result = "XQST0036"; break;
240         case XQST0037: result = "XQST0037"; break;
241         case XQST0038: result = "XQST0038"; break;
242         case XQST0039: result = "XQST0039"; break;
243         case XQST0040: result = "XQST0040"; break;
244         case XQST0042: result = "XQST0042"; break;
245         case XQST0043: result = "XQST0043"; break;
246         case XQST0045: result = "XQST0045"; break;
247         case XQST0046: result = "XQST0046"; break;
248         case XQST0047: result = "XQST0047"; break;
249         case XQST0048: result = "XQST0048"; break;
250         case XQST0049: result = "XQST0049"; break;
251         case XQST0053: result = "XQST0053"; break;
252         case XQST0054: result = "XQST0054"; break;
253         case XQST0055: result = "XQST0055"; break;
254         case XQST0056: result = "XQST0056"; break;
255         case XQST0057: result = "XQST0057"; break;
256         case XQST0058: result = "XQST0058"; break;
257         case XQST0059: result = "XQST0059"; break;
258         case XQST0060: result = "XQST0060"; break;
259         case XQST0063: result = "XQST0063"; break;
260         case XQST0065: result = "XQST0065"; break;
261         case XQST0066: result = "XQST0066"; break;
262         case XQST0067: result = "XQST0067"; break;
263         case XQST0068: result = "XQST0068"; break;
264         case XQST0069: result = "XQST0069"; break;
265         case XQST0070: result = "XQST0070"; break;
266         case XQST0071: result = "XQST0071"; break;
267         case XQST0073: result = "XQST0073"; break;
268         case XQST0075: result = "XQST0075"; break;
269         case XQST0076: result = "XQST0076"; break;
270         case XQST0077: result = "XQST0077"; break;
271         case XQST0078: result = "XQST0078"; break;
272         case XQST0079: result = "XQST0079"; break;
273         case XQST0082: result = "XQST0082"; break;
274         case XQST0085: result = "XQST0085"; break;
275         case XQST0087: result = "XQST0087"; break;
276         case XQST0088: result = "XQST0088"; break;
277         case XQST0089: result = "XQST0089"; break;
278         case XQST0090: result = "XQST0090"; break;
279         case XQST0093: result = "XQST0093"; break;
280         case XQTY0023: result = "XQTY0023"; break;
281         case XQTY0024: result = "XQTY0024"; break;
282         case XQTY0028: result = "XQTY0028"; break;
283         case XQTY0030: result = "XQTY0030"; break;
284         case XQTY0086: result = "XQTY0086"; break;
285         case XTDE0030: result = "XTDE0030"; break;
286         case XTDE0040: result = "XTDE0040"; break;
287         case XTDE0045: result = "XTDE0045"; break;
288         case XTDE0047: result = "XTDE0047"; break;
289         case XTDE0050: result = "XTDE0050"; break;
290         case XTDE0060: result = "XTDE0060"; break;
291         case XTDE0160: result = "XTDE0160"; break;
292         case XTDE0290: result = "XTDE0290"; break;
293         case XTDE0410: result = "XTDE0410"; break;
294         case XTDE0420: result = "XTDE0420"; break;
295         case XTDE0430: result = "XTDE0430"; break;
296         case XTDE0440: result = "XTDE0440"; break;
297         case XTDE0485: result = "XTDE0485"; break;
298         case XTDE0560: result = "XTDE0560"; break;
299         case XTDE0610: result = "XTDE0610"; break;
300         case XTDE0640: result = "XTDE0640"; break;
301         case XTDE0700: result = "XTDE0700"; break;
302         case XTDE0820: result = "XTDE0820"; break;
303         case XTDE0830: result = "XTDE0830"; break;
304         case XTDE0835: result = "XTDE0835"; break;
305         case XTDE0850: result = "XTDE0850"; break;
306         case XTDE0855: result = "XTDE0855"; break;
307         case XTDE0860: result = "XTDE0860"; break;
308         case XTDE0865: result = "XTDE0865"; break;
309         case XTDE0890: result = "XTDE0890"; break;
310         case XTDE0905: result = "XTDE0905"; break;
311         case XTDE0920: result = "XTDE0920"; break;
312         case XTDE0925: result = "XTDE0925"; break;
313         case XTDE0930: result = "XTDE0930"; break;
314         case XTDE0980: result = "XTDE0980"; break;
315         case XTDE1030: result = "XTDE1030"; break;
316         case XTDE1035: result = "XTDE1035"; break;
317         case XTDE1110: result = "XTDE1110"; break;
318         case XTDE1140: result = "XTDE1140"; break;
319         case XTDE1145: result = "XTDE1145"; break;
320         case XTDE1150: result = "XTDE1150"; break;
321         case XTDE1170: result = "XTDE1170"; break;
322         case XTDE1190: result = "XTDE1190"; break;
323         case XTDE1200: result = "XTDE1200"; break;
324         case XTDE1260: result = "XTDE1260"; break;
325         case XTDE1270: result = "XTDE1270"; break;
326         case XTDE1280: result = "XTDE1280"; break;
327         case XTDE1310: result = "XTDE1310"; break;
328         case XTDE1340: result = "XTDE1340"; break;
329         case XTDE1350: result = "XTDE1350"; break;
330         case XTDE1360: result = "XTDE1360"; break;
331         case XTDE1370: result = "XTDE1370"; break;
332         case XTDE1380: result = "XTDE1380"; break;
333         case XTDE1390: result = "XTDE1390"; break;
334         case XTDE1400: result = "XTDE1400"; break;
335         case XTDE1420: result = "XTDE1420"; break;
336         case XTDE1425: result = "XTDE1425"; break;
337         case XTDE1428: result = "XTDE1428"; break;
338         case XTDE1440: result = "XTDE1440"; break;
339         case XTDE1450: result = "XTDE1450"; break;
340         case XTDE1460: result = "XTDE1460"; break;
341         case XTDE1480: result = "XTDE1480"; break;
342         case XTDE1490: result = "XTDE1490"; break;
343         case XTDE1665: result = "XTDE1665"; break;
344         case XTMM9000: result = "XTMM9000"; break;
345         case XTRE0270: result = "XTRE0270"; break;
346         case XTRE0540: result = "XTRE0540"; break;
347         case XTRE0795: result = "XTRE0795"; break;
348         case XTRE1160: result = "XTRE1160"; break;
349         case XTRE1495: result = "XTRE1495"; break;
350         case XTRE1500: result = "XTRE1500"; break;
351         case XTRE1620: result = "XTRE1620"; break;
352         case XTRE1630: result = "XTRE1630"; break;
353         case XTSE0010: result = "XTSE0010"; break;
354         case XTSE0020: result = "XTSE0020"; break;
355         case XTSE0080: result = "XTSE0080"; break;
356         case XTSE0090: result = "XTSE0090"; break;
357         case XTSE0110: result = "XTSE0110"; break;
358         case XTSE0120: result = "XTSE0120"; break;
359         case XTSE0125: result = "XTSE0125"; break;
360         case XTSE0130: result = "XTSE0130"; break;
361         case XTSE0150: result = "XTSE0150"; break;
362         case XTSE0165: result = "XTSE0165"; break;
363         case XTSE0170: result = "XTSE0170"; break;
364         case XTSE0180: result = "XTSE0180"; break;
365         case XTSE0190: result = "XTSE0190"; break;
366         case XTSE0200: result = "XTSE0200"; break;
367         case XTSE0210: result = "XTSE0210"; break;
368         case XTSE0215: result = "XTSE0215"; break;
369         case XTSE0220: result = "XTSE0220"; break;
370         case XTSE0260: result = "XTSE0260"; break;
371         case XTSE0265: result = "XTSE0265"; break;
372         case XTSE0280: result = "XTSE0280"; break;
373         case XTSE0340: result = "XTSE0340"; break;
374         case XTSE0350: result = "XTSE0350"; break;
375         case XTSE0370: result = "XTSE0370"; break;
376         case XTSE0500: result = "XTSE0500"; break;
377         case XTSE0530: result = "XTSE0530"; break;
378         case XTSE0550: result = "XTSE0550"; break;
379         case XTSE0580: result = "XTSE0580"; break;
380         case XTSE0620: result = "XTSE0620"; break;
381         case XTSE0630: result = "XTSE0630"; break;
382         case XTSE0650: result = "XTSE0650"; break;
383         case XTSE0660: result = "XTSE0660"; break;
384         case XTSE0670: result = "XTSE0670"; break;
385         case XTSE0680: result = "XTSE0680"; break;
386         case XTSE0690: result = "XTSE0690"; break;
387         case XTSE0710: result = "XTSE0710"; break;
388         case XTSE0720: result = "XTSE0720"; break;
389         case XTSE0740: result = "XTSE0740"; break;
390         case XTSE0760: result = "XTSE0760"; break;
391         case XTSE0770: result = "XTSE0770"; break;
392         case XTSE0805: result = "XTSE0805"; break;
393         case XTSE0808: result = "XTSE0808"; break;
394         case XTSE0809: result = "XTSE0809"; break;
395         case XTSE0810: result = "XTSE0810"; break;
396         case XTSE0812: result = "XTSE0812"; break;
397         case XTSE0840: result = "XTSE0840"; break;
398         case XTSE0870: result = "XTSE0870"; break;
399         case XTSE0880: result = "XTSE0880"; break;
400         case XTSE0910: result = "XTSE0910"; break;
401         case XTSE0940: result = "XTSE0940"; break;
402         case XTSE0975: result = "XTSE0975"; break;
403         case XTSE1015: result = "XTSE1015"; break;
404         case XTSE1017: result = "XTSE1017"; break;
405         case XTSE1040: result = "XTSE1040"; break;
406         case XTSE1060: result = "XTSE1060"; break;
407         case XTSE1070: result = "XTSE1070"; break;
408         case XTSE1080: result = "XTSE1080"; break;
409         case XTSE1090: result = "XTSE1090"; break;
410         case XTSE1130: result = "XTSE1130"; break;
411         case XTSE1205: result = "XTSE1205"; break;
412         case XTSE1210: result = "XTSE1210"; break;
413         case XTSE1220: result = "XTSE1220"; break;
414         case XTSE1290: result = "XTSE1290"; break;
415         case XTSE1295: result = "XTSE1295"; break;
416         case XTSE1300: result = "XTSE1300"; break;
417         case XTSE1430: result = "XTSE1430"; break;
418         case XTSE1505: result = "XTSE1505"; break;
419         case XTSE1520: result = "XTSE1520"; break;
420         case XTSE1530: result = "XTSE1530"; break;
421         case XTSE1560: result = "XTSE1560"; break;
422         case XTSE1570: result = "XTSE1570"; break;
423         case XTSE1580: result = "XTSE1580"; break;
424         case XTSE1590: result = "XTSE1590"; break;
425         case XTSE1600: result = "XTSE1600"; break;
426         case XTSE1650: result = "XTSE1650"; break;
427         case XTSE1660: result = "XTSE1660"; break;
428         case XTTE0505: result = "XTTE0505"; break;
429         case XTTE0510: result = "XTTE0510"; break;
430         case XTTE0520: result = "XTTE0520"; break;
431         case XTTE0570: result = "XTTE0570"; break;
432         case XTTE0590: result = "XTTE0590"; break;
433         case XTTE0600: result = "XTTE0600"; break;
434         case XTTE0780: result = "XTTE0780"; break;
435         case XTTE0790: result = "XTTE0790"; break;
436         case XTTE0950: result = "XTTE0950"; break;
437         case XTTE0990: result = "XTTE0990"; break;
438         case XTTE1000: result = "XTTE1000"; break;
439         case XTTE1020: result = "XTTE1020"; break;
440         case XTTE1100: result = "XTTE1100"; break;
441         case XTTE1120: result = "XTTE1120"; break;
442         case XTTE1510: result = "XTTE1510"; break;
443         case XTTE1512: result = "XTTE1512"; break;
444         case XTTE1515: result = "XTTE1515"; break;
445         case XTTE1540: result = "XTTE1540"; break;
446         case XTTE1545: result = "XTTE1545"; break;
447         case XTTE1550: result = "XTTE1550"; break;
448         case XTTE1555: result = "XTTE1555"; break;
449         case XSDError: result = "XSDError"; break;
450     }
451 
452     Q_ASSERT_X(result, Q_FUNC_INFO, "Unknown enum value.");
453     return QLatin1String(result);
454 }
455 
resolveURI(const QUrl & relative,const QUrl & baseURI) const456 QUrl ReportContext::resolveURI(const QUrl &relative,
457                                const QUrl &baseURI) const
458 {
459     Q_ASSERT_X(!baseURI.isRelative(), Q_FUNC_INFO,
460                "The base URI passed from the engine wasn't absolute.");
461 
462     const QAbstractUriResolver *const resolver(uriResolver());
463 
464     if(resolver)
465     {
466         const QUrl final(resolver->resolve(relative, baseURI));
467         Q_ASSERT_X(final.isValid() || final.isEmpty(), Q_FUNC_INFO,
468                    "The QAbstractUriResolver must return a valid URI.");
469         Q_ASSERT_X(!final.isRelative(), Q_FUNC_INFO,
470                    "The QAbstractUriResolver must return an absolute URI.");
471         return final;
472     }
473     else
474         return baseURI.resolved(relative);
475 }
476 
477 QT_END_NAMESPACE
478