001package org.hl7.fhir.convertors.misc.searchparam;
002
003import java.io.FileInputStream;
004import java.io.FileOutputStream;
005import java.io.IOException;
006import java.util.ArrayList;
007import java.util.Collections;
008import java.util.Date;
009import java.util.List;
010
011/*
012  Copyright (c) 2011+, HL7, Inc.
013  All rights reserved.
014  
015  Redistribution and use in source and binary forms, with or without modification, 
016  are permitted provided that the following conditions are met:
017    
018   * Redistributions of source code must retain the above copyright notice, this 
019     list of conditions and the following disclaimer.
020   * Redistributions in binary form must reproduce the above copyright notice, 
021     this list of conditions and the following disclaimer in the documentation 
022     and/or other materials provided with the distribution.
023   * Neither the name of HL7 nor the names of its contributors may be used to 
024     endorse or promote products derived from this software without specific 
025     prior written permission.
026  
027  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
028  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
029  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
030  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
031  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
032  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
033  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
034  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
035  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
036  POSSIBILITY OF SUCH DAMAGE.
037  
038 */
039
040
041import org.hl7.fhir.exceptions.FHIRException;
042import org.hl7.fhir.exceptions.FHIRFormatError;
043import org.hl7.fhir.r5.formats.IParser.OutputStyle;
044import org.hl7.fhir.r5.formats.JsonParser;
045import org.hl7.fhir.r5.model.ConceptMap;
046import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
047import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
048import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
049import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
050import org.hl7.fhir.utilities.CSVReader;
051import org.hl7.fhir.utilities.Utilities;
052import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
053
054public class SearchParameterProcessor {
055
056  private static final String ROOT = "C:\\work\\org.hl7.fhir\\org.fhir.interversion\\package";
057  private final List<SPRelationship> list = new ArrayList<>();
058  private final List<String> list4 = new ArrayList<>();
059  private final List<String> list3 = new ArrayList<>();
060  private final List<String> list2 = new ArrayList<>();
061  private final List<String> list2b = new ArrayList<>();
062
063  //  private void generate(String name) throws IOException {
064//    StringBuilder b = new StringBuilder();
065//
066//    String rn = "";
067//    Collections.sort(list);
068//    for (String s : list) {
069//      String rnn = s.substring(0, s.indexOf("."));
070//      if (!rnn.equals(rn)) {
071//        rn = rnn;
072//        b.append(rn+"\r\n");
073//      }
074//      b.append(s+"\r\n");
075//    }
076//    TextFile.stringToFile(b.toString(), name);
077//  }
078//
079  public static void main(String[] args) throws IOException, FHIRException {
080    new SearchParameterProcessor().load();
081  }
082
083  private void load() throws IOException, FHIRException {
084    load4();
085    load3();
086    load2b();
087    load2();
088    loadCsv();
089
090    check4();
091    check3();
092    check2b();
093    check2();
094
095    generate("R3", "R4", "STU3", "R4");
096    generate("R4", "R3", "R4", "STU3");
097    generate("R2", "R4", "DSTU2", "R4");
098    generate("R4", "R2", "R4", "DSTU2");
099    generate("R2", "R3", "DSTU2", "STU3");
100    generate("R3", "R2", "STU3", "DSTU2");
101  }
102
103  private void generate(String src, String dst, String srcURL, String tgtURL) throws IOException {
104    ConceptMap map = new ConceptMap();
105    map.setId("search-parameters-" + src + "-to-" + dst);
106    map.setUrl("http://hl7.org/fhir/interversion/ConceptMap/" + map.getId());
107    map.setName("SearchParameterMap" + src + dst);
108    map.setTitle("Search Parameter Map - " + src + " to " + dst);
109    map.setStatus(PublicationStatus.DRAFT);
110    map.setDate(new Date());
111    map.setExperimental(false);
112    map.setPublisher("HL7");
113    ConceptMapGroupComponent group = map.addGroup();
114    group.setSource("http://hl7.org/fhir/" + srcURL);
115    group.setTarget("http://hl7.org/fhir/" + tgtURL);
116    for (SPRelationship sp : list) {
117      String s = sp.getByCode(src);
118      String d = sp.getByCode(dst);
119      if (!Utilities.noString(s) && !Utilities.noString(d)) {
120        SourceElementComponent e = makeElement(s, group);
121        e.addTarget().setCode(d).setRelationship(ConceptMapRelationship.RELATEDTO);
122      }
123    }
124    new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path(ROOT, "ConceptMap-" + map.getId() + ".json")), map);
125  }
126
127  private SourceElementComponent makeElement(String code, ConceptMapGroupComponent group) {
128    for (SourceElementComponent e : group.getElement()) {
129      if (e.getCode().equals(code))
130        return e;
131    }
132    return group.addElement().setCode(code);
133  }
134
135  private void check4() {
136    for (String s : list4) {
137      boolean ok = false;
138      for (SPRelationship t : list) {
139        if (s.equals(t.getR4()))
140          ok = true;
141      }
142      if (!ok)
143        System.out.println("R4 missing : " + s);
144    }
145    for (SPRelationship sp : list) {
146      if (!Utilities.noString(sp.getR4())) {
147        boolean ok = list4.contains(sp.getR4());
148        if (!ok)
149          System.out.println("R4 extra : " + sp.getR4());
150      }
151    }
152  }
153
154  private void check3() {
155    for (String s : list3) {
156      boolean ok = false;
157      for (SPRelationship t : list) {
158        if (s.equals(t.getR3()))
159          ok = true;
160      }
161      if (!ok)
162        System.out.println("R3 : " + s);
163    }
164    for (SPRelationship sp : list) {
165      if (!Utilities.noString(sp.getR3())) {
166        boolean ok = list3.contains(sp.getR3());
167        if (!ok)
168          System.out.println("R3 extra : " + sp.getR3());
169      }
170    }
171  }
172
173  private void check2b() {
174    for (String s : list2b) {
175      boolean ok = false;
176      for (SPRelationship t : list) {
177        if (s.equals(t.getR2b()))
178          ok = true;
179      }
180      if (!ok)
181        System.out.println("R2b : " + s);
182    }
183    for (SPRelationship sp : list) {
184      if (!Utilities.noString(sp.getR2b())) {
185        boolean ok = list2b.contains(sp.getR2b());
186        if (!ok)
187          System.out.println("R2b extra : " + sp.getR2b());
188      }
189    }
190  }
191
192  private void check2() {
193    for (String s : list2) {
194      boolean ok = false;
195      for (SPRelationship t : list) {
196        if (s.equals(t.getR2()))
197          ok = true;
198      }
199      if (!ok)
200        System.out.println("R2 : " + s);
201    }
202    for (SPRelationship sp : list) {
203      if (!Utilities.noString(sp.getR2())) {
204        boolean ok = list2.contains(sp.getR2());
205        if (!ok)
206          System.out.println("R2 extra : " + sp.getR2());
207      }
208    }
209  }
210
211  private void load4() throws FHIRFormatError, IOException {
212    org.hl7.fhir.r4.model.Bundle bundle = (org.hl7.fhir.r4.model.Bundle) new org.hl7.fhir.r4.formats.JsonParser().parse(ManagedFileAccess.inStream(Utilities.path("[tmp]", "sp4.json")));
213    for (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent be : bundle.getEntry()) {
214      org.hl7.fhir.r4.model.SearchParameter sp = (org.hl7.fhir.r4.model.SearchParameter) be.getResource();
215      for (org.hl7.fhir.r4.model.CodeType br : sp.getBase()) {
216        if (!Utilities.existsInList(br.asStringValue(), "DomainResource", "Resource"))
217          list4.add(br.asStringValue() + "." + sp.getCode());//+", "+sp.getType().toCode());
218      }
219    }
220    Collections.sort(list4);
221    System.out.println("R4 loaded - " + list4.size() + " parameters");
222  }
223
224  private void load3() throws FHIRFormatError, IOException {
225    org.hl7.fhir.dstu3.model.Bundle bundle = (org.hl7.fhir.dstu3.model.Bundle) new org.hl7.fhir.dstu3.formats.JsonParser().parse(ManagedFileAccess.inStream(Utilities.path("[tmp]", "sp3.json")));
226    for (org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent be : bundle.getEntry()) {
227      org.hl7.fhir.dstu3.model.SearchParameter sp = (org.hl7.fhir.dstu3.model.SearchParameter) be.getResource();
228      for (org.hl7.fhir.dstu3.model.CodeType br : sp.getBase()) {
229        if (!Utilities.existsInList(br.asStringValue(), "DomainResource", "Resource"))
230          list3.add(br.asStringValue() + "." + sp.getCode());//+", "+sp.getType().toCode());
231      }
232    }
233    Collections.sort(list3);
234    System.out.println("R3 loaded - " + list3.size() + " parameters");
235  }
236
237  private void load2() throws FHIRFormatError, IOException {
238    org.hl7.fhir.dstu2.model.Bundle bundle = (org.hl7.fhir.dstu2.model.Bundle) new org.hl7.fhir.dstu2.formats.JsonParser().parse(ManagedFileAccess.inStream(Utilities.path("[tmp]", "sp2.json")));
239    for (org.hl7.fhir.dstu2.model.Bundle.BundleEntryComponent be : bundle.getEntry()) {
240      org.hl7.fhir.dstu2.model.SearchParameter sp = (org.hl7.fhir.dstu2.model.SearchParameter) be.getResource();
241      String br = sp.getBase();
242      if (!Utilities.existsInList(br, "DomainResource", "Resource"))
243        list2.add(br + "." + sp.getCode());//+", "+sp.getType().toCode());
244    }
245    Collections.sort(list2);
246    System.out.println("R2 loaded - " + list2.size() + " parameters");
247  }
248
249  private void load2b() throws FHIRFormatError, IOException {
250    org.hl7.fhir.dstu2016may.model.Bundle bundle = (org.hl7.fhir.dstu2016may.model.Bundle) new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(ManagedFileAccess.inStream(Utilities.path("[tmp]", "sp2b.json")));
251    for (org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent be : bundle.getEntry()) {
252      org.hl7.fhir.dstu2016may.model.SearchParameter sp = (org.hl7.fhir.dstu2016may.model.SearchParameter) be.getResource();
253      String br = sp.getBase();
254      if (!Utilities.existsInList(br, "DomainResource", "Resource"))
255        list2b.add(br + "." + sp.getCode());//+", "+sp.getType().toCode());
256    }
257    Collections.sort(list2b);
258    System.out.println("R2b loaded - " + list2b.size() + " parameters");
259  }
260
261  private void loadCsv() throws IOException, FHIRException {
262    CSVReader csv = new CSVReader(ManagedFileAccess.inStream("C:\\work\\org.hl7.fhir\\org.fhir.interversion\\work\\search-params.csv"));
263    csv.readHeaders();
264    while (csv.line()) {
265      String r4 = csv.cell("R4");
266      String r3 = csv.cell("R3");
267      String r2b = csv.cell("R2b");
268      String r2 = csv.cell("R2");
269      if (!Utilities.noString(r4) || !Utilities.noString(r3) || !Utilities.noString(r2b) || !Utilities.noString(r2)) {
270        boolean ok = (!Utilities.noString(r4) && r4.contains(".")) ||
271          (!Utilities.noString(r3) && r3.contains(".")) ||
272          (!Utilities.noString(r2b) && r2b.contains(".")) ||
273          (!Utilities.noString(r2) && r2.contains("."));
274        if (ok) {
275          list.add(new SPRelationship(r4, r3, r2b, r2));
276        }
277      }
278    }
279    System.out.println("Map loaded - " + list.size() + " entries");
280  }
281
282
283}