/* SPDX-FileCopyrightText: 2005 Tobias Koenig SPDX-License-Identifier: MIT */ #include "definitions.h" #include #include #include #include #include #include #include #include "../src/settings.h" #include #include using namespace KWSDL; Definitions::Definitions() { } Definitions::~Definitions() { } void Definitions::setName(const QString &name) { mName = name; } QString Definitions::name() const { return mName; } void Definitions::setTargetNamespace(const QString &targetNamespace) { mTargetNamespace = targetNamespace; mType.setNameSpace(mTargetNamespace); } QString Definitions::targetNamespace() const { return mTargetNamespace; } #if 0 void Definitions::setBindings(const Binding::List &bindings) { mBindings = bindings; } #endif Binding::List Definitions::bindings() const { return mBindings; } #if 0 void Definitions::setImports(const Import::List &imports) { mImports = imports; } Import::List Definitions::imports() const { return mImports; } #endif void Definitions::setMessages(const Message::List &messages) { mMessages = messages; } Message::List Definitions::messages() const { return mMessages; } void Definitions::setPortTypes(const PortType::List &portTypes) { mPortTypes = portTypes; } PortType::List Definitions::portTypes() const { return mPortTypes; } #if 0 void Definitions::setService(const Service &service) { mService = service; } #endif Service::List Definitions::services() const { return mServices; } void Definitions::setType(const Type &type) { mType = type; } Type Definitions::type() const { return mType; } bool Definitions::loadXML(ParserContext *context, const QDomElement &element) { setTargetNamespace(element.attribute(QLatin1String("targetNamespace"))); mName = element.attribute(QLatin1String("name")); context->namespaceManager()->enterChild(element); QDomElement child = element.firstChildElement(); while (!child.isNull()) { NSManager namespaceManager(context, child); const QName tagName(child.tagName()); if (tagName.localName() == QLatin1String("import")) { QString oldTn = targetNamespace(); QString oldName = mName; importDefinition(context, child.attribute(QLatin1String("location"))); setTargetNamespace(oldTn); mName = std::move(oldName); } else if (tagName.localName() == QLatin1String("types")) { if (!mType.loadXML(context, child)) { return false; } } else if (tagName.localName() == QLatin1String("message")) { Message message(mTargetNamespace); message.loadXML(context, child); // qDebug() << "Definitions: found message" << message.name() << message.nameSpace(); mMessages.append(message); } else if (tagName.localName() == QLatin1String("portType")) { PortType portType(mTargetNamespace); portType.loadXML(context, child); mPortTypes.append(portType); } else if (tagName.localName() == QLatin1String("binding")) { Binding binding(mTargetNamespace); binding.loadXML(context, child); mBindings.append(binding); } else if (tagName.localName() == QLatin1String("service")) { const QString name = child.attribute(QLatin1String("name")); // qDebug() << "Service:" << name << "looking for" << mWantedService; // is this the service we want? if (mWantedService.isEmpty() || mWantedService == name) { Service service(mTargetNamespace); service.loadXML(context, &mBindings, child); mServices.append(service); } } else if (tagName.localName() == QLatin1String("documentation")) { // ignore documentation for now } else { context->messageHandler()->warning(QString::fromLatin1("Definitions: unknown tag %1").arg(child.tagName())); } child = child.nextSiblingElement(); } return true; } void Definitions::fixUpDefinitions(/*ParserContext *context, const QDomElement &element */) { if (mServices.isEmpty()) { if (!mBindings.isEmpty()) { qDebug() << "No service tag found in the wsdl file, generating one service per binding"; for (const Binding &bind : std::as_const(mBindings)) { Service service(mTargetNamespace); service.setName(bind.name() + "Service"); Port port(mTargetNamespace); port.setName(bind.name() + "Port"); QName bindingName(bind.portTypeName().prefix() + ":" + bind.name()); bindingName.setNameSpace(bind.nameSpace()); port.setBindingName(bindingName); Port::List portList; portList.append(port); service.setPorts(portList); mServices.append(service); } } else { Q_ASSERT(!mPortTypes.isEmpty()); qDebug() << "No service or binding tag found in the wsdl file, generating only messages"; for (const PortType &portType : std::as_const(mPortTypes)) { Binding binding(mTargetNamespace); binding.setName(portType.name() + "Binding"); binding.setPortTypeName(QName(portType.nameSpace(), portType.name())); binding.setType(Binding::UnknownBinding); mBindings.append(binding); Port port(mTargetNamespace); port.setName(portType.name()); port.setBindingName(QName(binding.nameSpace(), binding.name())); Service service(mTargetNamespace); service.setName(portType.name() + "Service"); service.setPorts(Port::List() << port); mServices.append(service); } } } } static QUrl urlForLocation(ParserContext *context, const QString &location) { QUrl url(location); if ((url.scheme().isEmpty() || url.scheme() == QLatin1String("file"))) { QDir dir(location); if (dir.isRelative()) { url = context->documentBaseUrl(); url.setPath(url.path() + QLatin1Char('/') + location); } } return url; } void Definitions::importDefinition(ParserContext *context, const QString &location) { if (location.isEmpty()) { context->messageHandler()->warning(QString::fromLatin1("Definitions import: location tag required: %1").arg(location)); return; } FileProvider provider(Settings::self()->useLocalFilesOnly(), Settings::self()->importPathList()); QString fileName; const QUrl locationUrl = urlForLocation(context, location); qDebug("Importing wsdl definition at %s", locationUrl.toEncoded().constData()); if (provider.get(locationUrl, fileName)) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { qDebug("Unable to open file %s", qPrintable(file.fileName())); return; } QDomDocument doc(QLatin1String("kwsdl")); QString errorMsg; int errorLine, errorColumn; bool ok = doc.setContent(&file, false, &errorMsg, &errorLine, &errorColumn); if (!ok) { qDebug("Error[%d:%d] %s", errorLine, errorColumn, qPrintable(errorMsg)); return; } // prepare the new context to avoid infinite recursion QDomElement rootNode = doc.documentElement(); NSManager namespaceManager(context, rootNode); const QName tagName(rootNode.tagName()); if (tagName.localName() == QLatin1String("definitions")) { // recursivity context->namespaceManager()->enterChild(rootNode); const QUrl oldBaseUrl = context->documentBaseUrl(); context->setDocumentBaseUrlFromFileUrl(locationUrl); loadXML(context, rootNode); context->setDocumentBaseUrl(oldBaseUrl); } else { qDebug("No definition tag found in imported wsdl file %s", locationUrl.toEncoded().constData()); } file.close(); provider.cleanUp(); } } #if 0 void Definitions::saveXML(ParserContext *context, QDomDocument &document) const { QDomElement element = document.createElement("definitions"); document.appendChild(element); if (!mTargetNamespace.isEmpty()) { element.setAttribute("targetNamespace", mTargetNamespace); } if (!mName.isEmpty()) { element.setAttribute("name", mName); } { Import::List::ConstIterator it(mImports.begin()); const Import::List::ConstIterator endIt(mImports.end()); for (; it != endIt; ++it) { (*it).saveXML(context, document, element); } } mType.saveXML(context, document, element); { Message::List::ConstIterator it(mMessages.begin()); const Message::List::ConstIterator endIt(mMessages.end()); for (; it != endIt; ++it) { (*it).saveXML(context, document, element); } } { PortType::List::ConstIterator it(mPortTypes.begin()); const PortType::List::ConstIterator endIt(mPortTypes.end()); for (; it != endIt; ++it) { (*it).saveXML(context, document, element); } } { Binding::List::ConstIterator it(mBindings.begin()); const Binding::List::ConstIterator endIt(mBindings.end()); for (; it != endIt; ++it) { (*it).saveXML(context, document, element); } } mService.saveXML(context, &mBindings, document, element); } #endif void Definitions::setWantedService(const QString &name) { mWantedService = name; }