瀏覽代碼

Make schema type customizable per object again.

Sascha Zelzer 11 年之前
父節點
當前提交
e7912730aa

+ 1 - 0
Libs/XNAT/Core/CMakeLists.txt

@@ -9,6 +9,7 @@ set(KIT_export_directive "CTK_XNAT_CORE_EXPORT")
 set(KIT_SRCS
   ctkXnatAPI.cpp
   ctkXnatDataModel.cpp
+  ctkXnatDefaultSchemaTypes.cpp
   ctkXnatException.cpp
   ctkXnatExperiment.cpp
   ctkXnatFile.cpp

+ 0 - 1
Libs/XNAT/Core/ctkXnatAPI.cpp

@@ -114,7 +114,6 @@ QList<QVariantMap> ctkXnatAPI::parseJsonResponse(qRestResult* restResult, const
 
   // e.g. {"ResultSet":{"Result": [{"p1":"v1","p2":"v2",...}], "totalRecords":"13"}}
   QScriptValue resultSet = scriptValue.property("ResultSet");
-  QScriptValue dataLength = resultSet.property("totalRecords");
   QScriptValue data = resultSet.property("Result");
   if (!data.isObject())
     {

+ 3 - 1
Libs/XNAT/Core/ctkXnatDataModel.cpp

@@ -24,6 +24,7 @@
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatSession.h"
 #include "ctkXnatProject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 #include <QDebug>
 
@@ -75,7 +76,8 @@ void ctkXnatDataModel::fetchImpl()
   QString projectsUri("/data/archive/projects");
 
   QUuid queryId = d->session->httpGet(projectsUri);
-  QList<ctkXnatObject*> projects = d->session->httpResults(queryId, ctkXnatProject::staticSchemaType());
+  QList<ctkXnatObject*> projects = d->session->httpResults(queryId,
+                                                           ctkXnatDefaultSchemaTypes::XSI_PROJECT);
 
   qDebug() << "ctkXnatDataModel::fetchImpl(): project number:" << projects.size();
 

+ 0 - 2
Libs/XNAT/Core/ctkXnatDataModel.h

@@ -35,8 +35,6 @@ class ctkXnatDataModel : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatDataModel, ctkXnatObject, "https://central.xnat.org/schemas/xnat/xnat.xsd")
-
   ctkXnatDataModel(ctkXnatSession* connection);
 
   QList<ctkXnatProject*> projects() const;

+ 31 - 0
Libs/XNAT/Core/ctkXnatDefaultSchemaTypes.cpp

@@ -0,0 +1,31 @@
+/*=============================================================================
+
+  Library: XNAT/Core
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  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.apache.org/licenses/LICENSE-2.0
+
+  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.
+
+=============================================================================*/
+
+#include "ctkXnatDefaultSchemaTypes.h"
+
+QString ctkXnatDefaultSchemaTypes::XSI_EXPERIMENT = "xnat:experimentData";
+QString ctkXnatDefaultSchemaTypes::XSI_FILE = "xnat:abstractResource";
+QString ctkXnatDefaultSchemaTypes::XSI_PROJECT = "xnat:projectData";
+QString ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION = "xnat:reconstructedImageData";
+QString ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION_RESOURCE = "xnat:reconstructionResource";
+QString ctkXnatDefaultSchemaTypes::XSI_SCAN = "xnat:imageScanData";
+QString ctkXnatDefaultSchemaTypes::XSI_SCAN_RESOURCE = "xnat:scanResource";
+QString ctkXnatDefaultSchemaTypes::XSI_SUBJECT = "xnat:subjectData";

+ 41 - 0
Libs/XNAT/Core/ctkXnatDefaultSchemaTypes.h

@@ -0,0 +1,41 @@
+/*=============================================================================
+
+  Library: XNAT/Core
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  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.apache.org/licenses/LICENSE-2.0
+
+  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 CTKXNATDEFAULTSCHEMATYPES_H
+#define CTKXNATDEFAULTSCHEMATYPES_H
+
+#include "ctkXNATCoreExport.h"
+
+#include <QString>
+
+struct CTK_XNAT_CORE_EXPORT ctkXnatDefaultSchemaTypes
+{
+  static QString XSI_EXPERIMENT; // = "xnat:experimentData"
+  static QString XSI_FILE; // = "xnat:abstractResource"
+  static QString XSI_PROJECT; // = "xnat:projectData"
+  static QString XSI_RECONSTRUCTION; // = "xnat:reconstructedImageData"
+  static QString XSI_RECONSTRUCTION_RESOURCE; // = "xnat:reconstructionResource"
+  static QString XSI_SCAN; // = "xnat:imageScanData"
+  static QString XSI_SCAN_RESOURCE; // = "xnat:scanResource"
+  static QString XSI_SUBJECT; // = "xnat:subjectData"
+};
+
+#endif // CTKXNATDEFAULTSCHEMATYPES_H

+ 3 - 3
Libs/XNAT/Core/ctkXnatException.cpp

@@ -1,9 +1,9 @@
 /*=============================================================================
 
-  Plugin: org.commontk.xnat
+  Library: XNAT/Core
 
-  Copyright (c) University College London,
-    Centre for Medical Image Computing
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.

+ 3 - 3
Libs/XNAT/Core/ctkXnatException.h

@@ -1,9 +1,9 @@
 /*=============================================================================
 
-  Plugin: org.commontk.xnat
+  Library: XNAT/Core
 
-  Copyright (c) University College London,
-    Centre for Medical Image Computing
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.

+ 6 - 4
Libs/XNAT/Core/ctkXnatExperiment.cpp

@@ -28,6 +28,7 @@
 #include "ctkXnatReconstruction.h"
 #include "ctkXnatScanFolder.h"
 #include "ctkXnatReconstructionFolder.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatExperimentPrivate : public ctkXnatObjectPrivate
 {
@@ -47,8 +48,8 @@ public:
 };
 
 
-ctkXnatExperiment::ctkXnatExperiment(ctkXnatSubject* parent)
-: ctkXnatObject(*new ctkXnatExperimentPrivate(), parent)
+ctkXnatExperiment::ctkXnatExperiment(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatExperimentPrivate(), parent, schemaType)
 {
 }
 
@@ -72,7 +73,8 @@ void ctkXnatExperiment::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid scansQueryId = session->httpGet(scansUri);
 
-  QList<ctkXnatObject*> scans = session->httpResults(scansQueryId, ctkXnatScan::staticSchemaType());
+  QList<ctkXnatObject*> scans = session->httpResults(scansQueryId,
+                                                     ctkXnatDefaultSchemaTypes::XSI_SCAN);
 
   if (!scans.isEmpty())
   {
@@ -84,7 +86,7 @@ void ctkXnatExperiment::fetchImpl()
   QUuid reconstructionsQueryId = session->httpGet(reconstructionsUri);
 
   QList<ctkXnatObject*> reconstructions = session->httpResults(reconstructionsQueryId,
-                                                                   ctkXnatReconstruction::staticSchemaType());
+                                                               ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION);
 
   if (!reconstructions.isEmpty())
   {

+ 2 - 2
Libs/XNAT/Core/ctkXnatExperiment.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatExperimentPrivate;
@@ -35,9 +36,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatExperiment : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatExperiment, ctkXnatObject, "xnat:experimentData")
+  ctkXnatExperiment(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_EXPERIMENT);
 
-  explicit ctkXnatExperiment(ctkXnatSubject* parent = 0);
   virtual ~ctkXnatExperiment();
 
   virtual QString resourceUri() const;

+ 2 - 2
Libs/XNAT/Core/ctkXnatFile.cpp

@@ -42,8 +42,8 @@ public:
 //  QString uri;
 };
 
-ctkXnatFile::ctkXnatFile(ctkXnatObject* parent)
-: ctkXnatObject(*new ctkXnatFilePrivate(), parent)
+ctkXnatFile::ctkXnatFile(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatFilePrivate(), parent, schemaType)
 {
 }
 

+ 2 - 2
Libs/XNAT/Core/ctkXnatFile.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatFilePrivate;
@@ -34,9 +35,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatFile : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatFile, ctkXnatObject, "xnat:abstractResource")
+  ctkXnatFile(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_FILE);
 
-  explicit ctkXnatFile(ctkXnatObject* parent = 0);
   virtual ~ctkXnatFile();
 
   virtual QString resourceUri() const;

+ 18 - 10
Libs/XNAT/Core/ctkXnatObject.cpp

@@ -28,25 +28,23 @@
 #include <QDebug>
 #include <QVariant>
 
+ctkXnatObject::ctkXnatObject(const ctkXnatObject&)
+{
+  throw ctkRuntimeException("Copy constructor not implemented");
+}
 
-ctkXnatObject::ctkXnatObject(ctkXnatObject* parent)
+ctkXnatObject::ctkXnatObject(ctkXnatObject* parent, const QString& schemaType)
 : d_ptr(new ctkXnatObjectPrivate())
 {
-  Q_D(ctkXnatObject);
   this->setParent(parent);
+  this->setSchemaType(schemaType);
 }
 
-ctkXnatObject::ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent)
+ctkXnatObject::ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent, const QString& schemaType)
 : d_ptr(&dd)
 {
-  Q_D(ctkXnatObject);
   this->setParent(parent);
-}
-
-
-ctkXnatObject::ctkXnatObject(const ctkXnatObject& /*other*/)
-{
-  throw ctkRuntimeException("Copy constructor not implemented");
+  this->setSchemaType(schemaType);
 }
 
 ctkXnatObject::~ctkXnatObject()
@@ -179,6 +177,11 @@ bool ctkXnatObject::isFetched() const
   return d->fetched;
 }
 
