View Javadoc
1   package ca.uhn.fhir.jpa.dao;
2   
3   import static org.apache.commons.lang3.StringUtils.isNotBlank;
4   
5   import java.util.*;
6   
7   import org.hl7.fhir.instance.hapi.validation.IValidationSupport;
8   import org.hl7.fhir.instance.model.api.*;
9   import org.springframework.beans.factory.annotation.Autowired;
10  import org.springframework.beans.factory.annotation.Qualifier;
11  
12  import ca.uhn.fhir.context.RuntimeResourceDefinition;
13  import ca.uhn.fhir.context.RuntimeSearchParam;
14  import ca.uhn.fhir.jpa.entity.ResourceTable;
15  import ca.uhn.fhir.jpa.util.DeleteConflict;
16  import ca.uhn.fhir.model.api.IResource;
17  import ca.uhn.fhir.model.api.Include;
18  import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
19  import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
20  import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
21  import ca.uhn.fhir.model.primitive.IdDt;
22  import ca.uhn.fhir.rest.api.*;
23  import ca.uhn.fhir.rest.api.server.RequestDetails;
24  import ca.uhn.fhir.rest.server.exceptions.*;
25  import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
26  import ca.uhn.fhir.util.FhirTerser;
27  import ca.uhn.fhir.validation.*;
28  
29  /*
30   * #%L
31   * HAPI FHIR JPA Server
32   * %%
33   * Copyright (C) 2014 - 2018 University Health Network
34   * %%
35   * Licensed under the Apache License, Version 2.0 (the "License");
36   * you may not use this file except in compliance with the License.
37   * You may obtain a copy of the License at
38   * 
39   * http://www.apache.org/licenses/LICENSE-2.0
40   * 
41   * Unless required by applicable law or agreed to in writing, software
42   * distributed under the License is distributed on an "AS IS" BASIS,
43   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44   * See the License for the specific language governing permissions and
45   * limitations under the License.
46   * #L%
47   */
48  
49  public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResourceDao<T> {
50  
51  	@Autowired()
52  	@Qualifier("myJpaValidationSupportDstu2")
53  	private IValidationSupport myJpaValidationSupport;
54  
55  	@Autowired()
56  	@Qualifier("myInstanceValidatorDstu2")
57  	private IValidatorModule myInstanceValidator;
58  
59  
60  	@Override
61  	protected IBaseOperationOutcome createOperationOutcome(String theSeverity, String theMessage, String theCode) {
62  		OperationOutcome oo = new OperationOutcome();
63  		oo.getIssueFirstRep().getSeverityElement().setValue(theSeverity);
64  		oo.getIssueFirstRep().getDiagnosticsElement().setValue(theMessage);
65  		oo.getIssueFirstRep().getCodeElement().setValue(theCode);
66  		return oo;
67  	}
68  
69  	@Override
70  	public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequestDetails) {
71  		ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, theResource, null, theId);
72  		notifyInterceptors(RestOperationTypeEnum.VALIDATE, requestDetails);
73  
74  		if (theMode == ValidationModeEnum.DELETE) {
75  			if (theId == null || theId.hasIdPart() == false) {
76  				throw new InvalidRequestException("No ID supplied. ID is required when validating with mode=DELETE");
77  			}
78  			final ResourceTable entity = readEntityLatestVersion(theId);
79  
80  			// Validate that there are no resources pointing to the candidate that
81  			// would prevent deletion
82  			List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
83  			if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
84  				validateOkToDelete(deleteConflicts, entity, true);
85  			}
86  			validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
87  
88  			OperationOutcome oo = new OperationOutcome();
89  			oo.addIssue().setSeverity(IssueSeverityEnum.INFORMATION).setDiagnostics("Ok to delete");
90  			return new MethodOutcome(new IdDt(theId.getValue()), oo);
91  		}
92  
93  		FhirValidator validator = getContext().newValidator();
94  
95  		validator.registerValidatorModule(myInstanceValidator);
96  
97  		validator.registerValidatorModule(new IdChecker(theMode));
98  
99  		ValidationResult result;
100 		if (isNotBlank(theRawResource)) {
101 			result = validator.validateWithResult(theRawResource);
102 		} else if (theResource != null) {
103 			result = validator.validateWithResult(theResource);
104 		} else {
105 			String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "cantValidateWithNoResource");
106 			throw new InvalidRequestException(msg);
107 		}
108 
109 		if (result.isSuccessful()) {
110 			MethodOutcome retVal = new MethodOutcome();
111 			retVal.setOperationOutcome(result.toOperationOutcome());
112 			return retVal;
113 		} else {
114 			throw new PreconditionFailedException("Validation failed", result.toOperationOutcome());
115 		}
116 
117 	}
118 
119 	private class IdChecker implements IValidatorModule {
120 
121 		private ValidationModeEnum myMode;
122 
123 		public IdChecker(ValidationModeEnum theMode) {
124 			myMode = theMode;
125 		}
126 
127 		@Override
128 		public void validateResource(IValidationContext<IBaseResource> theCtx) {
129 			boolean hasId = theCtx.getResource().getIdElement().hasIdPart();
130 			if (myMode == ValidationModeEnum.CREATE) {
131 				if (hasId) {
132 					throw new UnprocessableEntityException("Resource has an ID - ID must not be populated for a FHIR create");
133 				}
134 			} else if (myMode == ValidationModeEnum.UPDATE) {
135 				if (hasId == false) {
136 					throw new UnprocessableEntityException("Resource has no ID - ID must be populated for a FHIR update");
137 				}
138 			}
139 
140 		}
141 
142 	}
143 
144 }