diff --git a/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..328dabd1df744e76021b70da61157da8b1aad286 --- /dev/null +++ b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java @@ -0,0 +1,397 @@ +/** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.oceandsl.rqda.log.generator.graphml; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import org.eclipse.xtend2.lib.StringConcatenation; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.Functions.Function1; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.oceandsl.rqda.log.DatabaseUtils; +import org.oceandsl.rqda.log.PlotUtils; +import org.oceandsl.rqda.log.Tuple; +import org.oceandsl.rqda.log.Tuples; +import org.oceandsl.rqda.log.generator.IGenerator; + +/** + * @author Reiner Jung + * + * @since 1.0 + */ +@SuppressWarnings("all") +public class GraphmlGenerator implements IGenerator { + private int leafId = 0; + + private int edgeId = 0; + + @Override + public CharSequence generateAggregatedCodes(final DatabaseUtils databaseAccess) { + try { + StringConcatenation _builder = new StringConcatenation(); + String _createHeader = GraphmlTemplates.createHeader(); + _builder.append(_createHeader); + _builder.newLineIfNotEmpty(); + CharSequence _plotAggregatedCodes = this.plotAggregatedCodes(databaseAccess); + _builder.append(_plotAggregatedCodes); + _builder.newLineIfNotEmpty(); + String _createFooter = GraphmlTemplates.createFooter(); + _builder.append(_createFooter); + _builder.newLineIfNotEmpty(); + return _builder; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + @Override + public CharSequence generateAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) { + try { + StringConcatenation _builder = new StringConcatenation(); + String _createHeader = GraphmlTemplates.createHeader(); + _builder.append(_createHeader); + _builder.newLineIfNotEmpty(); + CharSequence _plotAllCategories = this.plotAllCategories(databaseAccess, plotCodes); + _builder.append(_plotAllCategories); + _builder.newLineIfNotEmpty(); + String _createFooter = GraphmlTemplates.createFooter(); + _builder.append(_createFooter); + _builder.newLineIfNotEmpty(); + return _builder; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + @Override + public CharSequence generateThemeMap(final DatabaseUtils databaseAccess, final boolean plotCodes, final String category) { + try { + StringConcatenation _builder = new StringConcatenation(); + String _createHeader = GraphmlTemplates.createHeader(); + _builder.append(_createHeader); + _builder.newLineIfNotEmpty(); + CharSequence _plotThemeNode = this.plotThemeNode(databaseAccess, plotCodes, category); + _builder.append(_plotThemeNode); + _builder.newLineIfNotEmpty(); + String _createFooter = GraphmlTemplates.createFooter(); + _builder.append(_createFooter); + _builder.newLineIfNotEmpty(); + return _builder; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + /** + * plot aggregated codes. + */ + private CharSequence plotAggregatedCodes(final DatabaseUtils databaseAccess) throws SQLException { + CharSequence _xblockexpression = null; + { + final Map<Integer, String> categories = databaseAccess.getCategories(); + final Map<Integer, String> codes = databaseAccess.getCodes(); + final Tuples<Integer, Integer> links = databaseAccess.getLinks(); + final HashMap<Integer, String> singleAssignedCodes = new HashMap<Integer, String>(); + final HashMap<Integer, List<Integer>> multiAssignedCodes = new HashMap<Integer, List<Integer>>(); + final Tuples<Integer, Integer> singleLinks = new Tuples<Integer, Integer>(); + Set<Map.Entry<Integer, String>> _entrySet = codes.entrySet(); + for (final Map.Entry<Integer, String> entry : _entrySet) { + { + final List<Integer> sharingCategories = databaseAccess.getCategoriesForCode(entry.getKey()); + int _size = sharingCategories.size(); + boolean _greaterThan = (_size > 1); + if (_greaterThan) { + multiAssignedCodes.put(entry.getKey(), sharingCategories); + } else { + int _size_1 = sharingCategories.size(); + boolean _equals = (_size_1 == 1); + if (_equals) { + singleAssignedCodes.put(entry.getKey(), entry.getValue()); + singleLinks.put(sharingCategories.get(0), entry.getKey()); + } + } + } + } + this.leafId = 0; + this.edgeId = 0; + Set<Integer> _keySet = categories.keySet(); + for (final Integer id : _keySet) { + if ((this.leafId < (id).intValue())) { + this.leafId = (id).intValue(); + } + } + StringConcatenation _builder = new StringConcatenation(); + final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> it) -> { + return GraphmlTemplates.createNode((it.getKey()).intValue(), it.getValue(), GraphmlTemplates.getColor(it.getValue())); + }; + String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(categories.entrySet(), _function)); + _builder.append(_join); + _builder.newLineIfNotEmpty(); + final Function1<Tuple<Integer, Integer>, String> _function_1 = (Tuple<Integer, Integer> it) -> { + int _plusPlus = this.edgeId++; + return GraphmlTemplates.createEdge(_plusPlus, (it.getLeft()).intValue(), (it.getRight()).intValue()); + }; + String _join_1 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(links.getTuples(), _function_1)); + _builder.append(_join_1); + _builder.newLineIfNotEmpty(); + final Function1<Map.Entry<Integer, String>, String> _function_2 = (Map.Entry<Integer, String> code) -> { + String _xblockexpression_1 = null; + { + final Integer categoryId = singleLinks.find4Right(code.getKey()); + String _createNode = GraphmlTemplates.createNode(this.leafId, code.getValue(), "#FFFFFF"); + int _plusPlus = this.edgeId++; + int _plusPlus_1 = this.leafId++; + String _createEdge = GraphmlTemplates.createEdge(_plusPlus, (categoryId).intValue(), _plusPlus_1); + _xblockexpression_1 = (_createNode + _createEdge); + } + return _xblockexpression_1; + }; + Iterable<String> _map = IterableExtensions.<Map.Entry<Integer, String>, String>map(singleAssignedCodes.entrySet(), _function_2); + _builder.append(_map); + _builder.newLineIfNotEmpty(); + final Function1<Map.Entry<Integer, List<Integer>>, CharSequence> _function_3 = (Map.Entry<Integer, List<Integer>> entry_1) -> { + return this.computeIndirectCategoryInterdependency(entry_1.getValue()); + }; + String _join_2 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, List<Integer>>, CharSequence>map(multiAssignedCodes.entrySet(), _function_3)); + _builder.append(_join_2); + _builder.newLineIfNotEmpty(); + _xblockexpression = _builder; + } + return _xblockexpression; + } + + private CharSequence computeIndirectCategoryInterdependency(final List<Integer> assignedCategories) { + String result = ""; + final Tuples<Integer, Integer> existingLinks = new Tuples<Integer, Integer>(); + for (int i = 0; (i < (assignedCategories.size() - 1)); i++) { + for (int j = (i + 1); (j < assignedCategories.size()); j++) { + boolean _edgeExists = PlotUtils.edgeExists(existingLinks, assignedCategories.get(i), assignedCategories.get(j)); + boolean _not = (!_edgeExists); + if (_not) { + String _result = result; + int _plusPlus = this.edgeId++; + String _createDashedEdge = GraphmlTemplates.createDashedEdge(_plusPlus, assignedCategories.get(i), + assignedCategories.get(j)); + result = (_result + _createDashedEdge); + existingLinks.put(assignedCategories.get(i), assignedCategories.get(j)); + } + } + } + return result; + } + + /** + * PLot all categories and their links. + * + * @param databaseAccess + * source model + * @param plotCodes + * whether to plot codes + * + * @throws SQLException + * @throws IOException + */ + private CharSequence plotAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) throws SQLException { + CharSequence _xblockexpression = null; + { + final Map<Integer, String> categories = databaseAccess.getCategories(); + final HashMap<Integer, String> existingCodes = new HashMap<Integer, String>(); + final Tuples<Integer, Integer> links = databaseAccess.getLinks(); + this.leafId = 0; + this.edgeId = 0; + Set<Integer> _keySet = categories.keySet(); + for (final Integer id : _keySet) { + if ((this.leafId < (id).intValue())) { + this.leafId = (id).intValue(); + } + } + StringConcatenation _builder = new StringConcatenation(); + final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> it) -> { + try { + String _createNode = GraphmlTemplates.createNode((it.getKey()).intValue(), it.getValue(), GraphmlTemplates.getColor(it.getValue())); + CharSequence _xifexpression = null; + if (plotCodes) { + _xifexpression = this.plotAllCategoryCodes(databaseAccess, (it.getKey()).intValue(), it.getValue(), links, existingCodes); + } + return (_createNode + _xifexpression); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + }; + String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(categories.entrySet(), _function)); + _builder.append(_join); + _builder.newLineIfNotEmpty(); + final Function1<Tuple<Integer, Integer>, String> _function_1 = (Tuple<Integer, Integer> it) -> { + int _plusPlus = this.edgeId++; + return GraphmlTemplates.createEdge(_plusPlus, (it.getLeft()).intValue(), (it.getRight()).intValue()); + }; + String _join_1 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(links.getTuples(), _function_1)); + _builder.append(_join_1); + _builder.newLineIfNotEmpty(); + _xblockexpression = _builder; + } + return _xblockexpression; + } + + /** + * Plot all code nodes corresponding to a given category and collect all links between the + * category and the codes for later processing. + * + * @param databaseAccess + * source model + * @param parentId + * id of the category + * @param parentName + * name of the category + * @param links + * tuples containing links + * @param existingNodes + * map of existing nodes to avoid code duplication + * + * @throws SQLException + * @throws IOException + */ + private CharSequence plotAllCategoryCodes(final DatabaseUtils databaseAccess, final int parentId, final String parentName, final Tuples<Integer, Integer> links, final Map<Integer, String> existingNodes) throws SQLException { + String result = ""; + List<String> _codesForCategory = databaseAccess.getCodesForCategory(parentName); + for (final String code : _codesForCategory) { + { + boolean _nodeExists = PlotUtils.nodeExists(existingNodes, code); + boolean _not = (!_nodeExists); + if (_not) { + String _result = result; + String _createNode = GraphmlTemplates.createNode(this.leafId, code, "#FFFFFF"); + result = (_result + _createNode); + int _plusPlus = this.leafId++; + existingNodes.put(Integer.valueOf(_plusPlus), code); + } + final Integer childId = PlotUtils.findNodeId(existingNodes, code); + boolean _edgeExists = PlotUtils.edgeExists(links, Integer.valueOf(parentId), childId); + boolean _not_1 = (!_edgeExists); + if (_not_1) { + links.put(Integer.valueOf(parentId), childId); + } + } + } + return result; + } + + /** + * Plot theme node and all subsequent categories and their code nodes. + * + * @param databaseAccess + * source model + * @param plotCodes + * whether to plot codes + * @param theme + * theme name + * + * @throws SQLException + * @throws IOException + */ + private CharSequence plotThemeNode(final DatabaseUtils databaseAccess, final boolean plotCodes, final String theme) throws SQLException { + CharSequence _xblockexpression = null; + { + final Map<Integer, String> categories = databaseAccess.getCategories(); + final Tuples<Integer, Integer> links = databaseAccess.getLinks(); + final HashMap<Integer, String> existingCategoryNodes = new HashMap<Integer, String>(); + this.leafId = 400; + this.edgeId = 0; + final Integer themeId = PlotUtils.findNodeId(categories, theme); + existingCategoryNodes.put(themeId, theme); + final Tuples<Integer, Integer> resultLinks = this.collectCategoriesAndLinks(categories, links, (themeId).intValue(), existingCategoryNodes); + final HashMap<Integer, String> existingCodeNodes = new HashMap<Integer, String>(); + StringConcatenation _builder = new StringConcatenation(); + String _createNode = GraphmlTemplates.createNode((themeId).intValue(), theme, GraphmlTemplates.getColor(theme)); + _builder.append(_createNode); + _builder.newLineIfNotEmpty(); + final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> category) -> { + return GraphmlTemplates.createNode((category.getKey()).intValue(), category.getValue(), GraphmlTemplates.getColor(category.getValue())); + }; + String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(existingCategoryNodes.entrySet(), _function)); + _builder.append(_join); + _builder.newLineIfNotEmpty(); + final Function1<Map.Entry<Integer, String>, CharSequence> _function_1 = (Map.Entry<Integer, String> code) -> { + try { + return this.plotAllCategoryCodes(databaseAccess, (code.getKey()).intValue(), code.getValue(), resultLinks, existingCodeNodes); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + }; + String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(existingCategoryNodes.entrySet(), _function_1)); + _builder.append(_join_1); + _builder.newLineIfNotEmpty(); + final Function1<Tuple<Integer, Integer>, String> _function_2 = (Tuple<Integer, Integer> tuple) -> { + int _plusPlus = this.edgeId++; + return GraphmlTemplates.createEdge(_plusPlus, (tuple.getLeft()).intValue(), (tuple.getRight()).intValue()); + }; + String _join_2 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(resultLinks.getTuples(), _function_2)); + _builder.append(_join_2); + _builder.newLineIfNotEmpty(); + _xblockexpression = _builder; + } + return _xblockexpression; + } + + /** + * Plot category nodes following recursively their category to category links. Also collect + * links for later processing. + * + * @param writer + * file writer + * @param categories + * map of category ids and names + * @param links + * tuples containing links between categories + * @param parentId + * the parent category + * @param existingNodes + * existing nodes + * + * @return returns links between code nodes and categories + * + * @throws IOException + * @throws SQLException + */ + private Tuples<Integer, Integer> collectCategoriesAndLinks(final Map<Integer, String> categories, final Tuples<Integer, Integer> links, final int parentId, final Map<Integer, String> existingNodes) throws SQLException { + final Tuples<Integer, Integer> resultLinks = new Tuples<Integer, Integer>(); + final Consumer<Tuple<Integer, Integer>> _function = (Tuple<Integer, Integer> it) -> { + try { + Integer _left = it.getLeft(); + boolean _tripleEquals = ((_left).intValue() == parentId); + if (_tripleEquals) { + final Integer id = it.getRight(); + final String label = categories.get(id); + if ((label != null)) { + existingNodes.put(id, label); + resultLinks.addAll(this.collectCategoriesAndLinks(categories, links, (id).intValue(), existingNodes)); + resultLinks.put(Integer.valueOf(parentId), id); + } else { + System.err.println(("Missing child category id " + id)); + } + } + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + }; + links.getTuples().forEach(_function); + return resultLinks; + } +} diff --git a/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..080aa914f8d0a5cd647253d5c9964dd46cd32229 --- /dev/null +++ b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java @@ -0,0 +1,193 @@ +/** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.oceandsl.rqda.log.generator.json; + +import java.util.List; +import java.util.Map; +import org.eclipse.xtend2.lib.StringConcatenation; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.Functions.Function1; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.eclipse.xtext.xbase.lib.ListExtensions; +import org.oceandsl.rqda.log.DatabaseUtils; +import org.oceandsl.rqda.log.Tuple; +import org.oceandsl.rqda.log.generator.IGenerator; + +/** + * @author Reiner Jung + * + * @since 1.0 + */ +@SuppressWarnings("all") +public class JsonGenerator implements IGenerator { + @Override + public CharSequence generateAggregatedCodes(final DatabaseUtils databaseAccess) { + StringConcatenation _builder = new StringConcatenation(); + return _builder; + } + + @Override + public CharSequence generateAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) { + StringConcatenation _builder = new StringConcatenation(); + CharSequence _createNodes = this.createNodes(databaseAccess, plotCodes); + _builder.append(_createNodes); + _builder.newLineIfNotEmpty(); + CharSequence _createEdges = this.createEdges(databaseAccess, plotCodes); + _builder.append(_createEdges); + _builder.newLineIfNotEmpty(); + return _builder; + } + + @Override + public CharSequence generateThemeMap(final DatabaseUtils database, final boolean plotCodes, final String category) { + StringConcatenation _builder = new StringConcatenation(); + return _builder; + } + + private CharSequence createNodes(final DatabaseUtils databaseAccess, final boolean plotCodes) { + try { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("nodes: ["); + _builder.newLine(); + _builder.append("\t"); + final Function1<Map.Entry<Integer, String>, CharSequence> _function = (Map.Entry<Integer, String> it) -> { + return this.createNode((it.getKey()).intValue(), it.getValue(), this.getCategoryShape(it), this.getCategoryColor(it)); + }; + String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(databaseAccess.getCategories().entrySet(), _function), ",\n"); + _builder.append(_join, "\t"); + _builder.append(","); + _builder.newLineIfNotEmpty(); + _builder.append("\t"); + final Function1<Map.Entry<Integer, String>, CharSequence> _function_1 = (Map.Entry<Integer, String> it) -> { + Integer _key = it.getKey(); + int _plus = ((_key).intValue() + 1000); + return this.createNode(_plus, it.getValue(), this.getCodeShape(it), this.getCodeColor(it)); + }; + String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(databaseAccess.getCodes().entrySet(), _function_1), ",\n"); + _builder.append(_join_1, "\t"); + _builder.newLineIfNotEmpty(); + _builder.append("]"); + _builder.newLine(); + return _builder; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + private String getCategoryShape(final Map.Entry<Integer, String> entry) { + return EShapes.BOX.label; + } + + private String getCategoryColor(final Map.Entry<Integer, String> entry) { + boolean _startsWith = entry.getValue().startsWith("Theme"); + if (_startsWith) { + return "yellow"; + } else { + return "lightblue"; + } + } + + private String getCodeShape(final Map.Entry<Integer, String> entry) { + return EShapes.ELLIPSE.label; + } + + private String getCodeColor(final Map.Entry<Integer, String> entry) { + return "white"; + } + + private CharSequence createNode(final int id, final String name, final String shape, final String color) { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("{ id: "); + _builder.append(id); + _builder.append(", label: \""); + _builder.append(name); + _builder.append("\", shape: \""); + _builder.append(shape); + _builder.append("\", color: { background: \""); + _builder.append(color); + _builder.append("\" border: \"black\"} }"); + return _builder; + } + + private CharSequence createEdges(final DatabaseUtils databaseAccess, final boolean plotCodes) { + try { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("edges: ["); + _builder.newLine(); + _builder.append("\t"); + final Function1<Tuple<Integer, Integer>, CharSequence> _function = (Tuple<Integer, Integer> it) -> { + return this.createLink(it.getLeft(), it.getRight()); + }; + String _join = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, CharSequence>map(databaseAccess.getLinks().getTuples(), _function), ",\n"); + _builder.append(_join, "\t"); + _builder.append(","); + _builder.newLineIfNotEmpty(); + _builder.append("\t"); + final Function1<Map.Entry<Integer, String>, Boolean> _function_1 = (Map.Entry<Integer, String> it) -> { + try { + boolean _isEmpty = databaseAccess.getCodesForCategory(it.getValue()).isEmpty(); + return Boolean.valueOf((!_isEmpty)); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + }; + final Function1<Map.Entry<Integer, String>, String> _function_2 = (Map.Entry<Integer, String> it) -> { + return this.createCategoryCodeLinks(databaseAccess, it); + }; + String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(IterableExtensions.<Map.Entry<Integer, String>>filter(databaseAccess.getCategories().entrySet(), _function_1), _function_2), ",\n"); + _builder.append(_join_1, "\t"); + _builder.newLineIfNotEmpty(); + _builder.append("]"); + _builder.newLine(); + return _builder; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + private String createCategoryCodeLinks(final DatabaseUtils databaseAccess, final Map.Entry<Integer, String> category) { + try { + String _xblockexpression = null; + { + final Map<Integer, String> codes = databaseAccess.getCodes(); + final List<String> categoryCodes = databaseAccess.getCodesForCategory(category.getValue()); + final Function1<String, CharSequence> _function = (String catCode) -> { + Integer _key = category.getKey(); + final Function1<Map.Entry<Integer, String>, Boolean> _function_1 = (Map.Entry<Integer, String> code) -> { + return Boolean.valueOf(catCode.equals(code.getValue())); + }; + Integer _key_1 = IterableExtensions.<Map.Entry<Integer, String>>findFirst(codes.entrySet(), _function_1).getKey(); + int _plus = ((_key_1).intValue() + 1000); + return this.createLink(_key, Integer.valueOf(_plus)); + }; + _xblockexpression = IterableExtensions.join(ListExtensions.<String, CharSequence>map(categoryCodes, _function), ",\n"); + } + return _xblockexpression; + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + private CharSequence createLink(final Integer left, final Integer right) { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("{ from: "); + _builder.append(left); + _builder.append(", to: "); + _builder.append(right); + _builder.append(" }"); + return _builder; + } +}