All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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

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.\n\nModifier 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.\n\nModifier 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); } /** * Either a duration for the length of the timing schedule, a range of possible length, or outer bounds for start and/or * end limits of the timing schedule. * *

This is a choice element with the following allowed types: *

    *
  • {@link Duration}
  • *
  • {@link Range}
  • *
  • {@link Period}
  • *
* * @param bounds * Length/Range of lengths, or (Start and/or end) limits * * @return * A reference to this Builder instance */ public Builder bounds(Element bounds) { this.bounds = bounds; return this; } /** * A total count of the desired number of repetitions across the duration of the entire timing specification. If countMax * is present, this element indicates the lower bound of the allowed range of count values. * * @param count * Number of times to repeat * * @return * A reference to this Builder instance */ public Builder count(PositiveInt count) { this.count = count; return this; } /** * If present, indicates that the count is a range - so to perform the action between [count] and [countMax] times. * * @param countMax * Maximum number of times to repeat * * @return * A reference to this Builder instance */ public Builder countMax(PositiveInt countMax) { this.countMax = countMax; return this; } /** * How long this thing happens for when it happens. If durationMax is present, this element indicates the lower bound of * the allowed range of the duration. * * @param duration * How long when it happens * * @return * A reference to this Builder instance */ public Builder duration(Decimal duration) { this.duration = duration; return this; } /** * If present, indicates that the duration is a range - so to perform the action between [duration] and [durationMax] * time length. * * @param durationMax * How long when it happens (Max) * * @return * A reference to this Builder instance */ public Builder durationMax(Decimal durationMax) { this.durationMax = durationMax; return this; } /** * The units of time for the duration, in UCUM units. * * @param durationUnit * s | min | h | d | wk | mo | a - unit of time (UCUM) * * @return * A reference to this Builder instance */ public Builder durationUnit(UnitsOfTime durationUnit) { this.durationUnit = durationUnit; return this; } /** * The number of times to repeat the action within the specified period. If frequencyMax is present, this element * indicates the lower bound of the allowed range of the frequency. * * @param frequency * Event occurs frequency times per period * * @return * A reference to this Builder instance */ public Builder frequency(PositiveInt frequency) { this.frequency = frequency; return this; } /** * If present, indicates that the frequency is a range - so to repeat between [frequency] and [frequencyMax] times within * the period or period range. * * @param frequencyMax * Event occurs up to frequencyMax times per period * * @return * A reference to this Builder instance */ public Builder frequencyMax(PositiveInt frequencyMax) { this.frequencyMax = frequencyMax; return this; } /** * Indicates the duration of time over which repetitions are to occur; e.g. to express "3 times per day", 3 would be the * frequency and "1 day" would be the period. If periodMax is present, this element indicates the lower bound of the * allowed range of the period length. * * @param period * Event occurs frequency times per period * * @return * A reference to this Builder instance */ public Builder period(Decimal period) { this.period = period; return this; } /** * If present, indicates that the period is a range from [period] to [periodMax], allowing expressing concepts such as * "do this once every 3-5 days. * * @param periodMax * Upper limit of period (3-4 hours) * * @return * A reference to this Builder instance */ public Builder periodMax(Decimal periodMax) { this.periodMax = periodMax; return this; } /** * The units of time for the period in UCUM units. * * @param periodUnit * s | min | h | d | wk | mo | a - unit of time (UCUM) * * @return * A reference to this Builder instance */ public Builder periodUnit(UnitsOfTime periodUnit) { this.periodUnit = periodUnit; return this; } /** * If one or more days of week is provided, then the action happens only on the specified day(s). * *

Adds new element(s) to the existing list * * @param dayOfWeek * mon | tue | wed | thu | fri | sat | sun * * @return * A reference to this Builder instance */ public Builder dayOfWeek(DayOfWeek... dayOfWeek) { for (DayOfWeek value : dayOfWeek) { this.dayOfWeek.add(value); } return this; } /** * If one or more days of week is provided, then the action happens only on the specified day(s). * *

Replaces the existing list with a new one containing elements from the Collection * * @param dayOfWeek * mon | tue | wed | thu | fri | sat | sun * * @return * A reference to this Builder instance */ public Builder dayOfWeek(Collection dayOfWeek) { this.dayOfWeek = new ArrayList<>(dayOfWeek); return this; } /** * Specified time of day for action to take place. * *

Adds new element(s) to the existing list * * @param timeOfDay * Time of day for action * * @return * A reference to this Builder instance */ public Builder timeOfDay(Time... timeOfDay) { for (Time value : timeOfDay) { this.timeOfDay.add(value); } return this; } /** * Specified time of day for action to take place. * *

Replaces the existing list with a new one containing elements from the Collection * * @param timeOfDay * Time of day for action * * @return * A reference to this Builder instance */ public Builder timeOfDay(Collection

Adds new element(s) to the existing list * * @param when * Code for time period of occurrence * * @return * A reference to this Builder instance */ public Builder when(EventTiming... when) { for (EventTiming value : when) { this.when.add(value); } return this; } /** * An approximate time period during the day, potentially linked to an event of daily living that indicates when the * action should occur. * *

Replaces the existing list with a new one containing elements from the Collection * * @param when * Code for time period of occurrence * * @return * A reference to this Builder instance */ public Builder when(Collection when) { this.when = new ArrayList<>(when); return this; } /** * The number of minutes from the event. If the event code does not indicate whether the minutes is before or after the * event, then the offset is assumed to be after the event. * * @param offset * Minutes from event (before or after) * * @return * A reference to this Builder instance */ public Builder offset(UnsignedInt offset) { this.offset = offset; return this; } /** * Build the {@link Repeat} * * @return * An immutable object of type {@link Repeat} * @throws IllegalStateException * if the current state cannot be built into a valid Repeat per the base specification */ @Override public Repeat build() { Repeat repeat = new Repeat(this); if (validating) { validate(repeat); } return repeat; } protected void validate(Repeat repeat) { super.validate(repeat); ValidationSupport.choiceElement(repeat.bounds, "bounds", Duration.class, Range.class, Period.class); ValidationSupport.checkList(repeat.dayOfWeek, "dayOfWeek", DayOfWeek.class); ValidationSupport.checkList(repeat.timeOfDay, "timeOfDay", Time.class); ValidationSupport.checkList(repeat.when, "when", EventTiming.class); ValidationSupport.requireValueOrChildren(repeat); } protected Builder from(Repeat repeat) { super.from(repeat); bounds = repeat.bounds; count = repeat.count; countMax = repeat.countMax; duration = repeat.duration; durationMax = repeat.durationMax; durationUnit = repeat.durationUnit; frequency = repeat.frequency; frequencyMax = repeat.frequencyMax; period = repeat.period; periodMax = repeat.periodMax; periodUnit = repeat.periodUnit; dayOfWeek.addAll(repeat.dayOfWeek); timeOfDay.addAll(repeat.timeOfDay); when.addAll(repeat.when); offset = repeat.offset; return this; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy