
001package org.hl7.fhir.r5.terminologies.utilities; 002 003import java.util.List; 004 005import org.hl7.fhir.exceptions.FHIRException; 006import org.hl7.fhir.exceptions.TerminologyServiceException; 007import org.hl7.fhir.r5.context.IWorkerContext; 008import org.hl7.fhir.r5.model.OperationOutcome.IssueType; 009import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.TerminologyServiceProtectionException; 010import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 011import org.hl7.fhir.utilities.Utilities; 012import org.hl7.fhir.utilities.i18n.I18nConstants; 013import org.hl7.fhir.utilities.validation.ValidationOptions; 014 015import java.util.ArrayList; 016 017@MarkedToMoveToAdjunctPackage 018public class TerminologyOperationContext { 019 020 public static class TerminologyServiceProtectionException extends FHIRException { 021 022 private TerminologyServiceErrorClass error; 023 private IssueType type; 024 private String diagnostics; 025 026 public TerminologyServiceProtectionException(String message, TerminologyServiceErrorClass error, IssueType type) { 027 super(message); 028 this.error = error; 029 this.type = type; 030 } 031 public TerminologyServiceProtectionException(String message, TerminologyServiceErrorClass error, IssueType type, String diagnostics) { 032 super(message); 033 this.error = error; 034 this.type = type; 035 this.diagnostics = diagnostics; 036 } 037 038 public TerminologyServiceErrorClass getError() { 039 return error; 040 } 041 042 public IssueType getType() { 043 return type; 044 } 045 public String getDiagnostics() { 046 return diagnostics; 047 } 048 049 } 050 051 public static boolean debugging = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("-agentlib:jdwp") > 0; 052 private static final int EXPANSION_DEAD_TIME_SECS = 60; 053 private long deadTime; 054 private int nestCount = 0; 055 private long startTime; 056 private List<String> contexts = new ArrayList<>(); 057 private IWorkerContext worker; 058 private boolean original; 059 private ValidationOptions options; 060 private String name; 061 private List<String> notes = new ArrayList<>(); 062 063 public TerminologyOperationContext(IWorkerContext worker, ValidationOptions options, String name) { 064 super(); 065 this.worker = worker; 066 this.original = true; 067 this.options = options; 068 this.name = name; 069 this.startTime = System.currentTimeMillis(); 070 071 if (EXPANSION_DEAD_TIME_SECS == 0 || debugging) { 072 deadTime = 0; 073 } else { 074 deadTime = System.currentTimeMillis() + (EXPANSION_DEAD_TIME_SECS * 1000); 075 } 076 } 077 078 private TerminologyOperationContext(ValidationOptions options, String name) { 079 super(); 080 this.options = options; 081 this.name = name; 082 this.startTime = System.currentTimeMillis(); 083 } 084 085 public TerminologyOperationContext copy() { 086 TerminologyOperationContext ret = new TerminologyOperationContext(this.options, name); 087 ret.worker = worker; 088 ret.contexts.addAll(contexts); 089 ret.deadTime = deadTime; 090 ret.notes = notes; 091 ret.startTime = startTime; 092 ret.nestCount = nestCount + 1; 093 return ret; 094 } 095 096 public void deadCheck(String note) { 097 note(note); 098 if (deadTime != 0 && System.currentTimeMillis() > deadTime) { 099 System.out.println(); 100 System.out.println("Operation took too long - longer than "+(deadTime - startTime)+"ms"); 101 for (String s : notes) { 102 System.out.println(s); 103 } 104 throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_TOO_COSTLY_TIME, contexts.get(0), EXPANSION_DEAD_TIME_SECS, name+" (local)"), TerminologyServiceErrorClass.TOO_COSTLY, IssueType.TOOCOSTLY); 105 } 106 } 107 108 public void seeContext(String context) { 109 if (contexts.contains(context)) { 110 throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_CIRCULAR_REFERENCE, context, contexts.toString()), TerminologyServiceErrorClass.PROCESSING, IssueType.PROCESSING); 111 } 112 contexts.add(context); 113 } 114 115 public boolean isOriginal() { 116 return original; 117 } 118 119 public ValidationOptions getOptions() { 120 return options; 121 } 122 123 public void note(String s) { 124 s = Utilities.padLeft("", ' ', nestCount)+" "+(System.currentTimeMillis() - startTime)+" "+s; 125 notes.add(s); 126 } 127}