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}