View Javadoc
1   package ca.uhn.fhir.context;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import org.hl7.fhir.instance.model.api.IBaseResource;
24  
25  import ca.uhn.fhir.model.api.annotation.ProvidesResources;
26  
27  /**
28   * Scans a class tagged with {@code ProvidesResources} and adds any resources listed to its FhirContext's resource
29   * definition list. This makes the profile generator find the classes.
30   *
31   * @see ca.uhn.fhir.model.api.annotation.ProvidesResources
32   */
33  public class ProvidedResourceScanner {
34  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ProvidedResourceScanner.class);
35  	private FhirContext myContext;
36  
37  	/**
38  	 * Constructor
39  	 * 
40  	 * @param theContext
41  	 *           - context whose resource definition list is to be updated by the scanner
42  	 */
43  	public ProvidedResourceScanner(FhirContext theContext) {
44  		myContext = theContext;
45  	}
46  
47  	/**
48  	 * If {@code theProvider} is tagged with the {@code ProvidesResources} annotation, this method will add every
49  	 * resource listed by the {@code resources} method.
50  	 * <p>
51  	 * Notes:
52  	 * </p>
53  	 * <ul>
54  	 * <li>if {@code theProvider} isn't annotated with {@code resources} nothing is done; it's expected that most
55  	 * RestfulServers and ResourceProviders won't be annotated.</li>
56  	 * <li>any object listed in {@code resources} that doesn't implement {@code IResource} will generate a warning in the
57  	 * log.</li>
58  	 * </ul>
59  	 *
60  	 * @param theProvider
61  	 *           - Normally, either a {@link ca.uhn.fhir.rest.server.RestfulServer} or a
62  	 *           {@link ca.uhn.fhir.rest.server.IResourceProvider} that might be annotated with
63  	 *           {@link ca.uhn.fhir.model.api.annotation.ProvidesResources}
64  	 */
65  	@SuppressWarnings("unchecked")
66  	public void scanForProvidedResources(Object theProvider) {
67  		ProvidesResources annotation = theProvider.getClass().getAnnotation(ProvidesResources.class);
68  		if (annotation == null)
69  			return;
70  		for (Class<?> clazz : annotation.resources()) {
71  			if (IBaseResource.class.isAssignableFrom(clazz)) {
72  				myContext.getResourceDefinition((Class<? extends IBaseResource>) clazz);
73  			} else {
74  				ourLog.warn(clazz.getSimpleName() + "is not assignable from IResource");
75  			}
76  		}
77  	}
78  
79  	/**
80  	 * Remove any metadata that was added by any {@code ProvidesResources} annotation
81  	 * present in {@code theProvider}. This method is callled from {@code RestfulService}
82  	 * when it is unregistering a Resource Provider.
83  	 *  
84  	 * @param theProvider
85  	 *           - Normally a {@link ca.uhn.fhir.rest.server.IResourceProvider} that might 
86  	 *           be annotated with {@link ca.uhn.fhir.model.api.annotation.ProvidesResources}
87  	 */
88  	public void removeProvidedResources(Object theProvider) {
89  		ProvidesResources annotation = theProvider.getClass().getAnnotation(ProvidesResources.class);
90  		if (annotation == null)
91  			return;
92  		for (Class<?> clazz : annotation.resources()) {
93  			if (IBaseResource.class.isAssignableFrom(clazz)) {
94  				// TODO -- not currently used but should be finished for completeness
95  			} else {
96  				ourLog.warn(clazz.getSimpleName() + "is not assignable from IResource");
97  			}
98  		}
99  	}
100 }