001package ca.uhn.fhir.jpa.model.entity; 002 003/* 004 * #%L 005 * HAPI FHIR JPA Model 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.context.FhirVersionEnum; 024import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; 025import ca.uhn.fhir.model.primitive.InstantDt; 026import org.hibernate.annotations.OptimisticLock; 027 028import javax.persistence.Column; 029import javax.persistence.EnumType; 030import javax.persistence.Enumerated; 031import javax.persistence.MappedSuperclass; 032import javax.persistence.Temporal; 033import javax.persistence.TemporalType; 034import javax.persistence.Transient; 035import java.util.Collection; 036import java.util.Date; 037 038import static org.apache.commons.lang3.StringUtils.defaultString; 039 040@MappedSuperclass 041public abstract class BaseHasResource extends BasePartitionable implements IBaseResourceEntity, IBasePersistedResource { 042 043 @Column(name = "RES_DELETED_AT", nullable = true) 044 @Temporal(TemporalType.TIMESTAMP) 045 private Date myDeleted; 046 047 @Column(name = "RES_VERSION", nullable = true, length = 7) 048 @Enumerated(EnumType.STRING) 049 @OptimisticLock(excluded = true) 050 private FhirVersionEnum myFhirVersion; 051 052 @Column(name = "HAS_TAGS", nullable = false) 053 @OptimisticLock(excluded = true) 054 private boolean myHasTags; 055 056 @Temporal(TemporalType.TIMESTAMP) 057 @Column(name = "RES_PUBLISHED", nullable = false) 058 @OptimisticLock(excluded = true) 059 private Date myPublished; 060 061 @Temporal(TemporalType.TIMESTAMP) 062 @Column(name = "RES_UPDATED", nullable = false) 063 @OptimisticLock(excluded = true) 064 private Date myUpdated; 065 066 /** 067 * This is stored as an optimization to avoid needing to query for this 068 * after an update 069 */ 070 @Transient 071 private transient String myTransientForcedId; 072 073 public String getTransientForcedId() { 074 return myTransientForcedId; 075 } 076 077 public void setTransientForcedId(String theTransientForcedId) { 078 assert !defaultString(theTransientForcedId).contains("/") : "Forced ID should not include type: " + theTransientForcedId; 079 myTransientForcedId = theTransientForcedId; 080 } 081 082 083 public abstract BaseTag addTag(TagDefinition theDef); 084 085 @Override 086 public Date getDeleted() { 087 return cloneDate(myDeleted); 088 } 089 090 @Override 091 public FhirVersionEnum getFhirVersion() { 092 return myFhirVersion; 093 } 094 095 public void setFhirVersion(FhirVersionEnum theFhirVersion) { 096 myFhirVersion = theFhirVersion; 097 } 098 099 abstract public ForcedId getForcedId(); 100 101 abstract public void setForcedId(ForcedId theForcedId); 102 103 @Override 104 public abstract Long getId(); 105 106 107 108 public void setDeleted(Date theDate) { 109 myDeleted = theDate; 110 } 111 112 @Override 113 public InstantDt getPublished() { 114 if (myPublished != null) { 115 return new InstantDt(getPublishedDate()); 116 } else { 117 return null; 118 } 119 } 120 121 public Date getPublishedDate() { 122 return cloneDate(myPublished); 123 } 124 125 public void setPublished(Date thePublished) { 126 myPublished = thePublished; 127 } 128 129 public void setPublished(InstantDt thePublished) { 130 myPublished = thePublished.getValue(); 131 } 132 133 @Override 134 public abstract Long getResourceId(); 135 136 @Override 137 public abstract String getResourceType(); 138 139 public abstract Collection<? extends BaseTag> getTags(); 140 141 @Override 142 public InstantDt getUpdated() { 143 return new InstantDt(getUpdatedDate()); 144 } 145 146 @Override 147 public Date getUpdatedDate() { 148 return cloneDate(myUpdated); 149 } 150 151 public void setUpdated(Date theUpdated) { 152 myUpdated = theUpdated; 153 } 154 155 public void setUpdated(InstantDt theUpdated) { 156 myUpdated = theUpdated.getValue(); 157 } 158 159 @Override 160 public abstract long getVersion(); 161 162 @Override 163 public boolean isHasTags() { 164 return myHasTags; 165 } 166 167 public void setHasTags(boolean theHasTags) { 168 myHasTags = theHasTags; 169 } 170 171 static Date cloneDate(Date theDate) { 172 Date retVal = theDate; 173 if (retVal != null) { 174 retVal = new Date(retVal.getTime()); 175 } 176 return retVal; 177 } 178 179}