001package org.hl7.fhir.r5.context;
002
003import java.io.File;
004import java.sql.Connection;
005import java.sql.DriverManager;
006import java.sql.PreparedStatement;
007import java.sql.SQLException;
008import java.sql.Statement;
009import java.sql.Types;
010import java.util.HashSet;
011import java.util.Set;
012
013import lombok.extern.slf4j.Slf4j;
014import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
015import org.hl7.fhir.utilities.json.model.JsonObject;
016import org.hl7.fhir.utilities.json.parser.JsonParser;
017
018@MarkedToMoveToAdjunctPackage
019@Slf4j
020public class OidIndexBuilder {
021
022  private File folder;
023  private File target;
024
025  public OidIndexBuilder(File ff, File of) {
026    super();
027    this.folder = ff;
028    this.target = of;
029  }
030
031  public void build() {
032    log.info("Generate OID index for "+folder.getAbsolutePath());
033    target.delete();
034    try {
035      Set<String> matches = new HashSet<String>();
036      
037      Connection db = DriverManager.getConnection("jdbc:sqlite:"+target.getAbsolutePath());
038      Statement stmt = db.createStatement();
039      stmt.execute("CREATE TABLE OIDMap (\r\n"+
040          "OID            nvarchar NOT NULL,\r\n"+
041          "TYPE           nvarchar NOT NULL,\r\n"+
042          "URL            nvarchar NOT NULL,\r\n"+
043          "VERSION        nvarchar NOT NULL,\r\n"+
044          "Status         nvarchar NOT NULL,\r\n"+
045          "PRIMARY KEY (OID, URL))\r\n");
046
047      PreparedStatement psql = db.prepareStatement("Insert into OIDMap (OID, TYPE, URL, VERSION, Status) values (?, ?, ?, ?, ?)");
048      for (File f : folder.listFiles()) {
049        if (!f.getName().startsWith(".") && f.getName().endsWith(".json")) {
050          try {
051            JsonObject json = JsonParser.parseObject(f);
052            processFile(psql, matches, json);
053          } catch (Exception e) {
054            log.error("Error processing "+f.getAbsolutePath()+" while generating OIDs: "+e.getMessage(), e);
055          }
056        }
057      }
058      db.close();
059    } catch (Exception e) {
060      log.error("Error processing "+folder.getAbsolutePath()+" while generating OIDs: "+e.getMessage(), e);
061    }
062  }  
063
064  private void processFile(PreparedStatement psql, Set<String> matches, JsonObject json) throws SQLException {
065    String rt = json.asString("resourceType");
066    if (rt != null) {
067      Set<String> oids = new HashSet<String>();
068      String url = null;
069      String status = json.asString("status");
070      String version = json.asString("version");
071      if ("NamingSystem".equals(rt)) {        
072        for (JsonObject id : json.getJsonObjects("uniqueId")) {
073          String t = id.asString("type");
074          String v = id.asString("value");
075          if ("url".equals(t) && v != null) {
076            url = v;
077          } else if ("oid".equals(t) && v != null) {
078            oids.add(v);
079          }
080        }
081        if (url != null) {
082          for (String s : oids) {
083            addOid(psql, matches, s, rt, url, version, status);
084          }
085        }
086      } else {            
087        if (json.hasPrimitive("url")) { 
088          url = json.asString("url");
089          if (json.has("oid")) {
090            oids.add(json.asString("oid"));
091          }
092          if (json.has("url")) {
093            String v = json.asString("url");
094            if (v != null && v.startsWith("urn:oid:")) {
095              oids.add(v.substring(8));
096            }
097          }
098
099          for (JsonObject id : json.getJsonObjects("identifier")) {
100            String v = id.asString("value");
101            if (v != null && v.startsWith("urn:oid:")) {
102              oids.add(v.substring(8));
103            }
104          }
105          if (!oids.isEmpty()) {
106            for (String s : oids) {
107              addOid(psql, matches, s, rt, url, version, status);
108            }
109          }
110        }
111      }
112    }
113  }
114
115  private void addOid(PreparedStatement psql, Set<String> matches, String oid, String type, String url, String version, String status) throws SQLException {
116    String key = oid+"@"+url;
117    if (!matches.contains(key)) {
118      matches.add(key);
119      psql.setString(1, oid);
120      psql.setString(2, type);
121      psql.setString(3, url);
122      if (version == null) {
123        psql.setNull(4, Types.NVARCHAR);
124      } else {
125        psql.setString(4, version);  
126      }
127      psql.setString(5, status);
128      psql.execute();
129    }
130
131  }
132
133}