OpenDolphin -wikipedia 風解説-

「医療用フリーソフト紹介」に OpenDolphin の項を追加しようかな?と思ってたら、LSC での販売終了のお知らせ

私がこの数奇?な運命を遂げたオープンソースの電子カルテに触ったのは比較的最近のことだ。具体的には、

猪股先生版 OpenDolphin https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m

を最近の Mac 環境に導入したときからだ。
参考:『OpenDolphin-2.7(m) を Mac OSX にインストールする

だから、きっちりとした記載をしようとするとえらく手間がかかる。
「日本初の Open Source の電子カルテ」というのがウリだったようなのだが、この点に関して「おや」と気になったことがあったので、前半はこの点を中心に気になったことを軽い感じでまとめていく。
現在では OpenDolphin をノーマルのまま単独で使う機会は減っていると思うので、後半では、これまでに明らかになった瑕疵やその改善策・発展形態に関して述べる。
なお、特別に断らない限り、ここでいう OpenDolphin とは Ver 2.7 系列をベースにしたバージョンを指しています。

歴史

経産省の助成を受けて・・・云々の話はネットで探せば出てくると思うので、細かな話は省く。
ただし、地域医療ネットワークで使われていた時代と開業医向けの商用電子カルテで使われていた時代とでは、運用形態や使われている技術が大きく異なるのでこの区別は技術的には重要。
また、後述するように OpenDolphin の基本設計に近い部分はまだオープンソース化する以前の eDolphin 時代になされているので、この点は気に留めておいてほしい。この歴史的経緯があまり強調されていないため、権利関係などにいささかの混乱をきたしている。
ポイントは

2001 経済産業省の公募事業に採択
2004 オープンソース化

です。

ところで、商用利用されるようになってから、いわゆる「本家」と称されている dolphin-dev リポジトリの管理会社は

digital globe → Life Science Computing(LSC) → Medley(メドレー)

と変遷している。
ただ、調べていくと、LSC 時代のある時(2018頃?)から、開発方針や対外的な協力関係は大きく変わったようだ。
前半は、俗っぽい言い方をするなら「喧嘩っぱやい」会社。権利意識が強く、実際、訴訟などもおこしていた。
商標に関しては司法的な判断も公開されており、その解説などは以下の記事を参考にあげておきます。

オープンソースと知財権に関するちょっと小難しい話


要するに LSC OpenDolphin 派生版としてA社が DolphinEvolution というプロダクツを販売していたが、「これは OpenDolphin の周知性のタダノリである」として LSC がA社を訴えたもの。
残念ながら、その結果は LSC 社が意図していたようなものにはならず、特許庁は LSC の訴えを退け、A 社の商標の保持を完全に認めている。その影響なのか、これ以降、開発体制なども刷新されたようだ。
後半は、うってかわってマイルドな路線に切り替わる。

電子カルテとしての特徴

よく
・カルテ2号用紙をメタファーとしたリッチな GUI
・使用頻度の多い項目を簡易にドラッグ&ドロップで入力できる「スタンプ」機能
が特徴としてあげられている。
これは見てもらった方が早いでしょうか。

ただし、現在(2021年)では、こういった特徴はブラウザ型の電子カルテなどにも取りいれられている。
開発時期を考えると当時としては医師目線で使いやすいシステムであったとは言えるでしょう。

ところで、こういった特徴はいつ頃から実装されたのだろうか?

残された公式の資料は多くはないが、オープンソース化された直後の 2004 年頃の資料では、以下のようなデモ画面が残されている。

この時点でも、スタンプ入力方式・2号用紙を意識したエディタ、スキーマエディタなどの機能の原型は出来上がっていたことがわかる。

また、メインの実装担当者には(このあと出てくる)京大佐藤(純三)先生であることが推測できる。

なお、商用化されてからの宣伝では、GUI などは増田茂が、スキーマエディタが松村哲理が開発したことになっているが、あくまでベースは eDolphin時代のもので、アナウンスされていたほどの関与、少なくともゼロから開発したものではなかったことがわかる。
著作権的にも、後期LSCは曖昧にしていたが、メドレーは「資料的には、開発ベースでは医師の関与は見つからない。あくまで、その時点で著作権を有していただけだったようだ」旨のアナウンスをしている。
(プログラムの著作権は、文芸作品などと違い、「コーディングした人・基本設計をした人」が必ずしも著作権者ではない。金銭的な対価を支払い、著作権を買い取ることができる。前期LSCとの契約上、著作権を有していただけのようだ)

