static final String APPLICATION_DICOM_JSON_CHARSET_UTF8 = "application/dicom+json; charset=utf-8"; static final String APPLICATION_DICOM_TRANSFER_SYNTAX = "application/dicom; transfer-syntax=*"; static final String APPLICATION_JSON_CHARSET_UTF8 = "application/json; charset=utf-8"; static final String BEARER = "Bearer "; static final String HEALTHCARE_HOST = "healthcare.googleapis.com"; static final String MULTIPART_RELATED_TYPE_APPLICATION_DICOM_BOUNDARY =
    "multipart/related; type=application/dicom; boundary="; static final String PARAM_DICOM_STORE_ID = "dicomStoreId"; static final String PARAM_INCLUDE_FIELD = "includefield"; static final String PARAM_INSTANCE_ID = "SOPInstanceUID"; static final String PARAM_LIMIT = "limit"; static final String PARAM_OFFSET = "offset"; static final String PARAM_PAGE_TOKEN = "pageToken"; static final String PARAM_SERIES_ID = "SeriesInstanceUID"; static final String PARAM_STUDY_ID = "StudyInstanceUID"; static final String SCHEME = "https"; public static final Integer VALUE_PARAM_MAX_LIMIT_FOR_INSTANCES = 15000; // max - 50 000 results public static final Integer VALUE_PARAM_MAX_LIMIT_FOR_SERIES = 5000; public static final Integer VALUE_PARAM_MAX_LIMIT_FOR_STUDY = 5000; static final String VALUE_PARAM_SERIES_INSTANCE_UID = "0020000E"; static final String VALUE_PARAM_STUDY_INSTANCE_UID = "0020000D"; public class AuthAdc {

  private static final List<String> SCOPES = Collections.singletonList(
      "https://www.googleapis.com/auth/cloud-healthcare"
  );
  private GoogleCredentials googleCredentials;

  public AuthAdc(GoogleCredentials googleCredentials) {
    this.googleCredentials = googleCredentials;
  }

  public AuthAdc() {
  }

  public void createCredentials(Path keyPath) throws IOException {
    InputStream inputStream = new FileInputStream(keyPath.toFile());
    googleCredentials = GoogleCredentials.fromStream(inputStream).createScoped(SCOPES);
  }

  public void createCredentials() throws IOException {
    googleCredentials = GoogleCredentials.getApplicationDefault().createScoped(SCOPES);
  }

  public GoogleCredentials getCredentials() throws IOException {
    googleCredentials.getRequestMetadata(); // Update token if it necessary.
    return googleCredentials;
  }
} public interface HttpClientFactory {

  CloseableHttpClient createHttpClient();
} public class DicomStorePathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public DicomStorePathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStore = queryBuilder.getDicomStoreId();
    if (dicomStore == null) {
      throw new DicomFuseException("DICOM Store must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES
        + dicomStore;
  }

} public class DicomStoresPathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public DicomStoresPathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES;
  }
} public class InstancePathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public InstancePathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStoreId = queryBuilder.getDicomStoreId();
    if (dicomStoreId == null) {
      throw new DicomFuseException("Dicom store must not be null!");
    }
    String studyId = queryBuilder.getStudyId();
    if (studyId == null) {
      throw new DicomFuseException("Study must not be null!");
    }
    String seriesId = queryBuilder.getSeriesId();
    if (seriesId == null) {
      throw new DicomFuseException("Series must not be null!");
    }
    String instanceId = queryBuilder.getInstanceId();
    if (instanceId == null) {
      throw new DicomFuseException("Instance must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES +
        dicomStoreId + DICOM_WEB + STUDIES + studyId + SERIES + seriesId + INSTANCES +
        instanceId;
  }
} public class InstancesPathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public InstancesPathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStoreId = queryBuilder.getDicomStoreId();
    if (dicomStoreId == null) {
      throw new DicomFuseException("Dicom store must not be null!");
    }
    String studyId = queryBuilder.getStudyId();
    if (studyId == null) {
      throw new DicomFuseException("Study must not be null!");
    }
    String seriesId = queryBuilder.getSeriesId();
    if (seriesId == null) {
      throw new DicomFuseException("Series must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES +
        dicomStoreId + DICOM_WEB + STUDIES + studyId + SERIES + seriesId + INSTANCES;
  }
} public class QueryBuilder {

  private CloudConf cloudConf;
  private String dicomStoreId;
  private String studyId;
  private String seriesId;
  private String instanceId;
  private Path instanceDataPath;
  private DicomPath dicomPath;
  private Integer offset = 0;

  private QueryBuilder() {
  }

  public static QueryBuilder forConfiguration(CloudConf cloudConf) {
    QueryBuilder queryBuilder = new QueryBuilder();
    queryBuilder.cloudConf = cloudConf;
    return queryBuilder;
  }

  public QueryBuilder setDicomStoreId(String dicomStoreId) {
    this.dicomStoreId = dicomStoreId;
    return this;
  }

  public QueryBuilder setStudyId(String studyId) {
    this.studyId = studyId;
    return this;
  }

  public QueryBuilder setSeriesId(String seriesId) {
    this.seriesId = seriesId;
    return this;
  }

  public QueryBuilder setInstanceId(String instanceId) {
    this.instanceId = instanceId;
    return this;
  }

  public QueryBuilder setInstanceDataPath(Path instanceDataPath) {
    this.instanceDataPath = instanceDataPath;
    return this;
  }

  public QueryBuilder setDicomPath(DicomPath dicomPath) {
    this.dicomPath = dicomPath;
    return this;
  }

  public QueryBuilder setOffset(Integer offset) {
    this.offset = offset;
    return this;
  }

  public CloudConf getCloudConf() {
    return cloudConf;
  }

  public String getDicomStoreId() {
    return dicomStoreId;
  }

  public String getStudyId() {
    return studyId;
  }

  public String getSeriesId() {
    return seriesId;
  }

  public String getInstanceId() {
    return instanceId;
  }

  public Path getInstanceDataPath() {
    return instanceDataPath;
  }

  public DicomPath getDicomPath() {
    return dicomPath;
  }

  public Integer getOffset() {
    return offset;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    QueryBuilder that = (QueryBuilder) o;
    return Objects.equals(cloudConf, that.cloudConf) &&
        Objects.equals(dicomStoreId, that.dicomStoreId) &&
        Objects.equals(studyId, that.studyId) &&
        Objects.equals(seriesId, that.seriesId) &&
        Objects.equals(instanceId, that.instanceId) &&
        Objects.equals(instanceDataPath, that.instanceDataPath) &&
        Objects.equals(dicomPath, that.dicomPath) &&
        Objects.equals(offset, that.offset);
  }

  @Override
  public int hashCode() {
    return Objects
        .hash(cloudConf, dicomStoreId, studyId, seriesId, instanceId, instanceDataPath, dicomPath,
            offset);
  }
} public class SeriesPathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public SeriesPathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStoreId = queryBuilder.getDicomStoreId();
    if (dicomStoreId == null) {
      throw new DicomFuseException("Dicom store must not be null!");
    }
    String studyId = queryBuilder.getStudyId();
    if (studyId == null) {
      throw new DicomFuseException("Study must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES +
        dicomStoreId + DICOM_WEB + STUDIES + studyId + SERIES;
  }
} public class SingleDicomStorePathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public SingleDicomStorePathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStore = queryBuilder.getDicomStoreId();
    if (dicomStore == null) {
      throw new DicomFuseException("DICOM Store must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES
        + dicomStore;
  }
} public class StudiesPathBuilder implements PathBuilder {

  private QueryBuilder queryBuilder;

  public StudiesPathBuilder(QueryBuilder queryBuilder) {
    this.queryBuilder = queryBuilder;
  }

  @Override
  public String toPath() throws DicomFuseException {
    String stage = queryBuilder.getCloudConf().getStage();
    if (stage == null) {
      throw new DicomFuseException("Stage must not be null!");
    }
    String project = queryBuilder.getCloudConf().getProject();
    if (project == null) {
      throw new DicomFuseException("Project must not be null!");
    }
    String location = queryBuilder.getCloudConf().getLocation();
    if (location == null) {
      throw new DicomFuseException("Location must not be null!");
    }
    String dataset = queryBuilder.getCloudConf().getDataSet();
    if (dataset == null) {
      throw new DicomFuseException("Dataset must not be null!");
    }
    String dicomStoreId = queryBuilder.getDicomStoreId();
    if (dicomStoreId == null) {
      throw new DicomFuseException("Dicom store must not be null!");
    }
    return stage + PROJECTS + project + LOCATIONS + location + DATASETS + dataset + DICOM_STORES +
        dicomStoreId + DICOM_WEB + STUDIES;
  }
} public class DicomPath {

  private static final String DCM_EXTENSION = ".dcm";
  private final DicomPathLevel dicomPathLevel;
  private final String dicomStoreId;
  private final String studyInstanceUID;
  private final String seriesInstanceUID;
  private final String sopInstanceUID;
  private final String fileName;


  public static class Builder {

    private final DicomPathLevel dicomPathLevel;
    private String dicomStoreId = "";
    private String studyInstanceUID = "";
    private String seriesInstanceUID = "";
    private String sopInstanceUID = "";
    private String fileName = "";

    public Builder(DicomPathLevel dicomPathLevel) {
      this.dicomPathLevel = dicomPathLevel;
    }

    public Builder dicomStoreId(String dicomStoreId) {
      this.dicomStoreId = dicomStoreId;
      return this;
    }

    public Builder studyInstanceUID(String studyInstanceUID) {
      this.studyInstanceUID = studyInstanceUID;
      return this;
    }

    public Builder seriesInstanceUID(String seriesInstanceUID) {
      this.seriesInstanceUID = seriesInstanceUID;
      return this;
    }

    public Builder sopInstanceUID(String sopInstanceUID) {
      this.sopInstanceUID = sopInstanceUID;
      return this;
    }

    public Builder fileName(String fileName) {
      this.fileName = fileName;
      return this;
    }

    public DicomPath build() {
      return new DicomPath(this);
    }
  }

  private DicomPath(Builder builder) {
    dicomPathLevel = builder.dicomPathLevel;
    dicomStoreId = builder.dicomStoreId;
    studyInstanceUID = builder.studyInstanceUID;
    seriesInstanceUID = builder.seriesInstanceUID;
    sopInstanceUID = builder.sopInstanceUID;
    fileName = builder.fileName;
  }

  public DicomPathLevel getDicomPathLevel() {
    return dicomPathLevel;
  }

  public String getDicomStoreId() {
    return dicomStoreId;
  }

  public String getStudyInstanceUID() {
    return studyInstanceUID;
  }

  public String getSeriesInstanceUID() {
    return seriesInstanceUID;
  }

  public String getSopInstanceUID() {
    return sopInstanceUID;
  }

  public String getFileName() {
    return fileName;
  }

  @Override
  public String toString() {
    StringBuilder stringBuilder = new StringBuilder();
    switch (dicomPathLevel) {
      case DATASET:
        break;
      case DICOM_STORE:
        stringBuilder.append(dicomStoreId);
        break;
      case STUDY:
        stringBuilder.append(dicomStoreId);
        stringBuilder.append("/");
        stringBuilder.append(studyInstanceUID);
        break;
      case SERIES:
        stringBuilder.append(dicomStoreId);
        stringBuilder.append("/");
        stringBuilder.append(studyInstanceUID);
        stringBuilder.append("/");
        stringBuilder.append(seriesInstanceUID);
        break;
      case INSTANCE:
        stringBuilder.append(dicomStoreId);
        stringBuilder.append("/");
        stringBuilder.append(studyInstanceUID);
        stringBuilder.append("/");
        stringBuilder.append(seriesInstanceUID);
        stringBuilder.append("/");
        stringBuilder.append(sopInstanceUID);
        stringBuilder.append(DCM_EXTENSION);
        break;
      case TEMP_FILE_IN_DICOM_STORE:
        stringBuilder.append(dicomStoreId);
        stringBuilder.append("/");
        stringBuilder.append(fileName);
        break;
      case TEMP_FILE_IN_SERIES:
        stringBuilder.append(dicomStoreId);
        stringBuilder.append("/");
        stringBuilder.append(studyInstanceUID);
        stringBuilder.append("/");
        stringBuilder.append(seriesInstanceUID);
        stringBuilder.append("/");
        stringBuilder.append(fileName);
        break;
      default:
    }
    return stringBuilder.toString();
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    DicomPath dicomPath = (DicomPath) o;
    return dicomPathLevel == dicomPath.dicomPathLevel &&
        Objects.equals(dicomStoreId, dicomPath.dicomStoreId) &&
        Objects.equals(studyInstanceUID, dicomPath.studyInstanceUID) &&
        Objects.equals(seriesInstanceUID, dicomPath.seriesInstanceUID) &&
        Objects.equals(sopInstanceUID, dicomPath.sopInstanceUID) &&
        Objects.equals(fileName, dicomPath.fileName);
  }

  @Override
  public int hashCode() {
    return Objects
        .hash(dicomPathLevel, dicomStoreId, studyInstanceUID, seriesInstanceUID, sopInstanceUID,
            fileName);
  }
} public class DicomStore {

  private String dicomStoreId;

  public DicomStore() {
  }

  @JsonCreator
  public DicomStore(@JsonProperty("name") String name) {
    String[] arr = name.split("/");
    this.dicomStoreId = arr[arr.length - 1];
  }

  public String getDicomStoreId() {
    return dicomStoreId;
  }

  public void setDicomStoreId(String dicomStoreId) {
    this.dicomStoreId = dicomStoreId;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    DicomStore that = (DicomStore) o;
    return dicomStoreId.equals(that.dicomStoreId);
  }

  @Override
  public int hashCode() {
    return Objects.hash(dicomStoreId);
  }
} public class DicomStores {

  private List<DicomStore> dicomStores;
  private String nextPageToken;

  public List<DicomStore> getDicomStores() {
    return dicomStores;
  }

  public String getNextPageToken() {
    return nextPageToken;
  }
} @JsonInclude(JsonInclude.Include.NON_NULL)
public class Instance {

