com.ibm.fhir.model.type.Timing Maven / Gradle / Ivy
/*
* (C) Copyright IBM Corp. 2019, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.ibm.fhir.model.type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.annotation.Generated;
import com.ibm.fhir.model.annotation.Binding;
import com.ibm.fhir.model.annotation.Choice;
import com.ibm.fhir.model.annotation.Constraint;
import com.ibm.fhir.model.annotation.Summary;
import com.ibm.fhir.model.type.code.BindingStrength;
import com.ibm.fhir.model.type.code.DayOfWeek;
import com.ibm.fhir.model.type.code.EventTiming;
import com.ibm.fhir.model.type.code.UnitsOfTime;
import com.ibm.fhir.model.util.ValidationSupport;
import com.ibm.fhir.model.visitor.Visitor;
/**
* Specifies an event that may occur multiple times. Timing schedules are used to record when things are planned,
* expected or requested to occur. The most common usage is in dosage instructions for medications. They are also used
* when planning care of various kinds, and may be used for reporting the schedule to which past regular activities were
* carried out.
*/
@Constraint(
id = "tim-1",
level = "Rule",
location = "Timing.repeat",
description = "if there's a duration, there needs to be duration units",
expression = "duration.empty() or durationUnit.exists()"
)
@Constraint(
id = "tim-2",
level = "Rule",
location = "Timing.repeat",
description = "if there's a period, there needs to be period units",
expression = "period.empty() or periodUnit.exists()"
)
@Constraint(
id = "tim-4",
level = "Rule",
location = "Timing.repeat",
description = "duration SHALL be a non-negative value",
expression = "duration.exists() implies duration >= 0"
)
@Constraint(
id = "tim-5",
level = "Rule",
location = "Timing.repeat",
description = "period SHALL be a non-negative value",
expression = "period.exists() implies period >= 0"
)
@Constraint(
id = "tim-6",
level = "Rule",
location = "Timing.repeat",
description = "If there's a periodMax, there must be a period",
expression = "periodMax.empty() or period.exists()"
)
@Constraint(
id = "tim-7",
level = "Rule",
location = "Timing.repeat",
description = "If there's a durationMax, there must be a duration",
expression = "durationMax.empty() or duration.exists()"
)
@Constraint(
id = "tim-8",
level = "Rule",
location = "Timing.repeat",
description = "If there's a countMax, there must be a count",
expression = "countMax.empty() or count.exists()"
)
@Constraint(
id = "tim-9",
level = "Rule",
location = "Timing.repeat",
description = "If there's an offset, there must be a when (and not C, CM, CD, CV)",
expression = "offset.empty() or (when.exists() and ((when in ('C' | 'CM' | 'CD' | 'CV')).not()))"
)
@Constraint(
id = "tim-10",
level = "Rule",
location = "Timing.repeat",
description = "If there's a timeOfDay, there cannot be a when, or vice versa",
expression = "timeOfDay.empty() or when.empty()"
)
@Constraint(
id = "timing-11",
level = "Warning",
location = "(base)",
description = "SHOULD contain a code from value set http://hl7.org/fhir/ValueSet/timing-abbreviation",
expression = "code.exists() implies (code.memberOf('http://hl7.org/fhir/ValueSet/timing-abbreviation', 'preferred'))",
generated = true
)
@Generated("com.ibm.fhir.tools.CodeGenerator")
public class Timing extends BackboneElement {
@Summary
private final List event;
@Summary
private final Repeat repeat;
@Summary
@Binding(
bindingName = "TimingAbbreviation",
strength = BindingStrength.Value.PREFERRED,
description = "Code for a known / defined timing pattern.",
valueSet = "http://hl7.org/fhir/ValueSet/timing-abbreviation"
)
private final CodeableConcept code;
private Timing(Builder builder) {
super(builder);
event = Collections.unmodifiableList(builder.event);
repeat = builder.repeat;
code = builder.code;
}
/**
* Identifies specific times when the event occurs.
*
* @return
* An unmodifiable list containing immutable objects of type {@link DateTime} that may be empty.
*/
public List getEvent() {
return event;
}
/**
* A set of rules that describe when the event is scheduled.
*
* @return
* An immutable object of type {@link Repeat} that may be null.
*/
public Repeat getRepeat() {
return repeat;
}
/**
* A code for the timing schedule (or just text in code.text). Some codes such as BID are ubiquitous, but many
* institutions define their own additional codes. If a code is provided, the code is understood to be a complete
* statement of whatever is specified in the structured timing data, and either the code or the data may be used to
* interpret the Timing, with the exception that .repeat.bounds still applies over the code (and is not contained in the
* code).
*
* @return
* An immutable object of type {@link CodeableConcept} that may be null.
*/
public CodeableConcept getCode() {
return code;
}
@Override
public boolean hasChildren() {
return super.hasChildren() ||
!event.isEmpty() ||
(repeat != null) ||
(code != null);
}
@Override
public void accept(java.lang.String elementName, int elementIndex, Visitor visitor) {
if (visitor.preVisit(this)) {
visitor.visitStart(elementName, elementIndex, this);
if (visitor.visit(elementName, elementIndex, this)) {
// visit children
accept(id, "id", visitor);
accept(extension, "extension", visitor, Extension.class);
accept(modifierExtension, "modifierExtension", visitor, Extension.class);
accept(event, "event", visitor, DateTime.class);
accept(repeat, "repeat", visitor);
accept(code, "code", visitor);
}
visitor.visitEnd(elementName, elementIndex, this);
visitor.postVisit(this);
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Timing other = (Timing) obj;
return Objects.equals(id, other.id) &&
Objects.equals(extension, other.extension) &&
Objects.equals(modifierExtension, other.modifierExtension) &&
Objects.equals(event, other.event) &&
Objects.equals(repeat, other.repeat) &&
Objects.equals(code, other.code);
}
@Override
public int hashCode() {
int result = hashCode;
if (result == 0) {
result = Objects.hash(id,
extension,
modifierExtension,
event,
repeat,
code);
hashCode = result;
}
return result;
}
@Override
public Builder toBuilder() {
return new Builder().from(this);
}
public static Builder builder() {
return new Builder();
}
public static class Builder extends BackboneElement.Builder {
private List event = new ArrayList<>();
private Repeat repeat;
private CodeableConcept code;
private Builder() {
super();
}
/**
* Unique id for the element within a resource (for internal references). This may be any string value that does not
* contain spaces.
*
* @param id
* Unique id for inter-element referencing
*
* @return
* A reference to this Builder instance
*/
@Override
public Builder id(java.lang.String id) {
return (Builder) super.id(id);
}
/**
* May be used to represent additional information that is not part of the basic definition of the element. To make the
* use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of
* extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part
* of the definition of the extension.
*
* Adds new element(s) to the existing list
*
* @param extension
* Additional content defined by implementations
*
* @return
* A reference to this Builder instance
*/
@Override
public Builder extension(Extension... extension) {
return (Builder) super.extension(extension);
}
/**
* May be used to represent additional information that is not part of the basic definition of the element. To make the
* use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of
* extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part
* of the definition of the extension.
*
*
Replaces the existing list with a new one containing elements from the Collection
*
* @param extension
* Additional content defined by implementations
*
* @return
* A reference to this Builder instance
*/
@Override
public Builder extension(Collection extension) {
return (Builder) super.extension(extension);
}
/**
* May be used to represent additional information that is not part of the basic definition of the element and that
* modifies the understanding of the element in which it is contained and/or the understanding of the containing
* element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe
* and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any
* implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the
* extension. Applications processing a resource are required to check for modifier extensions.
*
* Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot
* change the meaning of modifierExtension itself).
*
*
Adds new element(s) to the existing list
*
* @param modifierExtension
* Extensions that cannot be ignored even if unrecognized
*
* @return
* A reference to this Builder instance
*/
@Override
public Builder modifierExtension(Extension... modifierExtension) {
return (Builder) super.modifierExtension(modifierExtension);
}
/**
* May be used to represent additional information that is not part of the basic definition of the element and that
* modifies the understanding of the element in which it is contained and/or the understanding of the containing
* element's descendants. Usually modifier elements provide negation or qualification. To make the use of extensions safe
* and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any
* implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the
* extension. Applications processing a resource are required to check for modifier extensions.
*
*
Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot
* change the meaning of modifierExtension itself).
*
*
Replaces the existing list with a new one containing elements from the Collection
*
* @param modifierExtension
* Extensions that cannot be ignored even if unrecognized
*
* @return
* A reference to this Builder instance
*/
@Override
public Builder modifierExtension(Collection modifierExtension) {
return (Builder) super.modifierExtension(modifierExtension);
}
/**
* Identifies specific times when the event occurs.
*
* Adds new element(s) to the existing list
*
* @param event
* When the event occurs
*
* @return
* A reference to this Builder instance
*/
public Builder event(DateTime... event) {
for (DateTime value : event) {
this.event.add(value);
}
return this;
}
/**
* Identifies specific times when the event occurs.
*
*
Replaces the existing list with a new one containing elements from the Collection
*
* @param event
* When the event occurs
*
* @return
* A reference to this Builder instance
*/
public Builder event(Collection event) {
this.event = new ArrayList<>(event);
return this;
}
/**
* A set of rules that describe when the event is scheduled.
*
* @param repeat
* When the event is to occur
*
* @return
* A reference to this Builder instance
*/
public Builder repeat(Repeat repeat) {
this.repeat = repeat;
return this;
}
/**
* A code for the timing schedule (or just text in code.text). Some codes such as BID are ubiquitous, but many
* institutions define their own additional codes. If a code is provided, the code is understood to be a complete
* statement of whatever is specified in the structured timing data, and either the code or the data may be used to
* interpret the Timing, with the exception that .repeat.bounds still applies over the code (and is not contained in the
* code).
*
* @param code
* BID | TID | QID | AM | PM | QD | QOD | +
*
* @return
* A reference to this Builder instance
*/
public Builder code(CodeableConcept code) {
this.code = code;
return this;
}
/**
* Build the {@link Timing}
*
* @return
* An immutable object of type {@link Timing}
* @throws IllegalStateException
* if the current state cannot be built into a valid Timing per the base specification
*/
@Override
public Timing build() {
Timing timing = new Timing(this);
if (validating) {
validate(timing);
}
return timing;
}
protected void validate(Timing timing) {
super.validate(timing);
ValidationSupport.checkList(timing.event, "event", DateTime.class);
ValidationSupport.requireValueOrChildren(timing);
}
protected Builder from(Timing timing) {
super.from(timing);
event.addAll(timing.event);
repeat = timing.repeat;
code = timing.code;
return this;
}
}
/**
* A set of rules that describe when the event is scheduled.
*/
public static class Repeat extends BackboneElement {
@Summary
@Choice({ Duration.class, Range.class, Period.class })
private final Element bounds;
@Summary
private final PositiveInt count;
@Summary
private final PositiveInt countMax;
@Summary
private final Decimal duration;
@Summary
private final Decimal durationMax;
@Summary
@Binding(
bindingName = "UnitsOfTime",
strength = BindingStrength.Value.REQUIRED,
description = "A unit of time (units from UCUM).",
valueSet = "http://hl7.org/fhir/ValueSet/units-of-time|4.0.1"
)
private final UnitsOfTime durationUnit;
@Summary
private final PositiveInt frequency;
@Summary
private final PositiveInt frequencyMax;
@Summary
private final Decimal period;
@Summary
private final Decimal periodMax;
@Summary
@Binding(
bindingName = "UnitsOfTime",
strength = BindingStrength.Value.REQUIRED,
description = "A unit of time (units from UCUM).",
valueSet = "http://hl7.org/fhir/ValueSet/units-of-time|4.0.1"
)
private final UnitsOfTime periodUnit;
@Summary
@Binding(
bindingName = "DayOfWeek",
strength = BindingStrength.Value.REQUIRED,
valueSet = "http://hl7.org/fhir/ValueSet/days-of-week|4.0.1"
)
private final List dayOfWeek;
@Summary
private final List