
001package org.hl7.fhir.dstu3.model; 002 003 004 005/* 006 Copyright (c) 2011+, HL7, Inc. 007 All rights reserved. 008 009 Redistribution and use in source and binary forms, with or without modification, 010 are permitted provided that the following conditions are met: 011 012 * Redistributions of source code must retain the above copyright notice, this 013 list of conditions and the following disclaimer. 014 * Redistributions in binary form must reproduce the above copyright notice, 015 this list of conditions and the following disclaimer in the documentation 016 and/or other materials provided with the distribution. 017 * Neither the name of HL7 nor the names of its contributors may be used to 018 endorse or promote products derived from this software without specific 019 prior written permission. 020 021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 022 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 023 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 024 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 025 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 026 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 028 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 029 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 030 POSSIBILITY OF SUCH DAMAGE. 031 032*/ 033import static org.apache.commons.lang3.StringUtils.defaultString; 034import static org.apache.commons.lang3.StringUtils.isBlank; 035import static org.apache.commons.lang3.StringUtils.isNotBlank; 036 037import java.math.BigDecimal; 038import java.util.UUID; 039 040import org.apache.commons.lang3.ObjectUtils; 041import org.apache.commons.lang3.StringUtils; 042import org.apache.commons.lang3.Validate; 043import org.apache.commons.lang3.builder.HashCodeBuilder; 044import org.hl7.fhir.instance.model.api.IBaseResource; 045import org.hl7.fhir.instance.model.api.IIdType; 046import org.hl7.fhir.instance.model.api.IPrimitiveType; 047 048import ca.uhn.fhir.model.api.annotation.DatatypeDef; 049 050/** 051 * This class represents the logical identity for a resource, or as much of that 052 * identity is known. In FHIR, every resource must have a "logical ID" which is 053 * defined by the FHIR specification as: 054 * <p> 055 * <code> 056 * Any combination of upper or lower case ASCII letters ('A'..'Z', and 'a'..'z', numerals ('0'..'9'), '-' and '.', with a length limit of 64 characters. (This might be an integer, an un-prefixed OID, UUID or any other identifier pattern that meets these constraints.) 057 * </code> 058 * </p> 059 * <p> 060 * This class contains that logical ID, and can optionally also contain a 061 * relative or absolute URL representing the resource identity. For example, the 062 * following are all valid values for IdType, and all might represent the same 063 * resource: 064 * </p> 065 * <ul> 066 * <li><code>123</code> (just a resource's ID)</li> 067 * <li><code>Patient/123</code> (a relative identity)</li> 068 * <li><code>http://example.com/Patient/123 (an absolute identity)</code></li> 069 * <li> 070 * <code>http://example.com/Patient/123/_history/1 (an absolute identity with a version id)</code> 071 * </li> 072 * <li> 073 * <code>Patient/123/_history/1 (a relative identity with a version id)</code> 074 * </li> 075 * </ul> 076 * <p> 077 * Note that the 64 character 078 * limit applies only to the ID portion ("123" in the examples above). 079 * </p> 080 * <p> 081 * In most situations, you only need to populate the resource's ID (e.g. 082 * <code>123</code>) in resources you are constructing and the encoder will 083 * infer the rest from the context in which the object is being used. On the 084 * other hand, the parser will always try to populate the complete absolute 085 * identity on objects it creates as a convenience. 086 * </p> 087 * <p> 088 * Regex for ID: [a-z0-9\-\.]{1,64} 089 * </p> 090 */ 091@DatatypeDef(name = "id", profileOf=StringType.class) 092public final class IdType extends UriType implements IPrimitiveType<String>, IIdType { 093 public static final String URN_PREFIX = "urn:"; 094 095 /** 096 * This is the maximum length for the ID 097 */ 098 public static final int MAX_LENGTH = 64; // maximum length 099 100 private static final long serialVersionUID = 2L; 101 private String myBaseUrl; 102 private boolean myHaveComponentParts; 103 private String myResourceType; 104 private String myUnqualifiedId; 105 private String myUnqualifiedVersionId; 106 107 /** 108 * Create a new empty ID 109 */ 110 public IdType() { 111 super(); 112 } 113 114 /** 115 * Create a new ID, using a BigDecimal input. Uses 116 * {@link BigDecimal#toPlainString()} to generate the string representation. 117 */ 118 public IdType(BigDecimal thePid) { 119 if (thePid != null) { 120 setValue(toPlainStringWithNpeThrowIfNeeded(thePid)); 121 } else { 122 setValue(null); 123 } 124 } 125 126 /** 127 * Create a new ID using a long 128 */ 129 public IdType(long theId) { 130 setValue(Long.toString(theId)); 131 } 132 133 /** 134 * Create a new ID using a string. This String may contain a simple ID (e.g. 135 * "1234") or it may contain a complete URL 136 * (http://example.com/fhir/Patient/1234). 137 * 138 * <p> 139 * <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally 140 * represented in hex), a uuid, an oid, or any other combination of lowercase 141 * letters, numerals, "-" and ".", with a length limit of 36 characters. 142 * </p> 143 * <p> 144 * regex: [a-z0-9\-\.]{1,36} 145 * </p> 146 */ 147 public IdType(String theValue) { 148 setValue(theValue); 149 } 150 151 /** 152 * Constructor 153 * 154 * @param theResourceType 155 * The resource type (e.g. "Patient") 156 * @param theIdPart 157 * The ID (e.g. "123") 158 */ 159 public IdType(String theResourceType, BigDecimal theIdPart) { 160 this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart)); 161 } 162 163 /** 164 * Constructor 165 * 166 * @param theResourceType 167 * The resource type (e.g. "Patient") 168 * @param theIdPart 169 * The ID (e.g. "123") 170 */ 171 public IdType(String theResourceType, Long theIdPart) { 172 this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart)); 173 } 174 175 /** 176 * Constructor 177 * 178 * @param theResourceType 179 * The resource type (e.g. "Patient") 180 * @param theId 181 * The ID (e.g. "123") 182 */ 183 public IdType(String theResourceType, String theId) { 184 this(theResourceType, theId, null); 185 } 186 187 /** 188 * Constructor 189 * 190 * @param theResourceType 191 * The resource type (e.g. "Patient") 192 * @param theId 193 * The ID (e.g. "123") 194 * @param theVersionId 195 * The version ID ("e.g. "456") 196 */ 197 public IdType(String theResourceType, String theId, String theVersionId) { 198 this(null, theResourceType, theId, theVersionId); 199 } 200 201 /** 202 * Constructor 203 * 204 * @param theBaseUrl 205 * The server base URL (e.g. "http://example.com/fhir") 206 * @param theResourceType 207 * The resource type (e.g. "Patient") 208 * @param theId 209 * The ID (e.g. "123") 210 * @param theVersionId 211 * The version ID ("e.g. "456") 212 */ 213 public IdType(String theBaseUrl, String theResourceType, String theId, String theVersionId) { 214 myBaseUrl = theBaseUrl; 215 myResourceType = theResourceType; 216 myUnqualifiedId = theId; 217 myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionId, null); 218 myHaveComponentParts = true; 219 if (isBlank(myBaseUrl) && isBlank(myResourceType) && isBlank(myUnqualifiedId) && isBlank(myUnqualifiedVersionId)) { 220 myHaveComponentParts = false; 221 } 222 } 223 224 /** 225 * Creates an ID based on a given URL 226 */ 227 public IdType(UriType theUrl) { 228 setValue(theUrl.getValueAsString()); 229 } 230 231 public void applyTo(IBaseResource theResource) { 232 if (theResource == null) { 233 throw new NullPointerException("theResource can not be null"); 234 } else { 235 theResource.setId(new IdType(getValue())); 236 } 237 } 238 239 /** 240 * @deprecated Use {@link #getIdPartAsBigDecimal()} instead (this method was 241 * deprocated because its name is ambiguous) 242 */ 243 @Deprecated 244 public BigDecimal asBigDecimal() { 245 return getIdPartAsBigDecimal(); 246 } 247 248 @Override 249 public IdType copy() { 250 return new IdType(getValue()); 251 } 252 253 @Override 254 public boolean equals(Object theArg0) { 255 if (!(theArg0 instanceof IdType)) { 256 return false; 257 } 258 return StringUtils.equals(getValueAsString(), ((IdType)theArg0).getValueAsString()); 259 } 260 261 /** 262 * Returns true if this IdType matches the given IdType in terms of resource 263 * type and ID, but ignores the URL base 264 */ 265 @SuppressWarnings("deprecation") 266 public boolean equalsIgnoreBase(IdType theId) { 267 if (theId == null) { 268 return false; 269 } 270 if (theId.isEmpty()) { 271 return isEmpty(); 272 } 273 return ObjectUtils.equals(getResourceType(), theId.getResourceType()) 274 && ObjectUtils.equals(getIdPart(), theId.getIdPart()) 275 && ObjectUtils.equals(getVersionIdPart(), theId.getVersionIdPart()); 276 } 277 278 /** 279 * Returns the portion of this resource ID which corresponds to the server 280 * base URL. For example given the resource ID 281 * <code>http://example.com/fhir/Patient/123</code> the base URL would be 282 * <code>http://example.com/fhir</code>. 283 * <p> 284 * This method may return null if the ID contains no base (e.g. "Patient/123") 285 * </p> 286 */ 287 @Override 288 public String getBaseUrl() { 289 return myBaseUrl; 290 } 291 292 /** 293 * Returns only the logical ID part of this ID. For example, given the ID 294 * "http://example,.com/fhir/Patient/123/_history/456", this method would 295 * return "123". 296 */ 297 @Override 298 public String getIdPart() { 299 return myUnqualifiedId; 300 } 301 302 /** 303 * Returns the unqualified portion of this ID as a big decimal, or 304 * <code>null</code> if the value is null 305 * 306 * @throws NumberFormatException 307 * If the value is not a valid BigDecimal 308 */ 309 public BigDecimal getIdPartAsBigDecimal() { 310 String val = getIdPart(); 311 if (isBlank(val)) { 312 return null; 313 } 314 return new BigDecimal(val); 315 } 316 317 /** 318 * Returns the unqualified portion of this ID as a {@link Long}, or 319 * <code>null</code> if the value is null 320 * 321 * @throws NumberFormatException 322 * If the value is not a valid Long 323 */ 324 @Override 325 public Long getIdPartAsLong() { 326 String val = getIdPart(); 327 if (isBlank(val)) { 328 return null; 329 } 330 return Long.parseLong(val); 331 } 332 333 @Override 334 public String getResourceType() { 335 return myResourceType; 336 } 337 338 /** 339 * Returns the value of this ID. Note that this value may be a fully qualified 340 * URL, a relative/partial URL, or a simple ID. Use {@link #getIdPart()} to 341 * get just the ID portion. 342 * 343 * @see #getIdPart() 344 */ 345 @Override 346 public String getValue() { 347 String retVal = super.getValue(); 348 if (retVal == null && myHaveComponentParts) { 349 350 if (isLocal() || isUrn()) { 351 return myUnqualifiedId; 352 } 353 354 StringBuilder b = new StringBuilder(); 355 if (isNotBlank(myBaseUrl)) { 356 b.append(myBaseUrl); 357 if (myBaseUrl.charAt(myBaseUrl.length() - 1) != '/') { 358 b.append('/'); 359 } 360 } 361 362 if (isNotBlank(myResourceType)) { 363 b.append(myResourceType); 364 } 365 366 if (b.length() > 0 && isNotBlank(myUnqualifiedId)) { 367 b.append('/'); 368 } 369 370 if (isNotBlank(myUnqualifiedId)) { 371 b.append(myUnqualifiedId); 372 } else if (isNotBlank(myUnqualifiedVersionId)) { 373 b.append('/'); 374 } 375 376 if (isNotBlank(myUnqualifiedVersionId)) { 377 b.append('/'); 378 b.append("_history"); 379 b.append('/'); 380 b.append(myUnqualifiedVersionId); 381 } 382 retVal = b.toString(); 383 super.setValue(retVal); 384 } 385 return retVal; 386 } 387 388 @Override 389 public String getValueAsString() { 390 return getValue(); 391 } 392 393 @Override 394 public String asStringValue() { 395 return getValue(); 396 } 397 398 @Override 399 public String getVersionIdPart() { 400 return myUnqualifiedVersionId; 401 } 402 403 public Long getVersionIdPartAsLong() { 404 if (!hasVersionIdPart()) { 405 return null; 406 } else { 407 return Long.parseLong(getVersionIdPart()); 408 } 409 } 410 411 /** 412 * Returns true if this ID has a base url 413 * 414 * @see #getBaseUrl() 415 */ 416 public boolean hasBaseUrl() { 417 return isNotBlank(myBaseUrl); 418 } 419 420 @Override 421 public int hashCode() { 422 HashCodeBuilder b = new HashCodeBuilder(); 423 b.append(getValueAsString()); 424 return b.toHashCode(); 425 } 426 427 @Override 428 public boolean hasIdPart() { 429 return isNotBlank(getIdPart()); 430 } 431 432 @Override 433 public boolean hasResourceType() { 434 return isNotBlank(myResourceType); 435 } 436 437 @Override 438 public boolean hasVersionIdPart() { 439 return isNotBlank(getVersionIdPart()); 440 } 441 442 /** 443 * Returns <code>true</code> if this ID contains an absolute URL (in other 444 * words, a URL starting with "http://" or "https://" 445 */ 446 @Override 447 public boolean isAbsolute() { 448 if (StringUtils.isBlank(getValue())) { 449 return false; 450 } 451 return isUrlAbsolute(getValue()); 452 } 453 454 @Override 455 public boolean isEmpty() { 456 return super.isEmpty() && isBlank(getValue()); 457 } 458 459 @Override 460 public boolean isIdPartValid() { 461 String id = getIdPart(); 462 if (StringUtils.isBlank(id)) { 463 return false; 464 } 465 if (id.length() > 64) { 466 return false; 467 } 468 for (int i = 0; i < id.length(); i++) { 469 char nextChar = id.charAt(i); 470 if (nextChar >= 'a' && nextChar <= 'z') { 471 continue; 472 } 473 if (nextChar >= 'A' && nextChar <= 'Z') { 474 continue; 475 } 476 if (nextChar >= '0' && nextChar <= '9') { 477 continue; 478 } 479 if (nextChar == '-' || nextChar == '.') { 480 continue; 481 } 482 return false; 483 } 484 return true; 485 } 486 487 /** 488 * Returns <code>true</code> if the unqualified ID is a valid {@link Long} 489 * value (in other words, it consists only of digits) 490 */ 491 @Override 492 public boolean isIdPartValidLong() { 493 return isValidLong(getIdPart()); 494 } 495 496 /** 497 * Returns <code>true</code> if the ID is a local reference (in other words, 498 * it begins with the '#' character) 499 */ 500 @Override 501 public boolean isLocal() { 502 return defaultString(myUnqualifiedId).startsWith("#"); 503 } 504 505 public boolean isUrn() { 506 return defaultString(myUnqualifiedId).startsWith(URN_PREFIX); 507 } 508 509 @Override 510 public boolean isVersionIdPartValidLong() { 511 return isValidLong(getVersionIdPart()); 512 } 513 514 /** 515 * Set the value 516 * 517 * <p> 518 * <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally 519 * represented in hex), a uuid, an oid, or any other combination of lowercase 520 * letters, numerals, "-" and ".", with a length limit of 36 characters. 521 * </p> 522 * <p> 523 * regex: [a-z0-9\-\.]{1,36} 524 * </p> 525 */ 526 @Override 527 public IdType setValue(String theValue) { 528 // TODO: add validation 529 super.setValue(theValue); 530 531 myHaveComponentParts = false; 532 533 if (StringUtils.isBlank(theValue)) { 534 myBaseUrl = null; 535 super.setValue(null); 536 myUnqualifiedId = null; 537 myUnqualifiedVersionId = null; 538 myResourceType = null; 539 } else if (theValue.charAt(0) == '#' && theValue.length() > 1) { 540 super.setValue(theValue); 541 myBaseUrl = null; 542 myUnqualifiedId = theValue; 543 myUnqualifiedVersionId = null; 544 myResourceType = null; 545 myHaveComponentParts = true; 546 } else if (theValue.startsWith(URN_PREFIX)) { 547 myBaseUrl = null; 548 myUnqualifiedId = theValue; 549 myUnqualifiedVersionId = null; 550 myResourceType = null; 551 myHaveComponentParts = true; 552 } else { 553 int vidIndex = theValue.indexOf("/_history/"); 554 int idIndex; 555 if (vidIndex != -1) { 556 myUnqualifiedVersionId = theValue.substring(vidIndex + "/_history/".length()); 557 idIndex = theValue.lastIndexOf('/', vidIndex - 1); 558 myUnqualifiedId = theValue.substring(idIndex + 1, vidIndex); 559 } else { 560 idIndex = theValue.lastIndexOf('/'); 561 myUnqualifiedId = theValue.substring(idIndex + 1); 562 myUnqualifiedVersionId = null; 563 } 564 565 myBaseUrl = null; 566 if (idIndex <= 0) { 567 myResourceType = null; 568 } else { 569 int typeIndex = theValue.lastIndexOf('/', idIndex - 1); 570 if (typeIndex == -1) { 571 myResourceType = theValue.substring(0, idIndex); 572 } else { 573 if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) { 574 typeIndex = theValue.indexOf('/', typeIndex + 1); 575 } 576 if (typeIndex >= idIndex) { 577 // e.g. http://example.org/foo 578 // 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id. 579 // Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly 580 // recreate the url 581 myResourceType = myUnqualifiedId; 582 myUnqualifiedId = null; 583 super.setValue(null); 584 myHaveComponentParts = true; 585 } else { 586 myResourceType = theValue.substring(typeIndex + 1, idIndex); 587 } 588 589 if (typeIndex > 4) { 590 myBaseUrl = theValue.substring(0, typeIndex); 591 } 592 593 } 594 } 595 596 } 597 return this; 598 } 599 600 /** 601 * Set the value 602 * 603 * <p> 604 * <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally 605 * represented in hex), a uuid, an oid, or any other combination of lowercase 606 * letters, numerals, "-" and ".", with a length limit of 36 characters. 607 * </p> 608 * <p> 609 * regex: [a-z0-9\-\.]{1,36} 610 * </p> 611 */ 612 @Override 613 public void setValueAsString(String theValue) { 614 setValue(theValue); 615 } 616 617 @Override 618 public String toString() { 619 return getValue(); 620 } 621 622 /** 623 * Returns a new IdType containing this IdType's values but with no server 624 * base URL if one is present in this IdType. For example, if this IdType 625 * contains the ID "http://foo/Patient/1", this method will return a new 626 * IdType containing ID "Patient/1". 627 */ 628 @Override 629 public IdType toUnqualified() { 630 if (isLocal() || isUrn()) { 631 return new IdType(getValueAsString()); 632 } 633 return new IdType(getResourceType(), getIdPart(), getVersionIdPart()); 634 } 635 636 @Override 637 public IdType toUnqualifiedVersionless() { 638 if (isLocal() || isUrn()) { 639 return new IdType(getValueAsString()); 640 } 641 return new IdType(getResourceType(), getIdPart()); 642 } 643 644 @Override 645 public IdType toVersionless() { 646 if (isLocal() || isUrn()) { 647 return new IdType(getValueAsString()); 648 } 649 return new IdType(getBaseUrl(), getResourceType(), getIdPart(), null); 650 } 651 652 @Override 653 public IdType withResourceType(String theResourceName) { 654 if (isLocal() || isUrn()) { 655 return new IdType(getValueAsString()); 656 } 657 return new IdType(theResourceName, getIdPart(), getVersionIdPart()); 658 } 659 660 /** 661 * Returns a view of this ID as a fully qualified URL, given a server base and 662 * resource name (which will only be used if the ID does not already contain 663 * those respective parts). Essentially, because IdType can contain either a 664 * complete URL or a partial one (or even jut a simple ID), this method may be 665 * used to translate into a complete URL. 666 * 667 * @param theServerBase 668 * The server base (e.g. "http://example.com/fhir") 669 * @param theResourceType 670 * The resource name (e.g. "Patient") 671 * @return A fully qualified URL for this ID (e.g. 672 * "http://example.com/fhir/Patient/1") 673 */ 674 @Override 675 public IdType withServerBase(String theServerBase, String theResourceType) { 676 if (isLocal() || isUrn()) { 677 return new IdType(getValueAsString()); 678 } 679 return new IdType(theServerBase, theResourceType, getIdPart(), getVersionIdPart()); 680 } 681 682 /** 683 * Creates a new instance of this ID which is identical, but refers to the 684 * specific version of this resource ID noted by theVersion. 685 * 686 * @param theVersion The actual version string, e.g. "1". If theVersion is blank or null, returns the same as {@link #toVersionless()}} 687 * @return A new instance of IdType which is identical, but refers to the 688 * specific version of this resource ID noted by theVersion. 689 */ 690 @Override 691 public IdType withVersion(String theVersion) { 692 if (isBlank(theVersion)) { 693 return toVersionless(); 694 } 695 696 if (isLocal() || isUrn()) { 697 return new IdType(getValueAsString()); 698 } 699 700 String existingValue = getValue(); 701 702 int i = existingValue.indexOf("_history"); 703 String value; 704 if (i > 1) { 705 value = existingValue.substring(0, i - 1); 706 } else { 707 value = existingValue; 708 } 709 710 return new IdType(value + '/' + "_history" + '/' + theVersion); 711 } 712 713 private static boolean isUrlAbsolute(String theValue) { 714 String value = theValue.toLowerCase(); 715 return value.startsWith("http://") || value.startsWith("https://"); 716 } 717 718 private static boolean isValidLong(String id) { 719 if (StringUtils.isBlank(id)) { 720 return false; 721 } 722 for (int i = 0; i < id.length(); i++) { 723 if (Character.isDigit(id.charAt(i)) == false) { 724 return false; 725 } 726 } 727 return true; 728 } 729 730 /** 731 * Construct a new ID with with form "urn:uuid:[UUID]" where [UUID] is a new, 732 * randomly created UUID generated by {@link UUID#randomUUID()} 733 */ 734 public static IdType newRandomUuid() { 735 return new IdType("urn:uuid:" + UUID.randomUUID().toString()); 736 } 737 738 /** 739 * Retrieves the ID from the given resource instance 740 */ 741 public static IdType of(IBaseResource theResouce) { 742 if (theResouce == null) { 743 throw new NullPointerException("theResource can not be null"); 744 } else { 745 IIdType retVal = theResouce.getIdElement(); 746 if (retVal == null) { 747 return null; 748 } else if (retVal instanceof IdType) { 749 return (IdType) retVal; 750 } else { 751 return new IdType(retVal.getValue()); 752 } 753 } 754 } 755 756 private static String toPlainStringWithNpeThrowIfNeeded(BigDecimal theIdPart) { 757 if (theIdPart == null) { 758 throw new NullPointerException("BigDecimal ID can not be null"); 759 } 760 return theIdPart.toPlainString(); 761 } 762 763 private static String toPlainStringWithNpeThrowIfNeeded(Long theIdPart) { 764 if (theIdPart == null) { 765 throw new NullPointerException("Long ID can not be null"); 766 } 767 return theIdPart.toString(); 768 } 769 770 public String fhirType() { 771 return "id"; 772 } 773 774 @Override 775 public IIdType setParts(String theBaseUrl, String theResourceType, String theIdPart, String theVersionIdPart) { 776 if (isNotBlank(theVersionIdPart)) { 777 Validate.notBlank(theResourceType, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated"); 778 Validate.notBlank(theIdPart, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated"); 779 } 780 if (isNotBlank(theBaseUrl) && isNotBlank(theIdPart)) { 781 Validate.notBlank(theResourceType, "If theBaseUrl is populated and theIdPart is populated, theResourceType must be populated"); 782 } 783 784 setValue(null); 785 786 myBaseUrl = theBaseUrl; 787 myResourceType = theResourceType; 788 myUnqualifiedId = theIdPart; 789 myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionIdPart, null); 790 myHaveComponentParts = true; 791 792 return this; 793 } 794 795}