001package conexp.fx.core.exporter;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2023 Francesco Kriegel
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025
026import java.io.BufferedWriter;
027import java.io.File;
028import java.io.FileWriter;
029import java.io.IOException;
030import java.util.Map;
031import java.util.Map.Entry;
032
033import org.jsoup.nodes.Document;
034import org.jsoup.nodes.Element;
035
036import conexp.fx.core.context.MatrixContext;
037import conexp.fx.core.layout.AdditiveConceptLayout;
038import javafx.geometry.Point3D;
039
040public class CFXExporter<G, M> {
041
042  public static <G, M> void export(
043      MatrixContext<G, M> context,
044      Map<Integer, Integer> domainPermutation,
045      Map<Integer, Integer> codomainPermutation,
046      AdditiveConceptLayout<G, M> layout,
047      File file) {
048    Document xml = new Document("");
049    final Element domainEl = xml.appendElement("domain");
050//    domainEl.attr("type", formalContext.getDomainType() == null ? "unknown" : formalContext.getDomainType().toString());
051    domainEl.attr("size", String.valueOf(context.rowHeads().size()));
052    for (int domainIndex = 0; domainIndex < context.rowHeads().size(); domainIndex++) {
053      final int permIndex =
054          domainPermutation == null || !domainPermutation.containsKey(domainIndex) ? domainIndex : domainPermutation
055              .get(domainIndex);
056      final G object = context.rowHeads().get(permIndex);
057      final Element objectEl = domainEl.appendElement("object");
058      objectEl.attr("index", String.valueOf(permIndex));
059      objectEl.attr("name", object.toString());
060      objectEl.attr("selected", "true");// String.valueOf(formalContext.getSelectedObjects().contains(object)));
061    }
062    final Element codomainEl = xml.appendElement("codomain");
063//    codomainEl.attr("type", formalContext.getCodomainType() == null ? "unknown" : formalContext
064//        .getCodomainType()
065//        .toString());
066    codomainEl.attr("size", String.valueOf(context.colHeads().size()));
067    for (int codomainIndex = 0; codomainIndex < context.colHeads().size(); codomainIndex++) {
068      int permIndex =
069          codomainPermutation == null || !codomainPermutation.containsKey(codomainIndex) ? codomainIndex
070              : codomainPermutation.get(codomainIndex);
071      final M attribute = context.colHeads().get(permIndex);
072      final Element attributeEl = codomainEl.appendElement("attribute");
073      attributeEl.attr("index", String.valueOf(permIndex));
074      attributeEl.attr("name", attribute.toString());
075      attributeEl.attr("selected", String.valueOf(context.selectedAttributes().contains(attribute)));
076    }
077    final Element contextEl = xml.appendElement("context");
078    for (int domainIndex = 0; domainIndex < context.rowHeads().size(); domainIndex++) {
079      final int dpermIndex =
080          domainPermutation == null || !domainPermutation.containsKey(domainIndex) ? domainIndex : domainPermutation
081              .get(domainIndex);
082      final G object = context.rowHeads().get(dpermIndex);
083      for (int codomainIndex = 0; codomainIndex < context.colHeads().size(); codomainIndex++) {
084        int cpermIndex =
085            codomainPermutation == null || !codomainPermutation.containsKey(codomainIndex) ? codomainIndex
086                : codomainPermutation.get(codomainIndex);
087        final M attribute = context.colHeads().get(cpermIndex);
088        if (context._contains(dpermIndex, cpermIndex)) {
089          final Element incidenceEl = contextEl.appendElement("incidence");
090          incidenceEl.attr("object", object.toString());
091          incidenceEl.attr("attribute", attribute.toString());
092        } else {
093          final boolean upArrow = context.UpArrows.contains(object, attribute);
094          final boolean downArrow = context.DownArrows.contains(object, attribute);
095          if (upArrow && downArrow) {
096            final Element arrowsEl = contextEl.appendElement("both-arrows");
097            arrowsEl.attr("object", object.toString());
098            arrowsEl.attr("attribute", attribute.toString());
099          } else if (upArrow) {
100            final Element arrowsEl = contextEl.appendElement("up-arrow");
101            arrowsEl.attr("object", object.toString());
102            arrowsEl.attr("attribute", attribute.toString());
103          } else if (downArrow) {
104            final Element arrowsEl = contextEl.appendElement("down-arrow");
105            arrowsEl.attr("object", object.toString());
106            arrowsEl.attr("attribute", attribute.toString());
107          }
108        }
109      }
110    }
111    final Element latticeEl = xml.appendElement("lattice");
112    for (Entry<M, Point3D> attributeSeed : layout.seedsM.entrySet()) {
113      final Element seedEl = latticeEl.appendElement("attribute-seed");
114      seedEl.attr("attribute", attributeSeed.getKey().toString());
115      seedEl.attr("x", String.valueOf(attributeSeed.getValue().getX()));
116      seedEl.attr("y", String.valueOf(attributeSeed.getValue().getY()));
117      seedEl.attr("z", String.valueOf(attributeSeed.getValue().getZ()));
118    }
119    try {
120      if (!file.exists()) {
121        if (!file.getParentFile().exists())
122          file.mkdirs();
123        file.createNewFile();
124      }
125      final FileWriter fileWriter = new FileWriter(file);
126      final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
127      bufferedWriter.write(xml.toString());
128      bufferedWriter.close();
129      fileWriter.close();
130    } catch (IOException e) {
131      // TODO Auto-generated catch block
132      System.err.println("Unable to write CFX-File to " + file.toString());
133      e.printStackTrace();
134    }
135  }
136}