+QString ctkXnatObject::schemaType() const
+{
+  return this->property("xsiType");
+}
+
 void ctkXnatObject::fetch()
 {
   Q_D(ctkXnatObject);
@@ -200,6 +203,11 @@ ctkXnatSession* ctkXnatObject::session() const
   return dataModel ? dataModel->session() : NULL;
 }
 
+void ctkXnatObject::setSchemaType(const QString& schemaType)
+{
+  this->setProperty("xsiType", schemaType);
+}
+
 void ctkXnatObject::download(const QString& /*zipFilename*/)
 {
 }

+ 9 - 14
Libs/XNAT/Core/ctkXnatObject.h

@@ -34,11 +34,6 @@
 class ctkXnatSession;
 class ctkXnatObjectPrivate;
 
-#define CTK_XNAT_OBJECT(classType_, baseType_, schemaType_) \
-  classType_(const classType_& other) : baseType_(other) { throw ctkRuntimeException("Copy constructor not implemented"); } \
-  static const char* staticSchemaType() { return schemaType_; } \
-  virtual const char* schemaType() const { return schemaType_; }
-
 //----------------------------------------------------------------------------
 /// \ingroup XNATCore
 /// ctkXnatObject is the base class of the objects that represent the nodes in
@@ -48,15 +43,9 @@ class CTK_XNAT_CORE_EXPORT ctkXnatObject
 
 public:
 
