View Javadoc
1   package ca.uhn.fhir.validation;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   /*
7    * #%L
8    * HAPI FHIR - Core Library
9    * %%
10   * Copyright (C) 2014 - 2018 University Health Network
11   * %%
12   * Licensed under the Apache License, Version 2.0 (the "License");
13   * you may not use this file except in compliance with the License.
14   * You may obtain a copy of the License at
15   * 
16   * http://www.apache.org/licenses/LICENSE-2.0
17   * 
18   * Unless required by applicable law or agreed to in writing, software
19   * distributed under the License is distributed on an "AS IS" BASIS,
20   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   * See the License for the specific language governing permissions and
22   * limitations under the License.
23   * #L%
24   */
25  
26  import org.hl7.fhir.instance.model.api.IBaseResource;
27  
28  import ca.uhn.fhir.context.FhirContext;
29  import ca.uhn.fhir.parser.IParser;
30  import ca.uhn.fhir.parser.LenientErrorHandler;
31  import ca.uhn.fhir.rest.api.EncodingEnum;
32  import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
33  import ca.uhn.fhir.util.ObjectUtil;
34  
35  public class ValidationContext<T> extends BaseValidationContext<T> implements IValidationContext<T> {
36  
37  	private final IEncoder myEncoder;
38  	private final T myResource;
39  	private String myResourceAsString;
40  	private final EncodingEnum myResourceAsStringEncoding;
41  
42  	private ValidationContext(FhirContext theContext, T theResource, IEncoder theEncoder) {
43  		this(theContext, theResource, theEncoder, new ArrayList<SingleValidationMessage>());
44  	}
45  	
46  	private ValidationContext(FhirContext theContext, T theResource, IEncoder theEncoder, List<SingleValidationMessage> theMessages) {
47  		super(theContext, theMessages);
48  		myResource = theResource;
49  		myEncoder = theEncoder;
50  		if (theEncoder != null) {
51  			myResourceAsStringEncoding = theEncoder.getEncoding();
52  		} else {
53  			myResourceAsStringEncoding = null;
54  		}
55  	}
56  
57  	@Override
58  	public T getResource() {
59  		return myResource;
60  	}
61  
62  	@Override
63  	public String getResourceAsString() {
64  		if (myResourceAsString == null) {
65  			myResourceAsString = myEncoder.encode();
66  		}
67  		return myResourceAsString;
68  	}
69  
70  	@Override
71  	public EncodingEnum getResourceAsStringEncoding() {
72  		return myResourceAsStringEncoding;
73  	}
74  
75  	public static <T extends IBaseResource> IValidationContext<T> forResource(final FhirContext theContext, final T theResource) {
76  		return new ValidationContext<T>(theContext, theResource, new IEncoder() {
77  			@Override
78  			public String encode() {
79  				return theContext.newXmlParser().encodeResourceToString(theResource);
80  			}
81  
82  			@Override
83  			public EncodingEnum getEncoding() {
84  				return EncodingEnum.XML;
85  			}
86  		});
87  	}
88  
89  	private interface IEncoder {
90  		String encode();
91  
92  		EncodingEnum getEncoding();
93  	}
94  
95  	public static IValidationContext<IBaseResource> forText(final FhirContext theContext, final String theResourceBody) {
96  		ObjectUtil.requireNonNull(theContext, "theContext can not be null");
97  		ObjectUtil.requireNotEmpty(theResourceBody, "theResourceBody can not be null or empty");
98  		return new BaseValidationContext<IBaseResource>(theContext) {
99  
100 			private EncodingEnum myEncoding;
101 			private IBaseResource myParsed;
102 
103 			@Override
104 			public IBaseResource getResource() {
105 				if (myParsed == null) {
106 					IParser parser = getResourceAsStringEncoding().newParser(getFhirContext());
107 					LenientErrorHandler errorHandler = new LenientErrorHandler();
108 					errorHandler.setErrorOnInvalidValue(false);
109 					parser.setParserErrorHandler(errorHandler);
110 					myParsed = parser.parseResource(getResourceAsString());
111 				}
112 				return myParsed;
113 			}
114 
115 			@Override
116 			public String getResourceAsString() {
117 				return theResourceBody;
118 			}
119 
120 			@Override
121 			public EncodingEnum getResourceAsStringEncoding() {
122 				if (myEncoding == null) {
123 					myEncoding = EncodingEnum.detectEncodingNoDefault(theResourceBody);
124 					if (myEncoding == null) {
125 						throw new InvalidRequestException(theContext.getLocalizer().getMessage(ValidationContext.class, "unableToDetermineEncoding"));
126 					}
127 				}
128 				return myEncoding;
129 			}
130 
131 		};
132 	}
133 
134 	public static IValidationContext<IBaseResource> subContext(final IValidationContext<IBaseResource> theCtx, final IBaseResource theResource) {
135 		return new ValidationContext<IBaseResource>(theCtx.getFhirContext(), theResource, new IEncoder() {
136 			@Override
137 			public String encode() {
138 				return theCtx.getFhirContext().newXmlParser().encodeResourceToString(theResource);
139 			}
140 
141 			@Override
142 			public EncodingEnum getEncoding() {
143 				return EncodingEnum.XML;
144 			}
145 		}, theCtx.getMessages());
146 	}
147 }