Bläddra i källkod

Merge topic 'dah-exchange-data-implementation' into dah

* dah-exchange-data-implementation:
  ctkDicomAbstractApp::setState - Move comment from cpp to header file
  Extends ctkDicomAbstract{Host,App} with publishData convenient method
  Add ctkDicomObjectLocatorCache
  Add missing Q_INTERFACES to ctkDicomAbstractApp
Jean-Christophe Fillion-Robin 14 år sedan
förälder
incheckning
1022b4fda0

+ 34 - 11
Plugins/org.commontk.dah.app/ctkDicomAbstractApp.cpp

@@ -22,6 +22,7 @@
 // CTK includes
 #include "ctkDicomAbstractApp.h"
 #include <ctkDicomHostInterface.h>
+#include <ctkDicomObjectLocatorCache.h>
 #include <ctkPluginContext.h>
 #include <ctkServiceTracker.h>
 
@@ -29,10 +30,11 @@ class ctkDicomAbstractAppPrivate
 {
 public:
   ctkDicomAbstractAppPrivate(ctkPluginContext* context);
-  ~ctkDicomAbstractAppPrivate();
 
   ctkServiceTracker<ctkDicomHostInterface*> HostTracker;
   ctkDicomAppHosting::State currentState;
+
+  ctkDicomObjectLocatorCache ObjectLocatorCache;
 };
 
 //----------------------------------------------------------------------------
@@ -45,11 +47,6 @@ ctkDicomAbstractAppPrivate::ctkDicomAbstractAppPrivate(ctkPluginContext * contex
 }
 
 //----------------------------------------------------------------------------
-ctkDicomAbstractAppPrivate::~ctkDicomAbstractAppPrivate()
-{
-}
-
-//----------------------------------------------------------------------------
 // ctkDicomAbstractApp methods
 
 //----------------------------------------------------------------------------
@@ -63,10 +60,7 @@ ctkDicomAbstractApp::~ctkDicomAbstractApp()
 {
 }
 
-/**
-  * Method triggered by the host. Changes the state of the hosted application.
-  *@return true if state received and not illegal in the transition diagram from the reference, false if illegal or not recognized.
-  */
+//----------------------------------------------------------------------------
 bool ctkDicomAbstractApp::setState(ctkDicomAppHosting::State newState)
 {
   bool result = true;
@@ -145,7 +139,7 @@ bool ctkDicomAbstractApp::setState(ctkDicomAppHosting::State newState)
   return result;
 }
 
-
+//----------------------------------------------------------------------------
 ctkDicomHostInterface* ctkDicomAbstractApp::getHostInterface() const
 {
   ctkDicomHostInterface* host = d_ptr->HostTracker.getService();
@@ -153,4 +147,33 @@ ctkDicomHostInterface* ctkDicomAbstractApp::getHostInterface() const
   return host;
 }
 
+//----------------------------------------------------------------------------
+QList<ctkDicomAppHosting::ObjectLocator> ctkDicomAbstractApp::getData(
+  const QList<QUuid>& objectUUIDs,
+  const QList<QString>& acceptableTransferSyntaxUIDs,
+  bool includeBulkData)
+{
+  return this->objectLocatorCache()->getData(objectUUIDs, acceptableTransferSyntaxUIDs, includeBulkData);
+}
+
+//----------------------------------------------------------------------------
+ctkDicomObjectLocatorCache* ctkDicomAbstractApp::objectLocatorCache()const
+{
+  Q_D(const ctkDicomAbstractApp);
+  return const_cast<ctkDicomObjectLocatorCache*>(&d->ObjectLocatorCache);
+}
 
+//----------------------------------------------------------------------------
+bool ctkDicomAbstractApp::publishData(const ctkDicomAppHosting::AvailableData& availableData, bool lastData)
+{
+  if (!this->objectLocatorCache()->isCached(availableData))
+    {
+    return false;
+    }
+  bool success = this->getHostInterface()->notifyDataAvailable(availableData, lastData);
+  if(!success)
+    {
+    return false;
+    }
+  return true;
+}

+ 17 - 1
Plugins/org.commontk.dah.app/ctkDicomAbstractApp.h

@@ -29,6 +29,8 @@
 class ctkDicomAbstractAppPrivate;
 class ctkDicomHostInterface;
 class ctkPluginContext;