また、たいていのオープンソースのプロジェクトでは、「GUI の軽微な変更」程度の改変では、派生した独立のプロジェクトとみなされることはない。
オープンソースライセンス的にも、その程度の改変のソースコード提供者はプロジェクト自体のクレジットに値するほどではないとされている。

さらに、本体の「開発者」とされていた増田茂・松村哲理の LSC リポジトリへのソースコード提供は1回程度しかなく(後述する)、上記のような状況より、現在では、両者を LSC Dolphin の「開発者」とみなす人はほとんどいないようだ。

技術的特徴

技術的な話も少々。
開発言語は Java で、maven で管理されている。client, common, server という三つのプロジェクトからなる。この名称から予想されるようにクライアント・サーバーシステムである。
基本となる設計は、典型的な MCV(Model-Controller-Viewer) の三層アーキテクチャである。

ただし、サーバー-クライアントの通信は主に REST API を介して行われており、クライアントは必ずしもデスクトップアプリである必要はない(後述します)。

カルテ記載内容などを記録・保存しておく必要があるため、アプリケーションサーバー(WildFly)を介してデータベース(PostgreSQL)と連携して動作する。
保存形式を決めるモデルは、具体的には上記 common プロジェクト内の infomodel パッケージで定義されている。オブジェクトをデータベースに格納させる際には、ORM である hibernate を用いている。

なお、よく「Java で作成されているためマルチプラットフォームであり、クライアントが Windows/Mac/Linux で動作する」と紹介されているが、これはやや誤解を生む表現である。サーバープログラムも pure Java で書かれているため、適切に環境を整えればサーバープログラムを Windows/Mac/Linux に設置(デプロイ)し動作させることは可能である。
以下の動画は、サーバ・クライアント共に MacOS で動かしている例。
ターミナルよりサーバの起動コマンドを入力後、メッセージが返されているのでサーバープロセスが MacOS 上で動いているのがわかると思う。

ライセンス

ところで、オープンソースにつきものといえばライセンスだが、当初は GPL というかなり制約の厳しいライセンスを主張していた。が、これも体制の刷新を契機に取り扱いを変えてきている。
もちろん GitHub のリポジトリで謳われているライセンスは現在(2021年1月)でも GPL だが、メドレー本社はこれが妥当なものであるかは明言していない。

なお、ライセンスは曖昧ながらも、他社の商用利用(soso の GlassDolphinMIA の OpenDolphin)は原則許可、技術的特徴が明示されている猪股版(いわゆる OpenDolphin-2.7m)もその配布(や情報公開など)は許可されている。名称の利用に関しても、メドレー版との相違が誤認されないように情報公開されているなど適切に取り扱われていれば、許可されている。

これは以下のような事情があったためのようだ。

GitHub リポジトリでのプルリク・コードレビューがほぼない

この記事

開発者を限定する、というのはあってもいいのだが(ニッチな分野では不特定多数の開発者をアテにはできないことがしばしばある)、そうだとしてもプルリクやマージは普通に行われる。ところが、「イルカ」ではこのプロセスがつい最近まで一切なかった。ちょうど下請けや孫請けにつくらせたコードをそのままボンッとリポジトリに送りこむかのように突如としてバージョンアップ版が出現していた。

とあって、「んな、バカな」と思っていたのだが、調べたら本当だった。
こういう調べものをするとき、GitHub などの Git ホスティングサービスは便利で誰がいつどのような変更を行ったか容易に確かめることができる。
で、調べてみると・・・


確かにわずか3件。
また、この3件のうち GlassDolphin の linuxmania さんが送ったプルリクエスト(PR)は 2.6.3 時代のもので、2.7.0 アップデートにより現在ではほぼその痕跡は残していない。
MasudaNaika(増田茂医師  当時、開業中。現在、高槻病院勤務)が送った診療区分に関する bug fix はマージ(merge プルリクエストを取り込むこと)されて、現在でも生きているが、merge されたのは 2018/6/4 のことだ。
猪股版 OpenDolphin-2.7m のソースコードがこの bug を取り除いた形で GitHub 上に公開されたのは 2016/7/12 のことだから、この修正がどれほどの意味を持つのかという気はする。
実際、現在(2021/7)では、https://www.opendolphin.com/ では以下のように増田氏の名前は見当たらない。

Ver 2.2.1 時代のソースコードも
GitHub: https://github.com/nekop/opendolphin
に残されているが、このバージョンに至っては PR の痕跡は一切ない。

オープンソースのプロジェクトとしては運営形態がかなり特殊だったという指摘はもっともに思える。

https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/network/members より

