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.i18n.I18nConstants; 011import org.hl7.fhir.utilities.validation.ValidationOptions; 012 013import java.util.ArrayList; 014 015public class TerminologyOperationContext { 016 017 public static class TerminologyServiceProtectionException extends FHIRException { 018 019 private TerminologyServiceErrorClass error; 020 private IssueType type; 021 022 public TerminologyServiceProtectionException(String message, TerminologyServiceErrorClass error, IssueType type) { 023 super(message); 024 this.error = error; 025 this.type = type; 026 } 027 028 public TerminologyServiceErrorClass getError() { 029 return error; 030 } 031 032 public IssueType getType() { 033 return type; 034 } 035 036 } 037 038 public static boolean debugging = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("-agentlib:jdwp") > 0; 039 private static final int EXPANSION_DEAD_TIME_SECS = 60; 040 private long deadTime; 041 private List<String> contexts = new ArrayList<>(); 042 private IWorkerContext worker; 043 private boolean original; 044 private ValidationOptions options; 045 046 public TerminologyOperationContext(IWorkerContext worker, ValidationOptions options) { 047 super(); 048 this.worker = worker; 049 this.original = true; 050 this.options = options; 051 052 if (EXPANSION_DEAD_TIME_SECS == 0 || debugging) { 053 deadTime = 0; 054 } else { 055 deadTime = System.currentTimeMillis() + (EXPANSION_DEAD_TIME_SECS * 1000); 056 } 057 } 058 059 private TerminologyOperationContext(ValidationOptions options) { 060 super(); 061 this.options = options; 062 } 063 064 public TerminologyOperationContext copy() { 065 TerminologyOperationContext ret = new TerminologyOperationContext(this.options); 066 ret.worker = worker; 067 ret.contexts.addAll(contexts); 068 ret.deadTime = deadTime; 069 return ret; 070 } 071 072 public void deadCheck() { 073 if (deadTime != 0 && System.currentTimeMillis() > deadTime) { 074 throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_TOO_COSTLY_TIME, contexts.get(0), EXPANSION_DEAD_TIME_SECS), TerminologyServiceErrorClass.TOO_COSTLY, IssueType.TOOCOSTLY); 075 } 076 } 077 078 public void seeContext(String context) { 079 if (contexts.contains(context)) { 080 throw new TerminologyServiceProtectionException(worker.formatMessage(I18nConstants.VALUESET_CIRCULAR_REFERENCE, context, contexts.toString()), TerminologyServiceErrorClass.PROCESSING, IssueType.PROCESSING); 081 } 082 contexts.add(context); 083 } 084 085 public boolean isOriginal() { 086 return original; 087 } 088 089 public ValidationOptions getOptions() { 090 return options; 091 } 092 093 094}