-  /// No-op. Throws a ctkRuntimeException
-  ctkXnatObject(const ctkXnatObject& other);
-
   /// Destructs the ctkXnatObject.
   virtual ~ctkXnatObject();
 
-  /// Get the dynamic schema type of object.
-  virtual const char* schemaType() const = 0;
-
   /// Gets the ID of the object.
   QString id() const;
 
@@ -108,6 +97,8 @@ public:
   /// Tells if the children and the properties of the objects have been fetched.
   bool isFetched() const;
 
+  QString schemaType() const;
+
   /// Resets the object so that its properties and children needs to be fetched
   /// again at the next request.
   virtual void reset();
@@ -144,11 +135,13 @@ public:
 
 protected:
 
+  ctkXnatObject(const ctkXnatObject&);
+
   /// Constructs the ctkXnatObject.
-  ctkXnatObject(ctkXnatObject* parent = 0);
+  ctkXnatObject(ctkXnatObject* parent = 0, const QString& schemaType = QString::null);
 
   /// Constructs the ctkXnatObject with the given private part.
-  ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent = 0);
+  ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent = 0, const QString& schemaType = QString::null);
 
   /// Gets the object that represents the connection to the XNAT server
   /// that stores the current object.
@@ -159,7 +152,9 @@ protected:
 
 private:
 
