changeset 7:b14ed1ea3a23

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Oct 2023 11:14:45 +0200
parents 709e5347a390
children 26c08ff926a3
files .hgignore Plugin/CMakeLists.txt Plugin/JavaBytes.cpp Plugin/JavaBytes.h Plugin/JavaGlobalReference.cpp Plugin/JavaGlobalReference.h Plugin/JavaLocalObject.cpp Plugin/JavaLocalObject.h Plugin/JavaString.cpp Plugin/JavaString.h Plugin/OrthancBytes.cpp Plugin/OrthancBytes.cpp~ Plugin/OrthancBytes.h Plugin/OrthancBytes.h~ Plugin/OrthancString.cpp Plugin/OrthancString.cpp~ Plugin/OrthancString.h Plugin/OrthancString.h~ Plugin/Plugin.cpp
diffstat 19 files changed, 934 insertions(+), 311 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Oct 19 08:51:43 2023 +0200
+++ b/.hgignore	Thu Oct 19 11:14:45 2023 +0200
@@ -5,6 +5,7 @@
 *~
 Plugin/ThirdPartyDownloads/
 Plugin/i/
+Plugin/r/
 Plugin/w32/
 Plugin/w64/
 Plugin/s/
--- a/Plugin/CMakeLists.txt	Thu Oct 19 08:51:43 2023 +0200
+++ b/Plugin/CMakeLists.txt	Thu Oct 19 11:14:45 2023 +0200
@@ -108,9 +108,16 @@
 add_library(OrthancJava SHARED
   ${JSONCPP_SOURCES}
   ${PLUGIN_RESOURCES}
+
+  JavaBytes.cpp
   JavaEnvironment.cpp
+  JavaGlobalReference.cpp
+  JavaLocalObject.cpp
+  JavaString.cpp
   JavaVirtualMachine.cpp
   Mutex.cpp
+  OrthancBytes.cpp
+  OrthancString.cpp
   Plugin.cpp
   )
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaBytes.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,64 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "JavaBytes.h"
+
+#include <stdexcept>
+
+
+JavaBytes::JavaBytes(JNIEnv* env,
+                     jbyteArray bytes) :
+  env_(env),
+  bytes_(bytes)
+{
+  if (env == NULL ||
+      bytes == NULL)
+  {
+    throw std::runtime_error("Null pointer");
+  }
+
+  size_ = env->GetArrayLength(bytes);
+
+  if (size_ == 0)
+  {
+    data_ = NULL;
+  }
+  else
+  {
+    data_ = env->GetByteArrayElements(bytes_, &isCopy_);
+    if (data_ == NULL)
+    {
+      throw std::runtime_error("Cannot read array of bytes");
+    }
+  }
+}
+
+
+JavaBytes::~JavaBytes()
+{
+  if (size_ > 0)
+  {
+    env_->ReleaseByteArrayElements(bytes_, data_, 0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaBytes.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,56 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+#include <jni.h>
+
+
+class JavaBytes : public NonCopyable
+{
+private:
+  JNIEnv*      env_;
+  jbyteArray   bytes_;
+  jbyte*       data_;
+  jsize        size_;
+  jboolean     isCopy_;
+
+public:
+  JavaBytes(JNIEnv* env,
+            jbyteArray bytes);
+
+  ~JavaBytes();
+
+  const void* GetData() const
+  {
+    return data_;
+  }
+
+  size_t GetSize() const
+  {
+    return size_;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaGlobalReference.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,75 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "JavaGlobalReference.h"
+
+#include "JavaEnvironment.h"
+
+#include <cassert>
+#include <stdexcept>
+
+extern OrthancPluginContext* context_;
+
+
+JavaGlobalReference::JavaGlobalReference(JavaVirtualMachine& jvm,
+                                         jobject obj) :
+  jvm_(jvm),
+  obj_(NULL)
+{
+  if (obj == NULL)
+  {
+    throw std::runtime_error("Null pointer");
+  }
+
+  JavaEnvironment env(jvm);
+
+  obj_ = env.GetValue().NewGlobalRef(obj);
+  if (obj_ == NULL)
+  {
+    throw std::runtime_error("Cannot create global reference");
+  }
+}
+
+
+JavaGlobalReference::~JavaGlobalReference()
+{
+  assert(obj_ != NULL);
+
+  try
+  {
+    JavaEnvironment env(jvm_);
+    env.GetValue().DeleteGlobalRef(obj_);
+  }
+  catch (std::runtime_error& e)
+  {
+    OrthancPluginLogError(context_, e.what());
+  }
+}
+
+
+jobject JavaGlobalReference::GetValue()
+{
+  assert(obj_ != NULL);
+  return obj_;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaGlobalReference.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,43 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "JavaVirtualMachine.h"
+
+
+class JavaGlobalReference : public NonCopyable
+{
+private:
+  JavaVirtualMachine&  jvm_;
+  jobject              obj_;
+
+public:
+  JavaGlobalReference(JavaVirtualMachine& jvm,
+                      jobject obj);
+
+  ~JavaGlobalReference();
+
+  jobject GetValue();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaLocalObject.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,107 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "JavaLocalObject.h"
+
+#include <memory>
+#include <stdexcept>
+
+
+JavaLocalObject::JavaLocalObject(JavaEnvironment& env,
+                                 jobject obj,
+                                 bool objCanBeNull) :
+  env_(&env.GetValue()),
+  obj_(obj)
+{
+  if (!objCanBeNull && obj == NULL)
+  {
+    throw std::runtime_error("Null pointer");
+  }
+}
+
+
+JavaLocalObject::~JavaLocalObject()
+{
+  env_->DeleteLocalRef(obj_);
+}
+
+
+JavaLocalObject* JavaLocalObject::CreateArrayOfStrings(JavaEnvironment& env,
+                                                       const std::vector<std::string>& items)
+{
+  JavaLocalObject emptyString(env, env.GetValue().NewStringUTF(""));
+
+  jobjectArray obj = env.GetValue().NewObjectArray(
+    items.size(), env.GetValue().FindClass("java/lang/String"),
+    emptyString.GetValue());
+
+  if (obj == NULL)
+  {
+    throw std::runtime_error("Cannot create an array of Java strings");
+  }
+  else
+  {
+    std::unique_ptr<JavaLocalObject> result(new JavaLocalObject(env, obj));
+
+    for (size_t i = 0; i < items.size(); i++)
+    {
+      JavaLocalObject item(env, env.GetValue().NewStringUTF(items[i].c_str()));
+      env.GetValue().SetObjectArrayElement(obj, i, item.GetValue());
+    }
+
+    return result.release();
+  }
+}
+
+
+JavaLocalObject* JavaLocalObject::CreateDictionary(JavaEnvironment& env,
+                                                   const std::map<std::string, std::string>& items)
+{
+  // NB: In JNI, there are no generics. All the templated arguments
+  // are taken as instances of the "Object" base class.
+
+  jclass cls = env.FindClass("java/util/HashMap");
+  jmethodID constructor = env.GetMethodID(cls, "<init>", "()V");
+  jmethodID setter = env.GetMethodID(cls, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+  jobject obj = env.GetValue().NewObject(cls, constructor);
+
+  if (obj == NULL)
+  {
+    throw std::runtime_error("Cannot create a Java dictionary");
+  }
+  else
+  {
+    std::unique_ptr<JavaLocalObject> result(new JavaLocalObject(env, obj));
+
+    for (std::map<std::string, std::string>::const_iterator it = items.begin(); it != items.end(); ++it)
+    {
+      JavaLocalObject key(env, env.GetValue().NewStringUTF(it->first.c_str()));
+      JavaLocalObject value(env, env.GetValue().NewStringUTF(it->second.c_str()));
+      JavaLocalObject previousValue(env, env.GetValue().CallObjectMethod(obj, setter, key.GetValue(), value.GetValue()), true);
+      env.CheckException();
+    }
+
+    return result.release();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaLocalObject.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,55 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "JavaEnvironment.h"
+
+#include <map>
+
+
+class JavaLocalObject : public NonCopyable
+{
+private:
+  JNIEnv*  env_;
+  jobject  obj_;
+
+public:
+  JavaLocalObject(JavaEnvironment& env,
+                  jobject obj,
+                  bool objCanBeNull = false);
+
+  ~JavaLocalObject();
+
+  jobject GetValue()
+  {
+    return obj_;
+  }
+
+  static JavaLocalObject* CreateArrayOfStrings(JavaEnvironment& env,
+                                               const std::vector<std::string>& items);
+
+  static JavaLocalObject* CreateDictionary(JavaEnvironment& env,
+                                           const std::map<std::string, std::string>& items);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaString.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,57 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "JavaString.h"
+
+#include <stdexcept>
+
+
+JavaString::JavaString(JNIEnv* env,
+                       jstring javaStr) :
+  env_(env),
+  javaStr_(javaStr)
+{
+  if (env == NULL ||
+      javaStr == NULL)
+  {
+    throw std::runtime_error("Null pointer");
+  }
+
+  cStr_ = env_->GetStringUTFChars(javaStr_, &isCopy_);
+  if (cStr_ == NULL)
+  {
+    throw std::runtime_error("Cannot read string");
+  }
+}
+
+
+JavaString::~JavaString()
+{
+  /**
+   * "The ReleaseString-Chars call is necessary whether
+   * GetStringChars has set isCopy to JNI_TRUE or JNI_FALSE."
+   * https://stackoverflow.com/a/5863081
+   **/
+  env_->ReleaseStringUTFChars(javaStr_, cStr_);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/JavaString.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,50 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+#include <jni.h>
+
+
+class JavaString : public NonCopyable
+{
+private:
+  JNIEnv*      env_;
+  jstring      javaStr_;
+  const char*  cStr_;
+  jboolean     isCopy_;
+
+public:
+  JavaString(JNIEnv* env,
+             jstring javaStr);
+
+  ~JavaString();
+
+  const char* GetValue() const
+  {
+    return cStr_;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancBytes.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,40 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "OrthancBytes.h"
+
+extern OrthancPluginContext* context_;
+
+
+OrthancBytes::OrthancBytes()
+{
+  buffer_.data = NULL;
+  buffer_.size = 0;
+}
+
+
+OrthancBytes::~OrthancBytes()
+{
+  OrthancPluginFreeMemoryBuffer(context_, &buffer_);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancBytes.cpp~	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,61 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+
+class OrthancBytes : public NonCopyable
+{
+private:
+  OrthancPluginMemoryBuffer  buffer_;
+
+public:
+  OrthancBytes()
+  {
+    buffer_.data = NULL;
+    buffer_.size = 0;
+  }
+
+  ~OrthancBytes()
+  {
+    OrthancPluginFreeMemoryBuffer(context_, &buffer_);
+  }
+
+  OrthancPluginMemoryBuffer* GetMemoryBuffer()
+  {
+    return &buffer_;
+  }
+
+  const void* GetData() const
+  {
+    return buffer_.data;
+  }
+
+  size_t GetSize() const
+  {
+    return buffer_.size;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancBytes.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,56 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+#include <orthanc/OrthancCPlugin.h>
+
+
+class OrthancBytes : public NonCopyable
+{
+private:
+  OrthancPluginMemoryBuffer  buffer_;
+
+public:
+  OrthancBytes();
+
+  ~OrthancBytes();
+
+  OrthancPluginMemoryBuffer* GetMemoryBuffer()
+  {
+    return &buffer_;
+  }
+
+  const void* GetData() const
+  {
+    return buffer_.data;
+  }
+
+  size_t GetSize() const
+  {
+    return buffer_.size;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancBytes.h~	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,61 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+
+class OrthancBytes : public NonCopyable
+{
+private:
+  OrthancPluginMemoryBuffer  buffer_;
+
+public:
+  OrthancBytes()
+  {
+    buffer_.data = NULL;
+    buffer_.size = 0;
+  }
+
+  ~OrthancBytes()
+  {
+    OrthancPluginFreeMemoryBuffer(context_, &buffer_);
+  }
+
+  OrthancPluginMemoryBuffer* GetMemoryBuffer()
+  {
+    return &buffer_;
+  }
+
+  const void* GetData() const
+  {
+    return buffer_.data;
+  }
+
+  size_t GetSize() const
+  {
+    return buffer_.size;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancString.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,38 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "OrthancString.h"
+
+#include <orthanc/OrthancCPlugin.h>
+
+extern OrthancPluginContext* context_;
+
+
+OrthancString::~OrthancString()
+{
+  if (str_ != NULL)
+  {
+    OrthancPluginFreeString(context_, str_);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancString.cpp~	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,50 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+class OrthancString : public NonCopyable
+{
+private:
+  char*  str_;
+
+public:
+  OrthancString(char* str) :
+    str_(str)
+  {
+  }
+
+  ~OrthancString()
+  {
+    if (str_ != NULL)
+    {
+      OrthancPluginFreeString(context_, str_);
+    }
+  }
+
+  const char* GetValue() const
+  {
+    return str_;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancString.h	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,47 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "NonCopyable.h"
+
+
+class OrthancString : public NonCopyable
+{
+private:
+  char*  str_;
+
+public:
+  OrthancString(char* str) :
+    str_(str)
+  {
+  }
+
+  ~OrthancString();
+
+  const char* GetValue() const
+  {
+    return str_;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/OrthancString.h~	Thu Oct 19 11:14:45 2023 +0200
@@ -0,0 +1,50 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Java plugin for Orthanc
+ * Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+class OrthancString : public NonCopyable
+{
+private:
+  char*  str_;
+
+public:
+  OrthancString(char* str) :
+    str_(str)
+  {
+  }
+
+  ~OrthancString()
+  {
+    if (str_ != NULL)
+    {
+      OrthancPluginFreeString(context_, str_);
+    }
+  }
+
+  const char* GetValue() const
+  {
+    return str_;
+  }
+};
--- a/Plugin/Plugin.cpp	Thu Oct 19 08:51:43 2023 +0200
+++ b/Plugin/Plugin.cpp	Thu Oct 19 11:14:45 2023 +0200
@@ -22,6 +22,12 @@
  **/
 
 
+#include "JavaLocalObject.h"
+#include "JavaGlobalReference.h"
+#include "OrthancBytes.h"
+#include "OrthancString.h"
+#include "JavaBytes.h"
+#include "JavaString.h"
 #include "JavaEnvironment.h"
 #include "JavaVirtualMachine.h"
 
@@ -46,307 +52,6 @@
 static std::unique_ptr<JavaVirtualMachine> java_;
 
 
-
-class JavaString : public NonCopyable
-{
-private:
-  JNIEnv*      env_;
-  jstring      javaStr_;
-  const char*  cStr_;
-  jboolean     isCopy_;
-  
-public:
-  JavaString(JNIEnv* env,
-             jstring javaStr) :
-    env_(env),
-    javaStr_(javaStr)
-  {
-    if (env == NULL ||
-        javaStr == NULL)
-    {
-      throw std::runtime_error("Null pointer");
-    }
-
-    cStr_ = env_->GetStringUTFChars(javaStr_, &isCopy_);
-    if (cStr_ == NULL)
-    {
-      throw std::runtime_error("Cannot read string");
-    }
-  }
-
-  ~JavaString()
-  {
-    /**
-     * "The ReleaseString-Chars call is necessary whether
-     * GetStringChars has set isCopy to JNI_TRUE or JNI_FALSE."
-     * https://stackoverflow.com/a/5863081
-     **/
-    env_->ReleaseStringUTFChars(javaStr_, cStr_);
-  }
-
-  const char* GetValue() const
-  {
-    return cStr_;
-  }
-};
-
-
-class JavaBytes : public NonCopyable
-{
-private:
-  JNIEnv*      env_;
-  jbyteArray   bytes_;
-  jbyte*       data_;
-  jsize        size_;
-  jboolean     isCopy_;
-  
-public:
-  JavaBytes(JNIEnv* env,
-            jbyteArray bytes) :
-    env_(env),
-    bytes_(bytes)
-  {
-    if (env == NULL ||
-        bytes == NULL)
-    {
-      throw std::runtime_error("Null pointer");
-    }
-
-    size_ = env->GetArrayLength(bytes);
-
-    if (size_ == 0)
-    {
-      data_ = NULL;
-    }
-    else
-    {
-      data_ = env->GetByteArrayElements(bytes_, &isCopy_);
-      if (data_ == NULL)
-      {
-        throw std::runtime_error("Cannot read array of bytes");
-      }
-    }
-  }
-
-  ~JavaBytes()
-  {
-    if (size_ > 0)
-    {
-      env_->ReleaseByteArrayElements(bytes_, data_, 0);
-    }
-  }
-
-  const void* GetData() const
-  {
-    return data_;
-  }
-
-  size_t GetSize() const
-  {
-    return size_;
-  }
-};
-
-
-class OrthancString : public NonCopyable
-{
-private:
-  char*  str_;
-
-public:
-  OrthancString(char* str) :
-    str_(str)
-  {
-  }
-
-  ~OrthancString()
-  {
-    if (str_ != NULL)
-    {
-      OrthancPluginFreeString(context_, str_);
-    }
-  }
-
-  const char* GetValue() const
-  {
-    return str_;
-  }
-};
-
-
-class OrthancBytes : public NonCopyable
-{
-private:
-  OrthancPluginMemoryBuffer  buffer_;
-
-public:
-  OrthancBytes()
-  {
-    buffer_.data = NULL;
-    buffer_.size = 0;
-  }
-
-  ~OrthancBytes()
-  {
-    OrthancPluginFreeMemoryBuffer(context_, &buffer_);
-  }
-
-  OrthancPluginMemoryBuffer* GetMemoryBuffer()
-  {
-    return &buffer_;
-  }
-
-  const void* GetData() const
-  {
-    return buffer_.data;
-  }
-
-  size_t GetSize() const
-  {
-    return buffer_.size;
-  }
-};
-
-
-class JavaGlobalReference : public NonCopyable
-{
-private:
-  JavaVirtualMachine&  jvm_;
-  jobject obj_;
-
-public:
-  JavaGlobalReference(JavaVirtualMachine& jvm,
-                      jobject obj) :
-    jvm_(jvm),
-    obj_(NULL)
-  {
-    if (obj == NULL)
-    {
-      throw std::runtime_error("Null pointer");
-    }
-
-    JavaEnvironment env(jvm);
-
-    obj_ = env.GetValue().NewGlobalRef(obj);
-    if (obj_ == NULL)
-    {
-      throw std::runtime_error("Cannot create global reference");
-    }
-  }
-
-  ~JavaGlobalReference()
-  {
-    assert(obj_ != NULL);
-
-    try
-    {
-      JavaEnvironment env(jvm_);
-      env.GetValue().DeleteGlobalRef(obj_);
-    }
-    catch (std::runtime_error& e)
-    {
-      OrthancPluginLogError(context_, e.what());
-    }
-  }
-
-  jobject GetValue()
-  {
-    assert(obj_ != NULL);
-    return obj_;
-  }
-};
-
-
-class LocalJavaObject : public NonCopyable
-{
-private:
-  JNIEnv*  env_;
-  jobject  obj_;
-
-public:
-  LocalJavaObject(JavaEnvironment& env,
-                  jobject obj,
-                  bool objCanBeNull = false) :
-    env_(&env.GetValue()),
-    obj_(obj)
-  {
-    if (!objCanBeNull && obj == NULL)
-    {
-      throw std::runtime_error("Null pointer");
-    }
-  }
-
-  ~LocalJavaObject()
-  {
-    env_->DeleteLocalRef(obj_);
-  }
-
-  jobject GetValue()
-  {
-    return obj_;
-  }
-
-  static LocalJavaObject* CreateArrayOfStrings(JavaEnvironment& env,
-                                               const std::vector<std::string>& items)
-  {
-    LocalJavaObject emptyString(env, env.GetValue().NewStringUTF(""));
-
-    jobjectArray obj = env.GetValue().NewObjectArray(
-      items.size(), env.GetValue().FindClass("java/lang/String"),
-      emptyString.GetValue());
-
-    if (obj == NULL)
-    {
-      throw std::runtime_error("Cannot create an array of Java strings");
-    }
-    else
-    {
-      std::unique_ptr<LocalJavaObject> result(new LocalJavaObject(env, obj));
-
-      for (size_t i = 0; i < items.size(); i++)
-      {
-        LocalJavaObject item(env, env.GetValue().NewStringUTF(items[i].c_str()));
-        env.GetValue().SetObjectArrayElement(obj, i, item.GetValue());
-      }
-
-      return result.release();
-    }
-  }
-
-  static LocalJavaObject* CreateDictionary(JavaEnvironment& env,
-                                           const std::map<std::string, std::string>& items)
-  {
-    // NB: In JNI, there are no generics. All the templated arguments
-    // are taken as instances of the "Object" base class.
-
-    jclass cls = env.FindClass("java/util/HashMap");
-    jmethodID constructor = env.GetMethodID(cls, "<init>", "()V");
-    jmethodID setter = env.GetMethodID(cls, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-    jobject obj = env.GetValue().NewObject(cls, constructor);
-
-    if (obj == NULL)
-    {
-      throw std::runtime_error("Cannot create a Java dictionary");
-    }
-    else
-    {
-      std::unique_ptr<LocalJavaObject> result(new LocalJavaObject(env, obj));
-
-      for (std::map<std::string, std::string>::const_iterator it = items.begin(); it != items.end(); ++it)
-      {
-        LocalJavaObject key(env, env.GetValue().NewStringUTF(it->first.c_str()));
-        LocalJavaObject value(env, env.GetValue().NewStringUTF(it->second.c_str()));
-        LocalJavaObject previousValue(env, env.GetValue().CallObjectMethod(obj, setter, key.GetValue(), value.GetValue()), true);
-        env.CheckException();
-      }
-
-      return result.release();
-    }
-  }
-};
-
-
-
 #include "NativeSDK.cpp"
 
 
@@ -516,13 +221,13 @@
 
       JavaEnvironment env(*java_);
 
-      LocalJavaObject joutput(env, env.ConstructJavaWrapper("be/uclouvain/orthanc/RestOutput", output));
-      LocalJavaObject jmethod(env, env.ConstructEnumValue("be/uclouvain/orthanc/HttpMethod", request->method));
-      LocalJavaObject juri(env, env.GetValue().NewStringUTF(uri == NULL ? "" : uri));
-      std::unique_ptr<LocalJavaObject> jgroups(LocalJavaObject::CreateArrayOfStrings(env, groups));
-      std::unique_ptr<LocalJavaObject> jheaders(LocalJavaObject::CreateDictionary(env, headers));
-      std::unique_ptr<LocalJavaObject> jgetParameters(LocalJavaObject::CreateDictionary(env, getParameters));
-      LocalJavaObject jbody(env, env.ConstructByteArray(request->bodySize, request->body));
+      JavaLocalObject joutput(env, env.ConstructJavaWrapper("be/uclouvain/orthanc/RestOutput", output));
+      JavaLocalObject jmethod(env, env.ConstructEnumValue("be/uclouvain/orthanc/HttpMethod", request->method));
+      JavaLocalObject juri(env, env.GetValue().NewStringUTF(uri == NULL ? "" : uri));
+      std::unique_ptr<JavaLocalObject> jgroups(JavaLocalObject::CreateArrayOfStrings(env, groups));
+      std::unique_ptr<JavaLocalObject> jheaders(JavaLocalObject::CreateDictionary(env, headers));
+      std::unique_ptr<JavaLocalObject> jgetParameters(JavaLocalObject::CreateDictionary(env, getParameters));
+      JavaLocalObject jbody(env, env.ConstructByteArray(request->bodySize, request->body));
 
       jmethodID call = env.GetMethodID(
         env.GetObjectClass(callback), "call",
@@ -589,9 +294,9 @@
     {
       JavaEnvironment env(*java_);
 
-      LocalJavaObject c(env, env.ConstructEnumValue("be/uclouvain/orthanc/ChangeType", changeType));
-      LocalJavaObject r(env, env.ConstructEnumValue("be/uclouvain/orthanc/ResourceType", resourceType));
-      LocalJavaObject s(env, env.GetValue().NewStringUTF(resourceId == NULL ? "" : resourceId));
+      JavaLocalObject c(env, env.ConstructEnumValue("be/uclouvain/orthanc/ChangeType", changeType));
+      JavaLocalObject r(env, env.ConstructEnumValue("be/uclouvain/orthanc/ResourceType", resourceType));
+      JavaLocalObject s(env, env.GetValue().NewStringUTF(resourceId == NULL ? "" : resourceId));
 
       for (std::list<jobject>::const_iterator
              callback = callbacks.begin(); callback != callbacks.end(); ++callback)