mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-09 06:14:45 +00:00
Build OID -> URL Index
This commit is contained in:
parent
e8a162cabb
commit
a10ac3c590
@ -43,6 +43,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.Getter;
|
||||
@ -74,11 +75,13 @@ import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||
import org.hl7.fhir.r5.model.IdType;
|
||||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||
import org.hl7.fhir.r5.model.Library;
|
||||
import org.hl7.fhir.r5.model.Measure;
|
||||
import org.hl7.fhir.r5.model.NamingSystem;
|
||||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemIdentifierType;
|
||||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemType;
|
||||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
@ -133,11 +136,16 @@ import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nBase;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.json.JsonException;
|
||||
import org.hl7.fhir.utilities.json.model.JsonArray;
|
||||
import org.hl7.fhir.utilities.json.model.JsonProperty;
|
||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions.ValueSetMode;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -241,7 +249,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
|
||||
private UcumService ucumService;
|
||||
protected Map<String, byte[]> binaries = new HashMap<String, byte[]>();
|
||||
protected Map<String, String> oidCache = new HashMap<>();
|
||||
protected Map<String, String> oidCacheCS = new HashMap<>();
|
||||
protected Map<String, String> oidCacheOth = new HashMap<>();
|
||||
protected Map<String, String> oidCacheManual = new HashMap<>();
|
||||
protected List<String> oidFiles = new ArrayList<>();
|
||||
|
||||
protected Map<String, Map<String, ValidationResult>> validationCache = new HashMap<String, Map<String,ValidationResult>>();
|
||||
protected String name;
|
||||
@ -323,7 +334,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
codeSystemsUsed.addAll(other.codeSystemsUsed);
|
||||
ucumService = other.ucumService;
|
||||
binaries.putAll(other.binaries);
|
||||
oidCache.putAll(other.oidCache);
|
||||
oidCacheCS.putAll(other.oidCacheCS);
|
||||
oidCacheOth.putAll(other.oidCacheOth);
|
||||
validationCache.putAll(other.validationCache);
|
||||
tlogging = other.tlogging;
|
||||
locator = other.locator;
|
||||
@ -446,7 +458,36 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
}
|
||||
|
||||
if (r instanceof CodeSystem || r instanceof NamingSystem) {
|
||||
oidCache.clear();
|
||||
oidCacheCS.clear();
|
||||
String url = null;
|
||||
Set<String> oids = new HashSet<String>();
|
||||
if (r instanceof CodeSystem) {
|
||||
CodeSystem cs = (CodeSystem) r;
|
||||
url = cs.getUrl();
|
||||
for (Identifier id : cs.getIdentifier()) {
|
||||
if (id.hasValue() && id.getValue().startsWith("urn:oid:")) {
|
||||
oids.add(id.getValue().substring(8));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r instanceof NamingSystem) {
|
||||
NamingSystem ns = ((NamingSystem) r);
|
||||
if (ns.getKind() == NamingSystemType.CODESYSTEM) {
|
||||
for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) {
|
||||
if (id.getType() == NamingSystemIdentifierType.URI) {
|
||||
url = id.getValue();
|
||||
}
|
||||
if (id.getType() == NamingSystemIdentifierType.OID) {
|
||||
oids.add(id.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (url != null) {
|
||||
for (String s : oids) {
|
||||
oidCacheManual.put(s, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r instanceof CanonicalResource) {
|
||||
@ -2778,4 +2819,53 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||
this.cachingAllowed = cachingAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String urlForOid(boolean codeSystem, String oid) {
|
||||
if (oid == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> cache = codeSystem ?oidCacheCS : oidCacheOth;
|
||||
|
||||
if (cache.isEmpty()) {
|
||||
loadOidCache();
|
||||
}
|
||||
if (cache.containsKey(oid)) {
|
||||
return cache.get(oid);
|
||||
}
|
||||
switch (oid) {
|
||||
case "2.16.840.1.113883.6.1" : return "http://loinc.org";
|
||||
case "2.16.840.1.113883.6.96" : return "http://snomed.info/sct";
|
||||
default:return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void loadOidCache() {
|
||||
oidCacheCS.putAll(oidCacheManual);
|
||||
for (String ff : oidFiles) {
|
||||
File f = new File(ff);
|
||||
if (f.exists()) {
|
||||
org.hl7.fhir.utilities.json.model.JsonObject oids = null;
|
||||
try {
|
||||
oids = JsonParser.parseObject(f);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (oids != null && oids.has("cs")) {
|
||||
loadOids(oidCacheCS, oids.getJsonObject("cs"));
|
||||
}
|
||||
if (oids != null && oids.has("other")) {
|
||||
loadOids(oidCacheOth, oids.getJsonObject("other"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadOids(Map<String, String> cache, org.hl7.fhir.utilities.json.model.JsonObject oids) {
|
||||
for (JsonProperty p : oids.getProperties()) {
|
||||
JsonArray a = (JsonArray) p.getValue();
|
||||
for (String s : a.asStrings()) {
|
||||
cache.put(s, p.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1034,5 +1034,6 @@ public interface IWorkerContext {
|
||||
public boolean isForPublication();
|
||||
public void setForPublication(boolean value);
|
||||
|
||||
public String urlForOid(boolean codeSystem, String oid);
|
||||
|
||||
}
|
@ -482,6 +482,8 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
||||
packageTracker.packageLoaded(pi.id(), pi.version());
|
||||
}
|
||||
|
||||
oidFiles.add(pi.getFolders().get("package").oidIndexFile());
|
||||
|
||||
if ((types == null || types.size() == 0) && loader != null) {
|
||||
types = loader.getTypes();
|
||||
}
|
||||
@ -803,5 +805,6 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
||||
return VersionUtilities.getSpecUrl(getVersion())+"/";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -311,6 +311,22 @@ public class NpmPackage {
|
||||
}
|
||||
}
|
||||
}
|
||||
public JsonObject oidIndex() throws IOException {
|
||||
if (folder == null) {
|
||||
return null;
|
||||
} else {
|
||||
File ij = new File(fn(".oids.json"));
|
||||
if (ij.exists()) {
|
||||
return JsonParser.parseObject(ij);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String oidIndexFile() throws IOException {
|
||||
return fn(".oids.json");
|
||||
}
|
||||
}
|
||||
|
||||
private String path;
|
||||
@ -597,10 +613,37 @@ public class NpmPackage {
|
||||
JsonObject index = folder.index();
|
||||
if (index == null || index.forceArray("files").size() == 0) {
|
||||
indexFolder(desc, folder);
|
||||
}
|
||||
index = folder.oidIndex();
|
||||
if (index == null || index.forceArray("oids").size() == 0) {
|
||||
indexOidsInFolder(desc, folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void indexOidsInFolder(String desc, NpmPackageFolder folder) throws FileNotFoundException, IOException {
|
||||
List<String> remove = new ArrayList<>();
|
||||
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
|
||||
indexer.start(folder.folder != null ? Utilities.path(folder.folder.getAbsolutePath(), ".index.db") : null);
|
||||
for (String n : folder.listFiles()) {
|
||||
if (!indexer.seeOidsInFile(n, folder.fetchFile(n))) {
|
||||
remove.add(n);
|
||||
}
|
||||
}
|
||||
for (String n : remove) {
|
||||
folder.removeFile(n);
|
||||
}
|
||||
String json = JsonParser.compose(indexer.getOidIndex(), true);
|
||||
try {
|
||||
if (folder.folder != null) {
|
||||
TextFile.stringToFile(json, Utilities.path(folder.folder.getAbsolutePath(), ".oids.json"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TextFile.stringToFile(json, Utilities.path("[tmp]", ".oids.json"));
|
||||
throw new IOException("Error parsing "+(desc == null ? "" : desc+"#")+"package/"+folder.folderName+"/.oids.json: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void indexFolder(String desc, NpmPackageFolder folder) throws FileNotFoundException, IOException {
|
||||
List<String> remove = new ArrayList<>();
|
||||
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
|
||||
|
@ -7,8 +7,11 @@ import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.json.model.JsonArray;
|
||||
@ -31,12 +34,21 @@ public class NpmPackageIndexBuilder {
|
||||
private Connection conn;
|
||||
private PreparedStatement psql;
|
||||
private String dbFilename;
|
||||
private JsonObject oidIndex;
|
||||
private JsonObject oidIndexCS;
|
||||
private JsonObject oidIndexOther;
|
||||
|
||||
public void start(String filename) {
|
||||
index = new JsonObject();
|
||||
index.add("index-version", CURRENT_INDEX_VERSION);
|
||||
files = new JsonArray();
|
||||
index.add("files", files);
|
||||
|
||||
oidIndex = new JsonObject();
|
||||
oidIndexCS = new JsonObject();
|
||||
oidIndex.add("cs", oidIndexCS);
|
||||
oidIndexOther = new JsonObject();
|
||||
oidIndex.add("other", oidIndexOther);
|
||||
|
||||
|
||||
dbFilename = filename;
|
||||
@ -59,7 +71,7 @@ public class NpmPackageIndexBuilder {
|
||||
"Derivation nvarchar NULL,\r\n"+
|
||||
"PRIMARY KEY (FileName))\r\n");
|
||||
|
||||
psql = conn.prepareStatement("Insert into ResourceList (FileName, ResourceType, Id, Url, Version, Kind, Type, Supplements, Content, ValueSet) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
psql = conn.prepareStatement("Insert into ResourceList (FileName, ResourceType, Id, Url, Version, Kind, Type, Supplements, Content, ValueSet, OIDs) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
} catch (Exception e) {
|
||||
if (conn != null) {
|
||||
try {
|
||||
@ -109,6 +121,7 @@ public class NpmPackageIndexBuilder {
|
||||
if (json.hasPrimitive("derivation")) {
|
||||
fi.add("derivation", json.asString("derivation"));
|
||||
}
|
||||
|
||||
if (psql != null) {
|
||||
psql.setString(1, name); // FileName);
|
||||
psql.setString(2, json.asString("resourceType")); // ResourceType");
|
||||
@ -133,7 +146,70 @@ public class NpmPackageIndexBuilder {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean seeOidsInFile(String name, byte[] content) {
|
||||
if (name.endsWith(".json")) {
|
||||
try {
|
||||
JsonObject json = JsonParser.parseObject(content);
|
||||
String rt = json.asString("resourceType");
|
||||
if (rt != null) {
|
||||
Set<String> oids = new HashSet<String>();
|
||||
String url = null;
|
||||
if ("NamingSystem".equals(rt)) {
|
||||
|
||||
for (JsonObject id : json.getJsonObjects("uniqueId")) {
|
||||
String t = id.asString("type");
|
||||
String v = id.asString("value");
|
||||
if ("url".equals(t) && v != null) {
|
||||
url = v;
|
||||
} else if ("oid".equals(t) && v != null) {
|
||||
oids.add(v);
|
||||
}
|
||||
}
|
||||
JsonArray a = new JsonArray();
|
||||
("codesystem".equals(json.asString("kind")) ? oidIndexCS : oidIndexOther).add(url, a);
|
||||
for (String s : oids) {
|
||||
a.add(s);
|
||||
}
|
||||
} else {
|
||||
if (json.hasPrimitive("url")) {
|
||||
if (json.has("oid")) {
|
||||
oids.add(json.asString("oid"));
|
||||
}
|
||||
if (json.has("url")) {
|
||||
String v = json.asString("url");
|
||||
if (v != null && v.startsWith("urn:oid:")) {
|
||||
oids.add(v.substring(8));
|
||||
}
|
||||
}
|
||||
|
||||
for (JsonObject id : json.getJsonObjects("identifier")) {
|
||||
String v = id.asString("value");
|
||||
if (v != null && v.startsWith("urn:oid:")) {
|
||||
oids.add(v.substring(8));
|
||||
}
|
||||
}
|
||||
if (!oids.isEmpty()) {
|
||||
JsonArray a = new JsonArray();
|
||||
("CodeSystem".equals(rt) ? oidIndexCS : oidIndexOther).add(json.asString("url"), a);
|
||||
for (String s : oids) {
|
||||
a.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error parsing "+name+": "+e.getMessage());
|
||||
if (name.contains("openapi")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public String build() {
|
||||
try {
|
||||
if (conn != null) {
|
||||
@ -215,4 +291,8 @@ public class NpmPackageIndexBuilder {
|
||||
return dbFilename;
|
||||
}
|
||||
|
||||
public JsonObject getOidIndex() {
|
||||
return oidIndex;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user