  @JsonProperty("0020000D")
  private DicomAttribute<String> studyInstanceUID;
  @JsonProperty("0020000E")
  private DicomAttribute<String> seriesInstanceUID;
  @JsonProperty("00080018")
  private DicomAttribute<String> sopInstanceUID;

  public DicomAttribute<String> getStudyInstanceUID() {
    return studyInstanceUID;
  }

  public void setStudyInstanceUID(DicomAttribute<String> studyInstanceUID) {
    this.studyInstanceUID = studyInstanceUID;
  }

  public DicomAttribute<String> getSeriesInstanceUID() {
    return seriesInstanceUID;
  }

  public void setSeriesInstanceUID(DicomAttribute<String> seriesInstanceUID) {
    this.seriesInstanceUID = seriesInstanceUID;
  }

  public DicomAttribute<String> getSopInstanceUID() {
    return sopInstanceUID;
  }

  public void setSopInstanceUID(DicomAttribute<String> sopInstanceUID) {
    this.sopInstanceUID = sopInstanceUID;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Instance instance = (Instance) o;
    return studyInstanceUID.equals(instance.studyInstanceUID) &&
        seriesInstanceUID.equals(instance.seriesInstanceUID) &&
        sopInstanceUID.equals(instance.sopInstanceUID);
  }

