001package jmri.jmrit.operations.rollingstock.cars;
002
003import java.io.File;
004
005import org.jdom2.Document;
006import org.jdom2.Element;
007import org.jdom2.ProcessingInstruction;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011import jmri.InstanceManager;
012import jmri.InstanceManagerAutoDefault;
013import jmri.InstanceManagerAutoInitialize;
014import jmri.jmrit.operations.OperationsXml;
015import jmri.jmrit.operations.locations.LocationManagerXml;
016import jmri.jmrit.operations.rollingstock.RollingStockLogger;
017import jmri.jmrit.operations.setup.OperationsSetupXml;
018import jmri.jmrit.operations.setup.Setup;
019
020/**
021 * Loads and stores cars using xml files. Also loads and stores car road names,
022 * car types, car colors, car lengths, car owners, and car kernels.
023 *
024 * @author Daniel Boudreau Copyright (C) 2008
025 */
026public class CarManagerXml extends OperationsXml implements InstanceManagerAutoDefault, InstanceManagerAutoInitialize {
027    
028    // the directories under operations
029    static final String CAR_ROUTER_REPORTS = "carRouterReports"; // NOI18N
030    // sub directory under CAR_ROUTER_REPORTS
031    static final String CAR_ROUTER_REPORTS_RAW = "carRouterReports";
032    
033    public CarManagerXml() {
034    }
035
036    @Override
037    public void writeFile(String name) throws java.io.FileNotFoundException, java.io.IOException {
038        log.debug("writeFile {}", name);
039        // This is taken in large part from "Java and XML" page 368
040        File file = findFile(name);
041        if (file == null) {
042            file = new File(name);
043        }
044        // create root element
045        Element root = new Element("operations-config"); // NOI18N
046        Document doc = newDocument(root, dtdLocation + "operations-cars.dtd"); // NOI18N
047
048        // add XSLT processing instruction
049        java.util.Map<String, String> m = new java.util.HashMap<String, String>();
050        m.put("type", "text/xsl"); // NOI18N
051        m.put("href", xsltLocation + "operations-cars.xsl"); // NOI18N
052        ProcessingInstruction p = new ProcessingInstruction("xml-stylesheet", m); // NOI18N
053        doc.addContent(0, p);
054
055        // note all comments line feeds have been changed to processor directives
056        InstanceManager.getDefault(CarRoads.class).store(root);
057        InstanceManager.getDefault(CarTypes.class).store(root);
058        InstanceManager.getDefault(CarColors.class).store(root);
059        InstanceManager.getDefault(CarLengths.class).store(root);
060        InstanceManager.getDefault(CarOwners.class).store(root);
061        InstanceManager.getDefault(CarLoads.class).store(root);
062        InstanceManager.getDefault(KernelManager.class).store(root);
063        InstanceManager.getDefault(CarManager.class).store(root);
064
065        writeXML(file, doc);
066
067        // done - car file now stored, so can't be dirty
068        setDirty(false);
069    }
070
071    /**
072     * Read the contents of a roster XML file into this object. Note that this
073     * does not clear any existing entries.
074     */
075    @Override
076    public void readFile(String name) throws org.jdom2.JDOMException, java.io.IOException {
077        // suppress rootFromName(name) warning message by checking to see if file exists
078        if (findFile(name) == null) {
079            log.debug("{} file could not be found", name);
080            return;
081        }
082        // find root
083        Element root = rootFromName(name);
084        if (root == null) {
085            log.debug("{} file could not be read", name);
086            return;
087        }
088        
089        if (!root.getName().equals("operations-config")) {
090            log.warn("OperationsPro car file corrupted");
091            return;
092        }
093
094        InstanceManager.getDefault(CarRoads.class).load(root);
095        InstanceManager.getDefault(CarTypes.class).load(root);
096        InstanceManager.getDefault(CarColors.class).load(root);
097        InstanceManager.getDefault(CarLengths.class).load(root);
098        InstanceManager.getDefault(CarOwners.class).load(root);
099        InstanceManager.getDefault(CarLoads.class).load(root);
100        InstanceManager.getDefault(KernelManager.class).load(root);
101        InstanceManager.getDefault(CarManager.class).load(root);
102
103        log.debug("Cars have been loaded!");
104        InstanceManager.getDefault(RollingStockLogger.class).enableCarLogging(Setup.isCarLoggerEnabled());
105        // clear dirty bit
106        setDirty(false);
107        // clear location dirty flag, locations get modified during the loading of cars and locos
108        InstanceManager.getDefault(LocationManagerXml.class).setDirty(false);
109    }
110
111    @Override
112    public void setOperationsFileName(String name) {
113        operationsFileName = name;
114    }
115
116    @Override
117    public String getOperationsFileName() {
118        return operationsFileName;
119    }
120
121    private String operationsFileName = "OperationsCarRoster.xml"; // NOI18N
122    
123    public File createCarRouterReportFile(String name) {
124        return createFile(defaultCarRouterReportFileName(name), false); // don't backup
125    }
126
127    public File getCarRouterReportFile(String name) {
128        File file = new File(defaultCarRouterReportFileName(name));
129        return file;
130    }
131
132    public String defaultCarRouterReportFileName(String name) {
133        return OperationsXml.getFileLocation()
134                + OperationsXml.getOperationsDirectoryName()
135                + File.separator
136                + CAR_ROUTER_REPORTS
137                + File.separator
138                + Bundle.getMessage("RoutingReportCar", name);
139    }
140    
141    public File createRawCarRouterReportFile(String name) {
142        // must create 1st level directory first
143        createFile(defaultCarRouterReportFileName(name), false);
144        return createFile(defaultRawCarRouterReportFileName(name), false); // don't backup
145    }
146
147    public File getRawCarRouterReportFile(String name) {
148        File file = new File(defaultRawCarRouterReportFileName(name));
149        return file;
150    }
151
152    public String defaultRawCarRouterReportFileName(String name) {
153        return OperationsXml.getFileLocation()
154                + OperationsXml.getOperationsDirectoryName()
155                + File.separator
156                + CAR_ROUTER_REPORTS
157                + File.separator
158                + CAR_ROUTER_REPORTS_RAW
159                + File.separator
160                + Bundle.getMessage("RoutingReportCar", name);
161    }
162
163
164    public void dispose() {
165    }
166
167    private final static Logger log = LoggerFactory.getLogger(CarManagerXml.class);
168
169    @Override
170    public void initialize() {
171        InstanceManager.getDefault(OperationsSetupXml.class); // load setup
172        InstanceManager.getDefault(LocationManagerXml.class); // load locations
173        CarManagerXml.this.load();
174    }
175}