---
# System prepended metadata

title: JsonFileConfig
tags: [tirc-library]

---

---
tags: tirc-library
---

# JsonFileConfig

### maven

```xml=
<dependency>
    <groupId>tirc.lib</groupId>
    <artifactId>json_file_config</artifactId>
    <version>1.0.0</version>
</dependency>
```

目前版本與OOError專案相依

https://hackmd.io/@tirc/ryvdhgzJP

## 主要目的
* 提供以Json格式將參數檔寫入與讀取的功能
* 提供從jar檔中直接讀取參數檔功能
* 提供檔案加解密功能

## 主要元件
### JsonFileManager
主要用來將物件以json的格式存成檔案，
以及從檔案回復成物件等功能
(如果顯示異常可將code貼到mermaid online editor觀看)
```mermaid
classDiagram
class JsonFileManager{
    +save(String fileName, Object o) BaseErr
    +save(String path, String fileName, Object o) BaseErr
    +save(Object o, OutputStream outputStream) BaseErr
    +saveWithCipherKey(String fileName, String cipherKey, Object o) BaseErr
    +readWithCipherKey(String fileName, String cipherKey, Class~T~ type) Result~T~
    +read(String fileName, Class~T~ type) Result~T~
    +readORCopyDefault(String fileName, String defaultName, Class~T~ type) Result~T~
    +readFromResource(String fileName, Class~T~ type) Result~T~
    +readFromString(String content, Class~T~ type) Result~T~
}
```

### BaseJsonConfig
可將欲存成Json的物件繼承此類別，
其中提供了一些複制、重載、列印成字串等方法

```mermaid
classDiagram
class BasicJsonConfig {
    +reload(String str) Result~? extends BasicJsonConfig~
    +copy(BasicJsonConfig config)
    +toString() String
}
```

### 讀寫Json檔案 ###

使用JsonFileManager物件進行Json檔案讀取

```java=
/** 讀取檔案
 * @param fileName 檔案名稱
 * @param valueType Json檔案類別
 * @return 回傳Json物件，或者是讀取錯誤
 */
<T> Result<T> read(String fileName, Class<T> valueType)

/** 儲存檔案
 * @param fileName 檔案名稱
 * @param object Json物件
 * @return 若有錯誤則回傳
 */
BaseErr save(String fileName, Object object)

/** 儲存檔案，自動產生資料檔
 * @param path 檔案路徑，若不存在則自動產生
 * @param fileName 檔案名稱
 * @param object Json物件
 * @return 若有錯誤則回傳
 */
public static BaseErr save(String path, String fileName, Object object)

/** 讀取檔案，若發現不存在則讀取default檔案
 * @param fileName 目標讀取檔案
 * @param defaultName default檔案
 * @param valueType 讀取的類別
 * @return 回傳Json物件，或者是讀取錯誤
 */
<T> Result<T> readORCopyDefault(String fileName, String defaultName, Class<T> valueType)

/** 讀取resource中的檔案，目前使用來讀取jar檔中的內容
 * @param fileName 目標讀取檔案
 * @param valueType 讀取的類別
 * @return 回傳Json物件，或者是讀取錯誤
 */
<T> Result<T> readFromResource(String fileName, Class<T> valueType)
```

### 使用Json檔案輔助格式範例 ###

在繼承BasicJsonConfig類別後，即可使用 copy, reload, toString 等基本功能。
下列為MMA1_A1的部份參數參數檔