-  friend class ctkXnatConnection;
+  friend class ctkXnatSessionPrivate;
+
+  void setSchemaType(const QString& schemaType);
 
   /// The implementation of the fetch mechanism, called by the fetch() function.
   virtual void fetchImpl() = 0;

+ 5 - 3
Libs/XNAT/Core/ctkXnatProject.cpp

@@ -25,6 +25,7 @@
 #include "ctkXnatSession.h"
 #include "ctkXnatSubject.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatProjectPrivate : public ctkXnatObjectPrivate
 {
@@ -49,8 +50,8 @@ public:
 //  QString uri;
 };
 
-ctkXnatProject::ctkXnatProject(ctkXnatDataModel* parent)
-: ctkXnatObject(*new ctkXnatProjectPrivate(), parent)
+ctkXnatProject::ctkXnatProject(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatProjectPrivate(), parent, schemaType)
 {
 }
 
@@ -121,7 +122,8 @@ void ctkXnatProject::fetchImpl()
   QString subjectsUri = this->resourceUri() + "/subjects";
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(subjectsUri);
-  QList<ctkXnatObject*> subjects = session->httpResults(queryId, ctkXnatSubject::staticSchemaType());
+  QList<ctkXnatObject*> subjects = session->httpResults(queryId,
+                                                        ctkXnatDefaultSchemaTypes::XSI_SUBJECT);
 
   foreach (ctkXnatObject* subject, subjects)
   {

+ 2 - 2
Libs/XNAT/Core/ctkXnatProject.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatDataModel;
 class ctkXnatProjectPrivate;
@@ -34,9 +35,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatProject : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatProject, ctkXnatObject, "xnat::projectData")
+  ctkXnatProject(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_PROJECT);
 
-  explicit ctkXnatProject(ctkXnatDataModel* parent = 0);
   virtual ~ctkXnatProject();
 
   virtual QString resourceUri() const;

+ 4 - 3
Libs/XNAT/Core/ctkXnatReconstruction.cpp

@@ -25,6 +25,7 @@
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatReconstructionFolder.h"
 #include "ctkXnatReconstructionResource.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatReconstructionPrivate : public ctkXnatObjectPrivate
 {
@@ -44,8 +45,8 @@ public:
 };
 
 
-ctkXnatReconstruction::ctkXnatReconstruction(ctkXnatReconstructionFolder* parent)
-: ctkXnatObject(*new ctkXnatReconstructionPrivate(), parent)
+ctkXnatReconstruction::ctkXnatReconstruction(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatReconstructionPrivate(), parent, schemaType)
 {
 }
 
@@ -70,7 +71,7 @@ void ctkXnatReconstruction::fetchImpl()
   QUuid queryId = session->httpGet(reconstructionResourcesUri);
 
   QList<ctkXnatObject*> reconstructionResources = session->httpResults(queryId,
-                                                                   ctkXnatReconstructionResource::staticSchemaType());
+                                                                       ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION_RESOURCE);
 
   foreach (ctkXnatObject* reconstructionResource, reconstructionResources)
   {

+ 2 - 2
Libs/XNAT/Core/ctkXnatReconstruction.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatReconstructionFolder;
@@ -35,9 +36,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatReconstruction : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatReconstruction, ctkXnatObject, "xnat:reconstructedImageData")
+  ctkXnatReconstruction(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION);
 
-  explicit ctkXnatReconstruction(ctkXnatReconstructionFolder* parent = 0);
   virtual ~ctkXnatReconstruction();
 
   virtual QString resourceUri() const;