  @Override
  public int hashCode() {
    return Objects.hash(studyInstanceUID, seriesInstanceUID, sopInstanceUID);
  }
} public class Series {

  @JsonProperty("0020000D")
  private DicomAttribute<String> studyInstanceUID;
  @JsonProperty("0020000E")
  private DicomAttribute<String> seriesInstanceUID;

  public DicomAttribute<String> getStudyInstanceUID() {
    return studyInstanceUID;
  }

  public void setStudyInstanceUID(DicomAttribute<String> studyInstanceUID) {
    this.studyInstanceUID = studyInstanceUID;
  }

  public DicomAttribute<String> getSeriesInstanceUID() {
    return seriesInstanceUID;
  }

  public void setSeriesInstanceUID(DicomAttribute<String> seriesInstanceUID) {
    this.seriesInstanceUID = seriesInstanceUID;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Series series = (Series) o;
    return studyInstanceUID.equals(series.studyInstanceUID) &&
        seriesInstanceUID.equals(series.seriesInstanceUID);
  }

  @Override
  public int hashCode() {
    return Objects.hash(studyInstanceUID, seriesInstanceUID);
  }
} public class Study {

  @JsonProperty("0020000D")
  private DicomAttribute<String> studyInstanceUID;

  public DicomAttribute<String> getStudyInstanceUID() {
    return studyInstanceUID;
  }

  public void setStudyInstanceUID(DicomAttribute<String> studyInstanceUID) {
    this.studyInstanceUID = studyInstanceUID;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Study study = (Study) o;
    return studyInstanceUID.equals(study.studyInstanceUID);
  }

  @Override
  public int hashCode() {
    return Objects.hash(studyInstanceUID);
  }
} public class DicomFuseException extends Exception {

  private int statusCode;

  public DicomFuseException(String message) {
    super(message);
  }

  public DicomFuseException(String message, Exception e) {
    super(message, e);
  }

  public DicomFuseException(Exception e) {
    super(e);
  }

  public DicomFuseException(String message, int statusCode) {
    super(message);
    this.statusCode = statusCode;
  }

  public int getStatusCode() {
    return statusCode;
  }
} public class StowErrorFormatter {

  public static final String CONTENT_TYPE_DICOM_XML = "application/dicom+xml";

  public static String formatByMimeType(String errorBody, String mimeType) {
    switch (mimeType) {
      case CONTENT_TYPE_DICOM_XML:
        Document parsedError = Jsoup.parse(errorBody, "", Parser.xmlParser());
        parsedError.outputSettings().prettyPrint(true);
        return parsedError.toString();
      default:
        return errorBody;
    }
  }
}
import static com.google.dicomwebfuse.dao.Constants.APPLICATION_DICOM_JSON_CHARSET_UTF8;
import static com.google.dicomwebfuse.dao.Constants.APPLICATION_DICOM_TRANSFER_SYNTAX;
import static com.google.dicomwebfuse.dao.Constants.APPLICATION_JSON_CHARSET_UTF8;
import static com.google.dicomwebfuse.dao.Constants.BEARER;
import static com.google.dicomwebfuse.dao.Constants.HEALTHCARE_HOST;
import static com.google.dicomwebfuse.dao.Constants.MULTIPART_RELATED_TYPE_APPLICATION_DICOM_BOUNDARY;
import static com.google.dicomwebfuse.dao.Constants.PARAM_DICOM_STORE_ID;
import static com.google.dicomwebfuse.dao.Constants.PARAM_INCLUDE_FIELD;
import static com.google.dicomwebfuse.dao.Constants.PARAM_INSTANCE_ID;
import static com.google.dicomwebfuse.dao.Constants.PARAM_LIMIT;
import static com.google.dicomwebfuse.dao.Constants.PARAM_OFFSET;
import static com.google.dicomwebfuse.dao.Constants.PARAM_PAGE_TOKEN;
import static com.google.dicomwebfuse.dao.Constants.PARAM_SERIES_ID;
import static com.google.dicomwebfuse.dao.Constants.PARAM_STUDY_ID;
import static com.google.dicomwebfuse.dao.Constants.SCHEME;
import static com.google.dicomwebfuse.dao.Constants.VALUE_PARAM_MAX_LIMIT_FOR_INSTANCES;
import static com.google.dicomwebfuse.dao.Constants.VALUE_PARAM_MAX_LIMIT_FOR_SERIES;
import static com.google.dicomwebfuse.dao.Constants.VALUE_PARAM_MAX_LIMIT_FOR_STUDY;
import static com.google.dicomwebfuse.dao.Constants.VALUE_PARAM_SERIES_INSTANCE_UID;
import static com.google.dicomwebfuse.dao.Constants.VALUE_PARAM_STUDY_INSTANCE_UID;
import static org.apache.http.HttpHeaders.ACCEPT;
import static org.apache.http.HttpHeaders.AUTHORIZATION;
import static org.apache.http.HttpHeaders.CONTENT_TYPE;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.http.HttpStatusCodes;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.dicomwebfuse.auth.AuthAdc;
import com.google.dicomwebfuse.dao.http.HttpClientFactory;
import com.google.dicomwebfuse.dao.spec.DicomStorePathBuilder;
import com.google.dicomwebfuse.dao.spec.DicomStoresPathBuilder;
import com.google.dicomwebfuse.dao.spec.InstancePathBuilder;
import com.google.dicomwebfuse.dao.spec.InstancesPathBuilder;
import com.google.dicomwebfuse.dao.spec.QueryBuilder;
import com.google.dicomwebfuse.dao.spec.SeriesPathBuilder;
import com.google.dicomwebfuse.dao.spec.SingleDicomStorePathBuilder;
import com.google.dicomwebfuse.dao.spec.StudiesPathBuilder;
import com.google.dicomwebfuse.entities.DicomPath;
import com.google.dicomwebfuse.entities.DicomStore;
import com.google.dicomwebfuse.entities.DicomStores;
import com.google.dicomwebfuse.entities.Instance;
import com.google.dicomwebfuse.entities.Series;
import com.google.dicomwebfuse.entities.Study;
import com.google.dicomwebfuse.exception.DicomFuseException;
import com.google.dicomwebfuse.exception.StowErrorFormatter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.dicomwebfuse.dao;




public class FuseDaoImpl implements FuseDao {

  private AuthAdc authAdc;
  private ObjectMapper objectMapper;
  private HttpClientFactory httpClientFactory;

  public FuseDaoImpl(AuthAdc authAdc, HttpClientFactory httpClientFactory) {
    this.authAdc = authAdc;
    this.httpClientFactory = httpClientFactory;
    objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  }

  @Override
  public List<DicomStore> getAllDicomStores(QueryBuilder queryBuilder)
      throws DicomFuseException {