001package org.hl7.fhir.r5.utils; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.List; 006 007import org.hl7.fhir.r5.model.CanonicalResource; 008import org.hl7.fhir.r5.model.CapabilityStatement; 009import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent; 010import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent; 011import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent; 012import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent; 013import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent; 014import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent; 015import org.hl7.fhir.r5.model.CodeSystem; 016import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent; 017import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 018import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent; 019import org.hl7.fhir.r5.model.ConceptMap; 020import org.hl7.fhir.r5.model.ConceptMap.AdditionalAttributeComponent; 021import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent; 022import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent; 023import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent; 024import org.hl7.fhir.r5.model.DomainResource; 025import org.hl7.fhir.r5.model.ElementDefinition; 026import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditionalComponent; 027import org.hl7.fhir.r5.model.NamingSystem; 028import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent; 029import org.hl7.fhir.r5.model.OperationDefinition; 030import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionOverloadComponent; 031import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent; 032import org.hl7.fhir.r5.model.Questionnaire; 033import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; 034import org.hl7.fhir.r5.model.Resource; 035import org.hl7.fhir.r5.model.SearchParameter; 036import org.hl7.fhir.r5.model.StructureDefinition; 037import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; 038import org.hl7.fhir.r5.model.ValueSet; 039import org.hl7.fhir.utilities.Utilities; 040 041public class ResourceMinifier { 042 043 private static final List<String> VALIDATION_EXTENSIONS = 044 Arrays.asList(ToolingExtensions.EXT_OBLIGATION_INHERITS, ToolingExtensions.EXT_OBLIGATION_PROFILE_FLAG); 045 046 public boolean isMinified(String resName) { 047 return Utilities.existsInList(resName, "StructureDefinition", "CodeSystem", "ValueSet", "CapabilityStatement", 048 "ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "Questionnaire"); 049 } 050 051 public boolean minify(Resource res) { 052 if (res instanceof StructureDefinition) { 053 return minifySD((StructureDefinition) res); 054 } else if (res instanceof ValueSet) { 055 minifyVS((ValueSet) res); 056 } else if (res instanceof CodeSystem) { 057 minifyCS((CodeSystem) res); 058 } else if (res instanceof CapabilityStatement) { 059 minifyCS((CapabilityStatement) res); 060 } else if (res instanceof ConceptMap) { 061 minifyCM((ConceptMap) res); 062 } else if (res instanceof NamingSystem) { 063 minifyNS((NamingSystem) res); 064 } else if (res instanceof OperationDefinition) { 065 minifyOD((OperationDefinition) res); 066 } else if (res instanceof Questionnaire) { 067 minifyQ((Questionnaire) res); 068 } else if (res instanceof SearchParameter) { 069 minifySP((SearchParameter) res); 070 } 071 return true; 072 } 073 074 private void minifySP(SearchParameter sp) { 075 minCR(sp); 076 // nothing 077 } 078 079 private void minifyQ(Questionnaire q) { 080 minCR(q); 081 082 q.setApprovalDate(null); 083 q.setLastReviewDate(null); 084 q.setEffectivePeriod(null); 085 q.setCode(null); 086 for (QuestionnaireItemComponent item : q.getItem()) { 087 minifyQItem(item); 088 089 } 090 } 091 092 private void minifyQItem(QuestionnaireItemComponent item) { 093 item.setCode(null); 094 item.setPrefix(null); 095 item.setText(null); 096 for (QuestionnaireItemComponent child : item.getItem()) { 097 minifyQItem(child); 098 } 099 } 100 101 private void minifyOD(OperationDefinition od) { 102 minCR(od); 103 od.setComment(null); 104 for (OperationDefinitionParameterComponent p : od.getParameter()) { 105 minifyODP(p); 106 } 107 for (OperationDefinitionOverloadComponent ol : od.getOverload()) { 108 ol.setComment(null); 109 } 110 } 111 112 private void minifyODP(OperationDefinitionParameterComponent p) { 113 p.setDocumentation(null); 114 for (OperationDefinitionParameterComponent pp : p.getPart()) { 115 minifyODP(pp); 116 } 117 } 118 119 private void minifyNS(NamingSystem ns) { 120 minCR(ns); 121 122 ns.setApprovalDate(null); 123 ns.setLastReviewDate(null); 124 ns.setEffectivePeriod(null); 125 ns.setTopic(null); 126 ns.setAuthor(null); 127 ns.setEditor(null); 128 ns.setReviewer(null); 129 ns.setEndorser(null); 130 ns.setRelatedArtifact(null); 131 132 ns.setUsage(null); 133 for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) { 134 id.setComment(null); 135 } 136 } 137 138 private void minifyCM(ConceptMap cm) { 139 minCR(cm); 140 141 cm.setApprovalDate(null); 142 cm.setLastReviewDate(null); 143 cm.setEffectivePeriod(null); 144 cm.setTopic(null); 145 cm.setAuthor(null); 146 cm.setEditor(null); 147 cm.setReviewer(null); 148 cm.setEndorser(null); 149 cm.setRelatedArtifact(null); 150 151 for (org.hl7.fhir.r5.model.ConceptMap.PropertyComponent prop : cm.getProperty()) { 152 prop.setDescription(null); 153 } 154 for (AdditionalAttributeComponent attr : cm.getAdditionalAttribute()) { 155 attr.setDescription(null); 156 } 157 for (ConceptMapGroupComponent group : cm.getGroup()) { 158 for (SourceElementComponent elem : group.getElement()) { 159 for (TargetElementComponent tgt : elem.getTarget()) { 160 tgt.setComment(null); 161 } 162 } 163 } 164 } 165 166 private void minifyCS(CapabilityStatement cs) { 167 minCR(cs); 168 169 cs.setSoftware(null); 170 cs.setImplementation(null); 171 for (CapabilityStatementRestComponent rest : cs.getRest()) { 172 rest.setDocumentation(null); 173 rest.setSecurity(null); 174 for (CapabilityStatementRestResourceComponent res : rest.getResource()) { 175 res.setDocumentation(null); 176 for (ResourceInteractionComponent intr : res.getInteraction()) { 177 intr.setDocumentation(null); 178 } 179 for (CapabilityStatementRestResourceSearchParamComponent srch : res.getSearchParam()) { 180 srch.setDocumentation(null); 181 } 182 for (CapabilityStatementRestResourceOperationComponent op : res.getOperation()) { 183 op.setDocumentation(null); 184 } 185 } 186 for (SystemInteractionComponent intr : rest.getInteraction()) { 187 intr.setDocumentation(null); 188 } 189 for (CapabilityStatementRestResourceSearchParamComponent srch : rest.getSearchParam()) { 190 srch.setDocumentation(null); 191 } 192 for (CapabilityStatementRestResourceOperationComponent op : rest.getOperation()) { 193 op.setDocumentation(null); 194 } 195 } 196 cs.setMessaging(null); 197 cs.setDocument(null); 198 } 199 200 private void minifyCS(CodeSystem cs) { 201 minCR(cs); 202 203 cs.setApprovalDate(null); 204 cs.setLastReviewDate(null); 205 cs.setEffectivePeriod(null); 206 cs.setTopic(null); 207 cs.setAuthor(null); 208 cs.setEditor(null); 209 cs.setReviewer(null); 210 cs.setEndorser(null); 211 cs.setRelatedArtifact(null); 212 213 for (CodeSystemFilterComponent filter : cs.getFilter()) { 214 filter.setDescription(null); 215 } 216 for (PropertyComponent prop : cs.getProperty()) { 217 prop.setDescription(null); 218 } 219 for (ConceptDefinitionComponent cc : cs.getConcept()) { 220 minify(cc); 221 } 222 } 223 224 private void minify(ConceptDefinitionComponent cc) { 225 cc.setDefinition(null); 226 for (ConceptDefinitionComponent ccc : cc.getConcept()) { 227 minify(ccc); 228 } 229 } 230 231 private void minifyVS(ValueSet vs) { 232 minCR(vs); 233 234 vs.setApprovalDate(null); 235 vs.setLastReviewDate(null); 236 vs.setEffectivePeriod(null); 237 vs.setTopic(null); 238 vs.setAuthor(null); 239 vs.setEditor(null); 240 vs.setReviewer(null); 241 vs.setEndorser(null); 242 vs.setRelatedArtifact(null); 243 // can't remove anything else 244 } 245 246 private boolean minifySD(StructureDefinition sd) { 247 if (sd.getKind() == StructureDefinitionKind.LOGICAL) { 248 return false; 249 } 250 minCR(sd); 251 sd.setKeyword(null); 252 sd.setMapping(null); 253 if (sd.hasDifferential()) { 254 sd.setSnapshot(null); 255 } 256 for (ElementDefinition ed : sd.getDifferential().getElement()) { 257 minifyED(ed); 258 } 259 return true; 260 } 261 262 private void minifyED(ElementDefinition ed) { 263 ed.setLabel(null); 264 ed.setCode(null); 265 ed.getSlicing().setDescription(null); 266 ed.setShort(null); 267 ed.setDefinition(null); 268 ed.setComment(null); 269 ed.setRequirements(null); 270 ed.setAlias(null); 271 ed.setDefaultValue(null); 272 ed.setOrderMeaning(null); 273 ed.setMeaningWhenMissing(null); 274 ed.setExample(null); 275 ed.setIsModifierReason(null); 276 ed.getBinding().setDescription(null); 277 for (ElementDefinitionBindingAdditionalComponent abn : ed.getBinding().getAdditional()) { 278 abn.setDocumentation(null); 279 abn.setShortDoco(null); 280 } 281 ed.setMapping(null); 282 ed.setMustSupportElement(null); 283 } 284 285 private void minCR(CanonicalResource cr) { 286 minDR(cr); 287 cr.setIdentifier(null); 288 cr.setPublisher(null); 289 cr.setContact(null); 290 cr.setDescription(null); 291 cr.setPurpose(null); 292 cr.setCopyright(null); 293 cr.setCopyrightLabel(null); 294 } 295 296 private void minDR(DomainResource dr) { 297 minRes(dr); 298 dr.setText(null); 299 List<Resource> del = new ArrayList<>(); 300 for (Resource res : dr.getContained()) { 301 if (isMinified(res.fhirType())) { 302 minify(res); 303 } else { 304 del.add(res); 305 } 306 } 307 dr.getContained().removeAll(del); 308 dr.getExtension().removeIf(ext -> !Utilities.existsInList(ext.getUrl(), VALIDATION_EXTENSIONS)); 309 } 310 311 private void minRes(Resource res) { 312 res.setMeta(null); 313 res.setImplicitRules(null); 314 } 315 316}