All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hl7.fhir.dstu3.hapi.rest.server.ServerCapabilityStatementProvider Maven / Gradle / Ivy

There is a newer version: 7.4.0
Show newest version
/*
 * #%L
 * HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)
 * %%
 * Copyright (C) 2014 - 2015 University Health Network
 * %%
 * 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.
 * #L%
 */
package org.hl7.fhir.dstu3.hapi.rest.server;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.Bindings;
import ca.uhn.fhir.rest.server.IServerConformanceProvider;
import ca.uhn.fhir.rest.server.ResourceBinding;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerConfiguration;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
import ca.uhn.fhir.rest.server.method.IParameter;
import ca.uhn.fhir.rest.server.method.OperationMethodBinding;
import ca.uhn.fhir.rest.server.method.OperationMethodBinding.ReturnType;
import ca.uhn.fhir.rest.server.method.OperationParameter;
import ca.uhn.fhir.rest.server.method.SearchMethodBinding;
import ca.uhn.fhir.rest.server.method.SearchParameter;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.util.BaseServerCapabilityStatementProvider;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementKind;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.ConditionalDeleteStatus;
import org.hl7.fhir.dstu3.model.CapabilityStatement.ResourceInteractionComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.RestfulCapabilityMode;
import org.hl7.fhir.dstu3.model.CapabilityStatement.SystemRestfulInteraction;
import org.hl7.fhir.dstu3.model.CapabilityStatement.TypeRestfulInteraction;
import org.hl7.fhir.dstu3.model.CapabilityStatement.UnknownContentCode;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.OperationDefinition;
import org.hl7.fhir.dstu3.model.OperationDefinition.OperationDefinitionParameterComponent;
import org.hl7.fhir.dstu3.model.OperationDefinition.OperationKind;
import org.hl7.fhir.dstu3.model.OperationDefinition.OperationParameterUse;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.ResourceType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

