001package jmri.jmrix.can.cbus.eventtable;
002
003import java.io.File;
004import java.io.IOException;
005import java.nio.file.Files;
006import java.nio.file.Path;
007import java.nio.file.Paths;
008import java.nio.file.attribute.BasicFileAttributes;
009
010import java.nio.file.*;
011
012import javax.annotation.Nonnull;
013
014import jmri.jmrit.XmlFile;
015import jmri.jmrix.can.CanSystemConnectionMemo;
016import jmri.util.FileUtil;
017
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Class to provide access to the EventTableData.xml file.
023 * @author Steve Young Copyright (C) 2019
024 */
025public class CbusEventTableXmlFile extends XmlFile {
026
027    final CanSystemConnectionMemo memo;
028
029    public CbusEventTableXmlFile(@Nonnull CanSystemConnectionMemo memo){
030        this.memo = memo;
031    }
032
033    /**
034     * Get the full filename, including directory.
035     * @return String of file path.
036     */
037    public String getDefaultFileName() {
038        return getFileLocation() + File.separator + getFileName();
039    }
040
041    /**
042     * Get the Event Table Filename, no directory.
043     * @return just the filename.
044     */
045    public String getFileName() {
046        return "EventTableData.xml";  // NOI18N
047    }
048
049    /**
050     * Get the XML File for this connection.
051     * Migrates from previous single instance Event Table.
052     * @param store true to create new File if File does not exist.
053     * @return File, or if store is false and File not found, returns null.
054     */
055    public File getFile(boolean store) {
056        // Verify that directory:cbus exists
057        FileUtil.createDirectory(getFileLocation());
058        migrateFileLocation();
059
060        File file = findFile(getDefaultFileName());
061        if (file == null && store) {
062            file = new File(getDefaultFileName());
063        }
064        return file;
065    }
066
067    /**
068     * Absolute path to directory of Event Table file.
069     * No trailing file separator.
070     *
071     * @return path to location
072     */
073    public String getFileLocation() {
074        return FileUtil.getUserFilesPath() + "cbus" + File.separator + memo.getSystemPrefix() ;  // NOI18N
075    }
076
077    protected final String oldFileLocation = FileUtil.getUserFilesPath() + "cbus" ;
078
079    private void migrateFileLocation(){
080        if ( findFile(oldFileLocation + File.separator + getFileName()) == null ){
081            return;
082        }
083        try {
084            migrate(Paths.get(oldFileLocation), getFileLocation(), memo.getSystemPrefix() );
085            log.warn("Migrated existing CBUS Event Table Data to {}", memo.getUserName());
086        } catch(IOException e){
087            log.error("Unable to migrate CBUS Data ",e);
088        }
089    }
090
091    // also used in CbusNodeBackupFile for migrating to multi-system file support.
092    public static void migrate(Path fromPath, String newLocation,
093        String systemPrefix) throws IOException {
094
095        String oldCbusDirectory = File.separator + "cbus" + File.separator;
096        String newCbusDirectory = oldCbusDirectory + systemPrefix + File.separator; 
097
098        Files.walkFileTree(fromPath, new SimpleFileVisitor<Path>() {
099            @Override
100            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
101                String fileString = file.toAbsolutePath().toString();
102                if ( ! fileString.contains(newLocation) ) { // not in new directory
103                    String newPathString = fileString.replace( oldCbusDirectory  , newCbusDirectory);
104                    Files.copy(file, Paths.get(newPathString), StandardCopyOption.REPLACE_EXISTING);
105                    Files.delete(file);
106                }
107                return FileVisitResult.CONTINUE;
108            }
109        });
110    }
111
112    private final static Logger log = LoggerFactory.getLogger(CbusEventTableXmlFile.class);
113
114}