+ 5 - 4
Libs/XNAT/Core/ctkXnatReconstructionFolder.cpp

@@ -25,7 +25,7 @@
 #include "ctkXnatExperiment.h"
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatReconstruction.h"
-
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatReconstructionFolderPrivate : public ctkXnatObjectPrivate
 {
@@ -45,8 +45,8 @@ public:
 };
 
 
-ctkXnatReconstructionFolder::ctkXnatReconstructionFolder(ctkXnatExperiment* parent)
-: ctkXnatObject(*new ctkXnatReconstructionFolderPrivate(), parent)
+ctkXnatReconstructionFolder::ctkXnatReconstructionFolder(ctkXnatObject* parent)
+  : ctkXnatObject(*new ctkXnatReconstructionFolderPrivate(), parent, QString::null)
 {
   this->setProperty("ID", "reconstructions");
 }
@@ -71,7 +71,8 @@ void ctkXnatReconstructionFolder::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(reconstructionsUri);
 
-  QList<ctkXnatObject*> reconstructions = session->httpResults(queryId, ctkXnatReconstruction::staticSchemaType());
+  QList<ctkXnatObject*> reconstructions = session->httpResults(queryId,
+                                                               ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION);
 
   foreach (ctkXnatObject* reconstruction, reconstructions)
   {

+ 1 - 2
Libs/XNAT/Core/ctkXnatReconstructionFolder.h

@@ -35,9 +35,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatReconstructionFolder : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatReconstructionFolder, ctkXnatObject, "xnat:reconstructedImageFolder")
+  ctkXnatReconstructionFolder(ctkXnatObject* parent = NULL);
 
-  explicit ctkXnatReconstructionFolder(ctkXnatExperiment* parent = 0);
   virtual ~ctkXnatReconstructionFolder();
 
   virtual QString resourceUri() const;

+ 5 - 3
Libs/XNAT/Core/ctkXnatReconstructionResource.cpp

@@ -25,6 +25,7 @@
 #include "ctkXnatFile.h"
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatReconstruction.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatReconstructionResourcePrivate : public ctkXnatObjectPrivate
 {
@@ -44,8 +45,8 @@ public:
 };
 
 
-ctkXnatReconstructionResource::ctkXnatReconstructionResource(ctkXnatReconstruction* parent)
-: ctkXnatObject(*new ctkXnatReconstructionResourcePrivate(), parent)
+ctkXnatReconstructionResource::ctkXnatReconstructionResource(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatReconstructionResourcePrivate(), parent, schemaType)
 {
 }
 
@@ -69,7 +70,8 @@ void ctkXnatReconstructionResource::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(reconstructionResourceFilesUri);
 
-  QList<ctkXnatObject*> files = session->httpResults(queryId, ctkXnatFile::staticSchemaType());
+  QList<ctkXnatObject*> files = session->httpResults(queryId,
+                                                     ctkXnatDefaultSchemaTypes::XSI_FILE);
 
   foreach (ctkXnatObject* file, files)
   {

+ 3 - 2
Libs/XNAT/Core/ctkXnatReconstructionResource.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatReconstructionResourcePrivate;
@@ -35,9 +36,9 @@ class CTK_XNAT_CORE_EXPORT ctkXnatReconstructionResource : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatReconstructionResource, ctkXnatObject, "xnat:reconstructionResource")
+  ctkXnatReconstructionResource(ctkXnatObject* parent = 0,
+                                const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION_RESOURCE);
 
-  explicit ctkXnatReconstructionResource(ctkXnatReconstruction* parent = 0);
   virtual ~ctkXnatReconstructionResource();
 
   virtual QString resourceUri() const;

+ 5 - 3
Libs/XNAT/Core/ctkXnatScan.cpp

@@ -26,6 +26,7 @@
 #include "ctkXnatScanResource.h"
 #include "ctkXnatObject.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatScanPrivate : public ctkXnatObjectPrivate
 {
@@ -45,8 +46,8 @@ public:
 };
 
 
