public void create(File dstFolder, List<ExcelTable> tables, ExcelSproutOptions options) {
        Random rnd = new Random(options.getRandomSeed());
        //there are many tables
        //we have to decide: what table to what sheet, and what sheet to what workbook
        //we should not repeat tables about the same class, so there are possible groups
        //maybe a workbook should be full to have the best expected.ttl from the original model
        //here we calculate: what table to what workbook
        List<List<ExcelTable>> workbookClusters = getWorkbookClusters(tables, rnd);
        //now we have to decide which table will be in which sheet
        //the cleanest way is to have a table per sheet
        //TODO make this variable so more messy version are possible
        List<List<List<ExcelTable>>> workbookSheetTables = new ArrayList<>();
        for (List<ExcelTable> workbookTables : workbookClusters) {
            List<List<ExcelTable>> sheetTables = new ArrayList<>();
            for (ExcelTable tbl : workbookTables) {
                List<ExcelTable> sheet = Arrays.asList(tbl);
                sheetTables.add(sheet);
            }
            workbookSheetTables.add(sheetTables);
        }
        int maxDigits = String.valueOf(workbookSheetTables.size() - 1).length();
        Map<List<ExcelTable>, ExcelGeneratorSheetConfig> sheetConfigMap = new HashMap<>();
        //now we use the ExcelGenerator to generate the workbooks
        ExcelGenerator excelGenerator = new ExcelGenerator();
        for (int i = 0; i < workbookSheetTables.size(); i++) {
            List<List<ExcelTable>> sheets = workbookSheetTables.get(i);
            //create a config for this workbook
            ExcelGeneratorWorkbookConfig workbookConf = new ExcelGeneratorWorkbookConfig();
            //TODO configurable
            workbookConf.setFileName("workbook.xlsx");
            for (List<ExcelTable> sheet : sheets) {
                ExcelGeneratorSheetConfig sheetConf = new ExcelGeneratorSheetConfig();
                sheetConfigMap.put(sheet, sheetConf);
                StringBuilder sheetNameSB = new StringBuilder();
                //TODO a second table in the sheet means we maybe have to move the offset
                //      so that it will not overlap
                for (int k = 0; k < sheet.size(); k++) {
                    ExcelTable excelTable = sheet.get(k);
                    ExcelGeneratorTableConfig tableConf = new ExcelGeneratorTableConfig();
                    //TODO maybe make a getSingleOrDefault method
                    Point offset = (Point) excelTable.getSetup().getOrDefault("offset", new Point(0, 0));
                    tableConf.setOffset(offset);
                    //draw the ExcelCell matrix from ExcelTable
                    tableConf.setStaticCellDrawer(d -> {
                        //it uses the tableConf offset
                        d.exceltable(excelTable, options);
                    });
                    sheetConf.getTableConfigs().add(tableConf);
                    //TODO if only one table with one class: add provenance sheetname -> insts a class. (for all insts)
                    ClassConfig classConfig = excelTable.getSetup().getOrThrow("classes", ClassConfig.class);
                    if (classConfig.hasLabel()) {
                        sheetNameSB.append(classConfig.getLabel());
                    } else {
                        throw new RuntimeException("ClassConfig should give a label to name the sheet");
                    }
                    //in one sheet multiple tables could be existing
                    if (k != sheet.size() - 1) {
                        sheetNameSB.append(" & ");
                    }
                }
                //sheet name comes from table content
                sheetConf.setSheetName(sheetNameSB.toString());
                workbookConf.getSheetConfigs().add(sheetConf);
            }//per sheet
            ExcelGeneratorResult result = excelGenerator.generate(null, workbookConf);
            //System.out.println("save workbook " + i);
            //no extra folder when only one workbook
            File workbookFolder = workbookSheetTables.size() == 1 ? dstFolder : new File(dstFolder, String.format("%0" + maxDigits + "d", i));
            result.saveExcel(workbookFolder);
            //write provenance =================================================
            Model expectedModel = null;
            Model provenanceModel = null;
            CSVPrinter provenanceCSV = null;
            if (options.isWriteExpectedModel()) {
                expectedModel = ModelFactory.createDefaultModel();
                expectedModel.setNsPrefixes(options.getPrefixMapping());
                expectedModel.setNsPrefixes(PrefixMapping.Standard);
            }
            if (options.isWriteProvenanceModel()) {
                provenanceModel = ModelFactory.createDefaultModel();
                provenanceModel.setNsPrefixes(options.getPrefixMapping());
                provenanceModel.setNsPrefix("prov", PROV.NS);
                provenanceModel.setNsPrefix("csvw", CSVW.NS);
                provenanceModel.setNsPrefix("ss", SS.NS);
                provenanceModel.setNsPrefixes(PrefixMapping.Standard);
            }
            if (options.isWriteProvenanceCSV()) {
                try {
                    provenanceCSV = CSVFormat.DEFAULT.print(
                            new OutputStreamWriter(
                                    new GZIPOutputStream(
                                            new FileOutputStream(
                                                    new File(workbookFolder, "provenance.csv.gz")
                                            ))));
                    csvProvenanceHeader(provenanceCSV);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            //used in rdfProvenance for fast lookup reified statements
            Map<Statement, Resource> stmt2res = new HashMap<>();
            //need here sheetname for provenance
            for (List<ExcelTable> sheet : sheets) {
                ExcelGeneratorSheetConfig sheetConfig = sheetConfigMap.get(sheet);
                for (ExcelTable table : sheet) {
                    for (Entry<ExcelCell, Provenance> cell2prov : table.getCellProvMap().entrySet()) {
                        ExcelCell cell = cell2prov.getKey();
                        Provenance prov = cell2prov.getValue();
                        if (cell.getAddress() == null) {
                            //this was a temporary cell created for a merge 
                            //in TableGenerator putMultipleObjects method
                            continue;
                        }
                        if (prov.getStatements().isEmpty()) {
                            //no provenance information for this cell
                            continue;
                        }
                        if (options.isWriteExpectedModel()) {
                            expectedModel.add(prov.getStatements());
                        }
                        if (options.isWriteProvenanceModel()) {
                            rdfProvenance(cell, sheetConfig.getSheetName(), prov, stmt2res, provenanceModel);
                        }
                        if (options.isWriteProvenanceCSV()) {
                            csvProvenance(cell, sheetConfig.getSheetName(), prov, provenanceCSV, provenanceModel);
                        }
                    }
                }
            }
            //write to files
            if (options.isWriteExpectedModel()) {
                File file = new File(workbookFolder, "expected.ttl.gz");
                try (OutputStream os = file.getName().endsWith("gz") ? new GZIPOutputStream(new FileOutputStream(file)) : new FileOutputStream(file)) {
                    expectedModel.write(os, "TTL");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteProvenanceModel()) {
                File file = new File(workbookFolder, "provenance.ttl.gz");
                try (OutputStream os = file.getName().endsWith("gz") ? new GZIPOutputStream(new FileOutputStream(file)) : new FileOutputStream(file)) {
                    provenanceModel.write(os, "TTL");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteProvenanceCSV()) {
                try {
                    provenanceCSV.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteGenerationSummaryJson()) {
                //key is sheet name
                JSONObject perSheetPatternUsage = new JSONObject();
                JsonUtility.forceLinkedHashMap(perSheetPatternUsage);
                for (List<ExcelTable> sheet : sheets) {
                    ExcelGeneratorSheetConfig sheetConfig = sheetConfigMap.get(sheet);
                    //count how often
                    Map<String, Map<Object, Integer>> pattern2value2count = new HashMap<>();
                    for (ExcelTable tbl : sheet) {
                        for (Entry<ExcelCell, Provenance> entry : tbl.getCellProvMap().entrySet()) {
                            //skip the ones with no prov and no address (temp cells)
                            if (entry.getKey().getAddress() == null || entry.getValue().getStatements().isEmpty()) {
                                continue;
                            }
                            for (Entry<String, Object> e : entry.getValue().getUsedPatterns().entrySet()) {
                                Object val = e.getValue();
                                if(val instanceof JSONArray) {
                                    //because json array hash is always different
                                    val = val.toString();
                                }
                                Map<Object, Integer> value2count = pattern2value2count.computeIfAbsent(e.getKey(), k -> new HashMap<>());
                                value2count.put(val, value2count.getOrDefault(val, 0) + 1);
                            }
                        }
                    }
                    JSONObject patternUsage = new JSONObject();
                    JsonUtility.forceLinkedHashMap(patternUsage);
                    List<Entry<String, Map<Object, Integer>>> pattern2value2countList = new ArrayList<>(pattern2value2count.entrySet());
                    pattern2value2countList.sort((a,b) -> a.getKey().compareTo(b.getKey()));
                    for (Entry<String, Map<Object, Integer>> pattern2value2countEntry : pattern2value2countList) {
                        JSONArray array = new JSONArray();
                        for (Entry<Object, Integer> e : pattern2value2countEntry.getValue().entrySet()) {
                            JSONObject v2c = new JSONObject();
                            JsonUtility.forceLinkedHashMap(v2c);
                            v2c.put("value", e.getKey());
                            v2c.put("count", e.getValue());
                            array.put(v2c);
                        }
                        patternUsage.put(pattern2value2countEntry.getKey(), array);
                    }
                    perSheetPatternUsage.put(sheetConfig.getSheetName(), patternUsage);
                }
                options.getGenerationSummary().put("patternUsagePerSheet", perSheetPatternUsage);
                File file = new File(workbookFolder, "summary.json");
                try {
                    FileUtils.writeStringToFile(file, options.getGenerationSummary().toString(2), StandardCharsets.UTF_8);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }//per workbook
    }
public void create(File dstFolder, List<ExcelTable> tables, ExcelSproutOptions options) {
        Random rnd = new Random(options.getRandomSeed());
       
       
       
       
       
        List<List<ExcelTable>> workbookClusters = getWorkbookClusters(tables, rnd);
       
       
       
        List<List<List<ExcelTable>>> workbookSheetTables = new ArrayList<>();
        for (List<ExcelTable> workbookTables : workbookClusters) {
            List<List<ExcelTable>> sheetTables = new ArrayList<>();
            for (ExcelTable tbl : workbookTables) {
                List<ExcelTable> sheet = Arrays.asList(tbl);
                sheetTables.add(sheet);
            }
            workbookSheetTables.add(sheetTables);
        }
        int maxDigits = String.valueOf(workbookSheetTables.size() - 1).length();
        Map<List<ExcelTable>, ExcelGeneratorSheetConfig> sheetConfigMap = new HashMap<>();
       
        ExcelGenerator excelGenerator = new ExcelGenerator();
        for (int i = 0; i < workbookSheetTables.size(); i++) {
            List<List<ExcelTable>> sheets = workbookSheetTables.get(i);
           
            ExcelGeneratorWorkbookConfig workbookConf = new ExcelGeneratorWorkbookConfig();
           
            workbookConf.setFileName("workbook.xlsx");
            for (List<ExcelTable> sheet : sheets) {
                ExcelGeneratorSheetConfig sheetConf = new ExcelGeneratorSheetConfig();
                sheetConfigMap.put(sheet, sheetConf);
                StringBuilder sheetNameSB = new StringBuilder();
               
               
                for (int k = 0; k < sheet.size(); k++) {
                    ExcelTable excelTable = sheet.get(k);
                    ExcelGeneratorTableConfig tableConf = new ExcelGeneratorTableConfig();
                   
                    Point offset = (Point) excelTable.getSetup().getOrDefault("offset", new Point(0, 0));
                    tableConf.setOffset(offset);
                   
                    tableConf.setStaticCellDrawer(d -> {
                       
                        d.exceltable(excelTable, options);
                    });
                    sheetConf.getTableConfigs().add(tableConf);
                   
                    ClassConfig classConfig = excelTable.getSetup().getOrThrow("classes", ClassConfig.class);
                    if (classConfig.hasLabel()) {
                        sheetNameSB.append(classConfig.getLabel());
                    } else {
                        throw new RuntimeException("ClassConfig should give a label to name the sheet");
                    }
                   
                    if (k != sheet.size() - 1) {
                        sheetNameSB.append(" & ");
                    }
                }
               
                sheetConf.setSheetName(sheetNameSB.toString());
                workbookConf.getSheetConfigs().add(sheetConf);
            
            ExcelGeneratorResult result = excelGenerator.generate(null, workbookConf);
           
           
            File workbookFolder = workbookSheetTables.size() == 1 ? dstFolder : new File(dstFolder, String.format("%0" + maxDigits + "d", i));
            result.saveExcel(workbookFolder);
           
            Model expectedModel = null;
            Model provenanceModel = null;
            CSVPrinter provenanceCSV = null;
            if (options.isWriteExpectedModel()) {
                expectedModel = ModelFactory.createDefaultModel();
                expectedModel.setNsPrefixes(options.getPrefixMapping());
                expectedModel.setNsPrefixes(PrefixMapping.Standard);
            }
            if (options.isWriteProvenanceModel()) {
                provenanceModel = ModelFactory.createDefaultModel();
                provenanceModel.setNsPrefixes(options.getPrefixMapping());
                provenanceModel.setNsPrefix("prov", PROV.NS);
                provenanceModel.setNsPrefix("csvw", CSVW.NS);
                provenanceModel.setNsPrefix("ss", SS.NS);
                provenanceModel.setNsPrefixes(PrefixMapping.Standard);
            }
            if (options.isWriteProvenanceCSV()) {
                try {
                    provenanceCSV = CSVFormat.DEFAULT.print(
                            new OutputStreamWriter(
                                    new GZIPOutputStream(
                                            new FileOutputStream(
                                                    new File(workbookFolder, "provenance.csv.gz")
                                            ))));
                    csvProvenanceHeader(provenanceCSV);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
           
            Map<Statement, Resource> stmt2res = new HashMap<>();
           
            for (List<ExcelTable> sheet : sheets) {
                ExcelGeneratorSheetConfig sheetConfig = sheetConfigMap.get(sheet);
                for (ExcelTable table : sheet) {
                    for (Entry<ExcelCell, Provenance> cell2prov : table.getCellProvMap().entrySet()) {
                        ExcelCell cell = cell2prov.getKey();
                        Provenance prov = cell2prov.getValue();
                        if (cell.getAddress() == null) {
                           
                           
                            continue;
                        }
                        if (prov.getStatements().isEmpty()) {
                           
                            continue;
                        }
                        if (options.isWriteExpectedModel()) {
                            expectedModel.add(prov.getStatements());
                        }
                        if (options.isWriteProvenanceModel()) {
                            rdfProvenance(cell, sheetConfig.getSheetName(), prov, stmt2res, provenanceModel);
                        }
                        if (options.isWriteProvenanceCSV()) {
                            csvProvenance(cell, sheetConfig.getSheetName(), prov, provenanceCSV, provenanceModel);
                        }
                    }
                }
            }
           
            if (options.isWriteExpectedModel()) {
                File file = new File(workbookFolder, "expected.ttl.gz");
                try (OutputStream os = file.getName().endsWith("gz") ? new GZIPOutputStream(new FileOutputStream(file)) : new FileOutputStream(file)) {
                    expectedModel.write(os, "TTL");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteProvenanceModel()) {
                File file = new File(workbookFolder, "provenance.ttl.gz");
                try (OutputStream os = file.getName().endsWith("gz") ? new GZIPOutputStream(new FileOutputStream(file)) : new FileOutputStream(file)) {
                    provenanceModel.write(os, "TTL");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteProvenanceCSV()) {
                try {
                    provenanceCSV.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
            if (options.isWriteGenerationSummaryJson()) {
               
                JSONObject perSheetPatternUsage = new JSONObject();
                JsonUtility.forceLinkedHashMap(perSheetPatternUsage);
                for (List<ExcelTable> sheet : sheets) {
                    ExcelGeneratorSheetConfig sheetConfig = sheetConfigMap.get(sheet);
                   
                    Map<String, Map<Object, Integer>> pattern2value2count = new HashMap<>();
                    for (ExcelTable tbl : sheet) {
                        for (Entry<ExcelCell, Provenance> entry : tbl.getCellProvMap().entrySet()) {
                           
                            if (entry.getKey().getAddress() == null || entry.getValue().getStatements().isEmpty()) {
                                continue;
                            }
                            for (Entry<String, Object> e : entry.getValue().getUsedPatterns().entrySet()) {
                                Object val = e.getValue();
                                if(val instanceof JSONArray) {
                                   
                                    val = val.toString();
                                }
                                Map<Object, Integer> value2count = pattern2value2count.computeIfAbsent(e.getKey(), k -> new HashMap<>());
                                value2count.put(val, value2count.getOrDefault(val, 0) + 1);
                            }
                        }
                    }
                    JSONObject patternUsage = new JSONObject();
                    JsonUtility.forceLinkedHashMap(patternUsage);
                    List<Entry<String, Map<Object, Integer>>> pattern2value2countList = new ArrayList<>(pattern2value2count.entrySet());
                    pattern2value2countList.sort((a,b) -> a.getKey().compareTo(b.getKey()));
                    for (Entry<String, Map<Object, Integer>> pattern2value2countEntry : pattern2value2countList) {
                        JSONArray array = new JSONArray();
                        for (Entry<Object, Integer> e : pattern2value2countEntry.getValue().entrySet()) {
                            JSONObject v2c = new JSONObject();
                            JsonUtility.forceLinkedHashMap(v2c);
                            v2c.put("value", e.getKey());
                            v2c.put("count", e.getValue());
                            array.put(v2c);
                        }
                        patternUsage.put(pattern2value2countEntry.getKey(), array);
                    }
                    perSheetPatternUsage.put(sheetConfig.getSheetName(), patternUsage);
                }
                options.getGenerationSummary().put("patternUsagePerSheet", perSheetPatternUsage);
                File file = new File(workbookFolder, "summary.json");
                try {
                    FileUtils.writeStringToFile(file, options.getGenerationSummary().toString(2), StandardCharsets.UTF_8);
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        
    }
public void create(file dstfolder, list<exceltable> tables, excelsproutoptions options) { random rnd = new random(options.getrandomseed()); list<list<exceltable>> workbookclusters = getworkbookclusters(tables, rnd); list<list<list<exceltable>>> workbooksheettables = new arraylist<>(); for (list<exceltable> workbooktables : workbookclusters) { list<list<exceltable>> sheettables = new arraylist<>(); for (exceltable tbl : workbooktables) { list<exceltable> sheet = arrays.aslist(tbl); sheettables.add(sheet); } workbooksheettables.add(sheettables); } int maxdigits = string.valueof(workbooksheettables.size() - 1).length(); map<list<exceltable>, excelgeneratorsheetconfig> sheetconfigmap = new hashmap<>(); excelgenerator excelgenerator = new excelgenerator(); for (int i = 0; i < workbooksheettables.size(); i++) { list<list<exceltable>> sheets = workbooksheettables.get(i); excelgeneratorworkbookconfig workbookconf = new excelgeneratorworkbookconfig(); workbookconf.setfilename("workbook.xlsx"); for (list<exceltable> sheet : sheets) { excelgeneratorsheetconfig sheetconf = new excelgeneratorsheetconfig(); sheetconfigmap.put(sheet, sheetconf); stringbuilder sheetnamesb = new stringbuilder(); for (int k = 0; k < sheet.size(); k++) { exceltable exceltable = sheet.get(k); excelgeneratortableconfig tableconf = new excelgeneratortableconfig(); point offset = (point) exceltable.getsetup().getordefault("offset", new point(0, 0)); tableconf.setoffset(offset); tableconf.setstaticcelldrawer(d -> { d.exceltable(exceltable, options); }); sheetconf.gettableconfigs().add(tableconf); classconfig classconfig = exceltable.getsetup().getorthrow("classes", classconfig.class); if (classconfig.haslabel()) { sheetnamesb.append(classconfig.getlabel()); } else { throw new runtimeexception("classconfig should give a label to name the sheet"); } if (k != sheet.size() - 1) { sheetnamesb.append(" & "); } } sheetconf.setsheetname(sheetnamesb.tostring()); workbookconf.getsheetconfigs().add(sheetconf); excelgeneratorresult result = excelgenerator.generate(null, workbookconf); file workbookfolder = workbooksheettables.size() == 1 ? dstfolder : new file(dstfolder, string.format("%0" + maxdigits + "d", i)); result.saveexcel(workbookfolder); model expectedmodel = null; model provenancemodel = null; csvprinter provenancecsv = null; if (options.iswriteexpectedmodel()) { expectedmodel = modelfactory.createdefaultmodel(); expectedmodel.setnsprefixes(options.getprefixmapping()); expectedmodel.setnsprefixes(prefixmapping.standard); } if (options.iswriteprovenancemodel()) { provenancemodel = modelfactory.createdefaultmodel(); provenancemodel.setnsprefixes(options.getprefixmapping()); provenancemodel.setnsprefix("prov", prov.ns); provenancemodel.setnsprefix("csvw", csvw.ns); provenancemodel.setnsprefix("ss", ss.ns); provenancemodel.setnsprefixes(prefixmapping.standard); } if (options.iswriteprovenancecsv()) { try { provenancecsv = csvformat.default.print( new outputstreamwriter( new gzipoutputstream( new fileoutputstream( new file(workbookfolder, "provenance.csv.gz") )))); csvprovenanceheader(provenancecsv); } catch (ioexception ex) { throw new runtimeexception(ex); } } map<statement, resource> stmt2res = new hashmap<>(); for (list<exceltable> sheet : sheets) { excelgeneratorsheetconfig sheetconfig = sheetconfigmap.get(sheet); for (exceltable table : sheet) { for (entry<excelcell, provenance> cell2prov : table.getcellprovmap().entryset()) { excelcell cell = cell2prov.getkey(); provenance prov = cell2prov.getvalue(); if (cell.getaddress() == null) { continue; } if (prov.getstatements().isempty()) { continue; } if (options.iswriteexpectedmodel()) { expectedmodel.add(prov.getstatements()); } if (options.iswriteprovenancemodel()) { rdfprovenance(cell, sheetconfig.getsheetname(), prov, stmt2res, provenancemodel); } if (options.iswriteprovenancecsv()) { csvprovenance(cell, sheetconfig.getsheetname(), prov, provenancecsv, provenancemodel); } } } } if (options.iswriteexpectedmodel()) { file file = new file(workbookfolder, "expected.ttl.gz"); try (outputstream os = file.getname().endswith("gz") ? new gzipoutputstream(new fileoutputstream(file)) : new fileoutputstream(file)) { expectedmodel.write(os, "ttl"); } catch (ioexception ex) { throw new runtimeexception(ex); } } if (options.iswriteprovenancemodel()) { file file = new file(workbookfolder, "provenance.ttl.gz"); try (outputstream os = file.getname().endswith("gz") ? new gzipoutputstream(new fileoutputstream(file)) : new fileoutputstream(file)) { provenancemodel.write(os, "ttl"); } catch (ioexception ex) { throw new runtimeexception(ex); } } if (options.iswriteprovenancecsv()) { try { provenancecsv.close(); } catch (ioexception ex) { throw new runtimeexception(ex); } } if (options.iswritegenerationsummaryjson()) { jsonobject persheetpatternusage = new jsonobject(); jsonutility.forcelinkedhashmap(persheetpatternusage); for (list<exceltable> sheet : sheets) { excelgeneratorsheetconfig sheetconfig = sheetconfigmap.get(sheet); map<string, map<object, integer>> pattern2value2count = new hashmap<>(); for (exceltable tbl : sheet) { for (entry<excelcell, provenance> entry : tbl.getcellprovmap().entryset()) { if (entry.getkey().getaddress() == null || entry.getvalue().getstatements().isempty()) { continue; } for (entry<string, object> e : entry.getvalue().getusedpatterns().entryset()) { object val = e.getvalue(); if(val instanceof jsonarray) { val = val.tostring(); } map<object, integer> value2count = pattern2value2count.computeifabsent(e.getkey(), k -> new hashmap<>()); value2count.put(val, value2count.getordefault(val, 0) + 1); } } } jsonobject patternusage = new jsonobject(); jsonutility.forcelinkedhashmap(patternusage); list<entry<string, map<object, integer>>> pattern2value2countlist = new arraylist<>(pattern2value2count.entryset()); pattern2value2countlist.sort((a,b) -> a.getkey().compareto(b.getkey())); for (entry<string, map<object, integer>> pattern2value2countentry : pattern2value2countlist) { jsonarray array = new jsonarray(); for (entry<object, integer> e : pattern2value2countentry.getvalue().entryset()) { jsonobject v2c = new jsonobject(); jsonutility.forcelinkedhashmap(v2c); v2c.put("value", e.getkey()); v2c.put("count", e.getvalue()); array.put(v2c); } patternusage.put(pattern2value2countentry.getkey(), array); } persheetpatternusage.put(sheetconfig.getsheetname(), patternusage); } options.getgenerationsummary().put("patternusagepersheet", persheetpatternusage); file file = new file(workbookfolder, "summary.json"); try { fileutils.writestringtofile(file, options.getgenerationsummary().tostring(2), standardcharsets.utf_8); } catch (ioexception ex) { throw new runtimeexception(ex); } } }