diff --git a/.classpath b/.classpath index e212377..ae0ca56 100644 --- a/.classpath +++ b/.classpath @@ -25,5 +25,6 @@ + diff --git a/lib/jOpenDocument-1.3.jar b/lib/jOpenDocument-1.3.jar new file mode 100644 index 0000000..dfa77d2 Binary files /dev/null and b/lib/jOpenDocument-1.3.jar differ diff --git a/lib/jOpenDocument-src-1.3.zip b/lib/jOpenDocument-src-1.3.zip new file mode 100644 index 0000000..949f80f Binary files /dev/null and b/lib/jOpenDocument-src-1.3.zip differ diff --git a/src/fr/devinsy/statoolinfos/htmlize/ExportsPage.java b/src/fr/devinsy/statoolinfos/htmlize/ExportsPage.java index bf0e0c2..23018d1 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/ExportsPage.java +++ b/src/fr/devinsy/statoolinfos/htmlize/ExportsPage.java @@ -19,9 +19,7 @@ package fr.devinsy.statoolinfos.htmlize; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import org.apache.commons.io.FileUtils; @@ -33,6 +31,7 @@ import fr.devinsy.statoolinfos.core.Federation; import fr.devinsy.statoolinfos.core.StatoolInfosException; import fr.devinsy.statoolinfos.io.CSVFile; import fr.devinsy.statoolinfos.io.JSONFile; +import fr.devinsy.statoolinfos.io.ODSFile; import fr.devinsy.xidyn.XidynException; import fr.devinsy.xidyn.presenters.PresenterUtils; @@ -63,7 +62,7 @@ public class ExportsPage CSVFile.save(new File(htmlizeDirectory, "organizations.csv"), federation.getOrganizations()); CSVFile.save(new File(htmlizeDirectory, "services.csv"), federation.getAllServices()); } - catch (UnsupportedEncodingException | FileNotFoundException exception) + catch (IOException exception) { logger.error("Error during CSV export: " + exception.getMessage(), exception); } @@ -76,17 +75,22 @@ public class ExportsPage JSONFile.save(new File(htmlizeDirectory, "organizations.json"), federation.getOrganizations()); JSONFile.save(new File(htmlizeDirectory, "services.json"), federation.getAllServices()); } - catch (UnsupportedEncodingException | FileNotFoundException exception) + catch (IOException exception) { logger.error("Error during JSON export: " + exception.getMessage(), exception); } // - logger.info("EXPORTS ODS."); - // ODSFile.save(new File(htmlizeDirectory, "organizations.ods"), - // federation.getOrganizations()); - // ODSFile.save(new File(htmlizeDirectory, "services.ods"), - // federation.getAllServices()); + try + { + logger.info("EXPORTS ODS."); + ODSFile.save(new File(htmlizeDirectory, "organizations.ods"), federation.getOrganizations()); + ODSFile.save(new File(htmlizeDirectory, "services.ods"), federation.getAllServices()); + } + catch (Exception exception) + { + logger.error("Error during JSON export: " + exception.getMessage(), exception); + } // try diff --git a/src/fr/devinsy/statoolinfos/io/CSVFile.java b/src/fr/devinsy/statoolinfos/io/CSVFile.java index 9e0ba71..388358d 100644 --- a/src/fr/devinsy/statoolinfos/io/CSVFile.java +++ b/src/fr/devinsy/statoolinfos/io/CSVFile.java @@ -19,15 +19,9 @@ package fr.devinsy.statoolinfos.io; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; +import java.io.IOException; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.text.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,23 +46,6 @@ public class CSVFile public static final int MAX_LINE_SIZE = 4096; public static final String SEPARATOR = ";"; - /** - * Escape. - * - * @param string - * the string - * @return the string - */ - public static String escape(final String string) - { - String result; - - result = StringEscapeUtils.escapeCsv(string); - - // - return result; - } - /** * Save. * @@ -76,23 +53,20 @@ public class CSVFile * the file * @param source * the source - * @throws UnsupportedEncodingException - * the unsupported encoding exception - * @throws FileNotFoundException - * the file not found exception + * @throws IOException */ - public static void save(final File file, final Organizations source) throws UnsupportedEncodingException, FileNotFoundException + public static void save(final File file, final Organizations source) throws IOException { - PrintWriter out = null; + CSVWriter out = null; try { - out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); + out = new CSVWriter(file, ';'); write(out, source); } finally { - IOUtils.closeQuietly(out); + out.close(); } } @@ -103,23 +77,20 @@ public class CSVFile * the file * @param source * the source - * @throws UnsupportedEncodingException - * the unsupported encoding exception - * @throws FileNotFoundException - * the file not found exception + * @throws IOException + * Signals that an I/O exception has occurred. */ - public static void save(final File file, final Services source) throws UnsupportedEncodingException, FileNotFoundException + public static void save(final File file, final Services source) throws IOException { - PrintWriter out = null; + CSVWriter out = null; try { - out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); - + out = new CSVWriter(file, ';'); write(out, source); } finally { - IOUtils.closeQuietly(out); + out.close(); } } @@ -130,8 +101,9 @@ public class CSVFile * the out * @param source * the source + * @throws IOException */ - public static void write(final PrintWriter out, final Organizations organizations) + public static void write(final SpreadsheetWriter out, final Organizations organizations) throws IOException { // Build label list. StringList labels = new StringList(100); @@ -154,25 +126,21 @@ public class CSVFile dejavu.clear(); // Write label line. - StringList line = new StringList(); for (String label : labels) { - line.append(escape(label)).append(SEPARATOR); + out.writeCell(label); } - line.removeLast(); - out.println(line.toString()); + out.writeEndRow(); // Write organization lines. for (Organization organization : organizations) { - line = new StringList(100); for (String label : labels) { String value = organization.get(label); - line.append(escape(value)).append(SEPARATOR); + out.writeCell(value); } - line.removeLast(); - out.println(line.toString()); + out.writeEndRow(); } } @@ -183,8 +151,9 @@ public class CSVFile * the out * @param source * the source + * @throws IOException */ - public static void write(final PrintWriter out, final Services services) + public static void write(final SpreadsheetWriter out, final Services services) throws IOException { // Build label list. StringList labels = new StringList(100); @@ -211,20 +180,17 @@ public class CSVFile labels.add(index, "software.categories"); // Write label line. - StringList line = new StringList(); for (String label : labels) { - line.append(escape(label)).append(SEPARATOR); + out.writeCell(label); } - line.removeLast(); - out.println(line.toString()); + out.writeEndRow(); Categories categories = HtmlizerContext.instance().getCategories(); // Write service lines. for (Service service : services) { - line = new StringList(100); for (String label : labels) { String value; @@ -241,10 +207,9 @@ public class CSVFile value = service.get(label); } - line.append(escape(value)).append(SEPARATOR); + out.writeCell(value); } - line.removeLast(); - out.println(line.toString()); + out.writeEndRow(); } } } diff --git a/src/fr/devinsy/statoolinfos/io/CSVWriter.java b/src/fr/devinsy/statoolinfos/io/CSVWriter.java new file mode 100644 index 0000000..25d4544 --- /dev/null +++ b/src/fr/devinsy/statoolinfos/io/CSVWriter.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of StatoolInfos, simple service statistics tool. + * + * StatoolInfos is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * StatoolInfos is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with StatoolInfos. If not, see . + */ +package fr.devinsy.statoolinfos.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class CSVWriter. + */ +public class CSVWriter implements SpreadsheetWriter +{ + private static final Logger logger = LoggerFactory.getLogger(CSVWriter.class); + + private char separator; + private PrintWriter out; + private boolean isNewline; + + /** + * Instantiates a new CSV writer. + * + * @param file + * the file + * @param separator + * the separator + * @throws UnsupportedEncodingException + * the unsupported encoding exception + * @throws FileNotFoundException + * the file not found exception + */ + public CSVWriter(final File file, final char separator) throws UnsupportedEncodingException, FileNotFoundException + { + this.separator = separator; + this.out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); + this.isNewline = true; + } + + /** + * Close. + * + * @throws FileNotFoundException + * + * @throws IOException + * Signals that an I/O exception has occurred. + */ + @Override + public void close() throws FileNotFoundException, IOException + { + IOUtils.closeQuietly(this.out); + } + + /** + * Escape. + * + * @param string + * the string + * @return the string + */ + private String escape(final String string) + { + String result; + + if (string == null) + { + result = null; + } + else + { + if (StringUtils.containsAny(string, ',', '\n', '"', this.separator)) + { + result = String.format("\"%s\"", string); + } + else + { + result = string; + } + } + + // + return result; + } + + /** + * Write cell. + * + * @param content + * the content + */ + @Override + public void writeCell(final String content) + { + if (this.isNewline) + { + this.isNewline = false; + } + else + { + this.out.print(this.separator); + } + this.out.print(StringUtils.defaultIfBlank(escape(content), "")); + } + + /** + * Write endpage. + */ + @Override + public void writeEndpage() + { + this.out.println(); + } + + /** + * Write end row. + * + * @throws IOException + */ + @Override + public void writeEndRow() + { + this.out.println(); + this.isNewline = true; + } +} diff --git a/src/fr/devinsy/statoolinfos/io/ODSFile.java b/src/fr/devinsy/statoolinfos/io/ODSFile.java new file mode 100644 index 0000000..6366a10 --- /dev/null +++ b/src/fr/devinsy/statoolinfos/io/ODSFile.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of StatoolInfos, simple service statistics tool. + * + * StatoolInfos is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * StatoolInfos is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with StatoolInfos. If not, see . + */ +package fr.devinsy.statoolinfos.io; + +import java.io.File; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fr.devinsy.statoolinfos.core.Organizations; +import fr.devinsy.statoolinfos.core.Services; + +/** + * The Class ODSFile. + */ +public class ODSFile +{ + public static final int MAX_LINE_SIZE = 1024; + + private static final Logger logger = LoggerFactory.getLogger(ODSFile.class);; + + protected enum Status + { + MANDATORY, + OPTIONAL + } + + /** + * Save. + * + * @param file + * the file + * @param source + * the source + */ + public static void save(final File file, final Organizations source) throws IOException + { + ODSWriter out = null; + try + { + out = new ODSWriter(file); + CSVFile.write(out, source); + } + finally + { + out.close(); + } + } + + /** + * Save. + * + * @param file + * the file + * @param source + * the source + */ + public static void save(final File file, final Services source) throws IOException + { + ODSWriter out = null; + try + { + out = new ODSWriter(file); + CSVFile.write(out, source); + } + finally + { + out.close(); + } + } +} diff --git a/src/fr/devinsy/statoolinfos/io/ODSWriter.java b/src/fr/devinsy/statoolinfos/io/ODSWriter.java new file mode 100644 index 0000000..d7ee475 --- /dev/null +++ b/src/fr/devinsy/statoolinfos/io/ODSWriter.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of StatoolInfos, simple service statistics tool. + * + * StatoolInfos is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * StatoolInfos is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with StatoolInfos. If not, see . + */ +package fr.devinsy.statoolinfos.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import javax.swing.table.DefaultTableModel; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.jopendocument.dom.spreadsheet.Sheet; +import org.jopendocument.dom.spreadsheet.SpreadSheet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class ODSWriter. + */ +public class ODSWriter implements SpreadsheetWriter +{ + private static final Logger logger = LoggerFactory.getLogger(ODSWriter.class); + + private File file; + private SpreadSheet workbook; + private Sheet currentSheet; + private int currentSheetIndex; + private int currentRow; + private int currentColumn; + + /** + * Instantiates a new ODS writer. + * + * @param file + * the file + */ + public ODSWriter(final File file) + { + this.file = file; + this.workbook = SpreadSheet.createEmpty(new DefaultTableModel()); + + this.workbook.getSheet(0).setName(file.getName()); + + this.currentSheetIndex = 0; + this.currentSheet = this.workbook.getSheet(this.currentSheetIndex); + this.currentRow = 0; + this.currentColumn = 0; + } + + /** + * Close. + * + * @throws IOException + * + * @throws FileNotFoundException + */ + @Override + public void close() throws FileNotFoundException, IOException + { + this.workbook.saveAs(this.file); + } + + /** + * Write cell. + * + * @param content + * the content + */ + @Override + public void writeCell(final String content) + { + this.currentSheet.ensureColumnCount(this.currentColumn + 1); + this.currentSheet.ensureRowCount(this.currentRow + 1); + + if (NumberUtils.isCreatable(content)) + { + this.currentSheet.getCellAt(this.currentColumn, this.currentRow).setValue(Double.valueOf(content)); + } + else + { + this.currentSheet.getCellAt(this.currentColumn, this.currentRow).setValue(StringUtils.defaultIfBlank(content, "")); + } + + this.currentColumn += 1; + } + + /** + * Write endpage. + */ + @Override + public void writeEndpage() + { + } + + /** + * Write end row. + */ + @Override + public void writeEndRow() + { + this.currentRow += 1; + this.currentColumn = 0; + } +} diff --git a/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java b/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java new file mode 100644 index 0000000..6bd6332 --- /dev/null +++ b/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of StatoolInfos, simple service statistics tool. + * + * StatoolInfos is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * StatoolInfos is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with StatoolInfos. If not, see . + */ +package fr.devinsy.statoolinfos.io; + +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * The Interface SpreadsheetWriter. + */ +public interface SpreadsheetWriter +{ + void close() throws FileNotFoundException, IOException; + + void writeCell(String content); + + void writeEndpage(); + + void writeEndRow(); +}