-ctkXnatScan::ctkXnatScan(ctkXnatScanFolder* parent)
-: ctkXnatObject(*new ctkXnatScanPrivate(), parent)
+ctkXnatScan::ctkXnatScan(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatScanPrivate(), parent, schemaType)
 {
 }
 
@@ -70,7 +71,8 @@ void ctkXnatScan::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(scanResourcesUri);
 
-  QList<ctkXnatObject*> scanResources = session->httpResults(queryId, ctkXnatScanResource::staticSchemaType());
+  QList<ctkXnatObject*> scanResources = session->httpResults(queryId,
+                                                             ctkXnatDefaultSchemaTypes::XSI_SCAN_RESOURCE);
 
   foreach (ctkXnatObject* scanResource, scanResources)
   {

+ 2 - 2
Libs/XNAT/Core/ctkXnatScan.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatScanFolder;
@@ -35,9 +36,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScan : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatScan, ctkXnatObject, "xnat:imageScanData")
+  ctkXnatScan(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_SCAN);
 
-  explicit ctkXnatScan(ctkXnatScanFolder* parent = 0);
   virtual ~ctkXnatScan();
 
   virtual QString resourceUri() const;

+ 5 - 3
Libs/XNAT/Core/ctkXnatScanFolder.cpp

@@ -25,6 +25,7 @@
 #include "ctkXnatExperiment.h"
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatScan.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatScanFolderPrivate : public ctkXnatObjectPrivate
 {
@@ -44,8 +45,8 @@ public:
 };
 
 
-ctkXnatScanFolder::ctkXnatScanFolder(ctkXnatExperiment* parent)
-: ctkXnatObject(*new ctkXnatScanFolderPrivate(), parent)
+ctkXnatScanFolder::ctkXnatScanFolder(ctkXnatObject* parent)
+  : ctkXnatObject(*new ctkXnatScanFolderPrivate(), parent, QString::null)
 {
   this->setProperty("ID", "scans");
 }
@@ -70,7 +71,8 @@ void ctkXnatScanFolder::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(scansUri);
 
-  QList<ctkXnatObject*> scans = session->httpResults(queryId, ctkXnatScan::staticSchemaType());
+  QList<ctkXnatObject*> scans = session->httpResults(queryId,
+                                                     ctkXnatDefaultSchemaTypes::XSI_SCAN);
 
   foreach (ctkXnatObject* scan, scans)
   {

+ 1 - 2
Libs/XNAT/Core/ctkXnatScanFolder.h

@@ -35,9 +35,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScanFolder : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatScanFolder, ctkXnatObject, "xnat:imageScanFolder")
+  ctkXnatScanFolder(ctkXnatObject* parent = NULL);
 
-  explicit ctkXnatScanFolder(ctkXnatExperiment* parent = 0);
   virtual ~ctkXnatScanFolder();
 
   virtual QString resourceUri() const;

+ 5 - 3
Libs/XNAT/Core/ctkXnatScanResource.cpp

@@ -25,6 +25,7 @@
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatScan.h"
 #include "ctkXnatFile.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatScanResourcePrivate : public ctkXnatObjectPrivate
 {
@@ -44,8 +45,8 @@ public:
 };
 
 
-ctkXnatScanResource::ctkXnatScanResource(ctkXnatScan* parent)
-: ctkXnatObject(*new ctkXnatScanResourcePrivate(), parent)
+ctkXnatScanResource::ctkXnatScanResource(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatScanResourcePrivate(), parent, schemaType)
 {
 }
 
@@ -69,7 +70,8 @@ void ctkXnatScanResource::fetchImpl()
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(scanResourceFilesUri);
 
-  QList<ctkXnatObject*> files = session->httpResults(queryId, ctkXnatFile::staticSchemaType());
+  QList<ctkXnatObject*> files = session->httpResults(queryId,
+                                                     ctkXnatDefaultSchemaTypes::XSI_FILE);
 
   foreach (ctkXnatObject* file, files)
   {

+ 3 - 2
Libs/XNAT/Core/ctkXnatScanResource.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatConnection;
 class ctkXnatScan;
@@ -35,9 +36,9 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScanResource : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatScanResource, ctkXnatObject, "xnat:scanResource")
+  ctkXnatScanResource(ctkXnatObject* parent = 0,
+                      const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_SCAN_RESOURCE);
 
