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