Java tutorial
/******************************************************************************* * Copyright (C) 2005, 2016 Wolfgang Schramm and Contributors * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation version 2 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA *******************************************************************************/ package net.tourbook.importdata; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import net.tourbook.Messages; import net.tourbook.application.PerspectiveFactoryRawData; import net.tourbook.application.TourbookPlugin; import net.tourbook.common.UI; import net.tourbook.common.time.TimeTools; import net.tourbook.common.util.ITourViewer3; import net.tourbook.common.util.Util; import net.tourbook.common.widgets.ComboEnumEntry; import net.tourbook.data.TourData; import net.tourbook.data.TourPerson; import net.tourbook.data.TourTag; import net.tourbook.data.TourType; import net.tourbook.preferences.ITourbookPreferences; import net.tourbook.tour.TourEventId; import net.tourbook.tour.TourLogManager; import net.tourbook.tour.TourLogState; import net.tourbook.tour.TourLogView; import net.tourbook.tour.TourManager; import net.tourbook.ui.views.rawData.RawDataView; import net.tourbook.ui.views.tourBook.TVITourBookTour; import net.tourbook.ui.views.tourDataEditor.TourDataEditorView; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; public class RawDataManager { private static final String RAW_DATA_LAST_SELECTED_PATH = "raw-data-view.last-selected-import-path"; //$NON-NLS-1$ private static final String TEMP_IMPORTED_FILE = "received-device-data.txt"; //$NON-NLS-1$ // public static final String LOG_IMPORT_DELETE_TOUR_FILE = Messages.Log_Import_DeleteTourFiles; public static final String LOG_IMPORT_DELETE_TOUR_FILE_END = Messages.Log_Import_DeleteTourFiles_End; private static final String LOG_IMPORT_TOUR = Messages.Log_Import_Tour; public static final String LOG_IMPORT_TOUR_IMPORTED = Messages.Log_Import_Tour_Imported; private static final String LOG_IMPORT_TOUR_END = Messages.Log_Import_Tour_End; // public static final String LOG_REIMPORT_PREVIOUS_FILES = Messages.Log_Reimport_PreviousFiles; public static final String LOG_REIMPORT_END = Messages.Log_Reimport_PreviousFiles_End; // private static final String LOG_REIMPORT_ALL_TIME_SLICES = Messages.Log_Reimport_AllTimeSlices; private static final String LOG_REIMPORT_ONLY_ALTITUDE = Messages.Log_Reimport_Only_Altitude; private static final String LOG_REIMPORT_ONLY_GEAR = Messages.Log_Reimport_Only_Gear; private static final String LOG_REIMPORT_ONLY_POWER_SPEED = Messages.Log_Reimport_Only_PowerSpeed; private static final String LOG_REIMPORT_ONLY_POWER_PULSE = Messages.Log_Reimport_Only_PowerPulse; private static final String LOG_REIMPORT_ONLY_MARKER = Messages.Log_Reimport_Only_TourMarker; private static final String LOG_REIMPORT_ONLY_TEMPERATURE = Messages.Log_Reimport_Only_Temperature; private static final String LOG_REIMPORT_TOUR = Messages.Log_Reimport_Tour; // public static final int ADJUST_IMPORT_YEAR_IS_DISABLED = -1; // static final ComboEnumEntry<?>[] ALL_IMPORT_TOUR_TYPE_CONFIG; static { ALL_IMPORT_TOUR_TYPE_CONFIG = new ComboEnumEntry<?>[] { new ComboEnumEntry<>(Messages.Import_Data_TourTypeConfig_OneForAll, // TourTypeConfig.TOUR_TYPE_CONFIG_ONE_FOR_ALL), new ComboEnumEntry<>(Messages.Import_Data_TourTypeConfig_BySpeed, // TourTypeConfig.TOUR_TYPE_CONFIG_BY_SPEED) // }; } private static RawDataManager _instance = null; private final IPreferenceStore _prefStore = TourbookPlugin.getPrefStore(); /** * contains the device data imported from the device/file */ private final DeviceData _deviceData = new DeviceData(); /** * Contains tours which are imported or received and displayed in the import view. */ private final HashMap<Long, TourData> _toursInImportView = new HashMap<Long, TourData>(); /** * Contains tours which are imported from the last file name. */ private final HashMap<Long, TourData> _newlyImportedTours = new HashMap<Long, TourData>(); private String _lastImportedFileName; /** * Contains the filenames for all imported files which are displayed in the import view */ private final HashSet<String> _importedFileNames = new HashSet<String>(); /** * Contains filenames which are not directly imported but is imported from other imported files */ private final HashSet<String> _importedFileNamesChildren = new HashSet<String>(); private boolean _isImported; private boolean _isImportCanceled; // private int _importState_ImportYear = ADJUST_IMPORT_YEAR_IS_DISABLED; private static boolean _importState_IsAutoOpenImportLog = RawDataView.STATE_IS_AUTO_OPEN_IMPORT_LOG_VIEW_DEFAULT; private boolean _importState_IsConvertWayPoints = RawDataView.STATE_IS_CONVERT_WAYPOINTS_DEFAULT; private boolean _importState_IsCreateTourIdWithTime = RawDataView.STATE_IS_CREATE_TOUR_ID_WITH_TIME_DEFAULT; private boolean _importState_IsChecksumValidation = RawDataView.STATE_IS_CHECKSUM_VALIDATION_DEFAULT; private boolean _importState_IsMergeTracks = RawDataView.STATE_IS_MERGE_TRACKS_DEFAULT; private List<TourbookDevice> _devicesBySortPriority; private HashMap<String, TourbookDevice> _devicesByExtension; private final ArrayList<TourType> _tempTourTypes = new ArrayList<TourType>(); private final ArrayList<TourTag> _tempTourTags = new ArrayList<TourTag>(); /** * Filepath from the previous reimported tour */ private IPath _previousSelectedReimportFolder; /** * This is a wrapper to keep the {@link #isBackupImportFile} state. */ private class ImportFile { IPath filePath; boolean isBackupImportFile; public ImportFile(final org.eclipse.core.runtime.Path iPath) { filePath = iPath; } } public static enum ReImport { AllTimeSlices, // OnlyAltitudeValues, // OnlyGearValues, // OnlyPowerAndSpeedValues, // OnlyPowerAndPulseValues, // OnlyTourMarker, // OnlyTemperatureValues, // Tour, // } private RawDataManager() { } public static RawDataManager getInstance() { if (_instance == null) { _instance = new RawDataManager(); } return _instance; } /** * @return temp directory where received data are stored temporarily */ public static String getTempDir() { return TourbookPlugin.getDefault().getStateLocation().toFile().getAbsolutePath(); } public static boolean isAutoOpenImportLog() { return _importState_IsAutoOpenImportLog; } public void actionImportFromDevice() { final DataTransferWizardDialog dialog = new DataTransferWizardDialog(// PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), new DataTransferWizard(), Messages.Import_Wizard_Dlg_title); if (dialog.open() == Window.OK) { showRawDataView(); } } public void actionImportFromDeviceDirect() { final DataTransferWizard transferWizard = new DataTransferWizard(); final WizardDialog dialog = new DataTransferWizardDialog(// PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), transferWizard, Messages.Import_Wizard_Dlg_title); // create the dialog and shell which is required in setAutoDownload() dialog.create(); transferWizard.setAutoDownload(); if (dialog.open() == Window.OK) { showRawDataView(); } } /** * Import tours from files which are selected in a file selection dialog. */ public void actionImportFromFile() { final List<TourbookDevice> deviceList = DeviceManager.getDeviceList(); // create file filter list final int deviceLength = deviceList.size() + 1; final String[] filterExtensions = new String[deviceLength]; final String[] filterNames = new String[deviceLength]; int deviceIndex = 0; // add option to show all files filterExtensions[deviceIndex] = "*.*"; //$NON-NLS-1$ filterNames[deviceIndex] = "*.*"; //$NON-NLS-1$ deviceIndex++; // add option for every file extension for (final TourbookDevice device : deviceList) { filterExtensions[deviceIndex] = "*." + device.fileExtension; //$NON-NLS-1$ filterNames[deviceIndex] = device.visibleName + (" (*." + device.fileExtension + ")"); //$NON-NLS-1$ //$NON-NLS-2$ deviceIndex++; } final String lastSelectedPath = _prefStore.getString(RAW_DATA_LAST_SELECTED_PATH); // setup open dialog final FileDialog fileDialog = new FileDialog(Display.getDefault().getActiveShell(), (SWT.OPEN | SWT.MULTI)); fileDialog.setFilterExtensions(filterExtensions); fileDialog.setFilterNames(filterNames); fileDialog.setFilterPath(lastSelectedPath); // open file dialog final String firstFilePathName = fileDialog.open(); // check if user canceled the dialog if (firstFilePathName == null) { return; } final Path firstFilePath = Paths.get(firstFilePathName); final String filePathFolder = firstFilePath.getParent().toString(); // keep last selected path _prefStore.putValue(RAW_DATA_LAST_SELECTED_PATH, filePathFolder); final String[] selectedFileNames = fileDialog.getFileNames(); final ArrayList<OSFile> osFiles = new ArrayList<>(); for (final String fileName : selectedFileNames) { final Path filePath = Paths.get(filePathFolder, fileName); final OSFile osFile = new OSFile(filePath); osFiles.add(osFile); } if (_importState_IsAutoOpenImportLog) { TourLogManager.showLogView(); } runImport(osFiles, false, null); } /** * @param reimportId * ID how a tour is reimported. * @param tourViewer * Tour viewer where the selected tours should be reimported. */ public void actionReimportTour(final ReImport reimportId, final ITourViewer3 tourViewer) { final long start = System.currentTimeMillis(); // check if the tour editor contains a modified tour if (TourManager.isTourEditorModified()) { return; } if (actionReimportTour_10_Confirm(reimportId) == false) { return; } // prevent async error in the save tour method, cleanup environment tourViewer.getPostSelectionProvider().clearSelection(); Util.clearSelection(); TourManager.fireEvent(TourEventId.CLEAR_DISPLAYED_TOUR, null, null); // get selected tours final IStructuredSelection selectedTours = ((IStructuredSelection) tourViewer.getViewer().getSelection()); setImportId(); setImportCanceled(false); final IRunnableWithProgress importRunnable = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { boolean isReImported = false; File reimportedFile = null; int imported = 0; final int importSize = selectedTours.size(); monitor.beginTask(Messages.Import_Data_Dialog_Reimport_Task, importSize); // loop: all selected tours in the viewer for (final Object element : selectedTours.toArray()) { if (monitor.isCanceled()) { // stop reimporting but process reimported tours break; } monitor.worked(1); monitor.subTask(NLS.bind(Messages.Import_Data_Dialog_Reimport_SubTask, // new Object[] { ++imported, importSize })); TourData oldTourData = null; if (element instanceof TVITourBookTour) { oldTourData = TourManager.getInstance() .getTourData(((TVITourBookTour) element).getTourId()); } else if (element instanceof TourData) { oldTourData = (TourData) element; } if (oldTourData == null) { continue; } boolean isTourReImportedFromSameFile = false; if (reimportedFile != null && _newlyImportedTours.size() > 0) { // this case occures when a file contains multiple tours if (actionReimportTour_30(reimportId, reimportedFile, oldTourData)) { isReImported = true; isTourReImportedFromSameFile = true; } } if (isTourReImportedFromSameFile == false) { reimportedFile = actionReimportTour_20_GetImportFile(oldTourData); if (reimportedFile == null) { // user canceled file dialog break; } // import file is available if (actionReimportTour_30(reimportId, reimportedFile, oldTourData)) { isReImported = true; } } } if (isReImported) { updateTourData_InImportView_FromDb(monitor); // reselect tours, run in UI thread Display.getDefault().asyncExec(new Runnable() { @Override public void run() { tourViewer.reloadViewer(); tourViewer.getViewer().setSelection(selectedTours, true); } }); } } }; try { new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, true, importRunnable); } catch (final Exception e) { TourLogManager.logEx(e); } finally { final double time = (System.currentTimeMillis() - start) / 1000.0; TourLogManager.addLog(// TourLogState.DEFAULT, String.format(RawDataManager.LOG_REIMPORT_END, time)); } } private boolean actionReimportTour_10_Confirm(final ReImport reimportTour) { if (reimportTour == ReImport.Tour) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_TOUR, Messages.Import_Data_Dialog_ConfirmReimport_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_TOUR, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.AllTimeSlices) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_ALL_TIME_SLICES, Messages.Import_Data_Dialog_ConfirmReimportTimeSlices_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ALL_TIME_SLICES, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyAltitudeValues) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_ALTITUDE_VALUES, Messages.Import_Data_Dialog_ConfirmReimportAltitudeValues_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_ALTITUDE, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyGearValues) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_GEAR_VALUES, Messages.Import_Data_Dialog_ConfirmReimportGearValues_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_GEAR, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyPowerAndPulseValues) { if (actionReimportTour_12_ConfirmDialog( ITourbookPreferences.TOGGLE_STATE_REIMPORT_POWER_AND_PULSE_VALUES, Messages.Import_Data_Dialog_ConfirmReimportPowerAndPulseValues_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_POWER_PULSE, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyPowerAndSpeedValues) { if (actionReimportTour_12_ConfirmDialog( ITourbookPreferences.TOGGLE_STATE_REIMPORT_POWER_AND_SPEED_VALUES, Messages.Import_Data_Dialog_ConfirmReimportPowerAndSpeedValues_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_POWER_SPEED, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyTourMarker) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_TOUR_MARKER, Messages.Import_Data_Dialog_ConfirmReimportTourMarker_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_MARKER, TourLogView.CSS_LOG_TITLE); return true; } } else if (reimportTour == ReImport.OnlyTemperatureValues) { if (actionReimportTour_12_ConfirmDialog(ITourbookPreferences.TOGGLE_STATE_REIMPORT_TEMPERATURE_VALUES, Messages.Import_Data_Dialog_ConfirmReimportTemperatureValues_Message)) { TourLogManager.addLog(TourLogState.DEFAULT, // LOG_REIMPORT_ONLY_TEMPERATURE, TourLogView.CSS_LOG_TITLE); return true; } } return false; } private boolean actionReimportTour_12_ConfirmDialog(final String toggleState, final String confirmMessage) { if (_prefStore.getBoolean(toggleState)) { return true; } else { final MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm(// Display.getCurrent().getActiveShell(), // Messages.import_data_dlg_reimport_title, // confirmMessage, // Messages.App_ToggleState_DoNotShowAgain, // false, // toggle default state null, null); if (dialog.getReturnCode() == Window.OK) { _prefStore.setValue(toggleState, dialog.getToggleState()); return true; } } return false; } /** * @param tourData * @return Returns <code>null</code> when the user has canceled the file dialog. */ private File actionReimportTour_20_GetImportFile(final TourData tourData) { final String[] reimportFilePathName = { null }; Display.getDefault().syncExec(new Runnable() { @Override public void run() { final Shell activeShell = Display.getDefault().getActiveShell(); // get import file name final String oldImportFilePathName = tourData.getImportFilePathName(); if (oldImportFilePathName == null) { // in older versions the file path name is not saved final String tourDateTimeShort = TourManager.getTourDateTimeShort(tourData); MessageDialog.openInformation(activeShell, NLS.bind(Messages.Import_Data_Dialog_Reimport_Title, tourDateTimeShort), NLS.bind(Messages.Import_Data_Dialog_GetReimportedFilePath_Message, // tourDateTimeShort, tourDateTimeShort)); } else { // check import file final File importFile = new File(oldImportFilePathName); if (importFile.exists()) { reimportFilePathName[0] = oldImportFilePathName; } else { if (_previousSelectedReimportFolder != null) { /* * try to use the folder from the previously reimported tour */ final String oldImportFileName = new org.eclipse.core.runtime.Path( oldImportFilePathName).lastSegment(); final IPath newImportFilePath = _previousSelectedReimportFolder .append(oldImportFileName); final String newImportFilePathName = newImportFilePath.toOSString(); final File newImportFile = new File(newImportFilePathName); if (newImportFile.exists()) { // reimport file exists in the same folder reimportFilePathName[0] = newImportFilePathName; } } if (reimportFilePathName[0] == null) { MessageDialog.openInformation( // activeShell, Messages.import_data_dlg_reimport_title, NLS.bind(Messages.Import_Data_Dialog_GetAlternativePath_Message, oldImportFilePathName)); } } } if (reimportFilePathName[0] == null) { final String tourDateTimeShort = TourManager.getTourDateTimeShort(tourData); final FileDialog dialog = new FileDialog(activeShell, SWT.OPEN); dialog.setText(NLS.bind(Messages.Import_Data_Dialog_Reimport_Title, tourDateTimeShort)); if (oldImportFilePathName != null) { // select previous file location final IPath importFilePath = new org.eclipse.core.runtime.Path(oldImportFilePathName); final String importFileName = importFilePath.lastSegment(); dialog.setFileName(importFileName); dialog.setFilterPath(oldImportFilePathName); } else if (_previousSelectedReimportFolder != null) { dialog.setFilterPath(_previousSelectedReimportFolder.toOSString()); } reimportFilePathName[0] = dialog.open(); } } }); if (reimportFilePathName[0] == null) { // user has canceled the file dialog return null; } /* * Keep selected file path which is used to reimport following tours from the same folder * that the user do not have to reselect again and again. */ _previousSelectedReimportFolder = new org.eclipse.core.runtime.Path(reimportFilePathName[0]) .removeLastSegments(1); return new File(reimportFilePathName[0]); } private boolean actionReimportTour_30(final ReImport reimportId, final File reimportedFile, final TourData oldTourData) { boolean isTourReImported = false; final Long oldTourId = oldTourData.getTourId(); final String reimportFileNamePath = reimportedFile.getAbsolutePath(); /* * tour must be removed otherwise it would be recognized as a duplicate and therefor not * imported */ final TourData oldTourDataInImportView = _toursInImportView.remove(oldTourId); if (importRawData(reimportedFile, null, false, null, false)) { /* * tour(s) could be reimported from the file, check if it contains a valid tour */ TourData newTourData = actionReimportTour_40(reimportId, reimportedFile, oldTourData); if (newTourData == null) { // error is already logged } else { isTourReImported = true; TourLogManager.addSubLog(TourLogState.IMPORT_OK, reimportFileNamePath); // set reimport file path as new location newTourData.setImportFilePath(reimportFileNamePath); // check if tour is saved final TourPerson tourPerson = oldTourData.getTourPerson(); if (tourPerson != null) { // resave tour when the reimported tour was already saved newTourData.setTourPerson(tourPerson); /* * save tour but don't fire a change event because the tour editor would set the * tour to dirty */ final TourData savedTourData = TourManager.saveModifiedTour(newTourData, false); newTourData = savedTourData; } // check if tour is displayed in the import view if (oldTourDataInImportView != null) { // replace tour data in the import view _toursInImportView.put(newTourData.getTourId(), newTourData); } } } else { TourLogManager.addSubLog(TourLogState.IMPORT_ERROR, reimportFileNamePath); if (oldTourDataInImportView != null) { // reattach removed tour _toursInImportView.put(oldTourId, oldTourDataInImportView); } } return isTourReImported; } /** * @param reimportId * @param reimportedFile * @param oldTourData * @return Returns {@link TourData} with the reimported time slices or <code>null</code> when an * error occured. */ private TourData actionReimportTour_40(final ReImport reimportId, final File reimportedFile, final TourData oldTourData) { final String oldTourDateTimeShort = TourManager.getTourDateTimeShort(oldTourData); String message = null; for (final TourData reimportedTourData : _newlyImportedTours.values()) { // skip tours which have a different tour start time final long reimportTourStartTime = reimportedTourData.getTourStartTimeMS(); final long oldTourStartTime = oldTourData.getTourStartTimeMS(); final long timeDiff = reimportTourStartTime > oldTourStartTime ? reimportTourStartTime - oldTourStartTime : oldTourStartTime - reimportTourStartTime; if (timeDiff > 20000) { // disabled because .fit files can have different tour start times (of some seconds) // continue; } if (oldTourData.timeSerie != null && reimportedTourData.timeSerie != null) { /* * data series must have the same number of time slices, otherwise the markers can * be off the array bounds, this problem could be solved but takes time to do it. */ final int oldLength = oldTourData.timeSerie.length; final int reimportedLength = reimportedTourData.timeSerie.length; if (oldLength != reimportedLength) { // log error message = NLS.bind(Messages.Import_Data_Log_ReimportIsInvalid_WrongSliceNumbers, new Object[] { oldTourDateTimeShort, reimportedFile.toString(), oldLength, reimportedLength }); break; } } /* * ensure that the reimported tour has the same tour id */ final long oldTourId = oldTourData.getTourId().longValue(); final long reimportTourId = reimportedTourData.getTourId().longValue(); if (oldTourId != reimportTourId) { message = NLS.bind(Messages.Import_Data_Log_ReimportIsInvalid_DifferentTourId_Message, new Object[] { oldTourDateTimeShort, reimportedFile.toString(), oldTourId, reimportTourId }); break; } TourData newTourData = null; if (reimportId == ReImport.Tour) { // replace complete tour TourManager.getInstance().removeTourFromCache(oldTourData.getTourId()); newTourData = reimportedTourData; // keep body weight from old tour newTourData.setBodyWeight(oldTourData.getBodyWeight()); } else if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyAltitudeValues || reimportId == ReImport.OnlyGearValues || reimportId == ReImport.OnlyPowerAndPulseValues || reimportId == ReImport.OnlyPowerAndSpeedValues || reimportId == ReImport.OnlyTemperatureValues) { // replace part of the tour actionReimportTour_40_TimeSlices(reimportId, oldTourData, reimportedTourData); newTourData = oldTourData; } else if (reimportId == ReImport.OnlyTourMarker) { // reimport only tour markers oldTourData.setTourMarkers(reimportedTourData.getTourMarkers()); newTourData = oldTourData; } if (newTourData != null) { /* * compute computed values */ newTourData.clearComputedSeries(); newTourData.computeAltitudeUpDown(); newTourData.computeTourDrivingTime(); newTourData.computeComputedValues(); // maintain list, that another call of this method do not find this tour again _newlyImportedTours.remove(oldTourData.getTourId()); return newTourData; } } /* * A reimport failed, display an error message */ if (message == null) { // undefined error TourLogManager.logSubError(reimportedFile.toString()); } else { TourLogManager.logSubError(message); } TourLogManager.showLogView(); return null; } private void actionReimportTour_40_TimeSlices(final ReImport reimportId, final TourData oldTourData, final TourData reimportedTourData) { // ALTITUDE if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyAltitudeValues) { // reimport altitude only oldTourData.altitudeSerie = reimportedTourData.altitudeSerie; } // GEAR if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyGearValues) { // reimport gear only oldTourData.gearSerie = reimportedTourData.gearSerie; oldTourData.setFrontShiftCount(reimportedTourData.getFrontShiftCount()); oldTourData.setRearShiftCount(reimportedTourData.getRearShiftCount()); } // POWER if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyPowerAndPulseValues || reimportId == ReImport.OnlyPowerAndSpeedValues) { oldTourData.setCalories(reimportedTourData.getCalories()); // reimport power and speed only when it's from the device final boolean isDevicePower = reimportedTourData.isPowerSerieFromDevice(); if (isDevicePower) { final float[] powerSerie = reimportedTourData.getPowerSerie(); if (powerSerie != null) { oldTourData.setPowerSerie(powerSerie); } //SET_FORMATTING_OFF oldTourData.setPower_Avg(reimportedTourData.getPower_Avg()); oldTourData.setPower_Max(reimportedTourData.getPower_Max()); oldTourData.setPower_Normalized(reimportedTourData.getPower_Normalized()); oldTourData.setPower_FTP(reimportedTourData.getPower_FTP()); oldTourData.setPower_TotalWork(reimportedTourData.getPower_TotalWork()); oldTourData.setPower_TrainingStressScore(reimportedTourData.getPower_TrainingStressScore()); oldTourData.setPower_IntensityFactor(reimportedTourData.getPower_IntensityFactor()); oldTourData.setPower_PedalLeftRightBalance(reimportedTourData.getPower_PedalLeftRightBalance()); oldTourData.setPower_AvgLeftPedalSmoothness(reimportedTourData.getPower_AvgLeftPedalSmoothness()); oldTourData.setPower_AvgLeftTorqueEffectiveness( reimportedTourData.getPower_AvgLeftTorqueEffectiveness()); oldTourData.setPower_AvgRightPedalSmoothness(reimportedTourData.getPower_AvgRightPedalSmoothness()); oldTourData.setPower_AvgRightTorqueEffectiveness( reimportedTourData.getPower_AvgRightTorqueEffectiveness()); //SET_FORMATTING_ON } } // PULSE if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyPowerAndPulseValues) { // reimport pulse oldTourData.pulseSerie = reimportedTourData.pulseSerie; oldTourData.pulseTimeSerie = reimportedTourData.pulseTimeSerie; } // SPEED if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyPowerAndSpeedValues) { // reimport speed final boolean isDeviceSpeed = reimportedTourData.isSpeedSerieFromDevice(); if (isDeviceSpeed) { final float[] speedSerie = reimportedTourData.getSpeedSerieFromDevice(); if (speedSerie != null) { oldTourData.setSpeedSerie(speedSerie); } } } // TEMPERATURE if (reimportId == ReImport.AllTimeSlices || reimportId == ReImport.OnlyTemperatureValues) { // reimport temperature only oldTourData.temperatureSerie = reimportedTourData.temperatureSerie; } // ALL if (reimportId == ReImport.AllTimeSlices) { // reimport all other data series // update device data oldTourData.setDeviceFirmwareVersion(reimportedTourData.getDeviceFirmwareVersion()); oldTourData.setDeviceId(reimportedTourData.getDeviceId()); oldTourData.setDeviceName(reimportedTourData.getDeviceName()); oldTourData.cadenceSerie = reimportedTourData.cadenceSerie; oldTourData.distanceSerie = reimportedTourData.distanceSerie; oldTourData.latitudeSerie = reimportedTourData.latitudeSerie; oldTourData.longitudeSerie = reimportedTourData.longitudeSerie; oldTourData.timeSerie = reimportedTourData.timeSerie; } } public DeviceData getDeviceData() { return _deviceData; } private List<TourbookDevice> getDeviceListSortedByPriority() { if (_devicesBySortPriority == null) { _devicesBySortPriority = new ArrayList<TourbookDevice>(DeviceManager.getDeviceList()); // sort device list by sorting priority Collections.sort(_devicesBySortPriority, new Comparator<TourbookDevice>() { @Override public int compare(final TourbookDevice o1, final TourbookDevice o2) { // 1. sort by prio final int sortByPrio = o1.extensionSortPriority - o2.extensionSortPriority; // 2. sort by name if (sortByPrio == 0) { return o1.deviceId.compareTo(o2.deviceId); } return sortByPrio; } }); _devicesByExtension = new HashMap<String, TourbookDevice>(); for (final TourbookDevice device : _devicesBySortPriority) { _devicesByExtension.put(device.fileExtension.toLowerCase(), device); } } return _devicesBySortPriority; } public HashSet<String> getImportedFiles() { return _importedFileNames; } /** * @return Returns an {@link ArrayList} containing the imported tours. */ public ArrayList<TourData> getImportedTourList() { final Collection<TourData> importedToursCollection = _toursInImportView.values(); final ArrayList<TourData> importedTours = new ArrayList<>(importedToursCollection); return importedTours; } /** * @return Returns all {@link TourData} which has been imported or received and are displayed in * the import view, tour id is the key. */ public HashMap<Long, TourData> getImportedTours() { return _toursInImportView; } /** * @return Returns the import year or <code>-1</code> when the year was not set */ public int getImportYear() { return _importState_ImportYear; } public ArrayList<TourTag> getTempTourTags() { return _tempTourTags; } public ArrayList<TourType> getTempTourTypes() { return _tempTourTypes; } /** * Import a tour from a file, all imported tours can be retrieved with * {@link #getImportedTours()} * * @param importFile * the file to be imported * @param destinationPath * if not null copy the file to this path * @param buildNewFileNames * if <code>true</code> create a new filename depending on the content of the file, * keep old name if false * @param fileCollision * behavior if destination file exists (ask if null) * @param isTourDisplayedInImportView * When <code>true</code>, the newly imported tours are displayed in the import view, * otherwise they are imported into {@link #_newlyImportedTours} but not displayed in * the import view. * @return Returns <code>true</code> when the import was successfully */ public boolean importRawData(final File importFile, final String destinationPath, final boolean buildNewFileNames, final FileCollisionBehavior fileCollision, final boolean isTourDisplayedInImportView) { final String importFilePathName = importFile.getAbsolutePath(); final Display display = Display.getDefault(); // check if importFile exist if (importFile.exists() == false) { display.syncExec(new Runnable() { @Override public void run() { final Shell activeShell = display.getActiveShell(); // during initialisation there is no active shell if (activeShell != null) { MessageDialog.openError(activeShell, Messages.DataImport_Error_file_does_not_exist_title, NLS.bind(Messages.DataImport_Error_file_does_not_exist_msg, importFilePathName)); } } }); return false; } // find the file extension in the filename final int dotPos = importFilePathName.lastIndexOf("."); //$NON-NLS-1$ if (dotPos == -1) { return false; } final String fileExtension = importFilePathName.substring(dotPos + 1); final List<TourbookDevice> deviceList = getDeviceListSortedByPriority(); _isImported = false; BusyIndicator.showWhile(null, new Runnable() { @Override public void run() { boolean isDataImported = false; final ArrayList<String> additionalImportedFiles = new ArrayList<String>(); /* * try to import from all devices which have the defined extension */ for (final TourbookDevice device : deviceList) { final String deviceFileExtension = device.fileExtension; if (deviceFileExtension.equals("*") || deviceFileExtension.equalsIgnoreCase(fileExtension)) { //$NON-NLS-1$ // Check if the file we want to import requires confirmation and if yes, ask user if (device.userConfirmationRequired()) { display.syncExec(new Runnable() { @Override public void run() { final Shell activeShell = display.getActiveShell(); if (activeShell != null) { if (MessageDialog .openConfirm(Display.getCurrent().getActiveShell(), NLS.bind(Messages.DataImport_ConfirmImport_title, device.visibleName), device.userConfirmationMessage())) { _isImportCanceled = false; } else { _isImportCanceled = true; } } } }); } if (_isImportCanceled) { _isImported = true; // don't display an error to the user return; } // device file extension was found in the filename extension if (importRawData_10(device, importFilePathName, destinationPath, buildNewFileNames, fileCollision, isTourDisplayedInImportView)) { isDataImported = true; _isImported = true; final ArrayList<String> deviceImportedFiles = device.getAdditionalImportedFiles(); if (deviceImportedFiles != null) { additionalImportedFiles.addAll(deviceImportedFiles); } break; } if (_isImportCanceled) { break; } } } if (isDataImported == false && !_isImportCanceled) { /* * when data has not imported yet, try all available devices without checking * the file extension */ for (final TourbookDevice device : deviceList) { if (importRawData_10(device, importFilePathName, destinationPath, buildNewFileNames, fileCollision, isTourDisplayedInImportView)) { isDataImported = true; _isImported = true; final ArrayList<String> otherImportedFiles = device.getAdditionalImportedFiles(); if (otherImportedFiles != null) { additionalImportedFiles.addAll(otherImportedFiles); } break; } } } if (isDataImported) { _importedFileNames.add(_lastImportedFileName); if (additionalImportedFiles.size() > 0) { _importedFileNamesChildren.addAll(additionalImportedFiles); } } // cleanup additionalImportedFiles.clear(); } }); return _isImported; } /** * import the raw data of the given file * * @param device * the device which is able to process the data of the file * @param sourceFileName * the file to be imported * @param destinationPath * if not null copy the file to this path * @param buildNewFileName * if true create a new filename depending on the content of the file, keep old name * if false * @param fileCollision * behavior if destination file exists (ask if null) * @param isTourDisplayedInImportView * @return Returns <code>true</code> when data has been imported. */ private boolean importRawData_10(final TourbookDevice device, String sourceFileName, final String destinationPath, final boolean buildNewFileName, FileCollisionBehavior fileCollision, final boolean isTourDisplayedInImportView) { if (fileCollision == null) { fileCollision = new FileCollisionBehavior(); } _newlyImportedTours.clear(); device.setIsChecksumValidation(_importState_IsChecksumValidation); if (device.validateRawData(sourceFileName)) { // file contains valid raw data for the raw data reader if (_importState_ImportYear != -1) { device.setImportYear(_importState_ImportYear); } device.setMergeTracks(_importState_IsMergeTracks); device.setCreateTourIdWithTime(_importState_IsCreateTourIdWithTime); device.setConvertWayPoints(_importState_IsConvertWayPoints); // copy file to destinationPath if (destinationPath != null) { final String newFileName = importRawData_20_CopyFile(device, sourceFileName, destinationPath, buildNewFileName, fileCollision); if (newFileName == null) { return false; } sourceFileName = newFileName; } _lastImportedFileName = sourceFileName; boolean isImported = false; try { isImported = device.processDeviceData(sourceFileName, _deviceData, _toursInImportView, _newlyImportedTours); } catch (final Exception e) { TourLogManager.logEx(e); } if (isTourDisplayedInImportView) { _toursInImportView.putAll(_newlyImportedTours); } // keep tours in _newlyImportedTours because they are used when tours are reimported return isImported; } return false; } private String importRawData_20_CopyFile(final TourbookDevice device, final String sourceFileName, final String destinationPath, final boolean buildNewFileName, final FileCollisionBehavior fileCollision) { String destFileName = new File(sourceFileName).getName(); if (buildNewFileName) { destFileName = null; try { destFileName = device.buildFileNameFromRawData(sourceFileName); } catch (final Exception e) { TourLogManager.logEx(e); } finally { if (destFileName == null) { MessageDialog .openError(Display.getDefault().getActiveShell(), Messages.Import_Data_Error_CreatingFileName_Title, NLS.bind(Messages.Import_Data_Error_CreatingFileName_Message, // new Object[] { sourceFileName, new org.eclipse.core.runtime.Path(destinationPath) .addTrailingSeparator().toString(), TEMP_IMPORTED_FILE })); destFileName = TEMP_IMPORTED_FILE; } } } final File newFile = new File( (new org.eclipse.core.runtime.Path(destinationPath).addTrailingSeparator().toString() + destFileName)); // get source file final File fileIn = new File(sourceFileName); // check if file already exist if (newFile.exists()) { // TODO allow user to rename the file boolean keepFile = false; // for MessageDialog result if (fileCollision.value == FileCollisionBehavior.ASK) { final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); final MessageDialog messageDialog = new MessageDialog(shell, Messages.Import_Wizard_Message_Title, null, NLS.bind(Messages.Import_Wizard_Message_replace_existing_file, newFile), MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL }, 0); messageDialog.open(); final int returnCode = messageDialog.getReturnCode(); switch (returnCode) { case 1: // YES_TO_ALL fileCollision.value = FileCollisionBehavior.REPLACE; break; case 3: // NO_TO_ALL fileCollision.value = FileCollisionBehavior.KEEP; case 2: // NO keepFile = true; break; default: break; } } if (fileCollision.value == FileCollisionBehavior.KEEP || keepFile) { _isImportCanceled = true; fileIn.delete(); return null; } } // copy source file into destination file FileInputStream inReader = null; FileOutputStream outReader = null; try { inReader = new FileInputStream(fileIn); outReader = new FileOutputStream(newFile); int c; while ((c = inReader.read()) != -1) { outReader.write(c); } inReader.close(); outReader.close(); } catch (final FileNotFoundException e) { TourLogManager.logEx(e); return null; } catch (final IOException e) { TourLogManager.logEx(e); return null; } finally { // close the files if (inReader != null) { try { inReader.close(); } catch (final IOException e) { TourLogManager.logEx(e); return null; } } if (outReader != null) { try { outReader.close(); } catch (final IOException e) { TourLogManager.logEx(e); return null; } } } // delete source file fileIn.delete(); return newFile.getAbsolutePath(); } public void removeAllTours() { _toursInImportView.clear(); _importedFileNames.clear(); _importedFileNamesChildren.clear(); _tempTourTags.clear(); _tempTourTypes.clear(); } public void removeTours(final TourData[] removedTours) { final HashSet<?> oldFileNames = (HashSet<?>) _importedFileNames.clone(); for (final Object item : removedTours) { final TourData tourData = (TourData) item; final Long key = tourData.getTourId(); if (_toursInImportView.containsKey(key)) { _toursInImportView.remove(key); } } /* * Check if all tours from a file are removed, when yes, remove file path that the file can * not be reimported. When at least one tour is still used, all tours will be reimported * because it's not yet saved which tours are removed from a file and which are not. */ for (final Object item : oldFileNames) { if (item instanceof String) { final String oldFilePath = (String) item; boolean isNeeded = false; for (final TourData tourData : _toursInImportView.values()) { final String tourFilePathName = tourData.getImportFilePathName(); if (tourFilePathName != null && tourFilePathName.equals(oldFilePath)) { isNeeded = true; break; } } if (isNeeded == false) { // file path is not needed any more _importedFileNames.remove(oldFilePath); } } } } public ImportRunState runImport(final ArrayList<OSFile> importFiles, final boolean isEasyImport, final String fileGlobPattern) { final ImportRunState importRunState = new ImportRunState(); if (importFiles.size() == 0) { return importRunState; } final long start = System.currentTimeMillis(); /* * Log import */ final String css = isEasyImport // ? UI.EMPTY_STRING : TourLogView.CSS_LOG_TITLE; final String message = isEasyImport // ? String.format(EasyImportManager.LOG_EASY_IMPORT_002_TOUR_FILES_START, fileGlobPattern) : RawDataManager.LOG_IMPORT_TOUR; TourLogManager.addLog(TourLogState.DEFAULT, message, css); // check if devices are loaded if (_devicesByExtension == null) { getDeviceListSortedByPriority(); } final List<ImportFile> importFilePaths = new ArrayList<>(); /* * Convert to IPath because NIO Path DO NOT SUPPORT EXTENSIONS :-((( */ for (final OSFile osFile : importFiles) { final String absolutePath = osFile.getPath().toString(); final org.eclipse.core.runtime.Path iPath = new org.eclipse.core.runtime.Path(absolutePath); final ImportFile importFile = new ImportFile(iPath); importFile.isBackupImportFile = osFile.isBackupImportFile; importFilePaths.add(importFile); } // resort files by extension priority Collections.sort(importFilePaths, new Comparator<ImportFile>() { @Override public int compare(final ImportFile path1, final ImportFile path2) { final String file1Extension = path1.filePath.getFileExtension(); final String file2Extension = path2.filePath.getFileExtension(); if (file1Extension != null && file1Extension.length() > 0 && file2Extension != null && file2Extension.length() > 0) { final TourbookDevice file1Device = _devicesByExtension.get(file1Extension.toLowerCase()); final TourbookDevice file2Device = _devicesByExtension.get(file2Extension.toLowerCase()); if (file1Device != null && file2Device != null) { return file1Device.extensionSortPriority - file2Device.extensionSortPriority; } } // sort invalid files to the end return Integer.MAX_VALUE; } }); setImportCanceled(false); final IRunnableWithProgress importRunnable = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { int imported = 0; final int importSize = importFilePaths.size(); monitor.beginTask(Messages.import_data_importTours_task, importSize); setImportId(); int importCounter = 0; final ArrayList<String> notImportedFiles = new ArrayList<String>(); // loop: import all selected files for (final ImportFile filePath : importFilePaths) { if (monitor.isCanceled()) { // stop importing but process imported tours importRunState.isImportCanceled = true; break; } final String osFilePath = filePath.filePath.toOSString(); final String subTask = NLS.bind(Messages.import_data_importTours_subTask, // new Object[] { ++imported, importSize, osFilePath }); monitor.worked(1); monitor.subTask(subTask); // ignore files which are imported as children from other imported files if (_importedFileNamesChildren.contains(osFilePath)) { continue; } if (importRawData(new File(osFilePath), null, false, null, true)) { importCounter++; // update state TourData tourData = null; for (final TourData importedTourData : _newlyImportedTours.values()) { importedTourData.isBackupImportFile = filePath.isBackupImportFile; if (tourData == null) { tourData = importedTourData; } } if (tourData != null) { TourLogManager.addSubLog(// TourLogState.IMPORT_OK, String.format(// LOG_IMPORT_TOUR_IMPORTED, tourData.getTourStartTime().format(TimeTools.Formatter_DateTime_S), osFilePath)); } } else { notImportedFiles.add(osFilePath); TourLogManager.addSubLog(TourLogState.IMPORT_ERROR, osFilePath); } } if (importCounter > 0) { updateTourData_InImportView_FromDb(monitor); Display.getDefault().syncExec(new Runnable() { @Override public void run() { final RawDataView view = showRawDataView(); if (view != null) { view.reloadViewer(); if (isEasyImport == false) { // first tour is selected later view.selectFirstTour(); } } } }); } } }; try { new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, true, importRunnable); } catch (final Exception e) { TourLogManager.logEx(e); } final double time = (System.currentTimeMillis() - start) / 1000.0; TourLogManager.addLog(TourLogState.DEFAULT, String.format( isEasyImport ? EasyImportManager.LOG_EASY_IMPORT_002_END : RawDataManager.LOG_IMPORT_TOUR_END, time)); return importRunState; } public void setImportCanceled(final boolean importCanceled) { _isImportCanceled = importCanceled; } /** * Sets a unique id into the device data so that each import can be identified. */ public void setImportId() { _deviceData.importId = System.currentTimeMillis(); } public void setImportYear(final int year) { _importState_ImportYear = year; } public void setIsChecksumValidation(final boolean checked) { _importState_IsChecksumValidation = checked; } public void setMergeTracks(final boolean checked) { _importState_IsMergeTracks = checked; } public void setState_ConvertWayPoints(final boolean isConvertWayPoints) { _importState_IsConvertWayPoints = isConvertWayPoints; } public void setState_CreateTourIdWithTime(final boolean isActionChecked) { _importState_IsCreateTourIdWithTime = isActionChecked; } public void setState_IsOpenImportLogView(final boolean isOpenImportLog) { _importState_IsAutoOpenImportLog = isOpenImportLog; } private RawDataView showRawDataView() { final IWorkbench workbench = PlatformUI.getWorkbench(); final IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); try { final IViewPart rawDataView = window.getActivePage().findView(RawDataView.ID); if (rawDataView == null) { // show raw data perspective when raw data view is not visible workbench.showPerspective(PerspectiveFactoryRawData.PERSPECTIVE_ID, window); } // show raw data view return (RawDataView) Util.showView(RawDataView.ID, true); } catch (final WorkbenchException e) { TourLogManager.logEx(e); } return null; } /** * Update {@link TourData} from the database for all imported tours which are displayed in the * import view, a progress dialog is displayed. * * @param monitor */ public void updateTourData_InImportView_FromDb(final IProgressMonitor monitor) { final int numImportTours = _toursInImportView.size(); if (numImportTours == 0) { // nothing to do } else if (numImportTours < 3) { // don't show progress dialog updateTourData_InImportView_FromDb_Runnable(null); } else { if (monitor == null) { try { new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, false, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { updateTourData_InImportView_FromDb_Runnable(monitor); } }); } catch (final InvocationTargetException e) { TourLogManager.logEx(e); } catch (final InterruptedException e) { TourLogManager.logEx(e); } } else { updateTourData_InImportView_FromDb_Runnable(monitor); } } } private void updateTourData_InImportView_FromDb_Runnable(final IProgressMonitor monitor) { int workedDone = 0; final int workedAll = _toursInImportView.size(); if (monitor != null) { monitor.beginTask(Messages.import_data_updateDataFromDatabase_task, workedAll); } long editorTourId = -1; final TourDataEditorView tourDataEditor = TourManager.getTourDataEditor(); if (tourDataEditor != null) { final TourData tourData = tourDataEditor.getTourData(); if (tourData != null) { editorTourId = tourData.getTourId(); } } for (final TourData importedTourData : _toursInImportView.values()) { if (monitor != null) { monitor.worked(1); monitor.subTask( NLS.bind(Messages.import_data_updateDataFromDatabase_subTask, workedDone++, workedAll)); } if (importedTourData.isTourDeleted) { continue; } final Long tourId = importedTourData.getTourId(); try { final TourData dbTourData = TourManager.getInstance().getTourDataFromDb(tourId); if (dbTourData != null) { /* * Imported tour is saved in the database, set transient fields. */ // used to delete the device import file dbTourData.isTourFileDeleted = importedTourData.isTourFileDeleted; dbTourData.isTourFileMoved = importedTourData.isTourFileMoved; dbTourData.isBackupImportFile = importedTourData.isBackupImportFile; dbTourData.importFilePathOriginal = importedTourData.importFilePathOriginal; final Long dbTourId = dbTourData.getTourId(); // replace existing tours but do not add new tours if (_toursInImportView.containsKey(dbTourId)) { /* * check if the tour editor contains this tour, this should not be * necessary, just make sure the correct tour is used !!! */ if (editorTourId == dbTourId) { _toursInImportView.put(dbTourId, tourDataEditor.getTourData()); } else { _toursInImportView.put(dbTourId, dbTourData); } } } } catch (final Exception e) { TourLogManager.logEx(e); } } // prevent async error Display.getDefault().syncExec(new Runnable() { @Override public void run() { TourManager.fireEvent(TourEventId.CLEAR_DISPLAYED_TOUR, null, null); } }); } /** * Updates the model with modified tours * * @param modifiedTours */ public void updateTourDataModel(final ArrayList<TourData> modifiedTours) { for (final TourData tourData : modifiedTours) { if (tourData != null) { final Long tourId = tourData.getTourId(); // replace existing tour do not add new tours if (_toursInImportView.containsKey(tourId)) { _toursInImportView.put(tourId, tourData); } } } } }