-  explicit ctkXnatScanResource(ctkXnatScan* parent = 0);
   virtual ~ctkXnatScanResource();
 
   QString resourceUri() const;

+ 67 - 10
Libs/XNAT/Core/ctkXnatSession.cpp

@@ -35,6 +35,7 @@
 #include "ctkXnatScanFolder.h"
 #include "ctkXnatScanResource.h"
 #include "ctkXnatSubject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 #include <QDebug>
 #include <QScopedPointer>
@@ -77,6 +78,8 @@ public:
   QDateTime updateExpirationDate(qRestResult* restResult);
 
   void close();
+
+  static QList<ctkXnatObject*> results(qRestResult* restResult, QString schemaType);
 };
 
 ctkXnatSessionPrivate::ctkXnatSessionPrivate(const ctkXnatLoginProfile& loginProfile,
@@ -216,6 +219,61 @@ void ctkXnatSessionPrivate::close()
   dataModel.reset();
 }
 
+QList<ctkXnatObject*> ctkXnatSessionPrivate::results(qRestResult* restResult, QString schemaType)
+{
+  QList<ctkXnatObject*> results;
+  foreach (const QVariantMap& propertyMap, restResult->results())
+  {
+    QString customSchemaType;
+    if (propertyMap.contains("xsiType"))
+    {
+      customSchemaType = propertyMap["xsiType"].toString();
+    }
+
+    int typeId = 0;
+    // try to create an object based on the custom schema type first
+    if (!customSchemaType.isEmpty())
+    {
+      typeId = QMetaType::type(qPrintable(customSchemaType));
+      if (!typeId)
+      {
+        qWarning() << QString("No ctkXnatObject sub-class registered for the schema %1. Falling back to the default class.").arg(customSchemaType);
+      }
+    }
+
+    // Fall back. Create the default class according to the default schema type
+    if (!typeId)
+    {
+      typeId = QMetaType::type(qPrintable(schemaType));
+    }
+
+    if (!typeId)
+    {
+      qWarning() << QString("No ctkXnatObject sub-class registered as a meta-type for the schema %1. Skipping result.").arg(schemaType);
+      continue;
+    }
+
+    ctkXnatObject* object = reinterpret_cast<ctkXnatObject*>(QMetaType::construct(typeId));
+    if (!customSchemaType.isEmpty())
+    {
+      // We might have created the default ctkXnatObject sub-class, but can still set
+      // the custom schema type.
+      object->setSchemaType(customSchemaType);
+    }
+
+    // Fill in the properties
+    QMapIterator<QString, QVariant> it(propertyMap);
+    while (it.hasNext())
+    {
+      it.next();
+      object->setProperty(it.key().toAscii().data(), it.value());
+    }
+
+    results.push_back(object);
+  }
+  return results;
+}
+
 // ctkXnatSession class
 
 ctkXnatSession::ctkXnatSession(const ctkXnatLoginProfile& loginProfile)
