package com.mfh.comna.comn.cfg; import android.util.Pair; import com.mfh.comna.api.helper.AppHelper; import com.mfh.comn.config.SingleConfiguration; import com.mfh.comna.bizz.BizApplication; import com.mfh.comna.comn.database.dao.BaseFao; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * 单配置文件实现类基类 * * @author zhangyz created on 2013-5-26 * @since Framework 1.0 */ public abstract class BaseFileConfiguration implements SingleConfiguration{ public final static String FROM_ASSETS = "assets"; //资源文件的assets目录 public final static String FROM_INTERN = "intern";//内部存储的私有文件目录 public final static String FROM_EXTERN = "extern";//外部存储的文件目录 public final static String FROM_RAW = "raw"; //资源文件的raw目录 public final static String FROM_CLASSPATH = "classpath"; public final static String FROM_SERVER = "server"; protected String fromConfigPath;//原始来源 protected boolean bUpdated = false;//是否发生过修改 public BaseFileConfiguration() { super(); } /** * 执行修改提交,子类继承。注意子类发生修改时必须更改bUpdated标志为true。 * @param fos * @throws Exception * @author zhangyz created on 2013-5-26 */ protected abstract void writeCommitInner(OutputStream fos) throws Exception; private File unionFileDir(File dir, String filePath) { String absDirPath = dir.getAbsolutePath(); if (absDirPath.endsWith("/") == false) absDirPath += "/"; int index = filePath.lastIndexOf("/"); if (index > 0) { String rDir = filePath.substring(0, index + 1); if (rDir != null && rDir.length() > 0) absDirPath += rDir; filePath = filePath.substring(index + 1); } File file = new File (absDirPath, filePath); return file; } public static Pair<String, String> genPreAndPath(String configPath) { String[] strs = StringUtils.splitByWholeSeparator(configPath, ":"); String pre = FROM_ASSETS; String factPath = configPath; if (strs.length == 2) { pre = strs[0]; factPath = strs[1]; } Pair<String, String> ret = new Pair<String, String> (pre, factPath); return ret; } /** * 获取本配置文件可输出的文件对象 * @return * @author zhangyz created on 2013-5-26 */ public File getWriteAbleFile() { if (fromConfigPath == null) throw new RuntimeException("配置文件路径未指定!"); File fileOut; Pair<String, String> pair = genPreAndPath(fromConfigPath); String pre = pair.first; String factPath = pair.second; if (pre.equals(FROM_INTERN)) { File dir = BizApplication.getAppContext().getFilesDir(); fileOut = unionFileDir(dir, factPath); } else if (pre.equals(FROM_EXTERN)) { File dir = BizApplication.getAppContext().getExternalFilesDir(null); fileOut = unionFileDir(dir, factPath); } else throw new RuntimeException(pre + "类型的文件不支持写入"); if (fileOut.exists() == false) { if (fileOut.getParentFile().exists() == false) fileOut.getParentFile().mkdirs(); try { fileOut.createNewFile(); } catch (IOException e) { throw new RuntimeException("创建文件失败:" + e.getMessage(), e); } } return fileOut; } /** * 根据配置文件的位置读取出文件流 * @param configPath 具有文件来源前缀 * @return * @throws Exception * @author zhangyz created on 2013-5-26 */ protected InputStream readStream(String configPath) throws Exception{ this.fromConfigPath = configPath; Pair<String, String> pair = genPreAndPath(configPath); String pre = pair.first; String factPath = pair.second; try { if (pre.equals(FROM_ASSETS)) { return AppHelper.getAm().open(factPath); } else if (pre.equals(FROM_INTERN)) { File dir = BizApplication.getAppContext().getFilesDir(); File file = unionFileDir(dir, factPath); return new FileInputStream(file); } else if (pre.equals(FROM_EXTERN)) { File dir = BizApplication.getAppContext().getExternalFilesDir(null); File file = unionFileDir(dir, factPath); return new FileInputStream(file); } else if (pre.equals(FROM_RAW)) { int rId = Integer.parseInt(factPath); return BizApplication.getAppContext().getResources().openRawResource(rId); } else if (pre.equals(FROM_CLASSPATH)) {//似乎不起作用 if (factPath.startsWith("/") == false) factPath = "/" + factPath; return BaseFileConfiguration.class.getClassLoader().getResourceAsStream(factPath); } else if (pre.equals(FROM_SERVER)) { return BaseFao.returnSteam(factPath); } else throw new RuntimeException("不支持的配置文件来源协议:" + pre); } catch(IOException ex) { //IO异常,说明文件可能不存在 LoggerFactory.getLogger(((Object)this).getClass()).warn("读取配置文件" + configPath + "失败,可能损坏或不存在:" + ex.getMessage(), ex); return null; } } @Override public InputStream getReadStream() { try { return readStream(fromConfigPath); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void commitWrite() { if (!bUpdated) return; File file = this.getWriteAbleFile(); FileOutputStream fos = null; try { fos = new FileOutputStream(file); // 将Properties集合保存到流中 writeCommitInner(fos); } catch(Exception ex) { throw new RuntimeException("保存配置文件失败:" + ex.getMessage()); } finally { if (fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }