001/*-
002 * #%L
003 * HAPI FHIR JPA Server - International Patient Summary (IPS)
004 * %%
005 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.ips.api;
021
022import jakarta.annotation.Nullable;
023import org.apache.commons.lang3.Validate;
024import org.hl7.fhir.instance.model.api.IBaseResource;
025
026import java.util.ArrayList;
027import java.util.List;
028import java.util.Objects;
029
030/**
031 * Call {@link #newBuilder()} to create a new instance of this class.
032 */
033public class Section {
034
035        private final String myTitle;
036        private final String mySectionCode;
037        private final String mySectionDisplay;
038        private final List<Class<? extends IBaseResource>> myResourceTypes;
039        private final String myProfile;
040        private final INoInfoGenerator myNoInfoGenerator;
041
042        private final String mySectionSystem;
043
044        private Section(
045                        String theTitle,
046                        String theSectionSystem,
047                        String theSectionCode,
048                        String theSectionDisplay,
049                        List<Class<? extends IBaseResource>> theResourceTypes,
050                        String theProfile,
051                        INoInfoGenerator theNoInfoGenerator) {
052                myTitle = theTitle;
053                mySectionSystem = theSectionSystem;
054                mySectionCode = theSectionCode;
055                mySectionDisplay = theSectionDisplay;
056                myResourceTypes = List.copyOf(theResourceTypes);
057                myProfile = theProfile;
058                myNoInfoGenerator = theNoInfoGenerator;
059        }
060
061        @Nullable
062        public INoInfoGenerator getNoInfoGenerator() {
063                return myNoInfoGenerator;
064        }
065
066        public List<Class<? extends IBaseResource>> getResourceTypes() {
067                return myResourceTypes;
068        }
069
070        public String getProfile() {
071                return myProfile;
072        }
073
074        public String getTitle() {
075                return myTitle;
076        }
077
078        public String getSectionSystem() {
079                return mySectionSystem;
080        }
081
082        public String getSectionCode() {
083                return mySectionCode;
084        }
085
086        public String getSectionDisplay() {
087                return mySectionDisplay;
088        }
089
090        @Override
091        public boolean equals(Object theO) {
092                if (theO instanceof Section o) {
093                        return Objects.equals(myProfile, o.myProfile);
094                }
095                return false;
096        }
097
098        @Override
099        public int hashCode() {
100                return myProfile.hashCode();
101        }
102
103        /**
104         * Create a new empty section builder
105         */
106        public static SectionBuilder newBuilder() {
107                return new SectionBuilder();
108        }
109
110        /**
111         * Create a new section builder which is a clone of an existing section
112         */
113        public static SectionBuilder newBuilder(Section theSection) {
114                return new SectionBuilder(
115                                theSection.myTitle,
116                                theSection.mySectionSystem,
117                                theSection.mySectionCode,
118                                theSection.mySectionDisplay,
119                                theSection.myProfile,
120                                theSection.myNoInfoGenerator,
121                                theSection.myResourceTypes);
122        }
123
124        public static class SectionBuilder {
125
126                private String myTitle;
127                private String mySectionSystem;
128                private String mySectionCode;
129                private String mySectionDisplay;
130                private List<Class<? extends IBaseResource>> myResourceTypes = new ArrayList<>();
131                private String myProfile;
132                private INoInfoGenerator myNoInfoGenerator;
133
134                private SectionBuilder() {
135                        super();
136                }
137
138                public SectionBuilder(
139                                String theTitle,
140                                String theSectionSystem,
141                                String theSectionCode,
142                                String theSectionDisplay,
143                                String theProfile,
144                                INoInfoGenerator theNoInfoGenerator,
145                                List<Class<? extends IBaseResource>> theResourceTypes) {
146                        myTitle = theTitle;
147                        mySectionSystem = theSectionSystem;
148                        mySectionCode = theSectionCode;
149                        mySectionDisplay = theSectionDisplay;
150                        myNoInfoGenerator = theNoInfoGenerator;
151                        myProfile = theProfile;
152                        myResourceTypes = new ArrayList<>(theResourceTypes);
153                }
154
155                public SectionBuilder withTitle(String theTitle) {
156                        Validate.notBlank(theTitle);
157                        myTitle = theTitle;
158                        return this;
159                }
160
161                public SectionBuilder withSectionSystem(String theSectionSystem) {
162                        Validate.notBlank(theSectionSystem);
163                        mySectionSystem = theSectionSystem;
164                        return this;
165                }
166
167                public SectionBuilder withSectionCode(String theSectionCode) {
168                        Validate.notBlank(theSectionCode);
169                        mySectionCode = theSectionCode;
170                        return this;
171                }
172
173                public SectionBuilder withSectionDisplay(String theSectionDisplay) {
174                        Validate.notBlank(theSectionDisplay);
175                        mySectionDisplay = theSectionDisplay;
176                        return this;
177                }
178
179                /**
180                 * This method may be called multiple times if the section will contain multiple resource types
181                 */
182                public SectionBuilder withResourceType(Class<? extends IBaseResource> theResourceType) {
183                        Validate.notNull(theResourceType, "theResourceType must not be null");
184                        Validate.isTrue(!myResourceTypes.contains(theResourceType), "theResourceType has already been added");
185                        myResourceTypes.add(theResourceType);
186                        return this;
187                }
188
189                public SectionBuilder withProfile(String theProfile) {
190                        Validate.notBlank(theProfile);
191                        myProfile = theProfile;
192                        return this;
193                }
194
195                /**
196                 * Supplies a {@link INoInfoGenerator} which is used to create a stub resource
197                 * to place in this section if no actual contents are found. This can be
198                 * {@literal null} if you do not want any such stub to be included for this
199                 * section.
200                 */
201                @SuppressWarnings("UnusedReturnValue")
202                public SectionBuilder withNoInfoGenerator(@Nullable INoInfoGenerator theNoInfoGenerator) {
203                        myNoInfoGenerator = theNoInfoGenerator;
204                        return this;
205                }
206
207                public Section build() {
208                        Validate.notBlank(mySectionSystem, "No section system has been defined for this section");
209                        Validate.notBlank(mySectionCode, "No section code has been defined for this section");
210                        Validate.notBlank(mySectionDisplay, "No section display has been defined for this section");
211
212                        return new Section(
213                                        myTitle,
214                                        mySectionSystem,
215                                        mySectionCode,
216                                        mySectionDisplay,
217                                        myResourceTypes,
218                                        myProfile,
219                                        myNoInfoGenerator);
220                }
221        }
222}