001package arcommon.persistens;
002
003import java.io.BufferedWriter;
004import java.io.IOException;
005import java.io.Serializable;
006
007import arcommon.FileUtil;
008import arcommon.StringUtil;
009import arcommon.xml.XmlUtil;
010
011
012public class ObjectFile<T extends Serializable> {
013    private String fileName;
014    private String originalContent;
015    private T object;
016    private boolean saveUsingTempFile;
017    
018    public ObjectFile(String pfileName, T defaultObject) {
019        this(pfileName, defaultObject, true);
020    }
021    
022    @SuppressWarnings("unchecked")
023    public ObjectFile(String pfileName, T defaultObject, boolean psaveUsingTempFile) {
024        fileName = pfileName;
025        saveUsingTempFile = psaveUsingTempFile;
026        if (FileUtil.exists(fileName)) {
027            originalContent = FileUtil.readFile(fileName, XmlUtil.XML_ENCODING);
028            object = (T)XmlUtil.xmlStringToObject(originalContent);
029            if (object == null) {
030                throw new RuntimeException("object == null " + pfileName + "   " + originalContent);
031            }
032            if (!object.getClass().equals(defaultObject.getClass())) {
033                throw new ClassCastException("loadedObject.getClass() != defaultObject.getClass() " + object.getClass().getName() + " != " + defaultObject.getClass().getName());
034            }
035        } else {
036            object = defaultObject;
037        }
038    }
039    
040    public String getFileName() {
041        return fileName;
042    }
043    
044    public void setFileName(String pfileName) {
045        if (StringUtil.stringEquals(fileName, pfileName)) {
046            return ;
047        }
048        
049        fileName = pfileName;
050        originalContent = null;
051    }
052
053    public void setObject(T pobject) {
054        object = pobject;
055        originalContent = null;
056    }
057    
058    public T getObject() {
059        return object;
060    }
061    
062    public boolean saveIfChanged() {
063        String newXmlString = XmlUtil.objectToXmlString(object);
064        if (newXmlString.equals(originalContent)) {
065            return false;
066        }
067        
068        saveAlways(newXmlString);
069        return true;
070    }
071    
072    public void saveAlways() {
073        String newXmlString = XmlUtil.objectToXmlString(object);
074        saveAlways(newXmlString);
075    }
076    
077    private void saveAlways(final String newXmlString) {
078        if (saveUsingTempFile && originalContent != null) {
079            FileUtil.WriteUsingTempFileAction saveUsingTempFileAction = new FileUtil.WriteUsingTempFileAction() {
080                @Override
081                public void saveFile(String tempFileName, boolean append, String encoding) throws IOException {
082                    FileUtil.writeFile(tempFileName, newXmlString, false, XmlUtil.XML_ENCODING);
083                }
084                
085                @Override
086                public void writeContentOfFile(BufferedWriter out) throws IOException {
087                    throw new RuntimeException("Internal error. Should not be called");
088                }
089                
090                @Override
091                public boolean backupOldFile() {
092                    return false;
093                }
094            };
095            FileUtil.writeUsingTempFile(fileName, saveUsingTempFileAction);
096        } else {
097            FileUtil.writeFile(fileName, newXmlString, false, XmlUtil.XML_ENCODING);
098        }
099        
100        originalContent = newXmlString;
101    }
102    
103    @Override
104    public String toString() {
105        return fileName;
106    }
107}