@@ -223,15 +281,14 @@ ctkXnatSession::ctkXnatSession(const ctkXnatLoginProfile& loginProfile)
 {
   Q_D(ctkXnatSession);
 
-  qRegisterMetaType<ctkXnatProject>(ctkXnatProject::staticSchemaType());
-  qRegisterMetaType<ctkXnatSubject>(ctkXnatSubject::staticSchemaType());
-  qRegisterMetaType<ctkXnatExperiment>(ctkXnatExperiment::staticSchemaType());
-  qRegisterMetaType<ctkXnatScan>(ctkXnatScan::staticSchemaType());
-  qRegisterMetaType<ctkXnatScanFolder>(ctkXnatScanFolder::staticSchemaType());
-  qRegisterMetaType<ctkXnatReconstruction>(ctkXnatReconstruction::staticSchemaType());
-  qRegisterMetaType<ctkXnatScanResource>(ctkXnatScanResource::staticSchemaType());
-  qRegisterMetaType<ctkXnatFile>(ctkXnatFile::staticSchemaType());
-  qRegisterMetaType<ctkXnatReconstructionResource>(ctkXnatReconstructionResource::staticSchemaType());
+  qRegisterMetaType<ctkXnatProject>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_PROJECT));
+  qRegisterMetaType<ctkXnatSubject>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_SUBJECT));
+  qRegisterMetaType<ctkXnatExperiment>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_EXPERIMENT));
+  qRegisterMetaType<ctkXnatScan>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_SCAN));
+  qRegisterMetaType<ctkXnatReconstruction>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION));
+  qRegisterMetaType<ctkXnatScanResource>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_SCAN_RESOURCE));
+  qRegisterMetaType<ctkXnatFile>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_FILE));
+  qRegisterMetaType<ctkXnatReconstructionResource>(qPrintable(ctkXnatDefaultSchemaTypes::XSI_RECONSTRUCTION_RESOURCE));
 
   QString url = d->loginProfile.serverUrl().toString();
   d->xnat->setServerUrl(url);
@@ -377,7 +434,7 @@ QList<ctkXnatObject*> ctkXnatSession::httpResults(const QUuid& uuid, const QStri
   {
     d->throwXnatException("Http request failed.");
   }
-  return restResult->results<ctkXnatObject>(schemaType);
+  return d->results(restResult.data(), schemaType);
 }
 
 QList<QVariantMap> ctkXnatSession::httpSync(const QUuid& uuid)

+ 5 - 3
Libs/XNAT/Core/ctkXnatSubject.cpp

@@ -27,6 +27,7 @@
 #include "ctkXnatObjectPrivate.h"
 #include "ctkXnatExperiment.h"
 #include "ctkXnatProject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatSubjectPrivate : public ctkXnatObjectPrivate
 {
@@ -52,8 +53,8 @@ public:
   QList<ctkXnatProject*> projects;
 };
 
-ctkXnatSubject::ctkXnatSubject(ctkXnatProject* parent)
-: ctkXnatObject(*new ctkXnatSubjectPrivate(), parent)
+ctkXnatSubject::ctkXnatSubject(ctkXnatObject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatSubjectPrivate(), parent, schemaType)
 {
 }
 
@@ -101,7 +102,8 @@ void ctkXnatSubject::fetchImpl()
   QString experimentsUri = this->resourceUri() + "/experiments";
   ctkXnatSession* const session = this->session();
   QUuid queryId = session->httpGet(experimentsUri);
-  QList<ctkXnatObject*> experiments = session->httpResults(queryId, ctkXnatExperiment::staticSchemaType());
+  QList<ctkXnatObject*> experiments = session->httpResults(queryId,
+                                                           ctkXnatDefaultSchemaTypes::XSI_EXPERIMENT);
 
   foreach (ctkXnatObject* experiment, experiments)
   {

+ 2 - 2
Libs/XNAT/Core/ctkXnatSubject.h

@@ -25,6 +25,7 @@
 #include "ctkXNATCoreExport.h"
 
 #include "ctkXnatObject.h"
+#include "ctkXnatDefaultSchemaTypes.h"
 
 class ctkXnatProject;
 class ctkXnatSubjectPrivate;
@@ -34,9 +35,8 @@ class CTK_XNAT_CORE_EXPORT ctkXnatSubject : public ctkXnatObject
 
 public:
 
-  CTK_XNAT_OBJECT(ctkXnatSubject, ctkXnatObject, "xnat:subjectData")
+  ctkXnatSubject(ctkXnatObject* parent = 0, const QString& schemaType = ctkXnatDefaultSchemaTypes::XSI_SUBJECT);
 
-  explicit ctkXnatSubject(ctkXnatProject* parent = 0);
   virtual ~ctkXnatSubject();
 
   ctkXnatProject* getPrimaryProject() const;