001/**
002 * Copyright (C) 2014  Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
003 *
004 * This file is part of Dicoogle/dicoogle-sdk.
005 *
006 * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Dicoogle.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package pt.ua.dicoogle.sdk.settings;
020
021import java.io.BufferedOutputStream;
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.FileOutputStream;
025import java.io.IOException;
026import java.nio.MappedByteBuffer;
027import java.nio.channels.FileChannel;
028import java.nio.charset.Charset;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032
033/**
034 * @author: Frederico Valente
035 * 
036 * This object will be serialized to disk before shutdown and on configuration save.
037 * 
038 */
039public class Settings{
040    
041    private static final Logger log = LoggerFactory.getLogger(Settings.class);
042    
043    File settingsXmlFile; //xml file handler
044    String settingsXmlString;//xml file contents
045    
046    /**
047     * 
048     * @param settingsXmlFile an xml file pointing to the settings
049     * @throws IOException 
050     */
051    public Settings(File settingsXmlFile) throws IOException{
052        log.debug("Loading settings from: {}", settingsXmlFile.getAbsolutePath());
053        this.settingsXmlFile = settingsXmlFile;
054        
055        //creates the settings file if it does not exist
056        if(!settingsXmlFile.exists()){
057            settingsXmlFile.createNewFile();
058            settingsXmlString = "";
059            return;
060        }
061        
062        reload();
063    }
064
065    /**
066     * Given an xml string (possibly from an editor), makes it the current settings and stores it in disk
067     * @param xml
068     * @throws IOException 
069     */
070    public void setXml(String xml) throws IOException{
071        settingsXmlString = xml;
072        save();
073    }
074    
075    /**
076     * reloads the xml file
077     */
078    public final void reload() throws IOException{
079        //we have a settings file, lets read it to the string
080        try (FileInputStream stream = new FileInputStream(settingsXmlFile)) {
081            FileChannel fc = stream.getChannel();
082            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
083            String xmlSettings = Charset.defaultCharset().decode(bb).toString();
084            settingsXmlString = xmlSettings;
085        }
086        
087        log.debug("Settings for: {}", settingsXmlFile.getAbsolutePath());
088        log.debug(settingsXmlString);
089        log.debug("...");
090    }
091    
092    /**
093    * Saves the settings xml to disk (on the path provided to the constructor)
094    * TODO: this is poorly done, we should save to a tmp file and then move the files
095    * as opposed to just write on top of the old file
096    * TODO: also, we should validate the xml
097    */
098    public void save() throws IOException{
099        try(FileOutputStream fileOutputStream = new FileOutputStream(settingsXmlFile, true)){
100            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
101            bufferedOutputStream.write(settingsXmlString.getBytes(Charset.defaultCharset()));
102            bufferedOutputStream.flush();
103        }
104    }
105    
106    /**
107     * 
108     * @return the xml contents of the file
109     */
110    public String getXml(){return settingsXmlString;}
111    
112    /*
113     * Helper methods below
114     */
115    public String field(String name){return null;}
116    public int fieldAsInt(String name){return 0;}
117    public double fieldAsDouble(String name){return 0.0;}
118}