ctkCmdLineModuleManager.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #include "ctkCmdLineModuleManager.h"
  16. #include "ctkCmdLineModuleBackend.h"
  17. #include "ctkCmdLineModuleFrontend.h"
  18. #include "ctkCmdLineModuleFuture.h"
  19. #include "ctkCmdLineModuleXmlValidator.h"
  20. #include "ctkCmdLineModuleReference.h"
  21. #include "ctkCmdLineModuleReference_p.h"
  22. #include <ctkException.h>
  23. #include <QStringList>
  24. #include <QBuffer>
  25. #include <QUrl>
  26. #include <QHash>
  27. #include <QList>
  28. #include <QFuture>
  29. struct ctkCmdLineModuleManagerPrivate
  30. {
  31. ctkCmdLineModuleManagerPrivate(ctkCmdLineModuleManager::ValidationMode mode)
  32. : ValidationMode(mode)
  33. {}
  34. void checkBackends(const QUrl& location)
  35. {
  36. if (!this->SchemeToBackend.contains(location.scheme()))
  37. {
  38. throw ctkInvalidArgumentException(QString("No suitable backend registered for module at ") + location.toString());
  39. }
  40. }
  41. QHash<QString, ctkCmdLineModuleBackend*> SchemeToBackend;
  42. QHash<QUrl, ctkCmdLineModuleReference> LocationToRef;
  43. ctkCmdLineModuleManager::ValidationMode ValidationMode;
  44. };
  45. ctkCmdLineModuleManager::ctkCmdLineModuleManager(ValidationMode validationMode)
  46. : d(new ctkCmdLineModuleManagerPrivate(validationMode))
  47. {
  48. }
  49. ctkCmdLineModuleManager::~ctkCmdLineModuleManager()
  50. {
  51. }
  52. void ctkCmdLineModuleManager::registerBackend(ctkCmdLineModuleBackend *backend)
  53. {
  54. QList<QString> supportedSchemes = backend->schemes();
  55. // Check if there is already a backound registerd for any of the
  56. // supported schemes. We only supported one backend per scheme.
  57. foreach (QString scheme, supportedSchemes)
  58. {
  59. if (d->SchemeToBackend.contains(scheme))
  60. {
  61. throw ctkInvalidArgumentException(QString("A backend for scheme %1 is already registered.").arg(scheme));
  62. }
  63. }
  64. // All good
  65. foreach (QString scheme, supportedSchemes)
  66. {
  67. d->SchemeToBackend[scheme] = backend;
  68. }
  69. }
  70. ctkCmdLineModuleReference
  71. ctkCmdLineModuleManager::registerModule(const QUrl &location)
  72. {
  73. d->checkBackends(location);
  74. QByteArray xml = d->SchemeToBackend[location.scheme()]->rawXmlDescription(location);
  75. if (xml.isEmpty())
  76. {
  77. throw ctkInvalidArgumentException(QString("No XML output available from ") + location.toString());
  78. }
  79. ctkCmdLineModuleReference ref;
  80. ref.d->Location = location;
  81. ref.d->RawXmlDescription = xml;
  82. ref.d->Backend = d->SchemeToBackend[location.scheme()];
  83. if (d->ValidationMode != SKIP_VALIDATION)
  84. {
  85. // validate the outputted xml description
  86. QBuffer input(&xml);
  87. input.open(QIODevice::ReadOnly);
  88. ctkCmdLineModuleXmlValidator validator(&input);
  89. if (!validator.validateInput())
  90. {
  91. if (d->ValidationMode == STRICT_VALIDATION)
  92. {
  93. throw ctkInvalidArgumentException(QString("Validating module at %1 failed: %2")
  94. .arg(location.toString()).arg(validator.errorString()));
  95. }
  96. else
  97. {
  98. ref.d->XmlValidationErrorString = validator.errorString();
  99. }
  100. }
  101. }
  102. d->LocationToRef[location] = ref;
  103. emit moduleRegistered(ref);
  104. return ref;
  105. }
  106. void ctkCmdLineModuleManager::unregisterModule(const ctkCmdLineModuleReference& ref)
  107. {
  108. d->LocationToRef.remove(ref.location());
  109. emit moduleUnregistered(ref);
  110. }
  111. ctkCmdLineModuleReference ctkCmdLineModuleManager::moduleReference(const QUrl &location) const
  112. {
  113. return d->LocationToRef[location];
  114. }
  115. QList<ctkCmdLineModuleReference> ctkCmdLineModuleManager::moduleReferences() const
  116. {
  117. return d->LocationToRef.values();
  118. }
  119. ctkCmdLineModuleFuture ctkCmdLineModuleManager::run(ctkCmdLineModuleFrontend *frontend)
  120. {
  121. d->checkBackends(frontend->location());
  122. ctkCmdLineModuleFuture future = d->SchemeToBackend[frontend->location().scheme()]->run(frontend);
  123. frontend->setFuture(future);
  124. return future;
  125. }