+class ctkDicomObjectLocatorCache;
+
 /**
   * Provides a basic implementation for an application app.
   *
@@ -40,12 +42,26 @@ class ctkPluginContext;
 class org_commontk_dah_app_EXPORT ctkDicomAbstractApp : public QObject, public ctkDicomAppInterface
 {
   Q_OBJECT
-
+  Q_INTERFACES(ctkDicomAppInterface);
 public:
 
   ctkDicomAbstractApp(ctkPluginContext* context);
   virtual ~ctkDicomAbstractApp();
+
+  /**
+    * Method triggered by the host. Changes the state of the hosted application.
+    * @return true if state received and not illegal in the transition diagram from the reference, false if illegal or not recognized.
+    */
   virtual bool setState(ctkDicomAppHosting::State newState);
+  
+  virtual QList<ctkDicomAppHosting::ObjectLocator> getData(
+    const QList<QUuid>& objectUUIDs,
+    const QList<QString>& acceptableTransferSyntaxUIDs,
+    bool includeBulkData);
+
+  ctkDicomObjectLocatorCache* objectLocatorCache()const;
+
+  bool publishData(const ctkDicomAppHosting::AvailableData& availableData, bool lastData);
 
 protected:
   virtual ctkDicomHostInterface* getHostInterface() const;

+ 1 - 0
Plugins/org.commontk.dah.core/CMakeLists.txt