これは、猪股先生の OpenDolphin-2.7m の開発形態と比較するとわかりやすいかもしれない。
猪股先生のリポジトリにある
https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/
が Fork 元になって、いくつかのリポジトリに分岐(Fork 先)しているのがわかると思う。

Fork 先で新たな機能を実装したり bug fix などを行って Fork 元(上流ブランチ)にそのコードを取り込んで欲しい場合、行われるのが Pull Request (PR などと略される)というものだ。
私も Fork 後、PRを送ったことがある。
https://github.com/ANN2b-MD/OpenDolphin-2.7m
が Fork したリポジトリ。
Mac ビルド用に軽微な変更が必要があったため、ローカルでコードを修正した後、リモートのリポジトリに上げた。
以下のように PR → merge が行われた。
( https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/pull/6


このようなプロセスは GitHub 上の操作で比較的容易に実現できる。
この仕組みのおかげで、誰がいつどのような PR を行ったのか、また、それを merge する側はどのように評価(コードレビュー)したのかわかるようになっている。
上の場合は、コードレビューと言っても thanks だけですが(笑)。

通常のオープンソースのプロジェクトは、上記のように「本家」は大抵の場合、慣例的に一つであり、そこから各 Fork 先に枝分かれ状に分岐していく。逆に言えば、どれほど分岐しようとも、Fork 元をたどっていけば必ず一つの「源流」に行き着くことができる。
このように運営することのメリットは、分岐したブランチの開発者は誰でも本家に修正したコードを送ることができる、プロジェクトの最終産物(プロダクト)のバージョンの統一性が保たれる… などがある。
デメリットとしては、PR を送ったとしても必ずしも merge されるとは限らず、提案された機能などが最終プロダクトに取り込まれないといったことが挙げられる。(例えばこの記事の『マージされなかった Pull Request の例』参照)
なお、dolphin-dev は、当初、このポリシーを取らず、ソースコード提供者を特定の開発者に限定していた。この痕跡は dolphin-dev の README の以下ような記載からも窺い知れる。


OpenDolphinにはコミッターが存在しません。フォークされた場合はそれぞれ独立した開発者になっていただき、 GitHub 等でソースの共有をお願いしています。

このような開発形態にしたため、機能の異なるいくつかのバージョンが存在するようになった。
現在でもソースが一般公開されている猪股バージョンのほか、

・入院対応が(部分的に)可能なバージョン
・音声入力機能を具備したバージョン
・クライアントでの処方箋出力機能を持ったバージョン

などがあったようである。

なかには、データベースレベルでの互換性がなくなっているバージョンもあり、メドレーから関係者に対して、この点に関しての注意がなされたという。

 

誰がソースコード提供者なのかわかりにくい

oracle のサンプルコードや公式には開発者とはされていない人のコードが散見される。

Junzo SATO 氏のコード

これは以前から指摘されていたのだが、もうちょっと網羅的に調べてみた。

Panel2.java (client project)
私のリポジトリであれば、
https://github.com/ANN2b-MD/OpenDolphin-2.7m/blob/master/client/src/main/java/open/dolphin/client/Panel2.java

/**
 *
 * @author  Junzo SATO
 */
public class Panel2 extends JPanel implements Printable {
	
    private String patientName;

    private boolean printName;
    
    private int height;
    
    /** Creates a new instance of Panel2 */
    public Panel2() {
    }

しっかり読んでいるわけではないが、クライアントのエディタ画面を実装しているパネルはこの Panel2 のクラスが基本となっていたはずだ。

その他は以下のファイルに同氏の名前が残っていた。

SchemaHolder.java (client project)

public final class SchemaHolder extends AbstractComponentHolder implements ComponentHolder {
    
    private SchemaModel schema;
    
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    // Junzo SATO
    // to restrict the size of the component,
    // setBounds and setSize are overridden.
    private final int fixedSize = 192;//160;/////////////////////////////////////////
    private final int fixedWidth = fixedSize;
    private final int fixedHeight = fixedSize;
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    private boolean selected;
    
    private Position start;
    
    private Position end;
    
    private final KartePane kartePane;
    
    public SchemaHolder(KartePane kartePane, SchemaModel schema) {
        
        this.kartePane = kartePane;
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        // Junzo SATO
        // for simplicity, the acpect ratio of the fixed rect is set to 1.
        this.setDoubleBuffered(false);
        this.setOpaque(true);
        this.setBackground(Color.white);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        this.schema = schema;
        //this.setImageIcon(schema.getIcon());
        setIcon(adjustImageSize(schema.getIcon(), new Dimension(fixedWidth, fixedHeight)));
        
    }

KarteViewer.java (client project)

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    // Junzo SATO
    public void printPanel2(final PageFormat format) {
        String name = getContext().getPatient().getFullName();
        boolean printName = true;
        if (pPane==null) {
            printName = printName && Project.getBoolean("plain.print.patinet.name");
        }
        panel2.printPanel(format, 1, false, name, getActualHeight()+60, printName);
    }

KarteEditor.java (client project)

   /**
     * Courtesy of Junzo SATO
     */
    private byte[] getJPEGByte(Image image) {

        byte[] ret = null;

        try {
            JPanel myPanel = getUI();
            Dimension d = new Dimension(image.getWidth(myPanel), image.getHeight(myPanel));
            BufferedImage bf = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB);
            Graphics g = bf.getGraphics();
            g.setColor(Color.white);
            g.drawImage(image, 0, 0, d.width, d.height, myPanel);

            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ImageIO.write(bf, "jpeg", bo);
            ret = bo.toByteArray();

        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return ret;
    }

いずれも、クライアントのエディター上でカルテを表示・記載する際、かなり基本的となる部分で、特に Panel2.java では @author Junzo SATO と authoship を放棄していないことから、この方の著作権表記は retain していないとまずいと思われます。
そして、この時点での OpenDolphin の開発担当者は皆川和史ですから、彼らの理屈(ソースコード提供者は、すべてクレジットされなければいけないというような主張)からすれば、それを怠った皆川は GPL 違反をしていることになります。

なお、Juzo SATO 氏はこの資料から推測するに佐藤純三氏と思われます。


熊本大医療情報経営企画部→サイバーラボという経歴であることは分かりましたが、その後の足取りはネット上では掴めません。

なお、この発表は 2003 年(オープンソース化する以前)になされており、少なくとも UI や記録方式の基本的な部分は eDolphin 時代に確立していたことがわかります。(前述のようにこの実装レベルの担当者は佐藤氏メインだっと思われます)

しばしば、皆川和史や増田茂を設計者とみなすことに(関係者の間からも)疑念が呈されていますが、背景にこういった事情があったためのようです。
特に増田茂がドルフィンのコードにあたれるのはオープンソース化した後になるはずですから、基本設計には関与できないでしょう。
にもかかわらず、例えば、小林慎治のような人は「皆川和史がメインの開発者だ」主張するのですが、もしそう主張したいならば、それ相応の根拠を示すべきでしょう。
例えば、皆川和史は OpenMARS というOpenDolphin をベースにしたプロジェクトの開発を一時期していたようですが、現在ではほぼ必須とされるデータバックアップシステムの作成までは開発・提供されておらず(OpenDolphin のデータ構造の把握が不十分のためか)、基本設計レベルでの開発をしていたとは考えにくいように思います。
ところで OpenDolphin はソースが公開されていましたから、LSC バージョン以外にもプロダクツがあります。現在では廃業したグッディという会社のバージョンもそれなりに使われていたようです。
グッディ版のクライエントの KarteEditor.java の author 表記は以下のようにありませんが、このクラスの途中で Junzo SATO 氏の名前が確認できます。

これが LSC 版では以下のようになります。

Kazushi Minagawa と署名するのは、このコードの著作権を金銭的な対価を払って保有していた場合、そこまで問題になることではないでしょうが、GPL の精神を尊重した場合、いささか問題があるように思います。
少なくとも「すべてを開発した」というような言い方は間違いでしょう。

funabashi 氏のコード

これは比較的最近(2022 春頃)になって見つかった。(猪股先生のツィート参照)

この方が提供したコードは探すとかなり大量に出てくるため、ここでは一例だけ挙げておきます。

IDocument2.java (server project)

// Module
ModuleModel soa = null;
ModuleModel p = null; // 20131206 add funabashi
if (model.getModules()!=null && model.getModules().size()>0) {

この箇所は OpenDolphin のデータ構造を決めているかなり基本的な部分です。

Junzo SATO 氏のコードにしても funabashi 氏のコードにしてもデータ構造のかなり基本的な部分に関与する部分で、基本設計のかなりの部分がこれまで公的には開発者としてアナウンスされていない人の手によるものであることが推測されます。

Kushiro 氏のコード

この方のコードもけっこうある。
一例を挙げておく。

DoseaseView.java (client project)

/**
 *
 * @author kushiro
 */
public class DiseaseView extends javax.swing.JPanel implements IDiseaseView {

    /** Creates new form Baka */
    public DiseaseView() {
        initComponents();
    }

miura 氏のコード

OpenDolphin はそれ自体では保険点数算定のロジックを持たないが、この部分を受け持つレセコンと連動させるためには、薬剤一つをとっても内部的にレセコンと共通の識別子(レセ電コードなど)を保持しておく必要がある。

薬剤処方のレセ電コードなどを処理している BundleMed というクラスがあるのだが、そこに miura 氏がソースコードを修正した箇所がある。

//miura^ test 院内と院外がまとまるのを防ぐ 211 and 212 のケース 2013/07/22
        if (!this.getClassCode().startsWith("21") || !other.getClassCode().startsWith("21") || !this.getClassCode().equals(other.getClassCode())) {
            return false;
        }
//miura$

機能的にはかなり細かい部分だが、保険点数の算定の仕組みとそれがプログラム的にどう処理されているかわかっていないと手を入れにくい箇所だ。

ORACLE のコード

これはわかりやすかった。
以下の open.dolphin.helper パッケージの SpringUtilities.java は、oracle が公開しているサンプルコード(https://docs.oracle.com/javase/tutorial/uiswing/examples/layout/SpringGridProject/src/layout/SpringUtilities.java)とファイル名も含めてまったく同一だったからだ。

/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

package open.dolphin.helper;

import javax.swing.*;
import javax.swing.SpringLayout;
import java.awt.*;

/**
 * A 1.4 file that provides utility methods for
 * creating form- or grid-style layouts with SpringLayout.
 * These utilities are used by several programs, such as
 * SpringBox and SpringCompactGrid.
 */
public class SpringUtilities {
    /**
     * A debugging utility that prints to stdout the component's
     * minimum, preferred, and maximum sizes.
     */
    public static void printSizes(Component c) {
        System.out.println("minimumSize = " + c.getMinimumSize());
        System.out.println("preferredSize = " + c.getPreferredSize());
        System.out.println("maximumSize = " + c.getMaximumSize());
    }

けっこうあるもんですね。

Mirror-i corp 社のコード

オープンソース時代のドルフィンは ORCA との接続に CLAIM を採用していた。
来院患者の情報の CLAIM でのやり取りはクライアント・サーバーのどちらかが指定でき、クライアントプロジェクトの担当箇所に以下のコードがある。
(open.dolphin.impl.server パッケージの PVTClientServer.class)

/**
 * PVT socket server<br>
 * <br>
 * PVTServer() listen to ORCA for MML file through socket<br>
 * <br>
 * Creates 'Connection' thread on getting MML file from ORCA<br>
 *
 * @author Kazushi Minagawa, Digital Globe, Inc.
 *
 * Modified by Mirror-i corp for writing into postgreSQL
 *
 */
public final class PVTClientServer implements Runnable,open.dolphin.server.PVTServer {

    public static final int EOT = 0x04;
    public static final int ACK = 0x06;
    public static final int NAK = 0x15;

Mirror-i 社に外注に出したと思われる。

なぜソースコード管理が曖昧になってしまったのか

当然、この疑問は湧く。
これは、歴史的経緯を考えると分かりやすいかもしれない。
OpenDolphin には、地域医療ネットワークのクライアントとして使われていた時期とそこから一種のコンバートをして開業医さん向けのローカルなシステムとして使われていた時期がある(その後、クラウド化されるが、データベースをクラウドに上げただけで構成の本質は大きく変わっていない)。
このとき、永続化システムの切り替えは必須になってくるが、その移行方法に技術的に若干無理があったのかもしれない。
現在のコード上からも確認できるが、ローカル版(オンプレミス版)ではカルテ記載内容をかなり強引にバイナリ化して、データベースに格納している。
ソースコードにあたればわかると思うが、ここらへんのコードは極めて見通しが悪く可読性も低い。
また(これは個人的な推測になるが)この移行で担当者間で技術的な意図がうまく伝わってなかったのではないかと思われる。

ここは技術的な話になるので読み飛ばしてもらって結構だが、バイナリ化した理由は、初期設計の段階では PostgreSQL などで CLOB が上手く扱えなかったからだと思われる。

「開発者」と「著作権者」

ところで、日本のソフトウェアに関する著作権法においては、コーダーやプログラマーなど実際に手を動かして開発した人と著作権者は違っていてもいい。著作権を保有しているのは法人であってもかまわない。
ここが文芸作品や音楽作品と異なる点だ。

上で見たように OpenDolphin のソースコード上には、公式には「開発者」とみなされていない人が開発したコードが散見される。

代表的的な例は、佐藤純三氏で、上で示したようにソース上でもその署名が確認できる。オープンソース化された直後の資料などでも「コーダー」として紹介されている。
だから、基本設計のかなりの部分が同氏の手によるものと考えられるが、奇妙なことに商用化が進むにつれ、 同氏は「開発者」としても「著作権者」としてもクレジットされなくなる。

なぜこうなったかは推測するしかないのだが、同氏が手がけたコードを開発元に著作権ごと譲渡したか開発元が買い取ったかと考えるのが自然だろう。

こういった事情もソースコード管理が曖昧になった原因の一つかもしれない。

また「開発」という言葉をいささかミスリードを誘うように公式が一時期(デジタルグローブと LSC 開発時代のみだが)使っていたのも、事態をわかりにくくした。
例えば LSC Dolphin の GitHub リポジトリには

OpenDolphinは下記先生方の開発されたソースコードを含んでいます。
札幌市元町皮ふ科の松村先生
和歌山市増田内科の増田先生

という記載があるが、もちろんゼロから開発したわけではなく(そもそも両者はオープンソース化した後でしかプロジェクトに関われないのだから、基本設計に近い部分には関与できない)、それまでの蓄積の上で何がしかの改変を加えた程度の「開発」と考えるのが妥当だろう。
時限的に著作権は有していたかもしれないが、必ずしも「全てを開発した」上での著作権ではない。

弊害

実際に設計・実装・開発した人と(譲渡可能な財産権としての)著作権を有している人が乖離しているため、基本設計の根幹に関わる改変や機能追加が難しくなっている。
後述するようにガイドラインで具備が推奨されているバックアップシステム・システム停止時の閲覧システムを提供している開発グループはほとんどない(公的にその存在をアナウンスしているのは OpenDolphin-2.7m 開発グループのみ)。

誹謗中傷・誤情報の流布

日本のソフトウェアに関する著作権法の建て付けでは、必ずしも

「開発した人」=「著作権保有者」

ではない。
また、ドルフィンラボのリポジトリから、直接分岐せず Fork が行われたプロジェクトも多いため、プロジェクト産物間の差異を把握するのが難しくなっている。
そのため、ネット上には誤った情報が散見される。

例えば、小林慎治(当時、京都大。現在、保健科学院)は
「LSC OpenDolphin → 増田茂作成 OpenDolphin → OpenDolphin-2.7m
の順に Fork されたという誤認に基づいて記事を作成した。

また、小山哲央(アーク情報システム)は、この記事を X (twitter) 上で紹介。
その際に「故意にGPL違反した」と検証もせずに単なる主観を主張し、関係者から訂正を求められた。なお、小林氏元記事は「GPL の解釈によっては、クレジットが不適切」という内容で、「故意に」(=悪意を持って)何かをしたということは一言も書かれていない)。

松村哲理(医師。札幌元町皮ふ科院長)は、ソースコードの確認もせずに、誹謗中傷とも取られかねない単なる憶測を X(twitter) 上に投稿した。

もちろん、LSC リポジトリと OpenDolphin-2.7m リポジトリを比較すればわかるように、author の書き換えは行われていない。

現状と今後の課題

まず、これまでの「本家」を引き継いだメドレーだが、今後、開発・販売を再開する予定はないとしている。
→結局、「運営などの権利はもつが積極的には普及させない」ということになったようですね。
実際、稼働クライアントマシンの OS アップデート(Mac であれば Monterey, Win であれば Win11)は非推奨であることが公式にアナウンスされている。
apple の BigSur サポート・マイクロソフトの Win10 のサポートが終了すれば、メドレーのサポートも実質的に終了することになるでしょう。

一方、商用利用している他の組織は、「新機能を盛り込みながら、開発・サービスの提供を継続していく」とアナウンスはしていたが、実際には目立った機能の追加はなされていない。(そもそも GlassDolphin クライアントは MacOS では動作保証外)

これは、従来のソースコードを Java17 でビルドするとそのままでは動かない(Java17 問題)といった基本的な文法上の古さに加え、従来の OpenDolphin のアーキテクチャの基本的な欠点・設計上の脆弱性が広く認知されてきたことに由来すると思われる。

上で「サーバー-クライアント間の通信は API を介して行われている」と書いたが、オープンソースである以上、通信を行う際の URI は特定されており、この点がサイバー攻撃の格好の対象になってしまう。
ローカルで使っている分にはこれは致命的な欠点にはならないが、商用利用されているクラウド型ではサーバの位置(URL)が特定されてしまうと、不特定多数からの攻撃をピンポイントで受けるリスクが生じる。
(商用利用のサーバの URL が公開されていないのはおそらくこれが理由)

また、ログイン認証の仕組み・データ構造も明らかにされているため、このロジックの透明性を逆手にとってシステムに検知されずにデータの改竄を行う余地があることが示されている。(『OpenDolphin は「真正性」すら満たしていないかもしれない』参照)

しかし、問題点が特定されているということは、解決策も講じやすいということでもある。

実際、

・ログイン認証などはソースコードをクローズドにしたウェブレイヤーに任せてしまい、本来のドルフィンサーバを外部から遮蔽して安全性を担保する(3層クライアントサーバーアーキテクチャの採用)

といった改善策が提案されている。(図は『WebDolphORCA』より)

また、この方法論はデスクトップアプリの画像の取り扱いに起因する Java17 問題の自然な解決になっている。

Java17 問題

公開されている OpenDolphin では、古い GUI ライブラリの一部が使われている。Java17 より前の Java では特に問題なくビルド・デプロイできたが、Java17 になって、デプロイ時にかなり致命的なエラーを出すようになった。
しかし、バックエンドのソースコードに手を入れることで基本的にはこの問題は解決した。

JakartaEE 環境への移行

Java のエンタープライズ環境は、JavaEE から JakartaEE へと変化した。
現在(2022)は、この移行の過渡期と考えられており、実際、ウェブアプリをデプロイするアプリケーションサーバは、JavaEE・JakartaEE 両対応になっているものが多い。

OpenDolphin では、2.7m 系列がいち早く JakartaEE への移行を果たした。Java17・JakartaEE 9.1 に対応したバージョンが『OpenDolphin Ver6』で案内されている。

バイナリ記録の問題

OpenDolphin はカルテエディター上の文字・画像などを最終的には Blob として記録している。

この保存形式のせいで

・データベース(DB)からカルテ情報を直接復号するのが難しくなっている

・システム稼働中であってもDB上の文字情報を再利用するのに手間がかかる

という問題が生じている。

バックアップシステム問題

OpenDolphin プロジェクトが発足された当初、紙カルテ→電子カルテの移行が重要視され、電子カルテが満たすべき条件はそれほど厳しいものではなかった。
3原則が守られていれば、電子カルテと名乗ってもそれほど問題になることは無かった。
しかし、セキュリティの脆弱性に起因するシステムの改ざん・乗っ取りと言った事件が発生するに従い、この点を重視した条件が(推奨基準などで)課されることになった。

『医療情報システムの安全管理に関するガイドライン 5.2 版』(2022/3)では

1.バックアップサーバ
システムが停止した場合でも、バックアップサーバと汎用的なブラウザ等を用いて、日常診療に必要な最低限の診療録等を見読できるようにすること。

2.見読性確保のための外部出力
システムが停止した場合でも、見読目的に該当する患者の一連の診療録等を汎用のブラウザ等で見読ができるように、見読性を確保した形式で外部ファイルへ出力できるようにすること。

3.遠隔地のデータバックアップを使用した見読機能
大規模火災等の災害対策として、遠隔地に電子保存記録をバックアップするとともに、そのバックアップデータ等と汎用的なブラウザ等を用いて、日常診療に必要な最低限の診療録等を見読できるようにすること。

といった機能の具備が推奨されている。

簡単に言えば、仮に本体のシステムが停止したとしても、ストレージ本体あるいはあらかじめ保管していたバックアップデータから診察すべき患者のカルテ記載内容を別のシステム経由でも開示できるようにしておくようにという趣旨である。

これは、このガイドラインが公開準備段階にあった時期にシステム乗っ取り→通常診療の停止という事件が多発したためであろう。

OpenDolphin の構成は、上述のように標準的なクライアントサーバであるため、この系をいくら工夫しようが、上記の機能は実装できない。

しかし、OpenDolphin-2.7m は、以前から電子カルテ乗り換え時のデータコンバータ/サーバー停止時のデータ復旧ソフトがあったため、関係者の手によってこれをベースに上記の基準を満たす独立したソフトに改変され実用に供されている。その概略がブログ上でアナウンスされている。(→ OpenDolphin HTML/PDF Viewer

OpenDolphin のサーバ・クライアントが停止したとしてもデータベースから(厳密に言えばデータベースのバックアップデータのみからでも)カルテ記載内容を直接復号しブラウザ上に表示できるるため、ガイドラインの基準を完全にクリアしている。

なお、それ以外の OpenDolphin に関しては、この手の独立バックアップソフトの存在自体が開発者からアナウンスされておらず、電子カルテに乗り換え時のエピソード(直接データコンバートは行えず、新旧システムの併用。あるいは旧システムデータ紙出力の上、新システムへの手入力)から考えて少なくとも実用レベルのソフト自体が提供されていないと考えられる。

現在のガイドライン基準に照らしあわせると、このようなソフトは電子カルテとは言えない。

実際、一部の Dolphin は、(監査の観点から)地域によっては使用禁止となっている。

歴史的評価

OpenDolphin-2.7m の開発者である猪股弘明氏は標準型電子カルテの技術作業班の席上で以下のように「いにしえのオーパーツ」と評している

今となってはいにしえのオーパーツみたいなものですが、オープンドルフィンという経産省が旗振りをしたオープンソースの電子カルテがありました。あれは、商用化は、LSCというところがある程度やっていましたが、結局売れなくて、現在はメドレーが引き取ったような形になっています。オープンドルフィンは自力運用している施設が多くて、多分その次ぐらいに私がカスタマイズしたバージョンが普及していたようですが、私は対価は一銭ももらっていませんし、サポートもできる限り無料で答えていました。

商業的には成功とは言えなかったが、ソースコードが公開されていた関係上、以下に示すようにドルフィンプロジェクトに影響を受けたプロダクツが存在する。

OpenDolphin インスパイア系プロジェクト

現在の観点から見ると基本設計的には古くなった感のある OpenDolphin であるが、GUI リッチなエディタ・REST API の採用・ORM を利用した本格的な永続化システムなど当時としては最新の技術が採用され、現在でも通用する部分も多い。

そのため、これにインスパイアされたプロジェクトが存在する。

omcake

古林敬一先生が cakePHP で作成した「電子カルテもどき」(古林先生談)。
機能面での実装はまだ不十分であるが、カルテ記載内容の永続化方法は OpenDolphin の影響を受けている。

(参考)
古林先生のリポジトリ: https://github.com/keiichif/omcake

air-h-128k-il 氏のリポジトリ: https://github.com/air-h-128k-il/omcake 

WebDolphORCA

それまでしばしば問題とされてきた OpenDolphin のデータ抽出機能・閲覧機能を解決するため、猪股弘明氏を中心として OpenDolphin HTML/PDF Viewer プロジェクトが発足された。
このプロジェクトの目標はほぼ実現されたため、これをベースにして3層クラサバアーキテクチャの採用・ウェブ化・独自の WYSIWYG エディタの実装などがなされた電子カルテのプロトタイプが試験的に作成された。
まだ、完成はされていないが、プロトタイプの公開・進捗状況などは YouTube などで適宜アナウンスされている。

また、メイン開発者の猪股弘明氏が医療DXの一環として開発が予定されている標準型電子カルテの技術作業班に呼ばれた際には、WebDolphORCA をベースとしたシステムを提案したという。

(適宜更新予定。ただし、ある程度推測を含む事項などは β 版の方が充実しています)

ANN2b

協力:猪股弘明

pathComponents

pathComponents

NSString のインスタンスメソッド。

何をやっているかは公式の説明と図がわかりやすいでしょう。

The strings in the array appear in the order they did in the receiver. If the string begins or ends with the path separator, then the first or last component, respectively, will contain the separator.

 

Nitrogen の謎

使うばかりではアレなので、HorliX/Horos/OsiriX のソースコードを読む。

早速、AppController(現在でいうところの AppDelegate です)の init メソッド内の以下のところでつっかかる。

AppController.m

[[NSFileManager defaultManager] removeItemAtPath:[[NSFileManager defaultManager] tmpDirPath] error:NULL];

なんだよ tmpDirPath って(笑)。

もちろん、ノーマル NSFileManager にこんなメソッドはなく、おそらくどこかで拡張してんだろうなあと物色したら、Nitrogen というフォルダ(のサブフォルダ)に収められていた。

しかし、なんだろ、Nitrogen って?

Objective-C におけるクラスの拡張(というのだろうか?オーバーライドといっていい)は、カテゴリを使うという手法があるようだ。
カテゴリによって新たにつくられたクラスは、慣例的に「元のクラス+特徴」というファイル名を持つ。

だから、上の例では NSFileManager+N2.h と NSFileManager+N2.m で NSFileManager の拡張機能を担っている。

この N が Nitrogen から来ているのでは?と想像はつくが、なぜ Nitrogen というネーミングにしたんだろうねと疑問に思ったという次第です。

 

2024 年 9 月

福慈会の続きなど

福慈会』が、東京〜神奈川の精神科医のバイト先の参考資料、としてけっこう評判いいようなので、このコンセプトで続きやろうかなと。

と言っても、この手の「お手軽に働ける小〜中規模の精神病院」なんてそうあるものでもないが。

南晴病院、ワシン坂病院、かまくら山、青木病院・・・あたりは記事化できそう。

 

(続く)