```java=
import java.io.File;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import tirc.lib.err.ret.Result;
import tirc.lib.json.BasicJsonConfig;
import tirc.lib.json.JsonFileManager;

@JsonIgnoreProperties(ignoreUnknown=true)
public class Settings extends BasicJsonConfig {
    //儲存檔案的位置與名稱
    public final static String FILE_NAME = "settings.json";
    public final static String FILE_PATH = System.getenv("PUBLIC") + File.separator + "MMA1_A1";
    public final static String FILE_NAME_WITH_PATH = FILE_PATH + File.separator + FILE_NAME;
    public final static int REQUIRE_FILE_VERSION = 1;
	
    protected Settings(){}
	
    private static Settings instance = null;
    public static Settings getInstance(){
        if(instance == null){
            Result<Settings> ret = JsonFileManager.read(FILE_NAME_WITH_PATH, Settings.class);
            if(!ret.isSuccess()) {
                System.out.println("Read file fail! reason:" + ret.getErrToString());
                createInstanceAndSave();
            } else {
                if(REQUIRE_FILE_VERSION != ret.getData().ver) {
                    System.out.printf("Found different version json file! override it! expect: %d read: %d\n",
                    REQUIRE_FILE_VERSION, ret.getData().ver);
                    createInstanceAndSave();
                }else
                    instance = ret.getData();
            }
        }
        return instance;
    }
	
    private static void createInstanceAndSave() {
        instance = new Settings();
        instance.setVer( REQUIRE_FILE_VERSION );
        JsonFileManager.save(FILE_PATH, FILE_NAME, instance);
    }
	
    @JsonIgnore
    public Result<? extends BasicJsonConfig> onFileChange() {
        Result ret = super.onFileChange();
        System.out.println("onFileChange: " + toString());
        return ret;
    }
	
    public Result<?> reload(){
        return reload(FILE_NAME_WITH_PATH);
    }
	
    public void save() {
        JsonFileManager.save(FILE_PATH, FILE_NAME, instance);
    }
	
    @JsonIgnore
    public String getWatchFileName() {
        return FILE_NAME;
    }
    
    @JsonIgnore
    public String getWatchFileFullPath() {
        return FILE_NAME_WITH_PATH;
    }
	
    //這邊放需要記錄的參數，記得產生getter與setter
    private int liquefactionTubeQrcodeReaderPort=2112;
    private String plc1Ip="simulator";	

    public int getLiquefactionTubeQrcodeReaderPort() {
        return liquefactionTubeQrcodeReaderPort;
    }

    public void setLiquefactionTubeQrcodeReaderPort(int liquefactionTubeQrcodeReaderPort) {
        this.liquefactionTubeQrcodeReaderPort = liquefactionTubeQrcodeReaderPort;
    }

    public String getPlc1Ip() {
        return plc1Ip;
    }

    public void setPlc1Ip(String plc1Ip) {
        this.plc1Ip = plc1Ip;
    }
}
```
使用參數檔案功能
```java=
Settings.getInstance();
```

### 檔案監控 ###

在檔案發生修改時觸發原檔案更新，輸入的BasicJsonConfig物件需複寫下列方法，才能自動提供檔案監控機制。
* getWatchFileName方法：以提供欲監控檔案名稱。
* getWatchFileFullPath方法：以提供完整路徑，用來reload檔案。

```java=
FileWatcher fw = new FileWatcher(); 
fw.setWatchFolder(".");
fw.addWatchFile( basicJsonConfig );
fw.init();
```

客製化檔案修改發生時事件範例

```java=
FileWatcher fw = new FileWatcher();
fw.setWatchFolder(".");
fw.addWatchFile( file_name , new IFileWatchListener() {
    public void onNotify(Kind<?> kind, String fileName) {
        if(kind == StandardWatchEventKinds.ENTRY_MODIFY) {
            // put your code here
        }
    }
});
fw.init();
```

程式結束時記得呼叫

```java=
fw.deinit();
```


## Release Note ##
### v1.0.0 Release date: 2021.2.2 ###
* 移除test_tool相依性，將測項移至LibraryTestReportProject

### v0.0.4 Release date: 2020.3.16 ###
* 更新test_tool版本至v0.2
* 建置程式時加入原始碼

### v0.0.3 Release date: 2019.10.16 ###
* 重要修正：存檔時強制更改為UTF-8

### v0.0.2 Release date: 2018.8.29 ###
* 增加加密檔案讀取與儲存功能

### v0.0.1 Release date: 2018.4.24 ###
* 支援將物件以json格存儲存與讀取
* 支援若使用者參數檔不存在，則程式開啟時自動複製Default參數檔功能
* 支援修改檔案時即時更新記憶體中物件
* 支援讀取jar檔中唯讀型態之檔案格式
* 可自動列印與複製物件內所有變數