// Copyright © 2011-2020 Andy Goryachev <[email protected]> package goryachev.common.util; import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.util.Properties; public class CFileSettings implements CSettings.Provider { private File file; private Properties properties; private boolean sorted; public CFileSettings(File f) { this.file = f; this.properties = new Properties(); } public File getFile() { return file; } public void setSorted(boolean on) { sorted = on; } public boolean isSorted() { return sorted; } public String getProperty(String key) { return properties.getProperty(key); } public void setProperty(String key, String value) { if(value == null) { properties.remove(key); } else { properties.setProperty(key, value); } } public CList<String> getPropertyNames() { return new CList<String>(properties.stringPropertyNames()); } public void load() throws Exception { load(getFile()); } public void load(File f) throws Exception { BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); try { properties.load(in); } finally { CKit.close(in); } } public void save() throws Exception { save(getFile()); } public void save(File f) throws Exception { FileTools.ensureParentFolder(f); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "8859_1")); try { save(out); } finally { CKit.close(out); } } protected void save(BufferedWriter wr) throws Exception { synchronized(properties) { CList<String> keys = new CList(properties.stringPropertyNames()); if(sorted) { CComparator.sortStrings(keys); } for(String key: keys) { String val = properties.getProperty(key); key = saveConvert(key, true); val = saveConvert(val, false); wr.write(key); wr.write('='); wr.write(val); wr.newLine(); } } wr.flush(); } protected String saveConvert(String s, boolean escapeSpace) { int len = s.length(); int sz = len + len; if(sz < 0) { sz = Integer.MAX_VALUE; } StringBuffer sb = new StringBuffer(sz); for(int i=0; i<len; i++) { char ch = s.charAt(i); if((ch > 61) && (ch < 127)) { if(ch == '\\') { sb.append('\\'); sb.append('\\'); continue; } sb.append(ch); continue; } switch(ch) { case ' ': if(i == 0 || escapeSpace) { sb.append('\\'); } sb.append(' '); break; case '\t': sb.append('\\'); sb.append('t'); break; case '\n': sb.append('\\'); sb.append('n'); break; case '\r': sb.append('\\'); sb.append('r'); break; case '\f': sb.append('\\'); sb.append('f'); break; case '=': case ':': case '#': case '!': sb.append('\\'); sb.append(ch); break; default: if((ch < 0x0020) || (ch > 0x007e)) { sb.append('\\'); sb.append('u'); sb.append(Hex.toHexChar((ch >> 12) & 0xF)); sb.append(Hex.toHexChar((ch >> 8) & 0xF)); sb.append(Hex.toHexChar((ch >> 4) & 0xF)); sb.append(Hex.toHexChar(ch & 0xF)); } else { sb.append(ch); } } } return sb.toString(); } public static CFileSettings loadQuiet(File f) { CFileSettings s = new CFileSettings(f); s.setSorted(true); try { s.load(); } catch(Exception e) { } return s; } public void clear() { properties.clear(); } }