@@ -11,6 +11,7 @@ SET(PLUGIN_SRCS
   ctkDicomExchangeInterface.h
   ctkDicomExchangeService.cpp
   ctkDicomHostInterface.h
+  ctkDicomObjectLocatorCache.cpp
   ctkExchangeSoapMessageProcessor.cpp
   ctkSimpleSoapClient.cpp
   ctkSimpleSoapServer.cpp

+ 2 - 2
Plugins/org.commontk.dah.core/ctkDicomExchangeInterface.h

@@ -25,10 +25,10 @@
 
 #include <QRect>
 #include <QObject>
-#include <QUuid>
-
 #include "ctkDicomAppHostingTypes.h"
 
+class QUuid;
+
 struct ctkDicomExchangeInterface
 {
 

+ 167 - 0
Plugins/org.commontk.dah.core/ctkDicomObjectLocatorCache.cpp

@@ -0,0 +1,167 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QHash>
+#include <QUuid>
+
+// CTK includes
+#include "ctkDicomAppHostingTypes.h"
+#include "ctkDicomObjectLocatorCache.h"
+
+class ctkDicomObjectLocatorCachePrivate
+{
+public:
+  ctkDicomObjectLocatorCachePrivate();
+
+  QHash<QString, ctkDicomAppHosting::ObjectLocator> ObjectLocatorMap;
+};
+
+//----------------------------------------------------------------------------
+// ctkDicomObjectLocatorCachePrivate methods
+
+//----------------------------------------------------------------------------
+ctkDicomObjectLocatorCachePrivate::ctkDicomObjectLocatorCachePrivate()
+{
+}
+
+//----------------------------------------------------------------------------
+// ctkDicomObjectLocatorCache methods
+
+//----------------------------------------------------------------------------
+ctkDicomObjectLocatorCache::ctkDicomObjectLocatorCache() : d_ptr(new ctkDicomObjectLocatorCachePrivate())
+{
+}
+
+//----------------------------------------------------------------------------
+ctkDicomObjectLocatorCache::~ctkDicomObjectLocatorCache()
+{
+}
+
+//----------------------------------------------------------------------------
+bool ctkDicomObjectLocatorCache::isCached(const ctkDicomAppHosting::AvailableData& availableData)const
+{
+  Q_D(const ctkDicomObjectLocatorCache);
+  QList<QString> uuids = d->ObjectLocatorMap.keys();
+  // Loop over top level object descriptors
+  foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, availableData.objectDescriptors)
+    {
+    if (!uuids.contains(objectDescriptor.descriptorUUID))
+      {
+      return false;
+      }
+    }
+  // Loop over patients
+  foreach(const ctkDicomAppHosting::Patient& patient, availableData.patients)
+    {
+    // Loop over patient level object descriptors
+    foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, patient.objectDescriptors)
+      {
+      if (!uuids.contains(objectDescriptor.descriptorUUID))
+        {
+        return false;
+        }
+      }
+    // Loop over studies
+    foreach(const ctkDicomAppHosting::Study& study, patient.studies)
+      {
+      // Loop over study level object descriptors
+      foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, study.objectDescriptors)
+        {
+        if (!uuids.contains(objectDescriptor.descriptorUUID))
+          {
+          return false;
+          }
+        }
+      // Loop over series
+      foreach(const ctkDicomAppHosting::Series& series, study.series)
+        {
+        // Loop over series level object descriptors
+        foreach(const ctkDicomAppHosting::ObjectDescriptor& objectDescriptor, series.objectDescriptors)
+          {
+          if (!uuids.contains(objectDescriptor.descriptorUUID))
+            {
+            return false;
+            }
+          }
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+bool ctkDicomObjectLocatorCache::find(const QString& objectUuid,
+                                         ctkDicomAppHosting::ObjectLocator& objectLocator)const
+{
+  Q_D(const ctkDicomObjectLocatorCache);
+  if (!d->ObjectLocatorMap.contains(objectUuid))
+    {
+    return false;
+    }
+  objectLocator = d->ObjectLocatorMap.value(objectUuid);
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void ctkDicomObjectLocatorCache::insert(const QString& objectUuid,
+                                        const ctkDicomAppHosting::ObjectLocator& objectLocator)
+{
+  Q_D(ctkDicomObjectLocatorCache);
+  if(d->ObjectLocatorMap.contains(objectUuid))
+    {
+    return;
+    }
+  d->ObjectLocatorMap.insert(objectUuid, objectLocator);
+}
+
+//----------------------------------------------------------------------------
+bool ctkDicomObjectLocatorCache::remove(const QString& objectUuid)
+{
+  Q_D(ctkDicomObjectLocatorCache);
+  int removed = d->ObjectLocatorMap.remove(objectUuid);
+  Q_ASSERT(removed > 1);
+  return (removed == 1);
+}
+
+//----------------------------------------------------------------------------
+QList<ctkDicomAppHosting::ObjectLocator> ctkDicomObjectLocatorCache::getData(
+  const QList<QUuid>& objectUUIDs,
+  const QList<QString>& acceptableTransferSyntaxUIDs,
+  bool includeBulkData)
+{
+  QList<ctkDicomAppHosting::ObjectLocator> objectLocators;
+  foreach(const QUuid& uuid, objectUUIDs)
+    {
+    ctkDicomAppHosting::ObjectLocator objectLocator;
+    bool found = this->find(uuid, objectLocator);
+    if (!found)
+      {
+      // What to do .. ? Create an empty objectLocator ...
+      continue;
+      }
+    if (includeBulkData)
+      {
+      Q_UNUSED(acceptableTransferSyntaxUIDs);
+      // Not implemented
+      }
+    objectLocators << objectLocator;
+    }
+  return objectLocators;
+}

+ 63 - 0
Plugins/org.commontk.dah.core/ctkDicomObjectLocatorCache.h

@@ -0,0 +1,63 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef CTKDICOMEXCHANGEIMPL_H
+#define CTKDICOMEXCHANGEIMPL_H
+
+// Qt includes
+#include <QScopedPointer>
+
+// CTK includes
+#include "ctkDicomAppHostingTypes.h"
+#include <org_commontk_dah_core_Export.h>
+
+class ctkDicomObjectLocatorCachePrivate;
+class QUuid;
+
+/**
+  *
+  */
+class org_commontk_dah_core_EXPORT ctkDicomObjectLocatorCache
+{
+
+public:
+
+  ctkDicomObjectLocatorCache();
+  virtual ~ctkDicomObjectLocatorCache();
+
+  bool isCached(const ctkDicomAppHosting::AvailableData& availableData)const;
+
+  bool find(const QString& objectUuid, ctkDicomAppHosting::ObjectLocator& objectLocator)const;
+
+  void insert(const QString& objectUuid, const ctkDicomAppHosting::ObjectLocator& objectLocator);
+
+  bool remove(const QString& objectUuid);
+
+  QList<ctkDicomAppHosting::ObjectLocator> getData(
+    const QList<QUuid>& objectUUIDs,
+    const QList<QString>& acceptableTransferSyntaxUIDs,
+    bool includeBulkData);
+
+private:
+  Q_DECLARE_PRIVATE(ctkDicomObjectLocatorCache)
+  const QScopedPointer<ctkDicomObjectLocatorCachePrivate> d_ptr;
+};
+
+#endif // CTKDICOMEXCHANGEIMPL_H

+ 4 - 0
Plugins/org.commontk.dah.exampleapp/ctkExampleDicomAppLogic_p.h

@@ -23,6 +23,10 @@
 #ifndef CTKEXAMPLEDICOMAPPLOGIC_P_H
 #define CTKEXAMPLEDICOMAPPLOGIC_P_H
 
+// Qt includes
+#include <QUuid>
+
+// CTK includes
 #include <ctkDicomAbstractApp.h>
 #include <ctkDicomHostInterface.h>
 

+ 40 - 6
Plugins/org.commontk.dah.host/ctkDicomAbstractHost.cpp

@@ -19,9 +19,11 @@
 
 =============================================================================*/
 
+// CTK includes
+#include "ctkDicomAppService.h"
 #include "ctkDicomAbstractHost.h"
 #include "ctkDicomHostServer.h"
-#include "ctkDicomAppService.h"
+#include <ctkDicomObjectLocatorCache.h>
 
 class ctkDicomAbstractHostPrivate
 {
@@ -34,6 +36,7 @@ public:
   int AppPort;
   ctkDicomHostServer* Server;
   ctkDicomAppInterface* AppService;
+  ctkDicomObjectLocatorCache ObjectLocatorCache;
   // ctkDicomAppHosting::Status
 };
 
@@ -45,11 +48,11 @@ ctkDicomAbstractHostPrivate::ctkDicomAbstractHostPrivate(
   ctkDicomAbstractHost* hostInterface, int hostPort, int appPort) : HostPort(hostPort), AppPort(appPort)
 {
   // start server
-  if (this->HostPort==0)
+  if (this->HostPort == 0)
     {
     this->HostPort = 8080;
     }
-  if (this->AppPort==0)
+  if (this->AppPort == 0)
     {
     this->AppPort = 8081;
     }
@@ -78,6 +81,11 @@ ctkDicomAbstractHost::ctkDicomAbstractHost(int hostPort, int appPort) :
 }
 
 //----------------------------------------------------------------------------
+ctkDicomAbstractHost::~ctkDicomAbstractHost()
+{
+}
+
+//----------------------------------------------------------------------------
 int ctkDicomAbstractHost::getHostPort() const
 {
   Q_D(const ctkDicomAbstractHost);
@@ -92,13 +100,39 @@ int ctkDicomAbstractHost::getAppPort() const
 }
 
 //----------------------------------------------------------------------------
-ctkDicomAbstractHost::~ctkDicomAbstractHost()
+ctkDicomAppInterface* ctkDicomAbstractHost::getDicomAppService() const
 {
+  Q_D(const ctkDicomAbstractHost);
+  return d->AppService;
 }
 
 //----------------------------------------------------------------------------
-ctkDicomAppInterface* ctkDicomAbstractHost::getDicomAppService() const
+QList<ctkDicomAppHosting::ObjectLocator> ctkDicomAbstractHost::getData(
+  const QList<QUuid>& objectUUIDs,
+  const QList<QString>& acceptableTransferSyntaxUIDs,
+  bool includeBulkData)
+{
+  return this->objectLocatorCache()->getData(objectUUIDs, acceptableTransferSyntaxUIDs, includeBulkData);
+}
+
+//----------------------------------------------------------------------------
+ctkDicomObjectLocatorCache* ctkDicomAbstractHost::objectLocatorCache()const
 {
   Q_D(const ctkDicomAbstractHost);
-  return d->AppService;
+  return const_cast<ctkDicomObjectLocatorCache*>(&d->ObjectLocatorCache);
+}
+
+//----------------------------------------------------------------------------
+bool ctkDicomAbstractHost::publishData(const ctkDicomAppHosting::AvailableData& availableData, bool lastData)
+{
+  if (!this->objectLocatorCache()->isCached(availableData))
+    {
+    return false;
+    }
+  bool success = this->getDicomAppService()->notifyDataAvailable(availableData, lastData);
+  if(!success)
+    {
+    return false;
+    }
+  return true;
 }

+ 12 - 1
Plugins/org.commontk.dah.host/ctkDicomAbstractHost.h

@@ -29,6 +29,7 @@
 #include <org_commontk_dah_host_Export.h>
 
 class ctkDicomAbstractHostPrivate;
+class ctkDicomObjectLocatorCache;
 
 /**
   * Provides a basic implementation for an application host.
@@ -48,12 +49,22 @@ public:
     * Starts the soap sever on the specified port or choose port automatically.
     */
   ctkDicomAbstractHost(int hostPort = 0, int appPort = 0);
+  virtual ~ctkDicomAbstractHost();
   int getHostPort() const;
+
   int getAppPort() const;
-  virtual ~ctkDicomAbstractHost();
 
   ctkDicomAppInterface* getDicomAppService() const;
 
+  virtual QList<ctkDicomAppHosting::ObjectLocator> getData(
+    const QList<QUuid>& objectUUIDs,
+    const QList<QString>& acceptableTransferSyntaxUIDs,
+    bool includeBulkData);
+
+  ctkDicomObjectLocatorCache* objectLocatorCache()const;
+
+  bool publishData(const ctkDicomAppHosting::AvailableData& availableData, bool lastData);
+
 private:
 
   Q_DECLARE_PRIVATE(ctkDicomAbstractHost)