Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
James 2017-10-17 16:43:46 -04:00
commit fd4efd638f
8 changed files with 279 additions and 239 deletions

View File

@ -24,6 +24,7 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import java.util.*;
import java.util.Map.Entry;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@ -47,7 +48,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
@Qualifier("mySystemDaoDstu2")
private IFhirSystemDao<Bundle, MetaDt> mySystemDao;
@Autowired
@Autowired(required = false)
private IFulltextSearchSvc mySearchDao;
//@formatter:off
@ -178,7 +179,8 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
@OperationParam(name="searchParam", min=1, max=1) String theSearchParam,
@OperationParam(name="text", min=1, max=1) String theText
) {
JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
throw new InvalidRequestException("Parameter 'context' must be provided");
}
@ -188,16 +190,14 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
if (isBlank(theText)) {
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {
//@formatter:off
retVal.addParameter()
.addPart(new Parameter().setName("keyword").setValue(new StringDt(next.getTerm())))
.addPart(new Parameter().setName("score").setValue(new DecimalDt(next.getScore())));
//@formatter:on
}
return retVal;

View File

@ -1,5 +1,27 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.StringUtils.isBlank;
/*
@ -11,9 +33,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* 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.
@ -21,23 +43,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* limitations under the License.
* #L%
*/
import java.util.*;
import java.util.Map.Entry;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundle, Meta> {
@ -45,122 +50,122 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
@Qualifier("mySystemDaoDstu3")
private IFhirSystemDao<Bundle, Meta> mySystemDao;
@Autowired
@Autowired(required = false)
private IFulltextSearchSvc mySearchDao;
//@formatter:off
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerType.class, min=0, max=1),/"
@Operation(name="$get-resource-counts", idempotent=true, returnParameters= {
@OperationParam(name="AllergyIntolerance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Appointment", type=IntegerType.class, min=0, max=1),
@OperationParam(name="AppointmentResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="AuditEvent", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Basic", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Binary", type=IntegerType.class, min=0, max=1),
@OperationParam(name="BodySite", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Bundle", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CarePlan", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CarePlan2", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Claim", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ClaimResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ClinicalImpression", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Communication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CommunicationRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Composition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ConceptMap", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Condition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Conformance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Contract", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Contraindication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Coverage", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DataElement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Device", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceComponent", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceMetric", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceUseRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceUseStatement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DiagnosticOrder", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DiagnosticReport", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DocumentManifest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DocumentReference", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EligibilityRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EligibilityResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Encounter", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EnrollmentRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EnrollmentResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EpisodeOfCare", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ExplanationOfBenefit", type=IntegerType.class, min=0, max=1),
@OperationParam(name="FamilyMemberHistory", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Flag", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Goal", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Group", type=IntegerType.class, min=0, max=1),
@OperationParam(name="HealthcareService", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImagingObjectSelection", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImagingStudy", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Immunization", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImmunizationRecommendation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ListResource", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Location", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Media", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Medication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationAdministration", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationDispense", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationPrescription", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationStatement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MessageHeader", type=IntegerType.class, min=0, max=1),
@OperationParam(name="NamingSystem", type=IntegerType.class, min=0, max=1),
@OperationParam(name="NutritionOrder", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Observation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OperationDefinition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OperationOutcome", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Order", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OrderResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Organization", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Parameters", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Patient", type=IntegerType.class, min=0, max=1),
@OperationParam(name="PaymentNotice", type=IntegerType.class, min=0, max=1),
@OperationParam(name="PaymentReconciliation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Person", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Practitioner", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Procedure", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcedureRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcessRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcessResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Provenance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Questionnaire", type=IntegerType.class, min=0, max=1),
@OperationParam(name="QuestionnaireAnswers", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ReferralRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="RelatedPerson", type=IntegerType.class, min=0, max=1),
@OperationParam(name="RiskAssessment", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Schedule", type=IntegerType.class, min=0, max=1),
@OperationParam(name="SearchParameter", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Slot", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Specimen", type=IntegerType.class, min=0, max=1),
@OperationParam(name="StructureDefinition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Subscription", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Substance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Supply", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ValueSet", type=IntegerType.class, min=0, max=1),
@OperationParam(name="VisionPrescription", type=IntegerType.class, min=0, max=1)
@Operation(name = "$get-resource-counts", idempotent = true, returnParameters = {
@OperationParam(name = "AllergyIntolerance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Appointment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AppointmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AuditEvent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Basic", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Binary", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "BodySite", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Bundle", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan2", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Claim", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClaimResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClinicalImpression", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Communication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CommunicationRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Composition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ConceptMap", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Condition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Conformance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contract", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contraindication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Coverage", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DataElement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Device", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceComponent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceMetric", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticReport", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentManifest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentReference", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Encounter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EpisodeOfCare", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ExplanationOfBenefit", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "FamilyMemberHistory", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Flag", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Goal", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Group", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "HealthcareService", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingObjectSelection", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingStudy", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Immunization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImmunizationRecommendation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ListResource", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Location", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Media", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Medication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationAdministration", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationDispense", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationPrescription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MessageHeader", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NamingSystem", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NutritionOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Observation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationOutcome", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Order", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OrderResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Organization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Parameters", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Patient", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentNotice", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentReconciliation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Person", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Practitioner", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Procedure", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcedureRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Provenance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Questionnaire", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "QuestionnaireAnswers", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ReferralRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RelatedPerson", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RiskAssessment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Schedule", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "SearchParameter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Slot", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Specimen", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "StructureDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Subscription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Substance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Supply", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ValueSet", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "VisionPrescription", type = IntegerType.class, min = 0, max = 1)
})
@Description(shortDefinition="Provides the number of resources currently stored on the server, broken down by resource type")
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
//@formatter:on
public Parameters getResourceCounts() {
Parameters retVal = new Parameters();
Map<String, Long> counts = mySystemDao.getResourceCounts();
counts = new TreeMap<String, Long>(counts);
for (Entry<String, Long> nextEntry : counts.entrySet()) {
retVal.addParameter().setName((nextEntry.getKey())).setValue(new IntegerType(nextEntry.getValue().intValue()));
}
return retVal;
}
//@formatter:off
@Operation(name="$meta", idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = "$meta", idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
@ -168,14 +173,15 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
parameters.addParameter().setName("return").setValue(getDao().metaGetOperation(theRequestDetails));
return parameters;
}
@Operation(name="$suggest-keywords", idempotent=true)
@Operation(name = "$suggest-keywords", idempotent = true)
public Parameters suggestKeywords(
@OperationParam(name="context", min=1, max=1) String theContext,
@OperationParam(name="searchParam", min=1, max=1) String theSearchParam,
@OperationParam(name="text", min=1, max=1) String theText
) {
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
throw new InvalidRequestException("Parameter 'context' must be provided");
}
@ -185,21 +191,21 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
if (isBlank(theText)) {
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {
//@formatter:off
retVal.addParameter()
.addPart(new ParametersParameterComponent().setName("keyword").setValue(new StringType(next.getTerm())))
.addPart(new ParametersParameterComponent().setName("score").setValue(new DecimalType(next.getScore())));
.addPart(new ParametersParameterComponent().setName("keyword").setValue(new StringType(next.getTerm())))
.addPart(new ParametersParameterComponent().setName("score").setValue(new DecimalType(next.getScore())));
//@formatter:on
}
return retVal;
}
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
@ -210,4 +216,10 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
}
}
public static void validateFulltextSearchEnabled(IFulltextSearchSvc theSearchDao) {
if (theSearchDao == null || theSearchDao.isDisabled()) {
throw new InvalidRequestException("Fulltext searching is disabled on this server");
}
}
}

View File

@ -120,7 +120,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
protected Object myResourceProviders;
@Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
@Autowired
@Autowired(required = false)
protected IFulltextSearchSvc mySearchDao;
@Autowired
protected ISearchParamPresenceSvc mySearchParamPresenceSvc;

View File

@ -172,7 +172,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
protected IResourceTagDao myResourceTagDao;
@Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
@Autowired
@Autowired(required = false)
protected IFulltextSearchSvc mySearchDao;
@Autowired
protected ISearchDao mySearchEntityDao;

View File

@ -181,7 +181,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
protected IResourceTagDao myResourceTagDao;
@Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
@Autowired
@Autowired(required = false)
protected IFulltextSearchSvc mySearchDao;
@Autowired
protected ISearchDao mySearchEntityDao;

View File

@ -1646,7 +1646,6 @@
<artifactId>maven-scm-api</artifactId>
<version>1.9.5</version>
</dependency>
<!-- <dependency> <groupId>org.apache.maven.doxia</groupId> <artifactId>doxia-core</artifactId> <version>1.7</version> </dependency> -->
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-module-markdown</artifactId>
@ -1686,17 +1685,11 @@
</execution>
</executions>
</plugin>
<!-- <plugin> <groupId>com.github.github</groupId> <artifactId>site-maven-plugin</artifactId> <version>0.12</version> <configuration> <message>Building site for ${project.version}</message> <server>github</server>
</configuration> <executions> <execution> <goals> <goal>site</goal> </goals> <phase>site-deploy</phase> </execution> </executions> </plugin> -->
</plugins>
</build>
<reporting>
<plugins>
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <reportSets> <reportSet> <reports><report>checkstyle-aggregate</report></reports> </reportSet>
</reportSets> <configuration> <configLocation>config/sun_checks.xml</configLocation> <includes> hapi-fhir-base/src/main/java/**/*.java </includes> </configuration> </plugin> -->
<!-- <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.7.7.201606060606</version> <reportSets> <reportSet> <reports> <report>report</report> </reports> <configuration>
<dataFileIncludes>${baseDir}/hapi-fhir-base/target/jacoco.exec</dataFileIncludes> </configuration> </reportSet> </reportSets> </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changes-plugin</artifactId>

View File

@ -7,6 +7,17 @@
</properties>
<body>
<release version="3.1.0" date="TBD">
<action type="fix">
The Android client module has been restored to working order, and no longer
requires a special classifier or an XML parser to be present in order to
work. This means that the hapi-fhir-android library is much less likely
to cause conflicts with other libraries imported into an Android application
via Gradle.
<![CDATA[<br/><br/>]]>
See the
<![CDATA[<a href="http://hapifhir.io/doc_android.html">HAPI FHIR Android Documentation</a>]]>
for more information.
</action>
<action type="add">
A performance to the JPA server has been made which reduces the number
of writes to index tables when updating a resource with contents that
@ -102,7 +113,7 @@
classes (which are Java Enums for the various FHIR codesystems).
These were accidentally removed in HAPI FHIR 3.0.0. Thanks to
GitHub user @CarthageKing for reporting!
</action>
</action>
</release>
<release version="3.0.0" date="2017-09-27">
<action type="add">

View File

@ -1,93 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
<properties>
<title>Android Support</title>
<author email="jamesagnew@users.sourceforge.net">James Agnew</author>
</properties>
<body>
<section name="Android Client Development">
<p>
HAPI now has a specially built binary (JAR) which can be used on Android. Android developers
may use this JAR to take advantage of the FHIR model classes, and the FHIR client (running a FHIR server
on Android is not yet supported. Help wanted!)
</p>
<p>
The Android JAR ships as a "shade JAR", meaning it is a single JAR containing all of the
dependencies required in order to use HAPI FHIR. You should not need to include any other
libraries.
</p>
<p>
Note that the Android JAR is still new and hasn't received as much testing as other
parts of the library. We would greatly appreciate feedback, testing, etc. Also note that
because mobile apps run on less powerful hardware compared to desktop and server applications,
it is all the more important to keep a single instance of the <code>FhirContext</code>
around for good performance, since this object is expensive to create. We are hoping to
improve performance of the creation of this object in a future release. If you are an
Android developer and would like to help with this, please get in touch!
</p>
<subsection name="Get the Android JAR">
<p>
To add the HAPI library via Gradle, use the following
dependency. Note the following things:
</p>
<ul>
<li>The classifier should be set to the version of FHIR you want to support.</li>
<li>
You need to excluded a few things in order to get this to work. This is
a quirk because the way HAPI is built and will hopefully be resolved in a future
release.
</li>
</ul>
<source><![CDATA[dependencies {
compile "ca.uhn.hapi.fhir:hapi-fhir-android:2.2:dstu2@jar"
}]]></source>
<p>
You may also download a copy from the GitHub
<a href="https://github.com/jamesagnew/hapi-fhir/releases">Releases</a> page.
</p>
</subsection>
</section>
<section name="Performance">
<p>
On mobile devices, performance problems are particularly noticeable. This
is made worse by the fact that some Android devices have much slower performance
than modern desktop computers. See the
<a href="./doc_rest_client_http_config.html#performance">Client Configuration Performance</a>
page for some tips on how to improve client performance.
</p>
</section>
<section name="Examples">
<p>
The following is intended to be a selection of publicly available open source
Android applications which use HAPI FHIR and might be useful as a reference.
</p>
<p>
If you know of others, please let us know!
</p>
<ul>
<li>
<a href="https://github.com/hapifhir/hapi-fhir-android-integration-test">https://github.com/hapifhir/hapi-fhir-android-integration-test</a>
- hapi-fhir-android Integration Test and Reference Application is our test platform for validating new releases. Created by Thomas Andersen.
</li>
<li>
<a href="https://github.com/SynappzMA/FHIR-Android">https://github.com/SynappzMA/FHIR-Android</a>
- Nice FHIR DSTU2 search app
</li>
</ul>
</section>
</body>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
<properties>
<title>Android Support</title>
<author email="jamesagnew@users.sourceforge.net">James Agnew</author>
</properties>
<body>
<section name="Android Client Development">
<p>
HAPI now has a specially built module for use on Android. Android developers
may use this JAR to take advantage of the FHIR model classes, and the FHIR client (running a FHIR server
on Android is not yet supported. Get in touch if this is something you are interested in working on!)
</p>
<p>
As of HAPI FHIR 3.1.0, the <code>hapi-fhir-android</code> module has been streamlined in order
to reduce its footprint. Previous versions of the library included both an XML and a JSON parser
but this has been streamlined to only include JSON support in order to reduce the number of
libraries required in an Android build.
</p>
<p>
When using the HAPI FHIR Android client, the client will request only JSON responses
(via the HTTP <code>Accept</code> header) and will not be able to communicate
with FHIR servers that support only XML encoding (few, if any, servers actually exist
with this limitation that we are aware of).
</p>
<p>
The Android client also uses the <code>hapi-fhir-client-okhttp</code> module,
which is an HTTP client based on the OkHttp library. This library has proven to be
more powerful and less likely to cause issues on Android than the Apache HttpClient
implementation which is bundled by default.
</p>
<p>
Note that the Android JAR is still new and hasn't received as much testing as other
parts of the library. We would greatly appreciate feedback, testing, etc. Also note that
because mobile apps run on less powerful hardware compared to desktop and server applications,
it is all the more important to keep a single instance of the <code>FhirContext</code>
around for good performance, since this object is expensive to create. We are hoping to
improve performance of the creation of this object in a future release. If you are an
Android developer and would like to help with this, please get in touch!
</p>
<subsection name="Get the Android JAR">
<p>
To add the HAPI library via Gradle, you should add the
<a href="http://search.maven.org/#search%7Cga%7C1%7Chapi-fhir-android">hapi-fhir-android</a>
library to your Gradle file, as well as a structures library for the appropriate
version of FHIR that you want to support, e.g.
<a href="http://search.maven.org/#search%7Cga%7C1%7Chapi-fhir-structures">hapi-fhir-structures-dstu3</a>.
</p>
<source><![CDATA[dependencies {
compile "ca.uhn.hapi.fhir:hapi-fhir-android:3.1.0-SNAPSHOT"
compile "ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2:3.1.0-SNAPSHOT"
}]]></source>
<p>
Uou will also need to manually exclude the Woodstox StAX library from
inclusion, as this library uses namespaces which are prohibited on Android. You should also
exclude
</p>
<source><![CDATA[configurations {
all*.exclude group: 'org.codehaus.woodstox'
all*.exclude group: 'org.apache.httpcomponents'
}</source>
<p>
To see a sample Gradle file for a working Android project
using HAPI FHIR, see the
<a href="https://github.com/hapifhir/hapi-fhir-android-integration-test">Android Integration Test</a>
project.
</p>
</subsection>
</section>
<section name="Performance">
<p>
On mobile devices, performance problems are particularly noticeable. This
is made worse by the fact that some economy Android devices have much slower performance
than modern desktop computers. See the
<a href="./doc_rest_client_http_config.html#performance">Client Configuration Performance</a>
page for some tips on how to improve client performance.
</p>
</section>
<section name="Examples">
<p>
The following is intended to be a selection of publicly available open source
Android applications which use HAPI FHIR and might be useful as a reference.
</p>
<p>
If you know of others, please let us know!
</p>
<ul>
<li>
<a href="https://github.com/hapifhir/hapi-fhir-android-integration-test">https://github.com/hapifhir/hapi-fhir-android-integration-test</a>
- hapi-fhir-android Integration Test and Reference Application is our test platform for validating new releases. Created by Thomas Andersen.
</li>
<li>
<a href="https://github.com/SynappzMA/FHIR-Android">https://github.com/SynappzMA/FHIR-Android</a>
- Nice FHIR DSTU2 search app
</li>
</ul>
</section>
</body>
</document>