From 9f7eb593f59855e5e7ff6f19fb9585aa8b87d1ed Mon Sep 17 00:00:00 2001 From: Matija Obreza Date: Fri, 29 Jun 2018 15:15:24 +0200 Subject: [PATCH] Open Ms Access as a file source --- anno-gui/pom.xml | 2 +- .../java/org/genesys2/anno/gui/AppWindow.java | 11 +- .../org/genesys2/anno/gui/SpringConfig.java | 2 + .../anno/parser/MsAccessDataSourceParser.java | 109 ++++++++++++++++++ .../anno/parser/MsAccessRowReader.java | 97 ++++++++++++++++ 5 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessDataSourceParser.java create mode 100644 anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessRowReader.java diff --git a/anno-gui/pom.xml b/anno-gui/pom.xml index 3df132d..8ae07ee 100644 --- a/anno-gui/pom.xml +++ b/anno-gui/pom.xml @@ -164,7 +164,7 @@ com.healthmarketscience.jackcess jackcess - 2.1.4 + 2.1.6 org.hsqldb diff --git a/anno-gui/src/main/java/org/genesys2/anno/gui/AppWindow.java b/anno-gui/src/main/java/org/genesys2/anno/gui/AppWindow.java index b530c88..9512c6e 100644 --- a/anno-gui/src/main/java/org/genesys2/anno/gui/AppWindow.java +++ b/anno-gui/src/main/java/org/genesys2/anno/gui/AppWindow.java @@ -316,13 +316,6 @@ public class AppWindow { threadPool.shutdown(); } - public static boolean isMac() { - if (System.getProperty("os.name").equals("Mac OS X")) { - return true; - } - return false; - } - /** * Create contents of the window. */ @@ -833,8 +826,8 @@ public class AppWindow { public void addSourceFile() { FileDialog fd = new FileDialog(shlGenesysMagic, SWT.MULTI); - fd.setFilterNames(new String[] { "Supported source files", "Excel files", "CSV files" }); - fd.setFilterExtensions(new String[] { "*.xlsx;*.xls;*.csv;*.tab", "*.xlsx;*.xls", "*.csv;*.tab" }); + fd.setFilterNames(new String[] { "Supported source files", "Excel files", "CSV files", "MS Access" }); + fd.setFilterExtensions(new String[] { "*.xlsx;*.xls;*.csv;*.tab;*.accdb", "*.xlsx;*.xls", "*.csv;*.tab", "*.accdb" }); String response = fd.open(); if (response != null) { diff --git a/anno-gui/src/main/java/org/genesys2/anno/gui/SpringConfig.java b/anno-gui/src/main/java/org/genesys2/anno/gui/SpringConfig.java index 9528842..cd0c71e 100644 --- a/anno-gui/src/main/java/org/genesys2/anno/gui/SpringConfig.java +++ b/anno-gui/src/main/java/org/genesys2/anno/gui/SpringConfig.java @@ -30,6 +30,7 @@ import org.genesys2.anno.model.JdbcDrivers; import org.genesys2.anno.model.OAuthSettings; import org.genesys2.anno.model.Settings; import org.genesys2.anno.parser.CsvDataSourceParser; +import org.genesys2.anno.parser.MsAccessDataSourceParser; import org.genesys2.anno.parser.XlsxDataSourceParser; import org.genesys2.anno.reader.JDBCRowReader; import org.genesys2.anno.util.ConnectionUtils; @@ -65,6 +66,7 @@ public class SpringConfig { DataSourceLoaderImpl dataSourceLoader = new DataSourceLoaderImpl(); dataSourceLoader.registerParser(new XlsxDataSourceParser()); dataSourceLoader.registerParser(new CsvDataSourceParser()); + dataSourceLoader.registerParser(new MsAccessDataSourceParser()); return dataSourceLoader; } diff --git a/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessDataSourceParser.java b/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessDataSourceParser.java new file mode 100644 index 0000000..b92ba9b --- /dev/null +++ b/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessDataSourceParser.java @@ -0,0 +1,109 @@ +/* + * Copyright 2018 Global Crop Diversity Trust + * + * 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.genesys2.anno.parser; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.genesys2.anno.gui.DataSourceSheet; +import org.genesys2.anno.gui.IDataSourceSheet; +import org.genesys2.anno.gui.UnsupportedDataFormatException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.healthmarketscience.jackcess.Cursor; +import com.healthmarketscience.jackcess.Database; +import com.healthmarketscience.jackcess.DatabaseBuilder; +import com.healthmarketscience.jackcess.Row; +import com.healthmarketscience.jackcess.Table; + +/** + * The MsAccess DataSourceParser. + * + * @author Matija Obreza + */ +public class MsAccessDataSourceParser extends BasicDataSourceParser { + private static final Logger _log = LoggerFactory.getLogger(MsAccessDataSourceParser.class); + + private final String[] supportedExtensions = new String[] { ".accdb" }; + + @Override + public String[] getSupportedExtensions() { + return supportedExtensions; + } + + @Override + public Collection findSheets(File sourceFile) throws UnsupportedDataFormatException { + try { + try (Database db = DatabaseBuilder.open(sourceFile)) { + _log.debug("CHARSET: " + db.getCharset()); + db.getTableNames().stream().forEach(tableName -> System.out.println("Table: " + tableName)); + return db.getTableNames().stream().sorted().map(tableName -> { + DataSourceSheet sheetDataSource = new DataSourceSheet(sourceFile); + sheetDataSource.setSheetName(tableName); + _log.debug("Creating sheet for table {}", tableName); + return sheetDataSource; + }).collect(Collectors.toList()); + } + } catch (Throwable e) { + throw new UnsupportedDataFormatException(e.getMessage(), e); + } + } + + @Override + public List loadRows(IDataSourceSheet dataSourceSheet, int maxRows, int startAt) throws UnsupportedDataFormatException, FileNotFoundException, IOException { + File sourceFile = dataSourceSheet.getSourceFile(); + String sheetName = dataSourceSheet.getSheetName(); + + _log.debug("Reading {} from {}", sheetName, sourceFile); + + List rows = new ArrayList(maxRows); + + try { + try (Database db = DatabaseBuilder.open(sourceFile)) { + _log.debug("CHARSET: " + db.getCharset()); + Table table = db.getTable(sheetName); + rows.add(table.getColumns().stream().map(column -> column.getName()).toArray()); + + Cursor cursor = table.getDefaultCursor(); + cursor.moveNextRows(startAt); + for (int pos = maxRows; pos > 0; pos--) { + Row r = cursor.getNextRow(); + if (r != null) { + rows.add(r.values().toArray()); + } + } + } + return rows; + } catch (Throwable e) { + throw new UnsupportedDataFormatException(e.getMessage(), e); + } + } + + @Override + public RowReader createRowReader(IDataSourceSheet dataSourceSheet) throws UnsupportedDataFormatException, IOException { + File sourceFile = dataSourceSheet.getSourceFile(); + String sheetName = dataSourceSheet.getSheetName(); + + return new MsAccessRowReader(sourceFile, sheetName); + } + +} diff --git a/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessRowReader.java b/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessRowReader.java new file mode 100644 index 0000000..328dea8 --- /dev/null +++ b/anno-gui/src/main/java/org/genesys2/anno/parser/MsAccessRowReader.java @@ -0,0 +1,97 @@ +/* + * Copyright 2018 Global Crop Diversity Trust + * + * 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.genesys2.anno.parser; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.healthmarketscience.jackcess.Cursor; +import com.healthmarketscience.jackcess.Database; +import com.healthmarketscience.jackcess.DatabaseBuilder; +import com.healthmarketscience.jackcess.Row; +import com.healthmarketscience.jackcess.Table; + +/** + * The Ms Access RowReader. + * + * @author Matija Obreza + */ +public class MsAccessRowReader implements RowReader { + private static final Logger _log = LoggerFactory.getLogger(MsAccessRowReader.class); + private Database db; + private Table table; + private Cursor cursor; + + /** + * Instantiates a new ms access row reader. + * + * @param sourceFile + * the source file + * @param sheetName + * the sheet name + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public MsAccessRowReader(File sourceFile, String sheetName) throws IOException { + this.db = DatabaseBuilder.open(sourceFile); + _log.debug("CHARSET: " + db.getCharset()); + this.table = db.getTable(sheetName); + this.cursor = table.getDefaultCursor(); + + } + + /// This is called in case data starts beyond 1st row + @Override + public void setSkipRows(int skipRows) { + _log.info("Skipping rows {}", skipRows); + cursor.reset(); + + // try { + // cursor.moveNextRows(skipRows); + // } catch (IOException e) { + // _log.error("Could not skip rows", e); + // } + } + + @Override + public int getRowCount() { + return table.getRowCount(); + } + + @Override + public void close() throws IOException { + db.close(); + } + + @Override + public List readRows(int rowsToRead) throws IOException { + List rows = new ArrayList(rowsToRead); + int rowCount = 0; + while ((rowCount < rowsToRead) && cursor.moveToNextRow()) { + rowCount++; + Row r = cursor.getCurrentRow(); + if (r != null) { + rows.add(r.values().toArray()); + } + } + return rows; + } +} -- GitLab