001package jmri.jmrit.symbolicprog;
002
003import java.io.File;
004import java.util.ArrayList;
005import java.util.List;
006import java.util.jar.JarFile;
007import jmri.InstanceManager;
008import jmri.jmrit.XmlFile;
009import jmri.util.FileUtil;
010import jmri.util.XmlFilenameFilter;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Functions for use with programmer files, including the default file name.
016 * <p>
017 * This was refactored from LocoSelPane in JMRI 1.5.3, which was the right
018 * thing to do anyway. But the real reason was that on MacOS Classic the static
019 * member holding the default programmer name was being overwritten when the
020 * class was (erroneously) initialized for a second time. This refactoring did
021 * not fix the problem. What did fix it was an ugly hack in the
022 * {@link CombinedLocoSelPane} class; see comments there for more information.
023 *
024 * @author Bob Jacobsen Copyright (C) 2001, 2002
025 */
026public class ProgDefault {
027
028    static public String[] findListOfProgFiles() {
029        // create an array of file names from prefs/programmers, count entries
030        int np = 0;
031        String[] sp = {};
032        FileUtil.createDirectory(FileUtil.getUserFilesPath() + "programmers");
033        File fp = new File(FileUtil.getUserFilesPath() + "programmers");
034        XmlFilenameFilter filter = new XmlFilenameFilter();
035        if (fp.exists()) {
036            sp = fp.list(filter);
037            if (sp != null) {
038                np = sp.length;
039            } else {
040                sp = new String[]{};
041                np = 0;
042            }
043        } else {
044            log.warn("{}programmers was missing, though tried to create it", FileUtil.getUserFilesPath());
045        }
046        if (log.isDebugEnabled()) {
047            log.debug("Got {} programmers from {}", np, fp.getPath());
048        }
049        // create an array of file names from xml/programmers, count entries
050        fp = new File(XmlFile.xmlDir() + "programmers");
051        int nx = 0;
052        String[] sx = {};
053        if (fp.exists()) {
054            sx = fp.list(filter);
055            if (sx != null) {
056                nx = sx.length;
057            } else {
058                sx = new String[]{};
059            }
060            log.debug("Got {} programmers from {}", nx, fp.getPath());
061        } else {
062            // create an array of file names from jmri.jar!xml/programmers, count entries
063            List<String> sr = new ArrayList<>();
064            JarFile jar = FileUtil.jmriJarFile();
065            if (jar != null) {
066                jar.stream().forEach((je) -> {
067                    String name = je.getName();
068                    if (name.startsWith("xml" + File.separator + "programmers") && name.endsWith(".xml")) {
069                        sr.add(name.substring(name.lastIndexOf(File.separator)));
070                    }
071                });
072                sx = sr.toArray(new String[sr.size()]);
073                nx = sx.length;
074                log.debug("Got {} programmers from jmri.jar", nx);
075            }
076        }
077        // copy the programmer entries to the final array
078        // note: this results in duplicate entries if the same name is also local.
079        // But for now I can live with that.
080        String sbox[] = new String[np + nx];
081        int n = 0;
082        if (np > 0) {
083            for (String s : sp) {
084                sbox[n++] = s.substring(0, s.length() - 4);
085            }
086        }
087        if (nx > 0) {
088            for (String s : sx) {
089                sbox[n++] = s.substring(0, s.length() - 4);
090            }
091        }
092        return sbox;
093    }
094
095    synchronized static public String getDefaultProgFile() {
096        return InstanceManager.getDefault(ProgrammerConfigManager.class).getDefaultFile();
097    }
098
099    synchronized static public void setDefaultProgFile(String s) {
100        InstanceManager.getDefault(ProgrammerConfigManager.class).setDefaultFile(s);
101    }
102
103    private final static Logger log = LoggerFactory.getLogger(ProgDefault.class);
104}