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.FileOutputStream;
029import java.io.IOException;
030import java.io.OutputStreamWriter;
031import java.util.Map;
032
033import conexp.fx.core.context.MatrixContext;
034import conexp.fx.core.layout.AdditiveConceptLayout;
035
036public class HTMLExporter<G, M> {
037
038  public static <G, M> void export(
039      MatrixContext<G, M> context,
040      Map<Integer, Integer> domainPermutation,
041      Map<Integer, Integer> codomainPermutation,
042      AdditiveConceptLayout<G, M> layout,
043      boolean exportArrows,
044      boolean exportLabels,
045      File file) {
046    try {
047      if (!file.exists()) {
048        if (!file.getParentFile().exists())
049          file.mkdirs();
050        file.createNewFile();
051      }
052      BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
053      StringBuffer buffer =
054          toStringBuffer(
055              file.getName(),
056              context,
057              domainPermutation,
058              codomainPermutation,
059              layout,
060              exportArrows,
061              exportLabels);
062      outputWriter.append(buffer);
063      outputWriter.close();
064    } catch (IOException e) {
065      e.printStackTrace();
066    }
067  }
068
069  private static <G, M> StringBuffer toStringBuffer(
070      String name,
071      MatrixContext<G, M> formalContext,
072      Map<Integer, Integer> domainPermutation,
073      Map<Integer, Integer> codomainPermutation,
074      AdditiveConceptLayout<G, M> layout,
075      boolean exportArrows,
076      boolean exportLabels) {
077    StringBuffer buffer = new StringBuffer();
078    buffer
079        .append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\r\n\t http://www.w3.org/TR/html4/strict.dtd\">\r\n");
080    buffer.append("<html>\r\n");
081    buffer.append("<head>\r\n");
082    buffer.append("<title>" + name + "</title>\r\n");
083    buffer.append("</head>\r\n");
084    buffer.append("<body>\r\n");
085    buffer.append("<table border=\"1\">\r\n");
086    buffer.append("<tr>\r\n");
087    buffer.append("<th></th>\r\n");
088    for (int codomainIndex = 0; codomainIndex < formalContext.colHeads().size(); codomainIndex++) {
089      int permIndex =
090          codomainPermutation == null || !codomainPermutation.containsKey(codomainIndex) ? codomainIndex
091              : codomainPermutation.get(codomainIndex);
092      final M attribute = formalContext.colHeads().get(permIndex);
093      buffer.append("<th>" + (exportLabels ? attribute : "") + "</th>\r\n");
094    }
095    buffer.append("</tr>\r\n");
096    for (int domainIndex = 0; domainIndex < formalContext.rowHeads().size(); domainIndex++) {
097      buffer.append("<tr>\r\n");
098      final int dpermIndex =
099          domainPermutation == null || !domainPermutation.containsKey(domainIndex) ? domainIndex : domainPermutation
100              .get(domainIndex);
101      final G object = formalContext.rowHeads().get(dpermIndex);
102      buffer.append("<th>" + (exportLabels ? object : "") + "</th>\r\n");
103      for (int codomainIndex = 0; codomainIndex < formalContext.colHeads().size(); codomainIndex++) {
104        int cpermIndex =
105            codomainPermutation == null || !codomainPermutation.containsKey(codomainIndex) ? codomainIndex
106                : codomainPermutation.get(codomainIndex);
107        final M attribute = formalContext.colHeads().get(cpermIndex);
108        if (formalContext.contains(object, attribute))
109          buffer.append("<td>X</td>\r\n");
110        else if (exportArrows) {
111          final boolean isDownArrow = formalContext.DownArrows.contains(object, attribute);
112          final boolean isUpArrow = formalContext.UpArrows.contains(object, attribute);
113          if (isDownArrow) {
114            if (isUpArrow)
115              buffer.append("<td>b</td>\r\n");
116            else
117              buffer.append("<td>d</td>\r\n");
118          } else {
119            if (isUpArrow)
120              buffer.append("<td>u</td>\r\n");
121            else
122              buffer.append("<td>.</td>\r\n");
123          }
124        } else
125          buffer.append("<td>.</td>\r\n");
126      }
127      buffer.append("</tr>\r\n");
128    }
129    buffer.append("</table>\r\n");
130    buffer.append("</body>\r\n");
131    buffer.append("</html>\r\n");
132    return buffer;
133  }
134}