001/*-
002 * #%L
003 * HAPI FHIR JPA Server - International Patient Summary (IPS)
004 * %%
005 * Copyright (C) 2014 - 2024 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.StringUtils;
024import org.apache.commons.lang3.Validate;
025import org.hl7.fhir.instance.model.api.IBaseResource;
026
027import java.util.ArrayList;
028import java.util.List;
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) {
093                        Section o = (Section) theO;
094                        return StringUtils.equals(myProfile, o.myProfile);
095                }
096                return false;
097        }
098
099        @Override
100        public int hashCode() {
101                return myProfile.hashCode();
102        }
103
104        /**
105         * Create a new empty section builder
106         */
107        public static SectionBuilder newBuilder() {
108                return new SectionBuilder();
109        }
110
111        /**
112         * Create a new section builder which is a clone of an existing section
113         */
114        public static SectionBuilder newBuilder(Section theSection) {
115                return new SectionBuilder(
116                                theSection.myTitle,
117                                theSection.mySectionSystem,
118                                theSection.mySectionCode,
119                                theSection.mySectionDisplay,
120                                theSection.myProfile,
121                                theSection.myNoInfoGenerator,
122                                theSection.myResourceTypes);
123        }
124
125        public static class SectionBuilder {
126
127                private String myTitle;
128                private String mySectionSystem;
129                private String mySectionCode;
130                private String mySectionDisplay;
131                private List<Class<? extends IBaseResource>> myResourceTypes = new ArrayList<>();
132                private String myProfile;
133                private INoInfoGenerator myNoInfoGenerator;
134
135                private SectionBuilder() {
136                        super();
137                }
138
139                public SectionBuilder(
140                                String theTitle,
141                                String theSectionSystem,
142                                String theSectionCode,
143                                String theSectionDisplay,
144                                String theProfile,
145                                INoInfoGenerator theNoInfoGenerator,
146                                List<Class<? extends IBaseResource>> theResourceTypes) {
147                        myTitle = theTitle;
148                        mySectionSystem = theSectionSystem;
149                        mySectionCode = theSectionCode;
150                        mySectionDisplay = theSectionDisplay;
151                        myNoInfoGenerator = theNoInfoGenerator;
152                        myProfile = theProfile;
153                        myResourceTypes = new ArrayList<>(theResourceTypes);
154                }
155
156                public SectionBuilder withTitle(String theTitle) {
157                        Validate.notBlank(theTitle);
158                        myTitle = theTitle;
159                        return this;
160                }
161
162                public SectionBuilder withSectionSystem(String theSectionSystem) {
163                        Validate.notBlank(theSectionSystem);
164                        mySectionSystem = theSectionSystem;
165                        return this;
166                }
167
168                public SectionBuilder withSectionCode(String theSectionCode) {
169                        Validate.notBlank(theSectionCode);
170                        mySectionCode = theSectionCode;
171                        return this;
172                }
173
174                public SectionBuilder withSectionDisplay(String theSectionDisplay) {
175                        Validate.notBlank(theSectionDisplay);
176                        mySectionDisplay = theSectionDisplay;
177                        return this;
178                }
179
180                /**
181                 * This method may be called multiple times if the section will contain multiple resource types
182                 */
183                public SectionBuilder withResourceType(Class<? extends IBaseResource> theResourceType) {
184                        Validate.notNull(theResourceType, "theResourceType must not be null");
185                        Validate.isTrue(!myResourceTypes.contains(theResourceType), "theResourceType has already been added");
186                        myResourceTypes.add(theResourceType);
187                        return this;
188                }
189
190                public SectionBuilder withProfile(String theProfile) {
191                        Validate.notBlank(theProfile);
192                        myProfile = theProfile;
193                        return this;
194                }
195
196                /**
197                 * Supplies a {@link INoInfoGenerator} which is used to create a stub resource
198                 * to place in this section if no actual contents are found. This can be
199                 * {@literal null} if you do not want any such stub to be included for this
200                 * section.
201                 */
202                @SuppressWarnings("UnusedReturnValue")
203                public SectionBuilder withNoInfoGenerator(@Nullable INoInfoGenerator theNoInfoGenerator) {
204                        myNoInfoGenerator = theNoInfoGenerator;
205                        return this;
206                }
207
208                public Section build() {
209                        Validate.notBlank(mySectionSystem, "No section system has been defined for this section");
210                        Validate.notBlank(mySectionCode, "No section code has been defined for this section");
211                        Validate.notBlank(mySectionDisplay, "No section display has been defined for this section");
212
213                        return new Section(
214                                        myTitle,
215                                        mySectionSystem,
216                                        mySectionCode,
217                                        mySectionDisplay,
218                                        myResourceTypes,
219                                        myProfile,
220                                        myNoInfoGenerator);
221                }
222        }
223}