/**
 * Server FHIR Provider which serves the conformance statement for a RESTful server implementation
 *
 * 

* Note: This class is safe to extend, but it is important to note that the same instance of {@link CapabilityStatement} is always returned unless {@link #setCache(boolean)} is called with a value of * false. This means that if you are adding anything to the returned conformance instance on each call you should call setCache(false) in your provider constructor. *

*/ public class ServerCapabilityStatementProvider extends BaseServerCapabilityStatementProvider implements IServerConformanceProvider { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProvider.class); private String myPublisher = "Not provided"; /** * No-arg constructor and setter so that the ServerConformanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen. */ public ServerCapabilityStatementProvider() { super(); } /** * Constructor * * @deprecated Use no-args constructor instead. Deprecated in 4.0.0 */ @Deprecated public ServerCapabilityStatementProvider(RestfulServer theRestfulServer) { this(); } /** * Constructor - This is intended only for JAX-RS server */ public ServerCapabilityStatementProvider(RestfulServerConfiguration theServerConfiguration) { super(theServerConfiguration); } private void checkBindingForSystemOps( CapabilityStatementRestComponent rest, Set systemOps, BaseMethodBinding nextMethodBinding) { if (nextMethodBinding.getRestOperationType() != null) { String sysOpCode = nextMethodBinding.getRestOperationType().getCode(); if (sysOpCode != null) { SystemRestfulInteraction sysOp; try { sysOp = SystemRestfulInteraction.fromCode(sysOpCode); } catch (FHIRException e) { return; } if (sysOp == null) { return; } if (systemOps.contains(sysOp) == false) { systemOps.add(sysOp); rest.addInteraction().setCode(sysOp); } } } } private Map> collectMethodBindings(RequestDetails theRequestDetails) { Map> resourceToMethods = new TreeMap<>(); for (ResourceBinding next : getServerConfiguration(theRequestDetails).getResourceBindings()) { String resourceName = next.getResourceName(); for (BaseMethodBinding nextMethodBinding : next.getMethodBindings()) { if (resourceToMethods.containsKey(resourceName) == false) { resourceToMethods.put(resourceName, new ArrayList<>()); } resourceToMethods.get(resourceName).add(nextMethodBinding); } } for (BaseMethodBinding nextMethodBinding : getServerConfiguration(theRequestDetails).getServerBindings()) { String resourceName = ""; if (resourceToMethods.containsKey(resourceName) == false) { resourceToMethods.put(resourceName, new ArrayList<>()); } resourceToMethods.get(resourceName).add(nextMethodBinding); } return resourceToMethods; } private DateTimeType conformanceDate(RequestDetails theRequestDetails) { IPrimitiveType buildDate = getServerConfiguration(theRequestDetails).getConformanceDate(); if (buildDate != null && buildDate.getValue() != null) { try { return new DateTimeType(buildDate.getValueAsString()); } catch (DataFormatException e) { // fall through } } return DateTimeType.now(); } private String createNamedQueryName(SearchMethodBinding searchMethodBinding) { StringBuilder retVal = new StringBuilder(); if (searchMethodBinding.getResourceName() != null) { retVal.append(searchMethodBinding.getResourceName()); } retVal.append("-query-"); retVal.append(searchMethodBinding.getQueryName()); return retVal.toString(); } private String createOperationName(OperationMethodBinding theMethodBinding) { StringBuilder retVal = new StringBuilder(); if (theMethodBinding.getResourceName() != null) { retVal.append(theMethodBinding.getResourceName()); } retVal.append('-'); if (theMethodBinding.isCanOperateAtInstanceLevel()) { retVal.append('i'); } if (theMethodBinding.isCanOperateAtServerLevel()) { retVal.append('s'); } retVal.append('-'); // Exclude the leading $ retVal.append(theMethodBinding.getName(), 1, theMethodBinding.getName().length()); return retVal.toString(); } /** * Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The * value defaults to "Not provided" but may be set to null, which will cause this element to be omitted. */ public String getPublisher() { return myPublisher; } /** * Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The * value defaults to "Not provided" but may be set to null, which will cause this element to be omitted. */ public void setPublisher(String thePublisher) { myPublisher = thePublisher; } @SuppressWarnings("EnumSwitchStatementWhichMissesCases") @Override @Metadata public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) { RestfulServerConfiguration serverConfiguration = getServerConfiguration(theRequestDetails); Bindings bindings = serverConfiguration.provideBindings(); CapabilityStatement retVal = new CapabilityStatement(); retVal.setPublisher(myPublisher); retVal.setDateElement(conformanceDate(theRequestDetails)); retVal.setFhirVersion(FhirVersionEnum.DSTU3.getFhirVersionString()); retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big // effort since the parser // needs to be modified to actually allow it ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE)); String serverBase = serverConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest); retVal.getImplementation() .setUrl(serverBase) .setDescription(serverConfiguration.getImplementationDescription()); retVal.setKind(CapabilityStatementKind.INSTANCE); retVal.getSoftware().setName(serverConfiguration.getServerName()); retVal.getSoftware().setVersion(serverConfiguration.getServerVersion()); retVal.addFormat(Constants.CT_FHIR_XML_NEW); retVal.addFormat(Constants.CT_FHIR_JSON_NEW); retVal.addFormat(Constants.FORMAT_JSON); retVal.addFormat(Constants.FORMAT_XML); retVal.setStatus(PublicationStatus.ACTIVE); CapabilityStatementRestComponent rest = retVal.addRest(); rest.setMode(RestfulCapabilityMode.SERVER); Set systemOps = new HashSet<>(); Set operationNames = new HashSet<>(); Map> resourceToMethods = collectMethodBindings(theRequestDetails); Map> resourceNameToSharedSupertype = serverConfiguration.getNameToSharedSupertype(); for (Entry> nextEntry : resourceToMethods.entrySet()) { if (nextEntry.getKey().isEmpty() == false) { Set resourceOps = new HashSet<>(); CapabilityStatementRestResourceComponent resource = rest.addResource(); String resourceName = nextEntry.getKey(); RuntimeResourceDefinition def; FhirContext context = serverConfiguration.getFhirContext(); if (resourceNameToSharedSupertype.containsKey(resourceName)) { def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName)); } else { def = context.getResourceDefinition(resourceName); } resource.getTypeElement().setValue(def.getName()); resource.getProfile().setReference((def.getResourceProfile(serverBase))); TreeSet includes = new TreeSet<>(); // Map nameToSearchParam = new HashMap(); for (BaseMethodBinding nextMethodBinding : nextEntry.getValue()) { if (nextMethodBinding.getRestOperationType() != null) { String resOpCode = nextMethodBinding.getRestOperationType().getCode(); if (resOpCode != null) { TypeRestfulInteraction resOp; try { resOp = TypeRestfulInteraction.fromCode(resOpCode); } catch (Exception e) { resOp = null; } if (resOp != null) { if (resourceOps.contains(resOp) == false) { resourceOps.add(resOp); resource.addInteraction().setCode(resOp); } if ("vread".equals(resOpCode)) { // vread implies read resOp = TypeRestfulInteraction.READ; if (resourceOps.contains(resOp) == false) { resourceOps.add(resOp); resource.addInteraction().setCode(resOp); } } if (nextMethodBinding.isSupportsConditional()) { switch (resOp) { case CREATE: resource.setConditionalCreate(true); break; case DELETE: if (nextMethodBinding.isSupportsConditionalMultiple()) { resource.setConditionalDelete(ConditionalDeleteStatus.MULTIPLE); } else { resource.setConditionalDelete(ConditionalDeleteStatus.SINGLE); } break; case UPDATE: resource.setConditionalUpdate(true); break; default: break; } } } } } checkBindingForSystemOps(rest, systemOps, nextMethodBinding); if (nextMethodBinding instanceof SearchMethodBinding) { SearchMethodBinding methodBinding = (SearchMethodBinding) nextMethodBinding; if (methodBinding.getQueryName() != null) { String queryName = bindings.getNamedSearchMethodBindingToName().get(methodBinding); if (operationNames.add(queryName)) { rest.addOperation() .setName(methodBinding.getQueryName()) .setDefinition(new Reference("OperationDefinition/" + queryName)); } } else { handleNamelessSearchMethodBinding( rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding, theRequestDetails); } } else if (nextMethodBinding instanceof OperationMethodBinding) { OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding; String opName = bindings.getOperationBindingToId().get(methodBinding); if (operationNames.add(opName)) { // Only add each operation (by name) once rest.addOperation() .setName(methodBinding.getName().substring(1)) .setDefinition(new Reference("OperationDefinition/" + opName)); } } resource.getInteraction().sort(new Comparator() { @Override public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) { TypeRestfulInteraction o1 = theO1.getCode(); TypeRestfulInteraction o2 = theO2.getCode(); if (o1 == null && o2 == null) { return 0; } if (o1 == null) { return 1; } if (o2 == null) { return -1; } return o1.ordinal() - o2.ordinal(); } }); } for (String nextInclude : includes) { resource.addSearchInclude(nextInclude); } } else { for (BaseMethodBinding nextMethodBinding : nextEntry.getValue()) { checkBindingForSystemOps(rest, systemOps, nextMethodBinding); if (nextMethodBinding instanceof OperationMethodBinding) { OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding; String opName = bindings.getOperationBindingToId().get(methodBinding); if (operationNames.add(opName)) { ourLog.debug("Found bound operation: {}", opName); rest.addOperation() .setName(methodBinding.getName().substring(1)) .setDefinition(new Reference("OperationDefinition/" + opName)); } } } } } maybeAddBulkDataDeclarationToConformingToIg(retVal, serverConfiguration.getServerBindings()); return retVal; } private void handleNamelessSearchMethodBinding( CapabilityStatementRestComponent rest, CapabilityStatementRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet includes, SearchMethodBinding searchMethodBinding, RequestDetails theRequestDetails) { includes.addAll(searchMethodBinding.getIncludes()); List params = searchMethodBinding.getParameters(); List searchParameters = new ArrayList<>(); for (IParameter nextParameter : params) { if ((nextParameter instanceof SearchParameter)) { searchParameters.add((SearchParameter) nextParameter); } } sortSearchParameters(searchParameters); if (!searchParameters.isEmpty()) { // boolean allOptional = searchParameters.get(0).isRequired() == false; // // OperationDefinition query = null; // if (!allOptional) { // RestOperation operation = rest.addOperation(); // query = new OperationDefinition(); // operation.setDefinition(new ResourceReferenceDt(query)); // query.getDescriptionElement().setValue(searchMethodBinding.getDescription()); // query.addUndeclaredExtension(false, ExtensionConstants.QUERY_RETURN_TYPE, new CodeDt(resourceName)); // for (String nextInclude : searchMethodBinding.getIncludes()) { // query.addUndeclaredExtension(false, ExtensionConstants.QUERY_ALLOWED_INCLUDE, new StringDt(nextInclude)); // } // } for (SearchParameter nextParameter : searchParameters) { String nextParamName = nextParameter.getName(); String chain = null; String nextParamUnchainedName = nextParamName; if (nextParamName.contains(".")) { chain = nextParamName.substring(nextParamName.indexOf('.') + 1); nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.')); } String nextParamDescription = nextParameter.getDescription(); /* * If the parameter has no description, default to the one from the resource */ if (StringUtils.isBlank(nextParamDescription)) { RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName); if (paramDef != null) { nextParamDescription = paramDef.getDescription(); } } CapabilityStatementRestResourceSearchParamComponent param = resource.addSearchParam(); param.setName(nextParamUnchainedName); // if (StringUtils.isNotBlank(chain)) { // param.addChain(chain); // } // // if (nextParameter.getParamType() == RestSearchParameterTypeEnum.REFERENCE) { // for (String nextWhitelist : new TreeSet(nextParameter.getQualifierWhitelist())) { // if (nextWhitelist.startsWith(".")) { // param.addChain(nextWhitelist.substring(1)); // } // } // } param.setDocumentation(nextParamDescription); if (nextParameter.getParamType() != null) { param.getTypeElement() .setValueAsString(nextParameter.getParamType().getCode()); } for (Class nextTarget : nextParameter.getDeclaredTypes()) { RuntimeResourceDefinition targetDef = getServerConfiguration(theRequestDetails) .getFhirContext() .getResourceDefinition(nextTarget); if (targetDef != null) { ResourceType code; try { code = ResourceType.fromCode(targetDef.getName()); } catch (FHIRException e) { code = null; } // if (code != null) { // param.addTarget(targetDef.getName()); // } } } } } } @Read(type = OperationDefinition.class) public OperationDefinition readOperationDefinition(@IdParam IdType theId, RequestDetails theRequestDetails) { if (theId == null || theId.hasIdPart() == false) { throw new ResourceNotFoundException(Msg.code(628) + theId); } RestfulServerConfiguration serverConfiguration = getServerConfiguration(theRequestDetails); Bindings bindings = serverConfiguration.provideBindings(); List operationBindings = bindings.getOperationIdToBindings().get(theId.getIdPart()); if (operationBindings != null && !operationBindings.isEmpty()) { return readOperationDefinitionForOperation(operationBindings); } List searchBindings = bindings.getSearchNameToBindings().get(theId.getIdPart()); if (searchBindings != null && !searchBindings.isEmpty()) { return readOperationDefinitionForNamedSearch(searchBindings); } throw new ResourceNotFoundException(Msg.code(2257) + theId); } private OperationDefinition readOperationDefinitionForNamedSearch(List bindings) { OperationDefinition op = new OperationDefinition(); op.setStatus(PublicationStatus.ACTIVE); op.setKind(OperationKind.QUERY); op.setIdempotent(true); op.setSystem(false); op.setType(false); op.setInstance(false); Set inParams = new HashSet<>(); for (SearchMethodBinding binding : bindings) { if (isNotBlank(binding.getDescription())) { op.setDescription(binding.getDescription()); } if (isBlank(binding.getResourceProviderResourceName())) { op.setSystem(true); } else { op.setType(true); op.addResourceElement().setValue(binding.getResourceProviderResourceName()); } op.setCode(binding.getQueryName()); for (IParameter nextParamUntyped : binding.getParameters()) { if (nextParamUntyped instanceof SearchParameter) { SearchParameter nextParam = (SearchParameter) nextParamUntyped; if (!inParams.add(nextParam.getName())) { continue; } OperationDefinitionParameterComponent param = op.addParameter(); param.setUse(OperationParameterUse.IN); param.setType("string"); param.getSearchTypeElement() .setValueAsString(nextParam.getParamType().getCode()); param.setMin(nextParam.isRequired() ? 1 : 0); param.setMax("1"); param.setName(nextParam.getName()); } } if (isBlank(op.getName())) { if (isNotBlank(op.getDescription())) { op.setName(op.getDescription()); } else { op.setName(op.getCode()); } } } return op; } private OperationDefinition readOperationDefinitionForOperation(List bindings) { OperationDefinition op = new OperationDefinition(); op.setStatus(PublicationStatus.ACTIVE); op.setKind(OperationKind.OPERATION); op.setIdempotent(true); // We reset these to true below if we find a binding that can handle the level op.setSystem(false); op.setType(false); op.setInstance(false); Set inParams = new HashSet<>(); Set outParams = new HashSet<>(); for (OperationMethodBinding sharedDescription : bindings) { if (isNotBlank(sharedDescription.getDescription())) { op.setDescription(sharedDescription.getDescription()); } if (sharedDescription.isCanOperateAtInstanceLevel()) { op.setInstance(true); } if (sharedDescription.isCanOperateAtServerLevel()) { op.setSystem(true); } if (sharedDescription.isCanOperateAtTypeLevel()) { op.setType(true); } if (!sharedDescription.isIdempotent()) { op.setIdempotent(sharedDescription.isIdempotent()); } op.setCode(sharedDescription.getName().substring(1)); if (sharedDescription.isCanOperateAtInstanceLevel()) { op.setInstance(sharedDescription.isCanOperateAtInstanceLevel()); } if (sharedDescription.isCanOperateAtServerLevel()) { op.setSystem(sharedDescription.isCanOperateAtServerLevel()); } if (isNotBlank(sharedDescription.getResourceName())) { op.addResourceElement().setValue(sharedDescription.getResourceName()); } for (IParameter nextParamUntyped : sharedDescription.getParameters()) { if (nextParamUntyped instanceof OperationParameter) { OperationParameter nextParam = (OperationParameter) nextParamUntyped; if (!inParams.add(nextParam.getName())) { continue; } OperationDefinitionParameterComponent param = op.addParameter(); param.setUse(OperationParameterUse.IN); if (nextParam.getParamType() != null) { param.setType(nextParam.getParamType()); } if (nextParam.getSearchParamType() != null) { param.getSearchTypeElement().setValueAsString(nextParam.getSearchParamType()); } param.setMin(nextParam.getMin()); param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax())); param.setName(nextParam.getName()); } } for (ReturnType nextParam : sharedDescription.getReturnParams()) { if (!outParams.add(nextParam.getName())) { continue; } OperationDefinitionParameterComponent param = op.addParameter(); param.setUse(OperationParameterUse.OUT); if (nextParam.getType() != null) { param.setType(nextParam.getType()); } param.setMin(nextParam.getMin()); param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax())); param.setName(nextParam.getName()); } } if (isBlank(op.getName())) { if (isNotBlank(op.getDescription())) { op.setName(op.getDescription()); } else { op.setName(op.getCode()); } } if (op.hasSystem() == false) { op.setSystem(false); } if (op.hasInstance() == false) { op.setInstance(false); } return op; } /** * Sets the cache property (default is true). If set to true, the same response will be returned for each invocation. *

* See the class documentation for an important note if you are extending this class *

* * @deprecated Since 4.0.0 this doesn't do anything */ public ServerCapabilityStatementProvider setCache(boolean theCache) { return this; } @Override public void setRestfulServer(RestfulServer theRestfulServer) { // ignore } private void sortSearchParameters(List searchParameters) { Collections.sort(searchParameters, new Comparator() { @Override public int compare(SearchParameter theO1, SearchParameter theO2) { if (theO1.isRequired() == theO2.isRequired()) { return theO1.getName().compareTo(theO2.getName()); } if (theO1.isRequired()) { return -1; } return 1; } }); } private void maybeAddBulkDataDeclarationToConformingToIg( CapabilityStatement theCapabilityStatement, List theServerBindings) { boolean bulkExportEnabled = theServerBindings.stream() .filter(OperationMethodBinding.class::isInstance) .map(OperationMethodBinding.class::cast) .map(OperationMethodBinding::getName) .anyMatch(ProviderConstants.OPERATION_EXPORT::equals); if (bulkExportEnabled) { theCapabilityStatement.addInstantiates(Constants.BULK_DATA_ACCESS_IG_URL); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy