Changeset 13114 in josm


Ignore:
Timestamp:
2017-11-12T02:05:48+01:00 (7 days ago)
Author:
Don-vip
Message:

fix #11537 - Autosave also note layer

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/io/importexport/NoteImporter.java

    r12671 r13114  
    2525public class NoteImporter extends FileImporter {
    2626
    27     private static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
     27    /**
     28     * The Notes file filter (*.osn files).
     29     * @since 13114
     30     */
     31    public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
    2832            "osn", "osn", tr("Note Files"), true);
    2933
  • trunk/src/org/openstreetmap/josm/gui/layer/AutosaveTask.java

    r12856 r13114  
    3131import org.openstreetmap.josm.actions.OpenFileAction.OpenFileTask;
    3232import org.openstreetmap.josm.data.osm.DataSet;
     33import org.openstreetmap.josm.data.osm.NoteData;
     34import org.openstreetmap.josm.data.osm.NoteData.NoteDataUpdateListener;
    3335import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
    3436import org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter;
     
    3840import org.openstreetmap.josm.gui.MainApplication;
    3941import org.openstreetmap.josm.gui.Notification;
     42import org.openstreetmap.josm.gui.io.importexport.NoteExporter;
     43import org.openstreetmap.josm.gui.io.importexport.NoteImporter;
    4044import org.openstreetmap.josm.gui.io.importexport.OsmExporter;
    4145import org.openstreetmap.josm.gui.io.importexport.OsmImporter;
     
    5054
    5155/**
    52  * Saves data layers periodically so they can be recovered in case of a crash.
     56 * Saves data and note layers periodically so they can be recovered in case of a crash.
    5357 *
    5458 * There are 2 directories
     
    6872 * @since 10386 (new LayerChangeListener interface)
    6973 */
    70 public class AutosaveTask extends TimerTask implements LayerChangeListener, Listener {
     74public class AutosaveTask extends TimerTask implements LayerChangeListener, Listener, NoteDataUpdateListener {
    7175
    7276    private static final char[] ILLEGAL_CHARACTERS = {'/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':'};
     
    99103    public static final BooleanProperty PROP_NOTIFICATION = new BooleanProperty("autosave.notification", false);
    100104
    101     protected static final class AutosaveLayerInfo {
    102         private final OsmDataLayer layer;
     105    protected static final class AutosaveLayerInfo<T extends AbstractModifiableLayer> {
     106        private final T layer;
    103107        private String layerName;
    104108        private String layerFileName;
    105109        private final Deque<File> backupFiles = new LinkedList<>();
    106110
    107         AutosaveLayerInfo(OsmDataLayer layer) {
     111        AutosaveLayerInfo(T layer) {
    108112            this.layer = layer;
    109113        }
     
    112116    private final DataSetListenerAdapter datasetAdapter = new DataSetListenerAdapter(this);
    113117    private final Set<DataSet> changedDatasets = new HashSet<>();
    114     private final List<AutosaveLayerInfo> layersInfo = new ArrayList<>();
     118    private final Set<NoteData> changedNoteData = new HashSet<>();
     119    private final List<AutosaveLayerInfo<?>> layersInfo = new ArrayList<>();
    115120    private final Object layersLock = new Object();
    116121    private final Deque<File> deletedLayers = new LinkedList<>();
     
    167172    }
    168173
    169     private void setLayerFileName(AutosaveLayerInfo layer) {
     174    private void setLayerFileName(AutosaveLayerInfo<?> layer) {
    170175        int index = 0;
    171176        while (true) {
    172177            String filename = getFileName(layer.layer.getName(), index);
    173178            boolean foundTheSame = false;
    174             for (AutosaveLayerInfo info: layersInfo) {
     179            for (AutosaveLayerInfo<?> info: layersInfo) {
    175180                if (info != layer && filename.equals(info.layerFileName)) {
    176181                    foundTheSame = true;
     
    188193    }
    189194
    190     protected File getNewLayerFile(AutosaveLayerInfo layer, Date now, int startIndex) {
     195    protected File getNewLayerFile(AutosaveLayerInfo<?> layer, Date now, int startIndex) {
    191196        int index = startIndex;
    192197        while (true) {
    193198            String filename = String.format("%1$s_%2$tY%2$tm%2$td_%2$tH%2$tM%2$tS%2$tL%3$s",
    194199                    layer.layerFileName, now, index == 0 ? "" : ('_' + Integer.toString(index)));
    195             File result = new File(autosaveDir, filename + '.' + Config.getPref().get("autosave.extension", "osm"));
     200            File result = new File(autosaveDir, filename + '.' +
     201                    (layer.layer instanceof NoteLayer ?
     202                            Config.getPref().get("autosave.notes.extension", "osn") :
     203                            Config.getPref().get("autosave.extension", "osm")));
    196204            try {
    197205                if (index > PROP_INDEX_LIMIT.get())
     
    220228    }
    221229
    222     private void savelayer(AutosaveLayerInfo info) {
     230    private void savelayer(AutosaveLayerInfo<?> info) {
    223231        if (!info.layer.getName().equals(info.layerName)) {
    224232            setLayerFileName(info);
    225233            info.layerName = info.layer.getName();
    226234        }
    227         if (changedDatasets.remove(info.layer.data)) {
    228             File file = getNewLayerFile(info, new Date(), 0);
    229             if (file != null) {
    230                 info.backupFiles.add(file);
    231                 new OsmExporter().exportData(file, info.layer, true /* no backup with appended ~ */);
    232             }
     235        try {
     236            if (info.layer instanceof OsmDataLayer) {
     237                OsmDataLayer dataLayer = (OsmDataLayer) info.layer;
     238                if (changedDatasets.remove(dataLayer.data)) {
     239                    File file = getNewLayerFile(info, new Date(), 0);
     240                    if (file != null) {
     241                        info.backupFiles.add(file);
     242                        new OsmExporter().exportData(file, info.layer, true /* no backup with appended ~ */);
     243                    }
     244                }
     245            } else if (info.layer instanceof NoteLayer) {
     246                NoteLayer noteLayer = (NoteLayer) info.layer;
     247                if (changedNoteData.remove(noteLayer.getNoteData())) {
     248                    File file = getNewLayerFile(info, new Date(), 0);
     249                    if (file != null) {
     250                        info.backupFiles.add(file);
     251                        new NoteExporter().exportData(file, info.layer);
     252                    }
     253                }
     254            }
     255        } catch (IOException e) {
     256            Logging.error(e);
    233257        }
    234258        while (info.backupFiles.size() > PROP_FILES_PER_LAYER.get()) {
     
    244268        synchronized (layersLock) {
    245269            try {
    246                 for (AutosaveLayerInfo info: layersInfo) {
     270                for (AutosaveLayerInfo<?> info: layersInfo) {
    247271                    savelayer(info);
    248272                }
    249273                changedDatasets.clear();
     274                changedNoteData.clear();
    250275                if (PROP_NOTIFICATION.get() && !layersInfo.isEmpty()) {
    251276                    GuiHelper.runInEDT(this::displayNotification);
     
    273298        synchronized (layersLock) {
    274299            layer.data.addDataSetListener(datasetAdapter);
    275             layersInfo.add(new AutosaveLayerInfo(layer));
     300            layersInfo.add(new AutosaveLayerInfo<>(layer));
     301        }
     302    }
     303
     304    private void registerNewlayer(NoteLayer layer) {
     305        synchronized (layersLock) {
     306            layer.getNoteData().addNoteDataUpdateListener(this);
     307            layersInfo.add(new AutosaveLayerInfo<>(layer));
    276308        }
    277309    }
     
    281313        if (e.getAddedLayer() instanceof OsmDataLayer) {
    282314            registerNewlayer((OsmDataLayer) e.getAddedLayer());
     315        } else if (e.getAddedLayer() instanceof NoteLayer) {
     316            registerNewlayer((NoteLayer) e.getAddedLayer());
    283317        }
    284318    }
     
    290324                OsmDataLayer osmLayer = (OsmDataLayer) e.getRemovedLayer();
    291325                osmLayer.data.removeDataSetListener(datasetAdapter);
    292                 Iterator<AutosaveLayerInfo> it = layersInfo.iterator();
    293                 while (it.hasNext()) {
    294                     AutosaveLayerInfo info = it.next();
    295                     if (info.layer == osmLayer) {
    296 
    297                         savelayer(info);
    298                         File lastFile = info.backupFiles.pollLast();
    299                         if (lastFile != null) {
    300                             moveToDeletedLayersFolder(lastFile);
    301                         }
    302                         for (File file: info.backupFiles) {
    303                             if (Utils.deleteFile(file)) {
    304                                 Utils.deleteFile(getPidFile(file));
    305                             }
    306                         }
    307 
    308                         it.remove();
     326                cleanupLayer(osmLayer);
     327            }
     328        } else if (e.getRemovedLayer() instanceof NoteLayer) {
     329            synchronized (layersLock) {
     330                NoteLayer noteLayer = (NoteLayer) e.getRemovedLayer();
     331                noteLayer.getNoteData().removeNoteDataUpdateListener(this);
     332                cleanupLayer(noteLayer);
     333            }
     334        }
     335    }
     336
     337    private void cleanupLayer(AbstractModifiableLayer removedLayer) {
     338        Iterator<AutosaveLayerInfo<?>> it = layersInfo.iterator();
     339        while (it.hasNext()) {
     340            AutosaveLayerInfo<?> info = it.next();
     341            if (info.layer == removedLayer) {
     342
     343                savelayer(info);
     344                File lastFile = info.backupFiles.pollLast();
     345                if (lastFile != null) {
     346                    moveToDeletedLayersFolder(lastFile);
     347                }
     348                for (File file: info.backupFiles) {
     349                    if (Utils.deleteFile(file)) {
     350                        Utils.deleteFile(getPidFile(file));
    309351                    }
    310352                }
     353
     354                it.remove();
    311355            }
    312356        }
     
    316360    public void processDatasetEvent(AbstractDatasetChangedEvent event) {
    317361        changedDatasets.add(event.getDataset());
     362    }
     363
     364    @Override
     365    public void noteDataUpdated(NoteData data) {
     366        changedNoteData.add(data);
     367    }
     368
     369    @Override
     370    public void selectedNoteChanged(NoteData noteData) {
     371        // Do nothing
    318372    }
    319373
     
    329383    public List<File> getUnsavedLayersFiles() {
    330384        List<File> result = new ArrayList<>();
    331         File[] files = autosaveDir.listFiles(OsmImporter.FILE_FILTER);
     385        File[] files = autosaveDir.listFiles((FileFilter)
     386                pathname -> OsmImporter.FILE_FILTER.accept(pathname) || NoteImporter.FILE_FILTER.accept(pathname));
    332387        if (files == null)
    333388            return result;
Note: See TracChangeset for help on using the changeset viewer.