1
0
mirror of https://github.com/hapifhir/hapi-fhir.git synced 2025-04-02 05:18:38 +00:00

551 lines
23 KiB
Java
Raw Normal View History

2014-02-17 17:58:32 -05:00
package ca.uhn.fhir.context;
/*
* #%L
* HAPI FHIR - Core Library
* %%
2018-01-08 13:52:15 -05:00
* Copyright (C) 2014 - 2018 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%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
2014-02-17 17:58:32 -05:00
import java.io.IOException;
import java.io.InputStream;
2014-12-10 17:40:47 -05:00
import java.lang.annotation.Annotation;
Merge in HAPI 3.0.0 working branch! Squashed commit of the following: commit 12f89a423a1691fdbc360706fd94a03bd9144d17 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:38:51 2017 -0400 Minimize validation resources commit f6868cce5c73b34d5ecd53bf1a220fdccd6b4e09 Merge: 3b80779fd3 1e158311d8 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:05:34 2017 -0400 Forward port fix for #710 Merge branch 'master' into hapi3_refactor commit 3b80779fd3905cbf5322e6973334eb0ecb3d8426 Merge: 1f534985e8 356d9acaf7 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 12:31:09 2017 -0400 Forward port #705, #708, and #710 Merge branch 'master' into hapi3_refactor commit 1f534985e8106347d9cc9da2dd8145fdd869547f Merge: 7c39a47852 dedd3d635b Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 10:52:59 2017 -0400 Forward port #695 Merge branch 'master' into hapi3_refactor commit 7c39a47852142bee398101120678217ab0917c7e Merge: e0ffb84d21 6efafe62f1 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 09:53:17 2017 -0400 Forward port #688 Merge branch 'master' into hapi3_refactor commit e0ffb84d2129c209ccffc2611038592f37dddfd2 Merge: 52388c11c1 d19b00ff09 Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 14:59:46 2017 -0400 Merge branch 'master' into hapi3_refactor commit 52388c11c17cf038591244548f2a592f6b655cee Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 06:21:46 2017 -0400 Cleanup commit 209752cd638266b39574ae11c5989b624d5e85d3 Author: James <jamesagnew@gmail.com> Date: Thu Aug 10 11:18:19 2017 -0400 Fix tests commit 4543408dc8d63b5b9682a275e261d3168cdc2196 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:55:50 2017 -0400 Fix a potential deadlock commit ee360f537692672df473f94dae75c176b2287415 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:22:06 2017 -0400 Add R4 code to CLI commit 1a95ba3b6529afdaf81232b82cc303718c0187d6 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Aug 3 06:14:01 2017 -0400 More cleanup commit f0d88026817296edaa65132accd67d0c8ad8088c Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 11:27:43 2017 -0400 Tests are working! commit a4cbda357e8e7d024f24e3ee9a660b5366983ca1 Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:42:04 2017 -0400 Connection handling cleanup for new tests commit 0e2cecfbd0d7a546444a66e8411600040fd9a17b Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:16:28 2017 -0400 Clean up R4 JPA tests commit 40317a650d72c86e2529d5179cffe63399301de5 Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 09:12:38 2017 -0400 Work on R4 for JPA server commit e7f8f8c30d72ed30d739979964db38d41c5baec1 Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 20:43:47 2017 -0400 More work on porting tests commit 43c9003258696ab33e7bb335e882ab1c66fb61aa Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 07:09:29 2017 -0400 Work on porting DSTU1 tests commit 602857f1e26a69a2284e176b5e44a860d9b828ff Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 22:34:08 2017 -0400 More work on bring unit tests up to date commit e326a7b0cdb8368009119bba41886838a973e03e Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:36:38 2017 -0400 Credit for #686 and forward port the fix to R4 validator commit 96543c3992adcb406df3c8899dab79cf4bd5b4b4 Merge: 3fb75aa61a 9901b802c4 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:12:33 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3fb75aa61ad29d9f3876a1c30c912627486147af Author: James <jamesagnew@gmail.com> Date: Mon Jul 31 15:21:30 2017 -0400 More work on cleanup commit b02fbb6804127e77c61c4792eefd9fc0d23d63d0 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 22:11:07 2017 -0400 Work on porting STU1 tests commit 1ae37b0db3929ea4f37955adf8f026e33ccf43b2 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:56:10 2017 -0400 Try to get coverage report working commit 72b88849b30a94a9ff08d3a1ab50a05b2acbdfdd Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:27:02 2017 -0400 Fix android tests commit e5f6c35aeab8bbc056870a038e1862181049a020 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 19:31:18 2017 -0400 More work on getting legacy code cleaned up commit 0b513b0845a082b5c20b0033dfab4e29f5e4a934 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 18:41:13 2017 -0400 Continue work on removing deprecated API commit defea69aa38a2e0f4137ed9c8527956872ff70bf Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 17:10:01 2017 -0400 More cleanup of legacy code commit 9ae7295705cb58f5edcf7ee1259f023cbbe2fe51 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 07:11:45 2017 -0400 More cleanup of legacy code commit ebd3eeb5ee793cf5805cc726db353f3def35ab00 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 06:43:25 2017 -0400 More work on removing legacy code commit 92224c2532faf70171473d64429c3ceaf3e3406c Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 18:44:06 2017 -0400 Remove DSTU1 Bundle commit c52cacf71bae3f5c02ffae03881c21de1f3aba22 Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 14:27:42 2017 -0400 Now compiling commit b405e51773baf4ab3a3c387458cdc59541394cd1 Merge: c3ddf04e25 cb2cea54d7 Author: James Agnew <jamesagnew@gmail.com> Date: Fri Jul 28 06:21:02 2017 -0400 Merge branch 'master' into hapi3_refactor commit c3ddf04e2598b8d6214975ab0ae795f850396811 Author: James <jamesagnew@gmail.com> Date: Thu Jul 27 11:06:06 2017 -0400 Sync R4 releases in commit b13333c3c03ddb9a5061c3b22bf011f4592104f8 Author: James <jamesagnew@gmail.com> Date: Fri Jul 14 05:52:33 2017 -0400 JPA server is now able to handle placeholder IDs (e.g. urn:uuid:00....000) being used in Bundle.entry.request.url as a part of the conditional URL within transactions. commit 2e60ff7521b42890a32b97c2dda88ab233f5c91e Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 20:02:46 2017 -0400 Fix imports commit a92ace2e0dac6e24f6dada53bf97d03861fd21a1 Merge: 3196db96d1 1a6b3ea867 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 12:02:27 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3196db96d1c485310e746833df59c0e010b5b161 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 11:48:10 2017 -0400 Don't add false paging link to request commit bd4e1d338855a664045caa271d41616aed973a4d Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 21:32:16 2017 -0400 Finally building correctly! commit 6464ce9304703cb3c5ecc58491282ddacc900853 Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 16:38:28 2017 -0400 Work on refactor commit 0059f2e48e9d7c812c1d42a57c5b6059814f5155 Author: James <jamesagnew@gmail.com> Date: Sat Jul 8 07:16:20 2017 -0400 Keep working on refactor commit 6c2e87e8cc19863a811c11623d1c878c8b48f031 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 22:35:13 2017 -0400 Lots of work on refactor commit 11cab975047a0c28190e6533074fd3f11ddde240 Merge: 34ec6b8807 6c47bd4c51 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:57 2017 -0400 Merge branch 'master' into hapi3_refactor commit 34ec6b8807946aa6c97f0b5581dca9bd5f7b7a3e Merge: f8e647511b c520e60ac1 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:49 2017 -0400 Merge branch 'hapi3_refactor' of github.com:jamesagnew/hapi-fhir into hapi3_refactor commit f8e647511b4a82e7fde71a8850b8800e3d698b1f Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 18:46:55 2017 -0400 Work on hapi3 changes commit c520e60ac1198f340cfb9090a7a33f91aa2d1e61 Author: James <jamesagnew@gmail.com> Date: Wed Jul 5 08:08:40 2017 -0400 Keep working on refactor commit f1d2ee90926f7db900a5b3b4ab9a8948d18e49f2 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 22:10:59 2017 -0400 Continue refactor for HAPI 3 commit 9281ccafc32354222932c5a9f5ee8b0f206ebc05 Merge: ea1264cd8e 294d080bd3 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 20:34:16 2017 -0400 Merge branch 'master' into hapi3_refactor commit ea1264cd8e9b8c5297d218e91cf14bd48d0a92c7 Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 10:26:01 2017 -0400 Continue work on refactor commit fbe2f98a0238f3d4e065db4550dd2ef1b460c0d8 Merge: b2bef47100 0a4dcc32ec Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 06:21:22 2017 -0400 Merge branch 'master' into hapi3_refactor commit b2bef47100370e1248834523d73a630950032d7a Author: James <jamesagnew@gmail.com> Date: Tue Jun 27 21:13:23 2017 -0400 Work on refactor commit 8f76e4e46385daa9ce3442e2d9342453ce373ba3 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jun 25 21:55:35 2017 -0400 Lots of work on refactoring
2017-08-13 14:39:47 -04:00
import java.lang.reflect.*;
import java.util.*;
2014-07-02 08:57:07 -04:00
import java.util.Map.Entry;
2014-02-17 17:58:32 -05:00
2016-06-16 07:42:06 -04:00
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.*;
2014-12-10 14:28:25 -05:00
2017-02-01 05:55:35 -05:00
import ca.uhn.fhir.context.RuntimeSearchParam.RuntimeSearchParamStatusEnum;
Merge in HAPI 3.0.0 working branch! Squashed commit of the following: commit 12f89a423a1691fdbc360706fd94a03bd9144d17 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:38:51 2017 -0400 Minimize validation resources commit f6868cce5c73b34d5ecd53bf1a220fdccd6b4e09 Merge: 3b80779fd3 1e158311d8 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:05:34 2017 -0400 Forward port fix for #710 Merge branch 'master' into hapi3_refactor commit 3b80779fd3905cbf5322e6973334eb0ecb3d8426 Merge: 1f534985e8 356d9acaf7 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 12:31:09 2017 -0400 Forward port #705, #708, and #710 Merge branch 'master' into hapi3_refactor commit 1f534985e8106347d9cc9da2dd8145fdd869547f Merge: 7c39a47852 dedd3d635b Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 10:52:59 2017 -0400 Forward port #695 Merge branch 'master' into hapi3_refactor commit 7c39a47852142bee398101120678217ab0917c7e Merge: e0ffb84d21 6efafe62f1 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 09:53:17 2017 -0400 Forward port #688 Merge branch 'master' into hapi3_refactor commit e0ffb84d2129c209ccffc2611038592f37dddfd2 Merge: 52388c11c1 d19b00ff09 Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 14:59:46 2017 -0400 Merge branch 'master' into hapi3_refactor commit 52388c11c17cf038591244548f2a592f6b655cee Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 06:21:46 2017 -0400 Cleanup commit 209752cd638266b39574ae11c5989b624d5e85d3 Author: James <jamesagnew@gmail.com> Date: Thu Aug 10 11:18:19 2017 -0400 Fix tests commit 4543408dc8d63b5b9682a275e261d3168cdc2196 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:55:50 2017 -0400 Fix a potential deadlock commit ee360f537692672df473f94dae75c176b2287415 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:22:06 2017 -0400 Add R4 code to CLI commit 1a95ba3b6529afdaf81232b82cc303718c0187d6 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Aug 3 06:14:01 2017 -0400 More cleanup commit f0d88026817296edaa65132accd67d0c8ad8088c Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 11:27:43 2017 -0400 Tests are working! commit a4cbda357e8e7d024f24e3ee9a660b5366983ca1 Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:42:04 2017 -0400 Connection handling cleanup for new tests commit 0e2cecfbd0d7a546444a66e8411600040fd9a17b Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:16:28 2017 -0400 Clean up R4 JPA tests commit 40317a650d72c86e2529d5179cffe63399301de5 Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 09:12:38 2017 -0400 Work on R4 for JPA server commit e7f8f8c30d72ed30d739979964db38d41c5baec1 Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 20:43:47 2017 -0400 More work on porting tests commit 43c9003258696ab33e7bb335e882ab1c66fb61aa Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 07:09:29 2017 -0400 Work on porting DSTU1 tests commit 602857f1e26a69a2284e176b5e44a860d9b828ff Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 22:34:08 2017 -0400 More work on bring unit tests up to date commit e326a7b0cdb8368009119bba41886838a973e03e Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:36:38 2017 -0400 Credit for #686 and forward port the fix to R4 validator commit 96543c3992adcb406df3c8899dab79cf4bd5b4b4 Merge: 3fb75aa61a 9901b802c4 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:12:33 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3fb75aa61ad29d9f3876a1c30c912627486147af Author: James <jamesagnew@gmail.com> Date: Mon Jul 31 15:21:30 2017 -0400 More work on cleanup commit b02fbb6804127e77c61c4792eefd9fc0d23d63d0 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 22:11:07 2017 -0400 Work on porting STU1 tests commit 1ae37b0db3929ea4f37955adf8f026e33ccf43b2 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:56:10 2017 -0400 Try to get coverage report working commit 72b88849b30a94a9ff08d3a1ab50a05b2acbdfdd Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:27:02 2017 -0400 Fix android tests commit e5f6c35aeab8bbc056870a038e1862181049a020 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 19:31:18 2017 -0400 More work on getting legacy code cleaned up commit 0b513b0845a082b5c20b0033dfab4e29f5e4a934 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 18:41:13 2017 -0400 Continue work on removing deprecated API commit defea69aa38a2e0f4137ed9c8527956872ff70bf Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 17:10:01 2017 -0400 More cleanup of legacy code commit 9ae7295705cb58f5edcf7ee1259f023cbbe2fe51 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 07:11:45 2017 -0400 More cleanup of legacy code commit ebd3eeb5ee793cf5805cc726db353f3def35ab00 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 06:43:25 2017 -0400 More work on removing legacy code commit 92224c2532faf70171473d64429c3ceaf3e3406c Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 18:44:06 2017 -0400 Remove DSTU1 Bundle commit c52cacf71bae3f5c02ffae03881c21de1f3aba22 Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 14:27:42 2017 -0400 Now compiling commit b405e51773baf4ab3a3c387458cdc59541394cd1 Merge: c3ddf04e25 cb2cea54d7 Author: James Agnew <jamesagnew@gmail.com> Date: Fri Jul 28 06:21:02 2017 -0400 Merge branch 'master' into hapi3_refactor commit c3ddf04e2598b8d6214975ab0ae795f850396811 Author: James <jamesagnew@gmail.com> Date: Thu Jul 27 11:06:06 2017 -0400 Sync R4 releases in commit b13333c3c03ddb9a5061c3b22bf011f4592104f8 Author: James <jamesagnew@gmail.com> Date: Fri Jul 14 05:52:33 2017 -0400 JPA server is now able to handle placeholder IDs (e.g. urn:uuid:00....000) being used in Bundle.entry.request.url as a part of the conditional URL within transactions. commit 2e60ff7521b42890a32b97c2dda88ab233f5c91e Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 20:02:46 2017 -0400 Fix imports commit a92ace2e0dac6e24f6dada53bf97d03861fd21a1 Merge: 3196db96d1 1a6b3ea867 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 12:02:27 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3196db96d1c485310e746833df59c0e010b5b161 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 11:48:10 2017 -0400 Don't add false paging link to request commit bd4e1d338855a664045caa271d41616aed973a4d Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 21:32:16 2017 -0400 Finally building correctly! commit 6464ce9304703cb3c5ecc58491282ddacc900853 Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 16:38:28 2017 -0400 Work on refactor commit 0059f2e48e9d7c812c1d42a57c5b6059814f5155 Author: James <jamesagnew@gmail.com> Date: Sat Jul 8 07:16:20 2017 -0400 Keep working on refactor commit 6c2e87e8cc19863a811c11623d1c878c8b48f031 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 22:35:13 2017 -0400 Lots of work on refactor commit 11cab975047a0c28190e6533074fd3f11ddde240 Merge: 34ec6b8807 6c47bd4c51 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:57 2017 -0400 Merge branch 'master' into hapi3_refactor commit 34ec6b8807946aa6c97f0b5581dca9bd5f7b7a3e Merge: f8e647511b c520e60ac1 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:49 2017 -0400 Merge branch 'hapi3_refactor' of github.com:jamesagnew/hapi-fhir into hapi3_refactor commit f8e647511b4a82e7fde71a8850b8800e3d698b1f Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 18:46:55 2017 -0400 Work on hapi3 changes commit c520e60ac1198f340cfb9090a7a33f91aa2d1e61 Author: James <jamesagnew@gmail.com> Date: Wed Jul 5 08:08:40 2017 -0400 Keep working on refactor commit f1d2ee90926f7db900a5b3b4ab9a8948d18e49f2 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 22:10:59 2017 -0400 Continue refactor for HAPI 3 commit 9281ccafc32354222932c5a9f5ee8b0f206ebc05 Merge: ea1264cd8e 294d080bd3 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 20:34:16 2017 -0400 Merge branch 'master' into hapi3_refactor commit ea1264cd8e9b8c5297d218e91cf14bd48d0a92c7 Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 10:26:01 2017 -0400 Continue work on refactor commit fbe2f98a0238f3d4e065db4550dd2ef1b460c0d8 Merge: b2bef47100 0a4dcc32ec Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 06:21:22 2017 -0400 Merge branch 'master' into hapi3_refactor commit b2bef47100370e1248834523d73a630950032d7a Author: James <jamesagnew@gmail.com> Date: Tue Jun 27 21:13:23 2017 -0400 Work on refactor commit 8f76e4e46385daa9ce3442e2d9342453ce373ba3 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jun 25 21:55:35 2017 -0400 Lots of work on refactoring
2017-08-13 14:39:47 -04:00
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
2014-02-24 11:46:08 -05:00
import ca.uhn.fhir.model.primitive.XhtmlDt;
Merge in HAPI 3.0.0 working branch! Squashed commit of the following: commit 12f89a423a1691fdbc360706fd94a03bd9144d17 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:38:51 2017 -0400 Minimize validation resources commit f6868cce5c73b34d5ecd53bf1a220fdccd6b4e09 Merge: 3b80779fd3 1e158311d8 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 14:05:34 2017 -0400 Forward port fix for #710 Merge branch 'master' into hapi3_refactor commit 3b80779fd3905cbf5322e6973334eb0ecb3d8426 Merge: 1f534985e8 356d9acaf7 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 12:31:09 2017 -0400 Forward port #705, #708, and #710 Merge branch 'master' into hapi3_refactor commit 1f534985e8106347d9cc9da2dd8145fdd869547f Merge: 7c39a47852 dedd3d635b Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 10:52:59 2017 -0400 Forward port #695 Merge branch 'master' into hapi3_refactor commit 7c39a47852142bee398101120678217ab0917c7e Merge: e0ffb84d21 6efafe62f1 Author: James <jamesagnew@gmail.com> Date: Sun Aug 13 09:53:17 2017 -0400 Forward port #688 Merge branch 'master' into hapi3_refactor commit e0ffb84d2129c209ccffc2611038592f37dddfd2 Merge: 52388c11c1 d19b00ff09 Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 14:59:46 2017 -0400 Merge branch 'master' into hapi3_refactor commit 52388c11c17cf038591244548f2a592f6b655cee Author: James <jamesagnew@gmail.com> Date: Sat Aug 12 06:21:46 2017 -0400 Cleanup commit 209752cd638266b39574ae11c5989b624d5e85d3 Author: James <jamesagnew@gmail.com> Date: Thu Aug 10 11:18:19 2017 -0400 Fix tests commit 4543408dc8d63b5b9682a275e261d3168cdc2196 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:55:50 2017 -0400 Fix a potential deadlock commit ee360f537692672df473f94dae75c176b2287415 Author: James <jamesagnew@gmail.com> Date: Sat Aug 5 06:22:06 2017 -0400 Add R4 code to CLI commit 1a95ba3b6529afdaf81232b82cc303718c0187d6 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Aug 3 06:14:01 2017 -0400 More cleanup commit f0d88026817296edaa65132accd67d0c8ad8088c Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 11:27:43 2017 -0400 Tests are working! commit a4cbda357e8e7d024f24e3ee9a660b5366983ca1 Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:42:04 2017 -0400 Connection handling cleanup for new tests commit 0e2cecfbd0d7a546444a66e8411600040fd9a17b Author: James Agnew <jamesagnew@gmail.com> Date: Wed Aug 2 10:16:28 2017 -0400 Clean up R4 JPA tests commit 40317a650d72c86e2529d5179cffe63399301de5 Author: James <jamesagnew@gmail.com> Date: Wed Aug 2 09:12:38 2017 -0400 Work on R4 for JPA server commit e7f8f8c30d72ed30d739979964db38d41c5baec1 Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 20:43:47 2017 -0400 More work on porting tests commit 43c9003258696ab33e7bb335e882ab1c66fb61aa Author: James <jamesagnew@gmail.com> Date: Tue Aug 1 07:09:29 2017 -0400 Work on porting DSTU1 tests commit 602857f1e26a69a2284e176b5e44a860d9b828ff Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 22:34:08 2017 -0400 More work on bring unit tests up to date commit e326a7b0cdb8368009119bba41886838a973e03e Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:36:38 2017 -0400 Credit for #686 and forward port the fix to R4 validator commit 96543c3992adcb406df3c8899dab79cf4bd5b4b4 Merge: 3fb75aa61a 9901b802c4 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 31 17:12:33 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3fb75aa61ad29d9f3876a1c30c912627486147af Author: James <jamesagnew@gmail.com> Date: Mon Jul 31 15:21:30 2017 -0400 More work on cleanup commit b02fbb6804127e77c61c4792eefd9fc0d23d63d0 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 22:11:07 2017 -0400 Work on porting STU1 tests commit 1ae37b0db3929ea4f37955adf8f026e33ccf43b2 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:56:10 2017 -0400 Try to get coverage report working commit 72b88849b30a94a9ff08d3a1ab50a05b2acbdfdd Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 20:27:02 2017 -0400 Fix android tests commit e5f6c35aeab8bbc056870a038e1862181049a020 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 19:31:18 2017 -0400 More work on getting legacy code cleaned up commit 0b513b0845a082b5c20b0033dfab4e29f5e4a934 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 18:41:13 2017 -0400 Continue work on removing deprecated API commit defea69aa38a2e0f4137ed9c8527956872ff70bf Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 17:10:01 2017 -0400 More cleanup of legacy code commit 9ae7295705cb58f5edcf7ee1259f023cbbe2fe51 Author: James <jamesagnew@gmail.com> Date: Sun Jul 30 07:11:45 2017 -0400 More cleanup of legacy code commit ebd3eeb5ee793cf5805cc726db353f3def35ab00 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jul 30 06:43:25 2017 -0400 More work on removing legacy code commit 92224c2532faf70171473d64429c3ceaf3e3406c Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 18:44:06 2017 -0400 Remove DSTU1 Bundle commit c52cacf71bae3f5c02ffae03881c21de1f3aba22 Author: James <jamesagnew@gmail.com> Date: Sat Jul 29 14:27:42 2017 -0400 Now compiling commit b405e51773baf4ab3a3c387458cdc59541394cd1 Merge: c3ddf04e25 cb2cea54d7 Author: James Agnew <jamesagnew@gmail.com> Date: Fri Jul 28 06:21:02 2017 -0400 Merge branch 'master' into hapi3_refactor commit c3ddf04e2598b8d6214975ab0ae795f850396811 Author: James <jamesagnew@gmail.com> Date: Thu Jul 27 11:06:06 2017 -0400 Sync R4 releases in commit b13333c3c03ddb9a5061c3b22bf011f4592104f8 Author: James <jamesagnew@gmail.com> Date: Fri Jul 14 05:52:33 2017 -0400 JPA server is now able to handle placeholder IDs (e.g. urn:uuid:00....000) being used in Bundle.entry.request.url as a part of the conditional URL within transactions. commit 2e60ff7521b42890a32b97c2dda88ab233f5c91e Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 20:02:46 2017 -0400 Fix imports commit a92ace2e0dac6e24f6dada53bf97d03861fd21a1 Merge: 3196db96d1 1a6b3ea867 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 12:02:27 2017 -0400 Merge branch 'master' into hapi3_refactor commit 3196db96d1c485310e746833df59c0e010b5b161 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 13 11:48:10 2017 -0400 Don't add false paging link to request commit bd4e1d338855a664045caa271d41616aed973a4d Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 21:32:16 2017 -0400 Finally building correctly! commit 6464ce9304703cb3c5ecc58491282ddacc900853 Author: James <jamesagnew@gmail.com> Date: Sun Jul 9 16:38:28 2017 -0400 Work on refactor commit 0059f2e48e9d7c812c1d42a57c5b6059814f5155 Author: James <jamesagnew@gmail.com> Date: Sat Jul 8 07:16:20 2017 -0400 Keep working on refactor commit 6c2e87e8cc19863a811c11623d1c878c8b48f031 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 22:35:13 2017 -0400 Lots of work on refactor commit 11cab975047a0c28190e6533074fd3f11ddde240 Merge: 34ec6b8807 6c47bd4c51 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:57 2017 -0400 Merge branch 'master' into hapi3_refactor commit 34ec6b8807946aa6c97f0b5581dca9bd5f7b7a3e Merge: f8e647511b c520e60ac1 Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 21:43:49 2017 -0400 Merge branch 'hapi3_refactor' of github.com:jamesagnew/hapi-fhir into hapi3_refactor commit f8e647511b4a82e7fde71a8850b8800e3d698b1f Author: James Agnew <jamesagnew@gmail.com> Date: Thu Jul 6 18:46:55 2017 -0400 Work on hapi3 changes commit c520e60ac1198f340cfb9090a7a33f91aa2d1e61 Author: James <jamesagnew@gmail.com> Date: Wed Jul 5 08:08:40 2017 -0400 Keep working on refactor commit f1d2ee90926f7db900a5b3b4ab9a8948d18e49f2 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 22:10:59 2017 -0400 Continue refactor for HAPI 3 commit 9281ccafc32354222932c5a9f5ee8b0f206ebc05 Merge: ea1264cd8e 294d080bd3 Author: James Agnew <jamesagnew@gmail.com> Date: Mon Jul 3 20:34:16 2017 -0400 Merge branch 'master' into hapi3_refactor commit ea1264cd8e9b8c5297d218e91cf14bd48d0a92c7 Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 10:26:01 2017 -0400 Continue work on refactor commit fbe2f98a0238f3d4e065db4550dd2ef1b460c0d8 Merge: b2bef47100 0a4dcc32ec Author: James <jamesagnew@gmail.com> Date: Wed Jun 28 06:21:22 2017 -0400 Merge branch 'master' into hapi3_refactor commit b2bef47100370e1248834523d73a630950032d7a Author: James <jamesagnew@gmail.com> Date: Tue Jun 27 21:13:23 2017 -0400 Work on refactor commit 8f76e4e46385daa9ce3442e2d9342453ce373ba3 Author: James Agnew <jamesagnew@gmail.com> Date: Sun Jun 25 21:55:35 2017 -0400 Lots of work on refactoring
2017-08-13 14:39:47 -04:00
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.util.ReflectionUtil;
2014-02-17 17:58:32 -05:00
class ModelScanner {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
2014-12-10 14:28:25 -05:00
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
private FhirContext myContext;
private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
private Map<String, BaseRuntimeElementDefinition<?>> myNameToElementDefinitions = new HashMap<String, BaseRuntimeElementDefinition<?>>();
2014-02-18 18:10:50 -05:00
private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>();
private Map<String, Class<? extends IBaseResource>> myNameToResourceType = new HashMap<String, Class<? extends IBaseResource>>();
2014-02-22 15:33:02 -05:00
private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
2014-12-10 14:28:25 -05:00
private Set<Class<? extends IBase>> myScanAlso = new HashSet<Class<? extends IBase>>();
private FhirVersionEnum myVersion;
2015-05-02 14:04:43 -07:00
private Set<Class<? extends IBase>> myVersionTypes;
2016-02-26 18:16:35 -05:00
ModelScanner(FhirContext theContext, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions,
Collection<Class<? extends IBase>> theResourceTypes) throws ConfigurationException {
2014-12-01 08:13:32 -05:00
myContext = theContext;
myVersion = theVersion;
Set<Class<? extends IBase>> toScan;
2014-12-01 08:13:32 -05:00
if (theResourceTypes != null) {
toScan = new HashSet<Class<? extends IBase>>(theResourceTypes);
2014-12-01 08:13:32 -05:00
} else {
toScan = new HashSet<Class<? extends IBase>>();
2014-12-01 08:13:32 -05:00
}
init(theExistingDefinitions, toScan);
2014-03-04 16:41:18 -05:00
}
2014-02-18 18:10:50 -05:00
static Class<?> determineElementType(Field next) {
Class<?> nextElementType = next.getType();
if (List.class.equals(nextElementType)) {
nextElementType = ReflectionUtil.getGenericCollectionTypeOfField(next);
} else if (Collection.class.isAssignableFrom(nextElementType)) {
throw new ConfigurationException("Field '" + next.getName() + "' in type '" + next.getClass().getCanonicalName() + "' is a Collection - Only java.util.List curently supported");
}
return nextElementType;
}
@SuppressWarnings("unchecked")
static IValueSetEnumBinder<Enum<?>> getBoundCodeBinder(Field theNext) {
Class<?> bound = getGenericCollectionTypeOfCodedField(theNext);
if (bound == null) {
throw new ConfigurationException("Field '" + theNext + "' has no parameter for " + BoundCodeDt.class.getSimpleName() + " to determine enum type");
}
2016-07-03 10:23:48 -04:00
String fieldName = "VALUESET_BINDER";
try {
2016-07-03 10:23:48 -04:00
Field bindingField = bound.getField(fieldName);
return (IValueSetEnumBinder<Enum<?>>) bindingField.get(null);
2016-07-03 10:23:48 -04:00
} catch (Exception e) {
throw new ConfigurationException("Field '" + theNext + "' has type parameter " + bound.getCanonicalName() + " but this class has no valueset binding field (must have a field called " + fieldName + ")", e);
}
}
public Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
return myClassToElementDefinitions;
}
public Map<String, RuntimeResourceDefinition> getIdToResourceDefinition() {
return myIdToResourceDefinition;
}
public Map<String, BaseRuntimeElementDefinition<?>> getNameToElementDefinitions() {
return myNameToElementDefinitions;
}
public Map<String, RuntimeResourceDefinition> getNameToResourceDefinition() {
return myNameToResourceDefinitions;
}
public Map<String, RuntimeResourceDefinition> getNameToResourceDefinitions() {
return (myNameToResourceDefinitions);
}
public Map<String, Class<? extends IBaseResource>> getNameToResourceType() {
return myNameToResourceType;
}
public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() {
return myRuntimeChildUndeclaredExtensionDefinition;
}
private void init(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Set<Class<? extends IBase>> theTypesToScan) {
2014-07-04 09:27:36 -04:00
if (theExistingDefinitions != null) {
2014-07-02 08:57:07 -04:00
myClassToElementDefinitions.putAll(theExistingDefinitions);
}
2014-07-04 09:27:36 -04:00
2014-07-02 08:57:07 -04:00
int startSize = myClassToElementDefinitions.size();
long start = System.currentTimeMillis();
Map<String, Class<? extends IBaseResource>> resourceTypes = myNameToResourceType;
Set<Class<? extends IBase>> typesToScan = theTypesToScan;
myVersionTypes = scanVersionPropertyFile(typesToScan, resourceTypes, myVersion, myClassToElementDefinitions);
2014-02-18 18:10:50 -05:00
do {
for (Class<? extends IBase> nextClass : typesToScan) {
2014-02-18 18:10:50 -05:00
scan(nextClass);
}
2014-12-10 14:28:25 -05:00
for (Iterator<Class<? extends IBase>> iter = myScanAlso.iterator(); iter.hasNext();) {
2014-02-18 18:10:50 -05:00
if (myClassToElementDefinitions.containsKey(iter.next())) {
iter.remove();
}
}
typesToScan.clear();
typesToScan.addAll(myScanAlso);
2014-02-18 18:10:50 -05:00
myScanAlso.clear();
} while (!typesToScan.isEmpty());
2014-02-19 11:59:12 -05:00
2014-12-10 14:28:25 -05:00
for (Entry<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> nextEntry : myClassToElementDefinitions.entrySet()) {
2014-07-04 09:27:36 -04:00
if (theExistingDefinitions != null && theExistingDefinitions.containsKey(nextEntry.getKey())) {
2014-07-02 08:57:07 -04:00
continue;
}
BaseRuntimeElementDefinition<?> next = nextEntry.getValue();
boolean deferredSeal = false;
if (myContext.getPerformanceOptions().contains(PerformanceOptionsEnum.DEFERRED_MODEL_SCANNING)) {
if (next instanceof BaseRuntimeElementCompositeDefinition) {
deferredSeal = true;
}
}
if (!deferredSeal) {
next.sealAndInitialize(myContext, myClassToElementDefinitions);
}
2014-02-17 17:58:32 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-23 18:13:59 -05:00
myRuntimeChildUndeclaredExtensionDefinition = new RuntimeChildUndeclaredExtensionDefinition();
myRuntimeChildUndeclaredExtensionDefinition.sealAndInitialize(myContext, myClassToElementDefinitions);
long time = System.currentTimeMillis() - start;
2014-07-04 09:27:36 -04:00
int size = myClassToElementDefinitions.size() - startSize;
ourLog.debug("Done scanning FHIR library, found {} model entries in {}ms", size, time);
2014-02-17 17:58:32 -05:00
}
private boolean isStandardType(Class<? extends IBase> theClass) {
2015-12-30 11:27:12 -06:00
boolean retVal = myVersionTypes.contains(theClass);
return retVal;
}
/**
2018-09-08 03:30:35 +08:00
* There are two implementations of all of the annotations (e.g. {@link Child} since the HL7.org ones will eventually replace the HAPI
2016-02-26 18:16:35 -05:00
* ones. Annotations can't extend each other or implement interfaces or anything like that, so rather than duplicate all of the annotation processing code this method just creates an interface
* Proxy to simulate the HAPI annotations if the HL7.org ones are found instead.
*/
static <T extends Annotation> T pullAnnotation(AnnotatedElement theTarget, Class<T> theAnnotationType) {
T retVal = theTarget.getAnnotation(theAnnotationType);
2016-02-26 18:16:35 -05:00
return retVal;
}
2014-12-10 14:28:25 -05:00
private void scan(Class<? extends IBase> theClass) throws ConfigurationException {
2014-02-18 18:10:50 -05:00
BaseRuntimeElementDefinition<?> existingDef = myClassToElementDefinitions.get(theClass);
2014-02-17 17:58:32 -05:00
if (existingDef != null) {
2014-02-20 12:13:05 -05:00
return;
2014-02-17 17:58:32 -05:00
}
2016-02-26 18:16:35 -05:00
ResourceDef resourceDefinition = pullAnnotation(theClass, ResourceDef.class);
2014-02-17 17:58:32 -05:00
if (resourceDefinition != null) {
2015-02-16 11:33:46 -05:00
if (!IBaseResource.class.isAssignableFrom(theClass)) {
2016-02-26 18:16:35 -05:00
throw new ConfigurationException(
"Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
2014-02-17 17:58:32 -05:00
}
@SuppressWarnings("unchecked")
2014-12-10 17:40:47 -05:00
Class<? extends IBaseResource> resClass = (Class<? extends IBaseResource>) theClass;
2014-02-20 12:13:05 -05:00
scanResource(resClass, resourceDefinition);
return;
2014-02-17 17:58:32 -05:00
}
2016-02-26 18:16:35 -05:00
DatatypeDef datatypeDefinition = pullAnnotation(theClass, DatatypeDef.class);
2014-02-17 17:58:32 -05:00
if (datatypeDefinition != null) {
2014-12-10 14:28:25 -05:00
if (ICompositeType.class.isAssignableFrom(theClass)) {
2014-02-17 17:58:32 -05:00
@SuppressWarnings("unchecked")
2014-12-10 14:28:25 -05:00
Class<? extends ICompositeType> resClass = (Class<? extends ICompositeType>) theClass;
2014-02-20 12:13:05 -05:00
scanCompositeDatatype(resClass, datatypeDefinition);
2014-12-10 14:28:25 -05:00
} else if (IPrimitiveType.class.isAssignableFrom(theClass)) {
2014-02-20 12:13:05 -05:00
@SuppressWarnings({ "unchecked" })
2014-12-14 22:29:15 -05:00
Class<? extends IPrimitiveType<?>> resClass = (Class<? extends IPrimitiveType<?>>) theClass;
2014-02-20 12:13:05 -05:00
scanPrimitiveDatatype(resClass, datatypeDefinition);
}
return;
2014-02-17 17:58:32 -05:00
}
2016-02-26 18:16:35 -05:00
Block blockDefinition = pullAnnotation(theClass, Block.class);
2015-02-16 11:33:46 -05:00
2014-02-20 12:13:05 -05:00
if (blockDefinition != null) {
2015-05-05 13:16:10 -04:00
if (IResourceBlock.class.isAssignableFrom(theClass) || IBaseBackboneElement.class.isAssignableFrom(theClass) || IBaseDatatypeElement.class.isAssignableFrom(theClass)) {
2015-02-16 11:33:46 -05:00
scanBlock(theClass);
2014-02-21 21:06:11 -05:00
} else {
2016-02-26 18:16:35 -05:00
throw new ConfigurationException(
"Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName());
2014-02-20 12:13:05 -05:00
}
}
if (blockDefinition == null
//Redundant checking && datatypeDefinition == null && resourceDefinition == null
) {
throw new ConfigurationException("Resource class[" + theClass.getName() + "] does not contain any valid HAPI-FHIR annotations");
2014-02-20 12:13:05 -05:00
}
}
2015-02-16 11:33:46 -05:00
private void scanBlock(Class<? extends IBase> theClass) {
2014-02-20 12:13:05 -05:00
ourLog.debug("Scanning resource block class: {}", theClass.getName());
2014-02-18 18:10:50 -05:00
2014-08-07 08:27:52 -04:00
String resourceName = theClass.getCanonicalName();
2014-02-20 12:13:05 -05:00
if (isBlank(resourceName)) {
throw new ConfigurationException("Block type @" + Block.class.getSimpleName() + " annotation contains no name: " + theClass.getCanonicalName());
}
RuntimeResourceBlockDefinition blockDef = new RuntimeResourceBlockDefinition(resourceName, theClass, isStandardType(theClass), myContext, myClassToElementDefinitions);
myClassToElementDefinitions.put(theClass, blockDef);
2014-02-17 17:58:32 -05:00
}
2014-12-10 17:40:47 -05:00
private void scanCompositeDatatype(Class<? extends ICompositeType> theClass, DatatypeDef theDatatypeDefinition) {
2015-02-18 17:00:47 -05:00
ourLog.debug("Scanning datatype class: {}", theClass.getName());
2014-02-17 17:58:32 -05:00
RuntimeCompositeDatatypeDefinition elementDef;
2014-05-28 16:07:53 -04:00
if (theClass.equals(ExtensionDt.class)) {
elementDef = new RuntimeExtensionDtDefinition(theDatatypeDefinition, theClass, true, myContext, myClassToElementDefinitions);
2016-02-26 18:16:35 -05:00
// } else if (IBaseMetaType.class.isAssignableFrom(theClass)) {
// resourceDef = new RuntimeMetaDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
2014-05-28 16:07:53 -04:00
} else {
elementDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass), myContext, myClassToElementDefinitions);
2014-05-28 16:07:53 -04:00
}
myClassToElementDefinitions.put(theClass, elementDef);
myNameToElementDefinitions.put(elementDef.getName().toLowerCase(), elementDef);
/*
* See #423:
* If the type contains a field that has a custom type, we want to make
* sure that this type gets scanned as well
*/
elementDef.populateScanAlso(myScanAlso);
2014-02-17 17:58:32 -05:00
}
2014-02-19 17:33:46 -05:00
2014-08-15 15:55:39 -04:00
static Class<? extends Enum<?>> determineEnumTypeForBoundField(Field next) {
2016-03-18 19:41:43 +01:00
@SuppressWarnings("unchecked")
Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next);
return enumType;
}
private String scanPrimitiveDatatype(Class<? extends IPrimitiveType<?>> theClass, DatatypeDef theDatatypeDefinition) {
2014-02-22 15:33:02 -05:00
ourLog.debug("Scanning resource class: {}", theClass.getName());
String resourceName = theDatatypeDefinition.name();
if (isBlank(resourceName)) {
throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name: " + theClass.getCanonicalName());
2014-02-21 21:06:11 -05:00
}
2014-02-22 15:33:02 -05:00
BaseRuntimeElementDefinition<?> elementDef;
2014-02-22 15:33:02 -05:00
if (theClass.equals(XhtmlDt.class)) {
@SuppressWarnings("unchecked")
Class<XhtmlDt> clazz = (Class<XhtmlDt>) theClass;
elementDef = new RuntimePrimitiveDatatypeNarrativeDefinition(resourceName, clazz, isStandardType(clazz));
2015-04-13 08:32:49 -04:00
} else if (IBaseXhtml.class.isAssignableFrom(theClass)) {
@SuppressWarnings("unchecked")
Class<? extends IBaseXhtml> clazz = (Class<? extends IBaseXhtml>) theClass;
elementDef = new RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition(resourceName, clazz, isStandardType(clazz));
2015-04-13 08:32:49 -04:00
} else if (IIdType.class.isAssignableFrom(theClass)) {
elementDef = new RuntimeIdDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
2014-02-22 15:33:02 -05:00
} else {
elementDef = new RuntimePrimitiveDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
2014-02-22 15:33:02 -05:00
}
myClassToElementDefinitions.put(theClass, elementDef);
if (!theDatatypeDefinition.isSpecialization()) {
2015-12-30 11:27:12 -06:00
if (myVersion.isRi() && IDatatype.class.isAssignableFrom(theClass)) {
ourLog.debug("Not adding non RI type {} to RI context", theClass);
} else if (!myVersion.isRi() && !IDatatype.class.isAssignableFrom(theClass)) {
ourLog.debug("Not adding RI type {} to non RI context", theClass);
} else {
myNameToElementDefinitions.put(resourceName, elementDef);
2015-12-30 11:27:12 -06:00
}
}
2014-02-22 15:33:02 -05:00
return resourceName;
}
2014-12-10 17:40:47 -05:00
private String scanResource(Class<? extends IBaseResource> theClass, ResourceDef resourceDefinition) {
2014-02-22 15:33:02 -05:00
ourLog.debug("Scanning resource class: {}", theClass.getName());
boolean primaryNameProvider = true;
2014-02-22 15:33:02 -05:00
String resourceName = resourceDefinition.name();
if (isBlank(resourceName)) {
Class<?> parent = theClass.getSuperclass();
2014-08-26 08:10:15 -04:00
primaryNameProvider = false;
while (parent.equals(Object.class) == false && isBlank(resourceName)) {
2016-02-26 18:16:35 -05:00
ResourceDef nextDef = pullAnnotation(parent, ResourceDef.class);
if (nextDef != null) {
resourceName = nextDef.name();
}
parent = parent.getSuperclass();
}
if (isBlank(resourceName)) {
2016-02-26 18:16:35 -05:00
throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name(): " + theClass.getCanonicalName()
+ " - This is only allowed for types that extend other resource types ");
2014-02-22 15:33:02 -05:00
}
}
String resourceNameLowerCase = resourceName.toLowerCase();
Class<? extends IBaseResource> builtInType = myNameToResourceType.get(resourceNameLowerCase);
boolean standardType = builtInType != null && builtInType.equals(theClass) == true;
if (primaryNameProvider) {
if (builtInType != null && builtInType.equals(theClass) == false) {
primaryNameProvider = false;
}
}
String resourceId = resourceDefinition.id();
if (!isBlank(resourceId)) {
2014-03-13 17:33:12 -04:00
if (myIdToResourceDefinition.containsKey(resourceId)) {
2016-02-26 18:16:35 -05:00
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and "
+ myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
2014-03-13 17:33:12 -04:00
}
}
2014-08-15 15:55:39 -04:00
RuntimeResourceDefinition resourceDef = new RuntimeResourceDefinition(myContext, resourceName, theClass, resourceDefinition, standardType, myClassToElementDefinitions);
2014-02-22 15:33:02 -05:00
myClassToElementDefinitions.put(theClass, resourceDef);
if (primaryNameProvider) {
if (resourceDef.getStructureVersion() == myVersion) {
myNameToResourceDefinitions.put(resourceNameLowerCase, resourceDef);
2014-12-21 18:13:37 -05:00
}
}
2014-02-22 15:33:02 -05:00
myIdToResourceDefinition.put(resourceId, resourceDef);
scanResourceForSearchParams(theClass, resourceDef);
/*
* See #423:
* If the type contains a field that has a custom type, we want to make
* sure that this type gets scanned as well
*/
resourceDef.populateScanAlso(myScanAlso);
2014-02-22 15:33:02 -05:00
return resourceName;
2014-02-21 21:06:11 -05:00
}
2014-12-10 17:40:47 -05:00
private void scanResourceForSearchParams(Class<? extends IBaseResource> theClass, RuntimeResourceDefinition theResourceDef) {
Map<String, RuntimeSearchParam> nameToParam = new HashMap<String, RuntimeSearchParam>();
Map<Field, SearchParamDefinition> compositeFields = new LinkedHashMap<Field, SearchParamDefinition>();
/*
* Make sure we pick up fields in interfaces too.. This ensures that we
* grab the _id field which generally gets picked up via interface
*/
Set<Field> fields = new HashSet<Field>(Arrays.asList(theClass.getFields()));
Class<?> nextClass = theClass;
do {
for (Class<?> nextInterface : nextClass.getInterfaces()) {
fields.addAll(Arrays.asList(nextInterface.getFields()));
}
nextClass = nextClass.getSuperclass();
} while (nextClass.equals(Object.class) == false);
/*
* Now scan the fields for search params
*/
for (Field nextField : fields) {
2016-02-26 18:16:35 -05:00
SearchParamDefinition searchParam = pullAnnotation(nextField, SearchParamDefinition.class);
if (searchParam != null) {
RestSearchParameterTypeEnum paramType = RestSearchParameterTypeEnum.forCode(searchParam.type().toLowerCase());
2014-05-28 16:07:53 -04:00
if (paramType == null) {
2015-02-13 18:01:55 -05:00
throw new ConfigurationException("Search param " + searchParam.name() + " has an invalid type: " + searchParam.type());
2014-05-13 18:59:18 -04:00
}
Set<String> providesMembershipInCompartments;
providesMembershipInCompartments = new HashSet<>();
for (Compartment next : searchParam.providesMembershipIn()) {
if (paramType != RestSearchParameterTypeEnum.REFERENCE) {
2016-04-03 18:14:31 -04:00
StringBuilder b = new StringBuilder();
b.append("Search param ");
b.append(searchParam.name());
b.append(" on resource type ");
b.append(theClass.getName());
b.append(" provides compartment membership but is not of type 'reference'");
ourLog.warn(b.toString());
continue;
// throw new ConfigurationException(b.toString());
}
providesMembershipInCompartments.add(next.name());
}
if (paramType == RestSearchParameterTypeEnum.COMPOSITE) {
compositeFields.put(nextField, searchParam);
continue;
}
2016-02-26 18:16:35 -05:00
Collection<String> base = Collections.singletonList(theResourceDef.getName());
RuntimeSearchParam param = new RuntimeSearchParam(null, null, searchParam.name(), searchParam.description(), searchParam.path(), paramType, null, providesMembershipInCompartments, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE, base);
theResourceDef.addSearchParam(param);
nameToParam.put(param.getName(), param);
}
}
for (Entry<Field, SearchParamDefinition> nextEntry : compositeFields.entrySet()) {
SearchParamDefinition searchParam = nextEntry.getValue();
2014-08-15 15:55:39 -04:00
List<RuntimeSearchParam> compositeOf = new ArrayList<RuntimeSearchParam>();
2014-08-15 15:55:39 -04:00
for (String nextName : searchParam.compositeOf()) {
RuntimeSearchParam param = nameToParam.get(nextName);
2014-08-15 15:55:39 -04:00
if (param == null) {
2016-02-26 18:16:35 -05:00
ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parametr name itself. Valid values are: {}",
new Object[] { theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet() });
continue;
}
compositeOf.add(param);
}
2017-02-04 14:41:11 -05:00
RuntimeSearchParam param = new RuntimeSearchParam(null, null, searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf, null, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE);
theResourceDef.addSearchParam(param);
}
}
2016-05-02 11:42:55 -04:00
private Set<String> toTargetList(Class<? extends IBaseResource>[] theTarget) {
HashSet<String> retVal = new HashSet<String>();
for (Class<? extends IBaseResource> nextType : theTarget) {
ResourceDef resourceDef = nextType.getAnnotation(ResourceDef.class);
if (resourceDef != null) {
retVal.add(resourceDef.name());
}
}
return retVal;
}
private static Class<?> getGenericCollectionTypeOfCodedField(Field next) {
Class<?> type;
ParameterizedType collectionType = (ParameterizedType) next.getGenericType();
Type firstArg = collectionType.getActualTypeArguments()[0];
if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) {
ParameterizedType pt = ((ParameterizedType) firstArg);
firstArg = pt.getActualTypeArguments()[0];
type = (Class<?>) firstArg;
} else {
type = (Class<?>) firstArg;
}
return type;
}
static Set<Class<? extends IBase>> scanVersionPropertyFile(Set<Class<? extends IBase>> theDatatypes, Map<String, Class<? extends IBaseResource>> theResourceTypes, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingElementDefinitions) {
2015-05-02 14:04:43 -07:00
Set<Class<? extends IBase>> retVal = new HashSet<Class<? extends IBase>>();
2018-09-08 03:30:35 +08:00
try (InputStream str = theVersion.getVersionImplementation().getFhirVersionPropertiesFile()) {
Properties prop = new Properties();
prop.load(str);
for (Entry<Object, Object> nextEntry : prop.entrySet()) {
String nextKey = nextEntry.getKey().toString();
String nextValue = nextEntry.getValue().toString();
if (nextKey.startsWith("datatype.")) {
if (theDatatypes != null) {
try {
// Datatypes
2015-05-02 14:04:43 -07:00
@SuppressWarnings("unchecked")
Class<? extends IBase> dtType = (Class<? extends IBase>) Class.forName(nextValue);
if (theExistingElementDefinitions.containsKey(dtType)) {
continue;
}
2015-05-02 14:04:43 -07:00
retVal.add(dtType);
2015-02-16 11:33:46 -05:00
if (IElement.class.isAssignableFrom(dtType)) {
@SuppressWarnings("unchecked")
Class<? extends IElement> nextClass = (Class<? extends IElement>) dtType;
theDatatypes.add(nextClass);
} else if (IBaseDatatype.class.isAssignableFrom(dtType)) {
@SuppressWarnings("unchecked")
Class<? extends IBaseDatatype> nextClass = (Class<? extends IBaseDatatype>) dtType;
theDatatypes.add(nextClass);
} else {
ourLog.warn("Class is not assignable from " + IElement.class.getSimpleName() + " or " + IBaseDatatype.class.getSimpleName() + ": " + nextValue);
continue;
}
} catch (ClassNotFoundException e) {
2015-05-05 18:16:22 -04:00
throw new ConfigurationException("Unknown class[" + nextValue + "] for data type definition: " + nextKey.substring("datatype.".length()), e);
}
}
} else if (nextKey.startsWith("resource.")) {
// Resources
String resName = nextKey.substring("resource.".length()).toLowerCase();
try {
@SuppressWarnings("unchecked")
Class<? extends IBaseResource> nextClass = (Class<? extends IBaseResource>) Class.forName(nextValue);
if (theExistingElementDefinitions.containsKey(nextClass)) {
continue;
}
if (!IBaseResource.class.isAssignableFrom(nextClass)) {
2015-05-05 18:16:22 -04:00
throw new ConfigurationException("Class is not assignable from " + IBaseResource.class.getSimpleName() + ": " + nextValue);
}
theResourceTypes.put(resName, nextClass);
} catch (ClassNotFoundException e) {
2015-05-05 18:16:22 -04:00
throw new ConfigurationException("Unknown class[" + nextValue + "] for resource definition: " + nextKey.substring("resource.".length()), e);
}
} else {
2015-05-05 18:16:22 -04:00
throw new ConfigurationException("Unexpected property in version property file: " + nextKey + "=" + nextValue);
}
}
} catch (IOException e) {
throw new ConfigurationException("Failed to load model property file from classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
}
return retVal;
2015-04-20 07:31:45 -04:00
}
2014-02-17 17:58:32 -05:00
}