File: nsmanager.cpp

package info (click to toggle)
libkode 0.0~git20241211.68f9908-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 636 kB
  • sloc: cpp: 6,612; makefile: 5
file content (195 lines) | stat: -rw-r--r-- 5,921 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
    This file is part of KDE.

    Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
 */

#include "nsmanager.h"
#include "parsercontext.h"

#include <QDebug>
#include <QDomElement>

// maybe port to QXmlNamespaceSupport?

NSManager::NSManager() : mContext(nullptr), mParentManager(nullptr) {}

NSManager::NSManager(ParserContext *context, const QDomElement &child)
{
    mContext = context;
    mParentManager = context->namespaceManager();
    mMap = mParentManager->mMap;
    mCurrentNamespace = mParentManager->mCurrentNamespace;
    enterChild(child);
    mContext->setNamespaceManager(this);
}

NSManager::~NSManager()
{
    // Restore parent namespaces
    if (mContext) {
        mContext->setNamespaceManager(mParentManager);

        // Remember the prefixes used for the namespaces, even afterwards
        // qDebug() << this << "adding prefixes into parent manager" << mParentManager;
        mParentManager->addPrefixes(mMap);
    }
}

void NSManager::setCurrentNamespace(const QString &uri)
{
    mCurrentNamespace = uri;
}

void NSManager::setPrefix(const QString &prefix, const QString &uri)
{
    mMap.insert(prefix, uri);
}

QString NSManager::prefix(const QString &uri) const
{
    // Note that it's allowed to have two prefixes for the same namespace uri.
    // So we just pick one.
    QString pref = mMap.key(uri); // linear search
    if (pref.isEmpty() && uri != "http://schemas.xmlsoap.org/wsdl/") {
        qWarning() << "WARNING: No prefix found for" << uri;
    }
    return pref;
}

QString NSManager::uri(const QString &prefix) const
{
    if (prefix.isEmpty())
        return mCurrentNamespace;
    return mMap.value(prefix);
}

void NSManager::splitName(const QString &qname, QString &prefix, QString &localname) const
{
    int pos = qname.indexOf(QLatin1Char(':'));
    if (pos != -1) {
        prefix = qname.left(pos);
        localname = qname.mid(pos + 1);
    } else {
        prefix = QString();
        localname = qname;
    }
}

QString NSManager::fullName(const QString &nameSpace, const QString &localname) const
{
    if (prefix(nameSpace).isEmpty())
        return localname;
    else
        return prefix(nameSpace) + QLatin1Char(':') + localname;
}

QString NSManager::fullName(const QName &name) const
{
    return fullName(name.nameSpace(), name.localName());
}

QStringList NSManager::prefixes() const
{
    return mMap.keys();
}

QMap<QString, QString> NSManager::prefixMap() const
{
    return mMap;
}

void NSManager::addPrefixes(const QMap<QString, QString> &prefixes)
{
    for (QMap<QString, QString>::const_iterator it = prefixes.constBegin();
         it != prefixes.constEnd(); ++it) {
        const QString &prefix = it.key();
        const QString &ns = it.value();
        // Only write down this prefix if we don't have it yet
        // and if we don't have another prefix for this NS (this is mostly for backwards compat,
        // so that msexchange still uses TNS rather than 'M' or 'T'...)
        if (!mMap.contains(prefix) && mMap.key(ns).isEmpty())
            mMap.insert(prefix, ns);
    }
}

QStringList NSManager::soapEncNamespaces()
{
    return QStringList() << QLatin1String("http://schemas.xmlsoap.org/soap/encoding/")
                         << QLatin1String("http://www.w3.org/2003/05/soap-encoding");
}

QStringList NSManager::soapNamespaces()
{
    return QStringList() << QLatin1String("http://schemas.xmlsoap.org/wsdl/soap/")
                         << QLatin1String("http://schemas.xmlsoap.org/wsdl/soap12/");
}

QString NSManager::xmlNamespace()
{
    return QLatin1String("http://www.w3.org/XML/1998/namespace");
}

void NSManager::reset()
{
    mMap.clear();
}

void NSManager::dump() const
{
    QMap<QString, QString>::ConstIterator it;
    for (it = mMap.begin(); it != mMap.end(); ++it) {
        qDebug("%s\t%s", qPrintable(it.key()), qPrintable(it.value()));
    }
}

QString NSManager::nameSpace(const QDomElement &element) const
{
    if (!element.namespaceURI().isEmpty()) // namespace support was enabled in QDom: easy
        return element.namespaceURI();

    QString prefix, localname;
    splitName(element.tagName(), prefix, localname);
    return uri(prefix);
}

QString NSManager::localName(const QDomElement &element) const
{
    if (!element.namespaceURI().isEmpty()) // namespace support was enabled in QDom: easy
        return element.localName();

    QString prefix, localname;
    splitName(element.tagName(), prefix, localname);
    return localname;
}

void NSManager::enterChild(const QDomElement &element)
{
    const QDomNamedNodeMap attributes = element.attributes();
    for (int i = 0; i < attributes.count(); ++i) {
        QDomAttr attribute = attributes.item(i).toAttr();
        if (attribute.name().startsWith(QLatin1String("xmlns:"))) {
            QString prefix = attribute.name().mid(6);
            // if (prefix == "tns")
            //    qDebug() << this << "enterChild: setting tns to" << attribute.value();
            setPrefix(prefix, attribute.value());
        } else if (attribute.name() == QLatin1String("xmlns")) {
            setCurrentNamespace(attribute.value());
        }
    }
}