package com.opendoorlogistics.studio.appframe; import java.io.File; import java.util.concurrent.Callable; import com.opendoorlogistics.api.ExecutionReport; import com.opendoorlogistics.api.components.ProcessingApi; import com.opendoorlogistics.api.io.ImportFileType; import com.opendoorlogistics.api.tables.DatastoreManagerPlugin.DatastoreManagerPluginState; import com.opendoorlogistics.api.tables.ODLDatastoreAlterable; import com.opendoorlogistics.api.tables.ODLDatastoreUndoable; import com.opendoorlogistics.api.tables.ODLTableAlterable; import com.opendoorlogistics.api.tables.ODLTableReadOnly; import com.opendoorlogistics.core.scripts.execution.ExecutionReportImpl; import com.opendoorlogistics.core.tables.decorators.datastores.undoredo.UndoRedoDecorator; import com.opendoorlogistics.core.tables.io.PoiIO; import com.opendoorlogistics.core.tables.io.TableIOUtils; import com.opendoorlogistics.core.tables.utils.TableUtils; import com.opendoorlogistics.core.utils.ui.ExecutionReportDialog; import com.opendoorlogistics.studio.PreferencesManager; import com.opendoorlogistics.studio.PreferencesManager.PrefKey; import com.opendoorlogistics.studio.dialogs.ProgressDialog; import com.opendoorlogistics.studio.dialogs.ProgressDialog.OnFinishedSwingThreadCB; import com.opendoorlogistics.studio.panels.ProgressPanel; public class DatastoreLoader { enum LoadType { NDP, OPEN_EXCEL, IMPORT } private final LoadType loadType; private final AppFrame appFrame; private final ExecutionReport report = new ExecutionReportImpl(); private final File file; private final NewDatastoreProvider ndp; private final ImportFileType importOption; private final boolean hadDsOnStart; private DatastoreManagerPluginState datastoreMgrPluginState; private DatastoreLoader(AppFrame appFrame, LoadType loadType, File file, NewDatastoreProvider ndp, ImportFileType importOption) { this.appFrame = appFrame; this.loadType = loadType; this.file = file; this.ndp = ndp; this.importOption = importOption; this.hadDsOnStart = appFrame.getLoadedDatastore()!=null; } public static void loadExcel(AppFrame appFrame, File file) { new DatastoreLoader(appFrame, LoadType.OPEN_EXCEL, file, null,null).run("Loading " + file, "Loading file, please wait."); } public static void importFile(AppFrame appFrame, File file,ImportFileType option) { new DatastoreLoader(appFrame, LoadType.IMPORT, file, null,option).run("Importing " + file, "Importing file, please wait."); } public static void useNewDatastoreProvider(AppFrame appFrame, NewDatastoreProvider ndp) { new DatastoreLoader(appFrame, LoadType.NDP, null, ndp,null).run("Creating new datastore", "Creating new datastore, please wait."); } private void run(String title, String progressMessage) { ProgressDialog<ODLDatastoreUndoable<? extends ODLTableAlterable>> pd = new ProgressDialog<>(appFrame, title, false, true); pd.setLocationRelativeTo(appFrame); pd.setText("Loading file, please wait."); pd.start(new Callable<ODLDatastoreUndoable<? extends ODLTableAlterable>>() { @Override public ODLDatastoreUndoable<? extends ODLTableAlterable> call() throws Exception { ProcessingApi papi = ProgressPanel.createProcessingApi(appFrame.getApi(), pd); ODLDatastoreAlterable<? extends ODLTableAlterable> rawResult= loadFileInternal(papi); ODLDatastoreUndoable<? extends ODLTableAlterable> processed = postProcessNewDatastore(rawResult, papi); return processed; } }, new OnFinishedSwingThreadCB<ODLDatastoreUndoable<? extends ODLTableAlterable>>() { @Override public void onFinished(ODLDatastoreUndoable<? extends ODLTableAlterable> result, boolean userCancelled, boolean userFinishedNow) { switch (loadType) { case OPEN_EXCEL: finishOpenExcelOnEDT(result); break; case NDP: finishNDPOnEDT(result); break; case IMPORT: finishImportOnEDT(result); break; default: throw new IllegalArgumentException(); }; return; } }); } private ODLDatastoreAlterable<? extends ODLTableAlterable> loadFileInternal(ProcessingApi papi) { try { switch (loadType) { case OPEN_EXCEL: return PoiIO.importExcel(file, papi, report); case NDP: return ndp.create(papi.getApi()); case IMPORT: return TableIOUtils.importFile(file, importOption,papi,report); default: throw new IllegalArgumentException(); } } catch (Throwable e) { report.setFailed(e); return null; } } private void finishImportOnEDT(ODLDatastoreUndoable<? extends ODLTableAlterable> result){ if(result==null){ report.setFailed("Failed to import file: " + file.getAbsolutePath()); } if(!report.isFailed()){ // try to add to main datastore if we have one... if(appFrame.getLoadedDatastore()!=null){ if (!TableUtils.addDatastores(appFrame.getLoadedDatastore().getDs(), result, true)) { report.setFailed("Failed to add imported file to open datastore."); } } else{ // set as datastore appFrame.setDecoratedDatastore(result,datastoreMgrPluginState, null); } } // log info... if(!report.isFailed()){ for (int i = 0; i < result.getTableCount(); i++) { ODLTableReadOnly table = result.getTableAt(i); report.log("Imported table \"" + table.getName() + "\" with " + table.getRowCount() + " rows and " + table.getColumnCount() + " columns."); } report.log("Imported " + result.getTableCount() + " tables."); } ExecutionReportDialog.show(appFrame, "Import result", report); } private void finishOpenExcelOnEDT(ODLDatastoreUndoable<? extends ODLTableAlterable> result){ if(result==null){ report.setFailed("Could not open file " + file.getAbsolutePath()); } if(!report.isFailed()){ appFrame.setDecoratedDatastore(result,datastoreMgrPluginState, file); PreferencesManager.getSingleton().addRecentFile(file); PreferencesManager.getSingleton().setDirectory(PrefKey.LAST_IO_DIR, file); if(report.size()>0){ ExecutionReportDialog.show(appFrame, "Warning when opening file", report); } }else{ ExecutionReportDialog.show(appFrame, "Error opening file", report); } } private void finishNDPOnEDT(ODLDatastoreUndoable<? extends ODLTableAlterable> result){ if(result==null){ report.setFailed("Failed to create new datastore."); } if(!report.isFailed()){ appFrame.setDecoratedDatastore(result,datastoreMgrPluginState, null); if(report.size()>0){ ExecutionReportDialog.show(appFrame, "Warning when creating datastore", report); } }else{ ExecutionReportDialog.show(appFrame, "Error creating datastore", report); } } private ODLDatastoreUndoable<? extends ODLTableAlterable> postProcessNewDatastore(ODLDatastoreAlterable<? extends ODLTableAlterable> ds, ProcessingApi papi) { try{ // Are we completely replacing the DS (in which case we need to decorate it with extra functionality), // or just importing into an existing DS (so no need to decorated again)? boolean replacingDs = !(loadType == LoadType.IMPORT && hadDsOnStart); ODLDatastoreUndoable<? extends ODLTableAlterable> ret=null; if(replacingDs){ DatastoreManagerPluginState [] tmpArr = new DatastoreManagerPluginState[1]; ret =appFrame.decorateNewDatastore(ds, file, papi,tmpArr, report); datastoreMgrPluginState = tmpArr[0]; }else{ // just wrap in the undo / redo so we have the correct return type ret = new UndoRedoDecorator<ODLTableAlterable>(ODLTableAlterable.class, ds); } return ret; }catch(Exception e){ report.setFailed(e); } return null; } }