1 package ca.uhn.fhir.model.primitive;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import static org.apache.commons.lang3.StringUtils.*;
24
25 import java.math.BigDecimal;
26
27 import org.apache.commons.lang3.ObjectUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.Validate;
30
31 import ca.uhn.fhir.model.api.BasePrimitive;
32 import ca.uhn.fhir.model.api.annotation.DatatypeDef;
33 import ca.uhn.fhir.model.api.annotation.SimpleSetter;
34 import ca.uhn.fhir.parser.DataFormatException;
35 import ca.uhn.fhir.rest.server.Constants;
36 import ca.uhn.fhir.util.UrlUtil;
37
38
39
40
41
42
43
44
45
46
47
48
49 @DatatypeDef(name = "id")
50 public class IdDt extends BasePrimitive<String> {
51
52 private String myBaseUrl;
53 private boolean myHaveComponentParts;
54 private String myResourceType;
55 private String myUnqualifiedId;
56 private String myUnqualifiedVersionId;
57 private volatile String myValue;
58
59
60
61
62 public IdDt() {
63 super();
64 }
65
66
67
68
69 public IdDt(BigDecimal thePid) {
70 if (thePid != null) {
71 setValue(toPlainStringWithNpeThrowIfNeeded(thePid));
72 } else {
73 setValue(null);
74 }
75 }
76
77
78
79
80 public IdDt(long theId) {
81 setValue(Long.toString(theId));
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95 @SimpleSetter
96 public IdDt(@SimpleSetter.Parameter(name = "theId") String theValue) {
97 setValue(theValue);
98 }
99
100
101
102
103
104
105
106
107
108 public IdDt(String theResourceType, BigDecimal theIdPart) {
109 this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart));
110 }
111
112
113
114
115
116
117
118
119
120 public IdDt(String theResourceType, String theId) {
121 this(theResourceType, theId, null);
122 }
123
124
125
126
127
128
129
130
131
132
133
134 public IdDt(String theResourceType, String theId, String theVersionId) {
135 myResourceType = theResourceType;
136 myUnqualifiedId = theId;
137 myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionId, null);
138 myHaveComponentParts = true;
139 }
140
141
142
143
144 public IdDt(UriDt theUrl) {
145 setValue(theUrl.getValueAsString());
146 }
147
148
149
150
151 public BigDecimal asBigDecimal() {
152 return getIdPartAsBigDecimal();
153 }
154
155
156
157
158 @SuppressWarnings("deprecation")
159 public boolean equalsIgnoreBase(IdDt theId) {
160 if (theId == null) {
161 return false;
162 }
163 if (theId.isEmpty()) {
164 return isEmpty();
165 }
166 return ObjectUtils.equals(getResourceType(), theId.getResourceType()) && ObjectUtils.equals(getIdPart(), theId.getIdPart()) && ObjectUtils.equals(getVersionIdPart(), theId.getVersionIdPart());
167 }
168
169
170
171
172
173
174
175
176 public String getBaseUrl() {
177 return myBaseUrl;
178 }
179
180 public String getIdPart() {
181 return myUnqualifiedId;
182 }
183
184
185
186
187
188
189
190 public BigDecimal getIdPartAsBigDecimal() {
191 String val = getIdPart();
192 if (isBlank(val)) {
193 return null;
194 }
195 return new BigDecimal(val);
196 }
197
198
199
200
201
202
203
204 public Long getIdPartAsLong() {
205 String val = getIdPart();
206 if (isBlank(val)) {
207 return null;
208 }
209 return Long.parseLong(val);
210 }
211
212 public String getResourceType() {
213 return myResourceType;
214 }
215
216
217
218
219
220
221 @Override
222 public String getValue() {
223 if (myValue == null && myHaveComponentParts) {
224 StringBuilder b = new StringBuilder();
225 if (isNotBlank(myResourceType)) {
226 b.append(myResourceType);
227 b.append('/');
228 }
229 b.append(myUnqualifiedId);
230 if (isNotBlank(myUnqualifiedVersionId)) {
231 b.append('/');
232 b.append(Constants.PARAM_HISTORY);
233 b.append('/');
234 b.append(myUnqualifiedVersionId);
235 }
236 myValue = b.toString();
237 }
238 return myValue;
239 }
240
241 @Override
242 public String getValueAsString() {
243 return getValue();
244 }
245
246 public String getVersionIdPart() {
247 return myUnqualifiedVersionId;
248 }
249
250 public Long getVersionIdPartAsLong() {
251 if (!hasVersionIdPart()) {
252 return null;
253 } else {
254 return Long.parseLong(getVersionIdPart());
255 }
256 }
257
258
259
260
261
262
263 public boolean hasBaseUrl() {
264 return isNotBlank(myBaseUrl);
265 }
266
267 public boolean hasIdPart() {
268 return isNotBlank(getIdPart());
269 }
270
271 public boolean hasResourceType() {
272 return isNotBlank(myResourceType);
273 }
274
275 public boolean hasVersionIdPart() {
276 return isNotBlank(getVersionIdPart());
277 }
278
279
280
281
282 public boolean isAbsolute() {
283 if (StringUtils.isBlank(getValue())) {
284 return false;
285 }
286 return UrlUtil.isAbsolute(getValue());
287 }
288
289
290
291
292 public boolean isIdPartValidLong() {
293 String id = getIdPart();
294 if (StringUtils.isBlank(id)) {
295 return false;
296 }
297 for (int i = 0; i < id.length(); i++) {
298 if (Character.isDigit(id.charAt(i)) == false) {
299 return false;
300 }
301 }
302 return true;
303 }
304
305
306
307
308 public boolean isLocal() {
309 return myUnqualifiedId != null && myUnqualifiedId.isEmpty() == false && myUnqualifiedId.charAt(0) == '#';
310 }
311
312
313
314
315 @Override
316 public void setId(IdDt theId) {
317 setValue(theId.getValue());
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331 @Override
332 public void setValue(String theValue) throws DataFormatException {
333
334 myValue = theValue;
335 myHaveComponentParts = false;
336 if (StringUtils.isBlank(theValue)) {
337 myValue = null;
338 myUnqualifiedId = null;
339 myUnqualifiedVersionId = null;
340 myResourceType = null;
341 } else {
342 int vidIndex = theValue.indexOf("/_history/");
343 int idIndex;
344 if (vidIndex != -1) {
345 myUnqualifiedVersionId = theValue.substring(vidIndex + "/_history/".length());
346 idIndex = theValue.lastIndexOf('/', vidIndex - 1);
347 myUnqualifiedId = theValue.substring(idIndex + 1, vidIndex);
348 } else {
349 idIndex = theValue.lastIndexOf('/');
350 myUnqualifiedId = theValue.substring(idIndex + 1);
351 myUnqualifiedVersionId = null;
352 }
353
354 myBaseUrl = null;
355 if (idIndex <= 0) {
356 myResourceType = null;
357 } else {
358 int typeIndex = theValue.lastIndexOf('/', idIndex - 1);
359 if (typeIndex == -1) {
360 myResourceType = theValue.substring(0, idIndex);
361 } else {
362 myResourceType = theValue.substring(typeIndex + 1, idIndex);
363
364 if (typeIndex > 4) {
365 myBaseUrl = theValue.substring(0, typeIndex);
366 }
367
368 }
369 }
370
371 }
372 }
373
374
375
376
377
378
379
380
381
382
383
384
385 @Override
386 public void setValueAsString(String theValue) throws DataFormatException {
387 setValue(theValue);
388 }
389
390 @Override
391 public String toString() {
392 return getValue();
393 }
394
395 public IdDt toUnqualified() {
396 return new IdDt(getResourceType(), getIdPart(), getVersionIdPart());
397 }
398
399 public IdDt toUnqualifiedVersionless() {
400 return new IdDt(getResourceType(), getIdPart());
401 }
402
403 public IdDt toVersionless() {
404 String value = getValue();
405 int i = value.indexOf(Constants.PARAM_HISTORY);
406 if (i > 1) {
407 return new IdDt(value.substring(0, i - 1));
408 } else {
409 return this;
410 }
411 }
412
413 public IdDt withResourceType(String theResourceName) {
414 return new IdDt(theResourceName, getIdPart(), getVersionIdPart());
415 }
416
417
418
419
420
421
422
423
424
425
426
427 public String withServerBase(String theServerBase, String theResourceType) {
428 if (getValue().startsWith("http")) {
429 return getValue();
430 }
431 StringBuilder retVal = new StringBuilder();
432 retVal.append(theServerBase);
433 if (retVal.charAt(retVal.length() - 1) != '/') {
434 retVal.append('/');
435 }
436 if (isNotBlank(getResourceType())) {
437 retVal.append(getResourceType());
438 } else {
439 retVal.append(theResourceType);
440 }
441 retVal.append('/');
442 retVal.append(getIdPart());
443
444 if (hasVersionIdPart()) {
445 retVal.append('/');
446 retVal.append(Constants.PARAM_HISTORY);
447 retVal.append('/');
448 retVal.append(getVersionIdPart());
449 }
450
451 return retVal.toString();
452 }
453
454
455
456
457
458
459
460
461 public IdDt withVersion(String theVersion) {
462 Validate.notBlank(theVersion, "Version may not be null or empty");
463
464 String existingValue = getValue();
465
466 int i = existingValue.indexOf(Constants.PARAM_HISTORY);
467 String value;
468 if (i > 1) {
469 value = existingValue.substring(0, i - 1);
470 } else {
471 value = existingValue;
472 }
473
474 return new IdDt(value + '/' + Constants.PARAM_HISTORY + '/' + theVersion);
475 }
476
477 private static String toPlainStringWithNpeThrowIfNeeded(BigDecimal theIdPart) {
478 if (theIdPart == null) {
479 throw new NullPointerException("BigDecimal ID can not be null");
480 }
481 return theIdPart.toPlainString();
482 }
483
484 }