mirror of
				https://github.com/lacerta-doc/Lacerta.git
				synced 2025-09-09 12:09:25 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/develop' into feature/library/add_document_list
This commit is contained in:
		
						commit
						a03f7111cc
					
				
							
								
								
									
										17
									
								
								.github/ISSUE_TEMPLATE/不具合用テンプレート.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/ISSUE_TEMPLATE/不具合用テンプレート.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
---
 | 
			
		||||
name: 不具合用テンプレート
 | 
			
		||||
about: 不具合用テンプレート
 | 
			
		||||
title: "[BUG]: "
 | 
			
		||||
labels: バグ
 | 
			
		||||
assignees: ''
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# 概要
 | 
			
		||||
<!-- Issueの概要 -->
 | 
			
		||||
 | 
			
		||||
# 詳細
 | 
			
		||||
<!-- バグの詳細 -->
 | 
			
		||||
 | 
			
		||||
# 影響箇所
 | 
			
		||||
<!-- 予想される影響箇所(省略可) -->
 | 
			
		||||
							
								
								
									
										17
									
								
								.github/ISSUE_TEMPLATE/改善用テンプレート.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/ISSUE_TEMPLATE/改善用テンプレート.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
---
 | 
			
		||||
name: 改善用テンプレート
 | 
			
		||||
about: 改善用テンプレート
 | 
			
		||||
title: "[IMPROVE]"
 | 
			
		||||
labels: ''
 | 
			
		||||
assignees: ''
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# 概要
 | 
			
		||||
<!-- Issueの概要 -->
 | 
			
		||||
 | 
			
		||||
# 詳細
 | 
			
		||||
<!-- 改善内容の詳細 -->
 | 
			
		||||
 | 
			
		||||
# 影響箇所
 | 
			
		||||
<!-- 予想される影響箇所(省略可) -->
 | 
			
		||||
							
								
								
									
										16
									
								
								.github/ISSUE_TEMPLATE/新機能用テンプレート.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/ISSUE_TEMPLATE/新機能用テンプレート.md
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,10 +1,20 @@
 | 
			
		|||
---
 | 
			
		||||
name: 新機能用テンプレート
 | 
			
		||||
about: 新規開発Issue用テンプレート
 | 
			
		||||
about: 新規能用テンプレート
 | 
			
		||||
title: ''
 | 
			
		||||
labels: ''
 | 
			
		||||
labels: 新機能
 | 
			
		||||
assignees: ''
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
WIP
 | 
			
		||||
# 概要
 | 
			
		||||
<!-- Issueの概要 -->
 | 
			
		||||
 | 
			
		||||
# 詳細
 | 
			
		||||
<!-- 機能の詳細 -->
 | 
			
		||||
 | 
			
		||||
# 関連Issue
 | 
			
		||||
<!-- 関連するIssueがあれば -->
 | 
			
		||||
 | 
			
		||||
# 影響箇所
 | 
			
		||||
<!-- 予想される影響箇所(省略可) -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								.github/PULL_REQUEST_TEMPLATE/general.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.github/PULL_REQUEST_TEMPLATE/general.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
# 概要
 | 
			
		||||
<!-- PRの概要 -->
 | 
			
		||||
 | 
			
		||||
# 関連Issue
 | 
			
		||||
- #000 <!-- 関連するIssueを指定(なければ省略可) -->
 | 
			
		||||
 | 
			
		||||
# 詳細
 | 
			
		||||
<!-- 詳細 -->
 | 
			
		||||
 | 
			
		||||
# 影響箇所
 | 
			
		||||
<!-- 予想される影響箇所 -->
 | 
			
		||||
 | 
			
		||||
# チェック
 | 
			
		||||
<!-- 参考用, 全てにチェックがついている必要があるわけではありません -->
 | 
			
		||||
- [ ] 機能として完成している
 | 
			
		||||
  - [ ] WIP(Work in progress: 作業中)
 | 
			
		||||
- [ ] 正常にビルド/起動ができる
 | 
			
		||||
- [ ] 既存の機能を壊していない
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,6 @@
 | 
			
		|||
  <component name="GradleSettings">
 | 
			
		||||
    <option name="linkedExternalProjectsSettings">
 | 
			
		||||
      <GradleProjectSettings>
 | 
			
		||||
        <option name="testRunner" value="GRADLE" />
 | 
			
		||||
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
 | 
			
		||||
        <option name="gradleJvm" value="jbr-17" />
 | 
			
		||||
        <option name="modules">
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +29,7 @@
 | 
			
		|||
            <option value="$PROJECT_DIR$/shared/ui" />
 | 
			
		||||
            <option value="$PROJECT_DIR$/source" />
 | 
			
		||||
            <option value="$PROJECT_DIR$/utils" />
 | 
			
		||||
            <option value="$PROJECT_DIR$/vcs" />
 | 
			
		||||
          </set>
 | 
			
		||||
        </option>
 | 
			
		||||
        <option name="resolveExternalAnnotations" value="false" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ExternalStorageConfigurationManager" enabled="true" />
 | 
			
		||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
 | 
			
		||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
 | 
			
		||||
    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectType">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										40
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								README.md
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -4,6 +4,46 @@ WIP
 | 
			
		|||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## メモ
 | 
			
		||||
- アイコン: Google Material Icons https://fonts.google.com/icons (Weight:300, Grade:0, Optical size: 24px)
 | 
			
		||||
 | 
			
		||||
## モジュール構成
 | 
			
		||||
### モジュール一覧
 | 
			
		||||
- `component` : コンポーネント
 | 
			
		||||
  - `common` : 共通コンポーネント
 | 
			
		||||
    - UIの中で共通で使う要素(メニューアイテムとか)
 | 
			
		||||
  - `scanner` : スキャナー
 | 
			
		||||
    - スキャナーの実装
 | 
			
		||||
  - `viewer` : ビューワー
 | 
			
		||||
    - ドキュメントビューワーの実装
 | 
			
		||||
- `data` : データ
 | 
			
		||||
  - UIからデータを取得/保存するためのラッパーモジュール
 | 
			
		||||
  - `Document` : ドキュメント関係
 | 
			
		||||
    - WIP(JavaDocを参照してください, 余裕があったら追記します)
 | 
			
		||||
- `feature` : 機能モジュール(ナビゲーションからみた機能で分割)
 | 
			
		||||
  - `common`: 共通機能
 | 
			
		||||
    - 設定画面とか、どこからでも呼ばれうる画面
 | 
			
		||||
  - `debug`: デバッグメニュー
 | 
			
		||||
  - `home`: ホーム画面
 | 
			
		||||
  - `library`: ライブラリ画面
 | 
			
		||||
  - `scan`: スキャン画面
 | 
			
		||||
  - `search`: 検索画面
 | 
			
		||||
- `model` : モデル
 | 
			
		||||
  - データモデルをまとめたモジュール (WIP)
 | 
			
		||||
  - `document` : ドキュメント
 | 
			
		||||
  - `meta` : メタデータ
 | 
			
		||||
- `processor` : プロセッサ
 | 
			
		||||
  - いくつかの処理をまとめたモジュール
 | 
			
		||||
    - `DocumentProcessor` : ドキュメント処理(ドキュメントにページを追加したり更新したり) 
 | 
			
		||||
- `shared` : 
 | 
			
		||||
  - 共有リソース
 | 
			
		||||
- `source` : ソース
 | 
			
		||||
  - (バックエンドが使うのでとりあえず後回し、フロントから直接操作することは絶対にありません)
 | 
			
		||||
- `utils` : ユーティリティ
 | 
			
		||||
  - ちょっとしたユーティリティをまとめたモジュール
 | 
			
		||||
  - `LacertaLogger` : ロガー
 | 
			
		||||
  - `XmlMetaParser` : XMLメタデータパーサー(フロントから直接操作することは絶対にありません)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## コーディング規則/推奨(WIP)
 | 
			
		||||
### 規則
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,13 +11,35 @@ android {
 | 
			
		|||
        applicationId "one.nem.lacerta"
 | 
			
		||||
        minSdk 26
 | 
			
		||||
        targetSdk 33
 | 
			
		||||
 | 
			
		||||
        // ベータ, Internal, Release問わず毎回インクリメントする
 | 
			
		||||
        // https://developer.android.com/studio/publish/versioning#versioningsettings
 | 
			
		||||
        versionCode 1
 | 
			
		||||
        versionName "1.0"
 | 
			
		||||
        versionName "0.1.0"
 | 
			
		||||
 | 
			
		||||
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildTypes {
 | 
			
		||||
        debug { // 開発メンバー用
 | 
			
		||||
            debuggable true
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
 | 
			
		||||
            matchingFallbacks = ['release']
 | 
			
		||||
        }
 | 
			
		||||
        internal_release {
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
 | 
			
		||||
            matchingFallbacks = ['release']
 | 
			
		||||
        }
 | 
			
		||||
        beta_release {
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
 | 
			
		||||
            matchingFallbacks = ['release']
 | 
			
		||||
        }
 | 
			
		||||
        release {
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,17 @@
 | 
			
		|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools">
 | 
			
		||||
 | 
			
		||||
    <uses-feature
 | 
			
		||||
        android:name="android.hardware.camera"
 | 
			
		||||
        android:required="false" />
 | 
			
		||||
    <uses-permission android:name="android.permission.CAMERA" />
 | 
			
		||||
 | 
			
		||||
    <queries>
 | 
			
		||||
        <intent>
 | 
			
		||||
            <action android:name="android.media.action.IMAGE_CAPTURE" />
 | 
			
		||||
        </intent>
 | 
			
		||||
    </queries>
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:allowBackup="true"
 | 
			
		||||
        android:dataExtractionRules="@xml/data_extraction_rules"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +33,16 @@
 | 
			
		|||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
 | 
			
		||||
        <provider
 | 
			
		||||
            android:name="androidx.core.content.FileProvider"
 | 
			
		||||
            android:authorities="one.nem.lacerta.provider"
 | 
			
		||||
            android:exported="false"
 | 
			
		||||
            android:grantUriPermissions="true">
 | 
			
		||||
            <meta-data
 | 
			
		||||
                android:name="android.support.FILE_PROVIDER_PATHS"
 | 
			
		||||
                android:resource="@xml/file_paths" />
 | 
			
		||||
        </provider>
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
							
								
								
									
										4
									
								
								app/src/main/res/xml/provider_path.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								app/src/main/res/xml/provider_path.xml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<paths>
 | 
			
		||||
    <cache-path name="cache" path="." />
 | 
			
		||||
</paths>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
plugins {
 | 
			
		||||
    alias(libs.plugins.com.android.library)
 | 
			
		||||
    id 'com.google.dagger.hilt.android'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,5 +34,16 @@ dependencies {
 | 
			
		|||
    androidTestImplementation libs.androidx.test.ext.junit
 | 
			
		||||
    androidTestImplementation libs.androidx.test.espresso.core
 | 
			
		||||
 | 
			
		||||
    // Hilt (DI)
 | 
			
		||||
    implementation libs.com.google.dagger.hilt.android
 | 
			
		||||
    annotationProcessor libs.com.google.dagger.hilt.compiler
 | 
			
		||||
 | 
			
		||||
    implementation 'com.websitebeaver:documentscanner:1.0.0'
 | 
			
		||||
 | 
			
		||||
    implementation project(':shared:ui')
 | 
			
		||||
    implementation project(':model')
 | 
			
		||||
 | 
			
		||||
    implementation project(':processor')
 | 
			
		||||
 | 
			
		||||
    implementation project(':utils')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
package one.nem.lacerta.component.scanner;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public class CaptureResultAdapter extends RecyclerView.Adapter<CaptureResultAdapter.ViewHolder> {
 | 
			
		||||
    private final ArrayList<CapturedData> results;
 | 
			
		||||
 | 
			
		||||
    public CaptureResultAdapter(ArrayList<CapturedData> results) {
 | 
			
		||||
        this.results = results;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CaptureResultAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 | 
			
		||||
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_scanner_component_manager_stub, parent, false);
 | 
			
		||||
        return new CaptureResultAdapter.ViewHolder(view);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(CaptureResultAdapter.ViewHolder holder, int position) {
 | 
			
		||||
        CapturedData result = results.get(position);
 | 
			
		||||
        holder.textViewPath.setText(result.getPath());
 | 
			
		||||
        holder.textViewResolutionHeight.setText(result.getResolutionHeight());
 | 
			
		||||
        holder.textViewResolutionWidth.setText(result.getResolutionWidth());
 | 
			
		||||
        holder.imageView.setImageBitmap(result.getBitmap());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return results.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        public TextView textViewPath;
 | 
			
		||||
        public TextView textViewResolutionHeight;
 | 
			
		||||
        public TextView textViewResolutionWidth;
 | 
			
		||||
        public ImageView imageView;
 | 
			
		||||
 | 
			
		||||
        public ViewHolder(View view) {
 | 
			
		||||
            super(view);
 | 
			
		||||
            textViewPath = view.findViewById(R.id.textViewPath);
 | 
			
		||||
            textViewResolutionHeight = view.findViewById(R.id.textViewResHeight);
 | 
			
		||||
            textViewResolutionWidth = view.findViewById(R.id.textViewResWidth);
 | 
			
		||||
            imageView = view.findViewById(R.id.imageViewResult);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
package one.nem.lacerta.component.scanner;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
 | 
			
		||||
public class CapturedData {
 | 
			
		||||
 | 
			
		||||
    private String path;
 | 
			
		||||
    private String resolutionHeight;
 | 
			
		||||
    private String resolutionWidth;
 | 
			
		||||
    private String size;
 | 
			
		||||
    private Bitmap bitmap;
 | 
			
		||||
 | 
			
		||||
    // Constructor
 | 
			
		||||
 | 
			
		||||
    public CapturedData(String path, String resolutionHeight, String resolutionWidth, String size, Bitmap bitmap) {
 | 
			
		||||
        this.path = path;
 | 
			
		||||
        this.resolutionHeight = resolutionHeight;
 | 
			
		||||
        this.resolutionWidth = resolutionWidth;
 | 
			
		||||
        this.size = size;
 | 
			
		||||
        this.bitmap = bitmap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getters
 | 
			
		||||
 | 
			
		||||
    public String getPath() {
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getResolutionHeight() {
 | 
			
		||||
        return resolutionHeight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getResolutionWidth() {
 | 
			
		||||
        return resolutionWidth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getSize() {
 | 
			
		||||
        return size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Bitmap getBitmap() {
 | 
			
		||||
        return bitmap;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,250 @@
 | 
			
		|||
package one.nem.lacerta.component.scanner;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.activity.result.ActivityResultLauncher;
 | 
			
		||||
import androidx.activity.result.contract.ActivityResultContracts;
 | 
			
		||||
import androidx.core.content.FileProvider;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import android.os.Environment;
 | 
			
		||||
import android.provider.MediaStore;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.format.DateTimeFormatter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import dagger.hilt.android.AndroidEntryPoint;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentMeta;
 | 
			
		||||
import one.nem.lacerta.model.document.path.DocumentPath;
 | 
			
		||||
import one.nem.lacerta.processor.DocumentProcessor;
 | 
			
		||||
import one.nem.lacerta.processor.factory.DocumentProcessorFactory;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.repository.DeviceInfoUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link ScannerDataManagerStubFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
@AndroidEntryPoint
 | 
			
		||||
public class ScannerDataManagerStubFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: 時間があったらcacheを使うようにする?
 | 
			
		||||
 | 
			
		||||
    // Results
 | 
			
		||||
    private ArrayList<CapturedData> results = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    private Uri photoURI;
 | 
			
		||||
 | 
			
		||||
    private DocumentDetail documentDetail;
 | 
			
		||||
 | 
			
		||||
    private DocumentProcessor documentProcessor;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    DocumentProcessorFactory documentProcessorFactory;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    LacertaLogger logger;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    DeviceInfoUtils deviceInfoUtils;
 | 
			
		||||
 | 
			
		||||
    private final ActivityResultLauncher<Intent> cameraLauncher = registerForActivityResult(
 | 
			
		||||
            new ActivityResultContracts.StartActivityForResult(),
 | 
			
		||||
            result -> {
 | 
			
		||||
                if (result.getResultCode() == Activity.RESULT_OK) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        if (getActivity() == null) {
 | 
			
		||||
                            Log.d("ScannerDataManagerStubFragment", "getActivity() is null");
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (photoURI == null) {
 | 
			
		||||
                            Log.d("ScannerDataManagerStubFragment", "photoURI is null");
 | 
			
		||||
                            Toast.makeText(getActivity(), "photoURI is null", Toast.LENGTH_LONG).show();
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        Bitmap imageBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), photoURI);
 | 
			
		||||
                        results.add(new CapturedData("Placeholder", Integer.toString(imageBitmap.getHeight()), Integer.toString(imageBitmap.getWidth()), "Placeholder", imageBitmap));
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        Log.e("ScannerDataManagerStubFragment", "Error occurred while reading the file", e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    public ScannerDataManagerStubFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
    // TODO: Rename and change types and number of parameters
 | 
			
		||||
    public static ScannerDataManagerStubFragment newInstance() {
 | 
			
		||||
        ScannerDataManagerStubFragment fragment = new ScannerDataManagerStubFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        return inflater.inflate(R.layout.fragment_scanner_data_manager_stub, container, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onViewCreated(View view, Bundle savedInstanceState) {
 | 
			
		||||
        super.onViewCreated(view, savedInstanceState);
 | 
			
		||||
 | 
			
		||||
        view.findViewById(R.id.button_call_camera).setOnClickListener(v -> {
 | 
			
		||||
            Log.d("ScannerDataManagerStubFragment", "button_call_camera clicked");
 | 
			
		||||
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 | 
			
		||||
            if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
 | 
			
		||||
                File photoFile = null;
 | 
			
		||||
                try {
 | 
			
		||||
                    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
 | 
			
		||||
                    String imageFileName = "JPEG_" + timeStamp + "_";
 | 
			
		||||
                    File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
 | 
			
		||||
                    photoFile = File.createTempFile(imageFileName, ".jpg", storageDir);
 | 
			
		||||
                } catch (IOException ex) {
 | 
			
		||||
                    Log.e("ScannerDataManagerStubFragment", "Error occurred while creating the file", ex);
 | 
			
		||||
                }
 | 
			
		||||
                if (photoFile != null) {
 | 
			
		||||
                    photoURI = FileProvider.getUriForFile(getActivity(), "one.nem.lacerta.provider", photoFile);
 | 
			
		||||
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
 | 
			
		||||
                    cameraLauncher.launch(takePictureIntent);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    Log.d("ScannerDataManagerStubFragment", "photoFile is null");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                Log.d("ScannerDataManagerStubFragment", "camera not available");
 | 
			
		||||
            }
 | 
			
		||||
            updateResults();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        view.findViewById(R.id.button_create_documnent).setOnClickListener(v -> {
 | 
			
		||||
            Log.d("ScannerDataManagerStubFragment", "button_create_documnent clicked");
 | 
			
		||||
            Toast.makeText(getActivity(), "button_create_documnent clicked", Toast.LENGTH_LONG).show();
 | 
			
		||||
 | 
			
		||||
            this.documentDetail = createSampleDocumentDetail();
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        view.findViewById(R.id.button_init_document_processor).setOnClickListener(v -> {
 | 
			
		||||
            Log.d("ScannerDataManagerStubFragment", "button_init_document_processor clicked");
 | 
			
		||||
            Toast.makeText(getActivity(), "button_init_document_processor clicked", Toast.LENGTH_LONG).show();
 | 
			
		||||
            // TODO-rca: ここでDocumentProcessorを初期化する
 | 
			
		||||
            if (this.documentDetail == null) {
 | 
			
		||||
                Toast.makeText(getActivity(), "documentDetail is null", Toast.LENGTH_LONG).show();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            this.documentProcessor = documentProcessorFactory.create(this.documentDetail);
 | 
			
		||||
            Toast.makeText(getActivity(), "documentProcessor created", Toast.LENGTH_LONG).show();
 | 
			
		||||
            try {
 | 
			
		||||
                this.documentProcessor.init();
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                Toast.makeText(getActivity(), "Error occurred while initializing documentProcessor", Toast.LENGTH_LONG).show();
 | 
			
		||||
                Log.e("ScannerDataManagerStubFragment", "Error occurred while initializing documentProcessor", e);
 | 
			
		||||
            }
 | 
			
		||||
            Toast.makeText(getActivity(), "documentProcessor initialized", Toast.LENGTH_LONG).show();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        view.findViewById(R.id.button_add_page).setOnClickListener(v -> {
 | 
			
		||||
            Log.d("ScannerDataManagerStubFragment", "button_add_page clicked");
 | 
			
		||||
            Toast.makeText(getActivity(), "button_add_page clicked", Toast.LENGTH_LONG).show();
 | 
			
		||||
            if (this.documentProcessor == null) {
 | 
			
		||||
                Toast.makeText(getActivity(), "documentProcessor is null", Toast.LENGTH_LONG).show();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            Bitmap[] bitmaps = new Bitmap[results.size()];
 | 
			
		||||
            for (int i = 0; i < results.size(); i++) {
 | 
			
		||||
                bitmaps[i] = results.get(i).getBitmap();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                this.documentProcessor.addNewPagesToLast(bitmaps);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                Toast.makeText(getActivity(), "Error occurred while adding pages", Toast.LENGTH_LONG).show();
 | 
			
		||||
                Log.e("ScannerDataManagerStubFragment", "Error occurred while adding pages", e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Toast.makeText(getActivity(), "pages added", Toast.LENGTH_LONG).show();
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                this.documentProcessor.close();
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                Toast.makeText(getActivity(), "Error occurred while closing documentProcessor", Toast.LENGTH_LONG).show();
 | 
			
		||||
                Log.e("ScannerDataManagerStubFragment", "Error occurred while closing documentProcessor", e);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DocumentDetail createSampleDocumentDetail() {
 | 
			
		||||
 | 
			
		||||
        String id = UUID.randomUUID().toString();
 | 
			
		||||
 | 
			
		||||
        Toast.makeText(getActivity(), "Generated id: " + id, Toast.LENGTH_LONG).show();
 | 
			
		||||
        //logger.debug("CreateSample", "Generated id: " + id);
 | 
			
		||||
 | 
			
		||||
        DocumentMeta meta = new DocumentMeta(
 | 
			
		||||
                id,
 | 
			
		||||
                "Sample" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()),
 | 
			
		||||
                new Date(),
 | 
			
		||||
                new Date());
 | 
			
		||||
 | 
			
		||||
        DocumentPath path = new DocumentPath(
 | 
			
		||||
                deviceInfoUtils.getExternalStorageDirectoryString(),
 | 
			
		||||
                "Sample" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()));
 | 
			
		||||
 | 
			
		||||
        return new DocumentDetail(meta, path, "SampleAuthor", "SampleDefaultBranch");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        Log.d("ScannerDataManagerStubFragment", "onResume");
 | 
			
		||||
        updateResults();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void updateResults() {
 | 
			
		||||
        Log.d("ScannerDataManagerStubFragment", "updateResults");
 | 
			
		||||
 | 
			
		||||
        // TODO-rca: エラーハンドリング
 | 
			
		||||
        RecyclerView recyclerView = getView().findViewById(R.id.result_recycler_view);
 | 
			
		||||
 | 
			
		||||
        recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
 | 
			
		||||
        recyclerView.setAdapter(new CaptureResultAdapter(this.results));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,75 +0,0 @@
 | 
			
		|||
package one.nem.lacerta.component.scanner;
 | 
			
		||||
 | 
			
		||||
import android.graphics.BitmapFactory;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.constraintlayout.utils.widget.ImageFilterView;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
import com.websitebeaver.documentscanner.DocumentScanner;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link ScannerScanFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class ScannerScanFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    // TODO: Rename parameter arguments, choose names that match
 | 
			
		||||
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
 | 
			
		||||
//    private static final String MAX_SCAN_COUNT = "max_scan_count"; // 規定値
 | 
			
		||||
 | 
			
		||||
    // TODO: Rename and change types of parameters
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public ScannerScanFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ScannerScanFragment newInstance(String param1) {
 | 
			
		||||
        ScannerScanFragment fragment = new ScannerScanFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
//        args.putString(MAX_SCAN_COUNT, param1);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
//            mParam1 = getArguments().getString(MAX_SCAN_COUNT);
 | 
			
		||||
//            scan(Integer.parseInt(mParam1));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public DocumentScanner getDocumentScanner() {
 | 
			
		||||
        return new DocumentScanner(
 | 
			
		||||
                this,
 | 
			
		||||
                (croppedImageResults) -> {
 | 
			
		||||
                    // display the first cropped image
 | 
			
		||||
                    croppedImageView.setImageBitmap(
 | 
			
		||||
                            BitmapFactory.decodeFile(croppedImageResults.get(0))
 | 
			
		||||
                    );
 | 
			
		||||
                    return null;
 | 
			
		||||
                },
 | 
			
		||||
                (errorMessage) -> {
 | 
			
		||||
                    // an error happened
 | 
			
		||||
                    return null;
 | 
			
		||||
                },
 | 
			
		||||
                () -> {
 | 
			
		||||
                    // user canceled document scan
 | 
			
		||||
                    return null;
 | 
			
		||||
                },
 | 
			
		||||
                null,
 | 
			
		||||
                null,
 | 
			
		||||
                null
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,64 +0,0 @@
 | 
			
		|||
package one.nem.lacerta.component.scanner;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link ScannerScanResultFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class ScannerScanResultFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    // TODO: Rename parameter arguments, choose names that match
 | 
			
		||||
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
 | 
			
		||||
    // TODO: Rename and change types of parameters
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
 | 
			
		||||
    public ScannerScanResultFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Use this factory method to create a new instance of
 | 
			
		||||
     * this fragment using the provided parameters.
 | 
			
		||||
     *
 | 
			
		||||
     * @param param1 Parameter 1.
 | 
			
		||||
     * @param param2 Parameter 2.
 | 
			
		||||
     * @return A new instance of fragment ScannerScanResultFragment.
 | 
			
		||||
     */
 | 
			
		||||
    // TODO: Rename and change types and number of parameters
 | 
			
		||||
    public static ScannerScanResultFragment newInstance(String param1, String param2) {
 | 
			
		||||
        ScannerScanResultFragment fragment = new ScannerScanResultFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            mParam1 = getArguments().getString(ARG_PARAM1);
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        return inflater.inflate(R.layout.fragment_scanner_scan_result, container, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:theme="@style/Theme.Lacerta"
 | 
			
		||||
    tools:context=".ScannerDataManagerStubFragment" >
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/action_button_container"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        android:weightSum="2"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent">
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.button.MaterialButton
 | 
			
		||||
            android:id="@+id/button_call_camera"
 | 
			
		||||
            style="@style/Widget.Material3.Button.IconButton.Filled"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_margin="16px"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:text="Call camera" />
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/init_button_container"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        android:layout_weight="1"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        android:weightSum="2"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@id/action_button_container">
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.button.MaterialButton
 | 
			
		||||
            android:id="@+id/button_create_documnent"
 | 
			
		||||
            style="@style/Widget.Material3.Button.IconButton.Filled"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_margin="16px"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:text="Create Doc Obj" />
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.button.MaterialButton
 | 
			
		||||
            android:id="@+id/button_init_document_processor"
 | 
			
		||||
            style="@style/Widget.Material3.Button.IconButton.Filled"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_margin="16px"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:text="Init Processor" />
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/doc_button_container"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        android:weightSum="2"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@id/init_button_container">
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.button.MaterialButton
 | 
			
		||||
            android:id="@+id/button_add_page"
 | 
			
		||||
            style="@style/Widget.Material3.Button.IconButton.Filled"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_margin="16px"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:text="Add page to last" />
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/result_recycler_view"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        android:layout_weight="1"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@id/doc_button_container" />
 | 
			
		||||
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".ScannerScanFragment">
 | 
			
		||||
 | 
			
		||||
    <!-- TODO: Update blank fragment layout -->
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:text="@string/hello_blank_fragment" />
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,133 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    tools:context=".MainActivity">
 | 
			
		||||
 | 
			
		||||
    <androidx.constraintlayout.utils.widget.ImageFilterView
 | 
			
		||||
        android:id="@+id/cropped_image_view"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        app:layout_constraintBottom_toTopOf="@+id/linear_layout_buttons">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:orientation="horizontal"
 | 
			
		||||
            android:layout_margin="12dp">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="match_parent"
 | 
			
		||||
                android:layout_weight="0"
 | 
			
		||||
                android:text="Saturation" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekBar_saturation"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:max="200"
 | 
			
		||||
                android:progress="100"/>
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:orientation="horizontal"
 | 
			
		||||
            android:layout_margin="12dp">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="match_parent"
 | 
			
		||||
                android:layout_weight="0"
 | 
			
		||||
                android:text="Contrast" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekBar_contrast"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:max="200"
 | 
			
		||||
                android:progress="100"/>
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:orientation="horizontal"
 | 
			
		||||
            android:layout_margin="12dp">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="match_parent"
 | 
			
		||||
                android:layout_weight="0"
 | 
			
		||||
                android:text="Brightness" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekBar_brightness"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:max="200"
 | 
			
		||||
                android:progress="100"
 | 
			
		||||
                android:layout_weight="1"/>
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:orientation="horizontal"
 | 
			
		||||
            android:layout_margin="12dp">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="match_parent"
 | 
			
		||||
                android:layout_weight="0"
 | 
			
		||||
                android:text="Warmth" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekBar_warmth"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:max="500"
 | 
			
		||||
                android:progress="100"
 | 
			
		||||
                android:layout_weight="1"/>
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/linear_layout_buttons"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent">
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/button_save_image"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:insetLeft="12dp"
 | 
			
		||||
            android:insetRight="12dp"
 | 
			
		||||
            android:text="Save Image" />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/button_kill_me"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:insetLeft="12dp"
 | 
			
		||||
            android:insetRight="12dp"
 | 
			
		||||
            android:text="Kill me" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="wrap_content"
 | 
			
		||||
    android:layout_margin="24px">
 | 
			
		||||
 | 
			
		||||
    <ImageView
 | 
			
		||||
        android:id="@+id/imageViewResult"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
        tools:srcCompat="@android:drawable/presence_video_online"
 | 
			
		||||
        android:adjustViewBounds="true"/>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/imageViewResult">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="2"
 | 
			
		||||
                android:text="Resolution:"
 | 
			
		||||
                android:textIsSelectable="false"
 | 
			
		||||
                android:textSize="16sp" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/textViewResHeight"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:text="Height"
 | 
			
		||||
                android:textIsSelectable="false"
 | 
			
		||||
                android:textSize="16sp" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/textViewResWidth"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:text="Width"
 | 
			
		||||
                android:textIsSelectable="false"
 | 
			
		||||
                android:textSize="16sp" />
 | 
			
		||||
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/textViewPath"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:text="Path"
 | 
			
		||||
            android:textIsSelectable="false"
 | 
			
		||||
            android:textSize="16sp" />
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,9 @@ dependencies {
 | 
			
		|||
    // JGit
 | 
			
		||||
    implementation 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
 | 
			
		||||
 | 
			
		||||
    // Java Faker
 | 
			
		||||
    implementation 'com.github.javafaker:javafaker:1.0.2'
 | 
			
		||||
 | 
			
		||||
    // Room
 | 
			
		||||
    implementation libs.androidx.room.runtime
 | 
			
		||||
    annotationProcessor libs.androidx.room.compiler
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
package one.nem.lacerta.data;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.ListItemType;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.LibraryItemPage;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
 | 
			
		||||
public interface LacertaLibrary {
 | 
			
		||||
 | 
			
		||||
    // Get History
 | 
			
		||||
    LibraryItemPage getRecentDocument(int limit);
 | 
			
		||||
    LibraryItemPage getRecentDocument(int limit, int offset);
 | 
			
		||||
 | 
			
		||||
    // Get Library page
 | 
			
		||||
    LibraryItemPage getLibraryPage(int limit);
 | 
			
		||||
    LibraryItemPage getLibraryPage(int limit, int offset);
 | 
			
		||||
    LibraryItemPage getLibraryPage(String pageId, int limit);
 | 
			
		||||
    LibraryItemPage getLibraryPage(String pageId, int limit, int offset);
 | 
			
		||||
 | 
			
		||||
    // GetDocument
 | 
			
		||||
    DocumentDetail getDocumentDetailById(String id);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								data/src/main/java/one/nem/lacerta/data/LacertaSearch.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								data/src/main/java/one/nem/lacerta/data/LacertaSearch.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
package one.nem.lacerta.data;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.ListItem;
 | 
			
		||||
 | 
			
		||||
public interface LacertaSearch {
 | 
			
		||||
 | 
			
		||||
    ArrayList<ListItem> autoSearch(String query, int limit);
 | 
			
		||||
 | 
			
		||||
    ArrayList<ListItem> autoSearch(String query, int limit, int offset);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
package one.nem.lacerta.data.impl;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.data.LacertaLibrary;
 | 
			
		||||
import one.nem.lacerta.model.LibraryItemPage;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
 | 
			
		||||
public class LacertaLibraryImpl implements LacertaLibrary {
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getRecentDocument(int limit) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getRecentDocument(int limit, int offset) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(int limit) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(int limit, int offset) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(String pageId, int limit) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(String pageId, int limit, int offset) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DocumentDetail getDocumentDetailById(String id) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,219 @@
 | 
			
		|||
package one.nem.lacerta.data.impl;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.data.LacertaLibrary;
 | 
			
		||||
import one.nem.lacerta.model.LibraryItemPage;
 | 
			
		||||
import one.nem.lacerta.model.ListItem;
 | 
			
		||||
import one.nem.lacerta.model.ListItemType;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentMeta;
 | 
			
		||||
import one.nem.lacerta.model.document.path.DocumentPath;
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
import com.github.javafaker.DateAndTime;
 | 
			
		||||
import com.github.javafaker.Faker;
 | 
			
		||||
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LacertaLibraryのスタブ実装
 | 
			
		||||
 */
 | 
			
		||||
public class LacertaLibraryStubImpl implements LacertaLibrary {
 | 
			
		||||
 | 
			
		||||
    LacertaLogger logger;
 | 
			
		||||
 | 
			
		||||
    Faker faker;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    public LacertaLibraryStubImpl(LacertaLogger logger) {
 | 
			
		||||
        faker = new Faker(); // Init Faker
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
        logger.debug("LibraryStub", "Initialized");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal Methods
 | 
			
		||||
 | 
			
		||||
    // Generate Stub Data
 | 
			
		||||
    private LibraryItemPage generateStubLibraryItemPage(int limit, String pageId) {
 | 
			
		||||
        logger.debug("LibraryStub", "generateStubLibraryItemPage");
 | 
			
		||||
        ArrayList<ListItem> listItems = new ArrayList<>();
 | 
			
		||||
        int itemTotal = faker.number().numberBetween(1, limit); // 実際に返却するアイテム数を決定
 | 
			
		||||
        int folderTotal;
 | 
			
		||||
        // フォルダ数の抽選
 | 
			
		||||
        if (itemTotal > 4) {
 | 
			
		||||
            folderTotal = faker.number().numberBetween(1, itemTotal - 2);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            if (itemTotal > 2) {
 | 
			
		||||
                folderTotal = 1;
 | 
			
		||||
            }
 | 
			
		||||
            else { // ドキュメント数がゼロにならないように
 | 
			
		||||
                folderTotal = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        int documentTotal = itemTotal - folderTotal; // ドキュメント数を決定
 | 
			
		||||
        logger.debug("LibraryStub", "itemTotal: " + itemTotal);
 | 
			
		||||
        logger.debug("LibraryStub", "folderTotal: " + folderTotal);
 | 
			
		||||
        logger.debug("LibraryStub", "documentTotal: " + documentTotal);
 | 
			
		||||
 | 
			
		||||
        // フォルダを生成
 | 
			
		||||
        for (int i = 0; i < folderTotal; i++) {
 | 
			
		||||
            listItems.add(generateStubListItem(ListItemType.ITEM_TYPE_FOLDER));
 | 
			
		||||
        }
 | 
			
		||||
        // ドキュメントを生成
 | 
			
		||||
        for (int i = 0; i < documentTotal; i++) {
 | 
			
		||||
            listItems.add(generateStubListItem(ListItemType.ITEM_TYPE_DOCUMENT));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        LibraryItemPage libraryItemPage = new LibraryItemPage();
 | 
			
		||||
        libraryItemPage.setListItems(listItems);
 | 
			
		||||
        if (pageId == null) {
 | 
			
		||||
            libraryItemPage.setPageId(UUID.randomUUID().toString());
 | 
			
		||||
        } else {
 | 
			
		||||
            libraryItemPage.setPageId(pageId);
 | 
			
		||||
        }
 | 
			
		||||
        libraryItemPage.setPageTitle("FakePage" + faker.number().digits(3));
 | 
			
		||||
 | 
			
		||||
        return libraryItemPage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ListItem generateStubListItem(ListItemType itemType) {
 | 
			
		||||
        if (itemType == ListItemType.ITEM_TYPE_FOLDER) {
 | 
			
		||||
            ListItem listItem = new ListItem();
 | 
			
		||||
            listItem.setTitle("FakeFolder" + faker.number().digits(3));
 | 
			
		||||
            listItem.setDescription("Updated at " + DateFormat.getDateTimeInstance().format(faker.date().birthday()));
 | 
			
		||||
            listItem.setItemType(ListItemType.ITEM_TYPE_FOLDER);
 | 
			
		||||
            listItem.setItemId(UUID.randomUUID().toString());
 | 
			
		||||
            return listItem;
 | 
			
		||||
        } else if (itemType == ListItemType.ITEM_TYPE_DOCUMENT) {
 | 
			
		||||
            ListItem listItem = new ListItem();
 | 
			
		||||
            listItem.setTitle("FakeDocument" + faker.book().title());
 | 
			
		||||
            listItem.setDescription("Updated at " + DateFormat.getDateTimeInstance().format(faker.date().birthday()));
 | 
			
		||||
            listItem.setItemType(ListItemType.ITEM_TYPE_DOCUMENT);
 | 
			
		||||
            listItem.setItemId(UUID.randomUUID().toString());
 | 
			
		||||
            return listItem;
 | 
			
		||||
        } else {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private LibraryItemPage getRecentDocumentPage(int limit) {
 | 
			
		||||
        int itemTotal = faker.number().numberBetween(1, limit);
 | 
			
		||||
        ArrayList<ListItem> listItems = new ArrayList<>();
 | 
			
		||||
        for (int i = 0; i < itemTotal; i++) {
 | 
			
		||||
            listItems.add(generateStubListItem(ListItemType.ITEM_TYPE_DOCUMENT));
 | 
			
		||||
        }
 | 
			
		||||
        // DescriptionからDateを抽出して新しい順にソート
 | 
			
		||||
        listItems.sort((a, b) -> {
 | 
			
		||||
            String aDate = a.getDescription().substring(11);
 | 
			
		||||
            String bDate = b.getDescription().substring(11);
 | 
			
		||||
            return bDate.compareTo(aDate);
 | 
			
		||||
        });
 | 
			
		||||
        LibraryItemPage libraryItemPage = new LibraryItemPage();
 | 
			
		||||
        libraryItemPage.setListItems(listItems);
 | 
			
		||||
        libraryItemPage.setPageId(UUID.randomUUID().toString());
 | 
			
		||||
        libraryItemPage.setPageTitle("RecentDocument");
 | 
			
		||||
        return libraryItemPage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private DocumentDetail generateStubDocumentDetail(String id) throws IllegalArgumentException {
 | 
			
		||||
 | 
			
		||||
        if (Objects.isNull(id)) {
 | 
			
		||||
            throw new IllegalArgumentException("id is null");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        DocumentMeta documentMeta = new DocumentMeta();
 | 
			
		||||
        documentMeta.setId(id);
 | 
			
		||||
        documentMeta.setTitle("FakeDocument" + faker.book().title());
 | 
			
		||||
        documentMeta.setCreatedAt(faker.date().birthday());
 | 
			
		||||
        documentMeta.setUpdatedAt(faker.date().birthday()); // TODO-rca: 更新日のほうが古くなることがあるのでなんとかする?
 | 
			
		||||
        ArrayList<String> tagIds = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        DocumentDetail documentDetail = new DocumentDetail();
 | 
			
		||||
        documentDetail.setMeta(documentMeta);
 | 
			
		||||
        documentDetail.setPath(null); // TODO-rca: なんとかする
 | 
			
		||||
        documentDetail.setAuthor(faker.name().fullName());
 | 
			
		||||
        documentDetail.setRepository(null); // TODO-rca: なんとかする
 | 
			
		||||
        return documentDetail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 履歴ページを取得する
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getRecentDocument(int limit) {
 | 
			
		||||
        return getRecentDocumentPage(limit);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 履歴ページを取得する
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @param offset 取得するアイテムのオフセット
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getRecentDocument(int limit, int offset) {
 | 
			
		||||
        return getRecentDocumentPage(limit);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ライブラリページを取得する
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(int limit) {
 | 
			
		||||
        return generateStubLibraryItemPage(limit, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ライブラリページを取得する
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @param offset 取得するアイテムのオフセット
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(int limit, int offset) {
 | 
			
		||||
        return generateStubLibraryItemPage(limit, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ライブラリページを取得する
 | 
			
		||||
     * @param pageId ページID
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(String pageId, int limit) {
 | 
			
		||||
        return generateStubLibraryItemPage(limit, pageId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ライブラリページを取得する
 | 
			
		||||
     * @param pageId ページID
 | 
			
		||||
     * @param limit 取得するアイテム数
 | 
			
		||||
     * @param offset 取得するアイテムのオフセット
 | 
			
		||||
     * @return ページオブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public LibraryItemPage getLibraryPage(String pageId, int limit, int offset) {
 | 
			
		||||
        return generateStubLibraryItemPage(limit, pageId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ドキュメント詳細を取得する
 | 
			
		||||
     * @param id ドキュメントID
 | 
			
		||||
     * @return ドキュメント詳細オブジェクト
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public DocumentDetail getDocumentDetailById(String id) throws IllegalArgumentException {
 | 
			
		||||
        return generateStubDocumentDetail(id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
package one.nem.lacerta.data.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.data.LacertaSearch;
 | 
			
		||||
import one.nem.lacerta.model.ListItem;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.data.LacertaLibrary;
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
public class LacertaSearchStubImpl implements LacertaSearch {
 | 
			
		||||
 | 
			
		||||
    private LacertaLibrary library;
 | 
			
		||||
    private LacertaLogger logger;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    public LacertaSearchStubImpl(LacertaLibrary library, LacertaLogger logger) {
 | 
			
		||||
        this.library = library;
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 検索
 | 
			
		||||
     * @param query 検索クエリ
 | 
			
		||||
     * @param limit 最大取得件数
 | 
			
		||||
     * @return 検索結果
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public ArrayList<ListItem> autoSearch(String query, int limit) {
 | 
			
		||||
        logger.debug("SearchStub", "autoSearch");
 | 
			
		||||
        logger.debug("SearchStub", "query: " + query);
 | 
			
		||||
        return library.getLibraryPage(limit).getListItems();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 検索
 | 
			
		||||
     * @param query 検索クエリ
 | 
			
		||||
     * @param limit 最大取得件数
 | 
			
		||||
     * @param offset オフセット
 | 
			
		||||
     * @return 検索結果
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public ArrayList<ListItem> autoSearch(String query, int limit, int offset) {
 | 
			
		||||
        logger.debug("SearchStub", "autoSearch");
 | 
			
		||||
        logger.debug("SearchStub", "query: " + query);
 | 
			
		||||
        return library.getLibraryPage(limit, offset).getListItems();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
package one.nem.lacerta.data.module;
 | 
			
		||||
 | 
			
		||||
import dagger.Binds;
 | 
			
		||||
import dagger.Module;
 | 
			
		||||
import dagger.hilt.InstallIn;
 | 
			
		||||
import dagger.hilt.android.components.FragmentComponent;
 | 
			
		||||
import dagger.hilt.migration.DisableInstallInCheck;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.data.LacertaLibrary;
 | 
			
		||||
import one.nem.lacerta.data.impl.LacertaLibraryStubImpl;
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
@Module
 | 
			
		||||
// Fragmentにinstall
 | 
			
		||||
@InstallIn(FragmentComponent.class)
 | 
			
		||||
abstract public class LacertaLibraryModule {
 | 
			
		||||
 | 
			
		||||
    @Binds
 | 
			
		||||
    public abstract LacertaLibrary bindLacertaLibrary(LacertaLibraryStubImpl impl);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
package one.nem.lacerta.data.module;
 | 
			
		||||
 | 
			
		||||
import dagger.Binds;
 | 
			
		||||
import dagger.Module;
 | 
			
		||||
import dagger.hilt.InstallIn;
 | 
			
		||||
import dagger.hilt.android.components.FragmentComponent;
 | 
			
		||||
import one.nem.lacerta.data.LacertaSearch;
 | 
			
		||||
import one.nem.lacerta.data.impl.LacertaSearchStubImpl;
 | 
			
		||||
 | 
			
		||||
@Module
 | 
			
		||||
@InstallIn(FragmentComponent.class)
 | 
			
		||||
abstract public class LacertaSearchModule {
 | 
			
		||||
 | 
			
		||||
    @Binds
 | 
			
		||||
    public abstract LacertaSearch bindLacertaSearch(LacertaSearchStubImpl impl);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -62,4 +62,13 @@ dependencies {
 | 
			
		|||
    // Shared
 | 
			
		||||
    implementation project(':shared:ui')
 | 
			
		||||
 | 
			
		||||
    // Scanner
 | 
			
		||||
    implementation project(':component:scanner')
 | 
			
		||||
 | 
			
		||||
    // Processor
 | 
			
		||||
    implementation project(':processor')
 | 
			
		||||
 | 
			
		||||
    // LacertaVcs
 | 
			
		||||
    implementation project(':vcs')
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
package one.nem.lacerta.feature.debug;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuDocProcessorTesterFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class DebugMenuDocProcessorTesterFragment extends Fragment {
 | 
			
		||||
    public DebugMenuDocProcessorTesterFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuDocProcessorTesterFragment newInstance() {
 | 
			
		||||
        DebugMenuDocProcessorTesterFragment fragment = new DebugMenuDocProcessorTesterFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_doc_processor_tester, container, false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
package one.nem.lacerta.feature.debug;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.AnimatorRes;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import dagger.hilt.android.AndroidEntryPoint;
 | 
			
		||||
import one.nem.lacerta.data.LacertaLibrary;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.LibraryItemPage;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
import one.nem.lacerta.model.ListItem;
 | 
			
		||||
import one.nem.lacerta.model.ListItemType;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuLibraryItemListPageFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
@AndroidEntryPoint
 | 
			
		||||
public class DebugMenuLibraryItemListPageFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    LacertaLibrary lacertaLibrary;
 | 
			
		||||
 | 
			
		||||
    public DebugMenuLibraryItemListPageFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuLibraryItemListPageFragment newInstance() {
 | 
			
		||||
        DebugMenuLibraryItemListPageFragment fragment = new DebugMenuLibraryItemListPageFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_library_item_list_page, container, false);
 | 
			
		||||
 | 
			
		||||
        LibraryItemPage libraryItemPage = lacertaLibrary.getRecentDocument(10);
 | 
			
		||||
        for (ListItem listItem : libraryItemPage.getListItems()) {
 | 
			
		||||
            System.out.println(listItem.getTitle());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        RecyclerView recyclerView = view.findViewById(R.id.item_recycler_view);
 | 
			
		||||
        recyclerView.setAdapter(new ItemAdapter(libraryItemPage.getListItems()));
 | 
			
		||||
 | 
			
		||||
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemViewHolder> {
 | 
			
		||||
        private ArrayList<ListItem> listItems;
 | 
			
		||||
 | 
			
		||||
        public ItemAdapter(ArrayList<ListItem> listItems) {
 | 
			
		||||
            this.listItems = listItems;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 | 
			
		||||
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_debug_menu_document, parent, false);
 | 
			
		||||
            return new ItemViewHolder(view);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onBindViewHolder(ItemViewHolder holder, int position) {
 | 
			
		||||
            ListItem listItem = listItems.get(position);
 | 
			
		||||
            holder.document_list_item_title.setText(listItem.getTitle());
 | 
			
		||||
            holder.document_list_item_description.setText(listItem.getDescription());
 | 
			
		||||
            holder.document_list_item_updated_at.setText(listItem.getItemType().toString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getItemCount() {
 | 
			
		||||
            return listItems.size();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class ItemViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
            TextView document_list_item_title;
 | 
			
		||||
            TextView document_list_item_description;
 | 
			
		||||
            TextView document_list_item_updated_at;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            public ItemViewHolder(View itemView) {
 | 
			
		||||
                super(itemView);
 | 
			
		||||
                document_list_item_title = itemView.findViewById(R.id.document_list_item_title);
 | 
			
		||||
                document_list_item_description = itemView.findViewById(R.id.document_list_item_description);
 | 
			
		||||
                document_list_item_updated_at = itemView.findViewById(R.id.document_list_item_updated_at);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import android.view.ViewGroup;
 | 
			
		|||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import dagger.hilt.android.AndroidEntryPoint;
 | 
			
		||||
import one.nem.lacerta.feature.debug.common.adapter.DebugMenuListItemAdapter;
 | 
			
		||||
import one.nem.lacerta.feature.debug.common.model.DebugMenuListItem;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,7 @@ import one.nem.lacerta.feature.debug.common.model.DebugMenuListItem;
 | 
			
		|||
 * Use the {@link DebugMenuTopFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
@AndroidEntryPoint
 | 
			
		||||
public class DebugMenuTopFragment extends Fragment {
 | 
			
		||||
    public DebugMenuTopFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
| 
						 | 
				
			
			@ -46,8 +48,10 @@ public class DebugMenuTopFragment extends Fragment {
 | 
			
		|||
        recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
 | 
			
		||||
        List<DebugMenuListItem> debugMenuListItems = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Meta Data", "View meta data", R.id.action_debugMenuTopFragment_to_debugMenuMetaDataFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Document Tester", "placeholder", R.id.action_debugMenuTopFragment_to_debugMenuDocumentTesterTopFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Scanner", "placeholder", R.id.action_debugMenuTopFragment_to_scannerDataManagerStubFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Document List", "placeholder", R.id.action_debugMenuTopFragment_to_debugMenuLibraryItemListPageFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("VCS", "placeholder", R.id.action_debugMenuTopFragment_to_debugMenuVcsGeneralFragment, true));
 | 
			
		||||
 | 
			
		||||
        DebugMenuListItemAdapter adapter = new DebugMenuListItemAdapter(debugMenuListItems);
 | 
			
		||||
        recyclerView.setAdapter(adapter);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
package one.nem.lacerta.feature.debug;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import dagger.hilt.android.AndroidEntryPoint;
 | 
			
		||||
import one.nem.lacerta.vcs.LacertaVcs;
 | 
			
		||||
import one.nem.lacerta.vcs.factory.LacertaVcsFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuVcsGeneralActionFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@AndroidEntryPoint
 | 
			
		||||
public class DebugMenuVcsGeneralActionFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    LacertaVcsFactory lacertaVcsFactory;
 | 
			
		||||
 | 
			
		||||
    public DebugMenuVcsGeneralActionFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuVcsGeneralActionFragment newInstance() {
 | 
			
		||||
        DebugMenuVcsGeneralActionFragment fragment = new DebugMenuVcsGeneralActionFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_vcs_general_action, container, false);
 | 
			
		||||
 | 
			
		||||
        view.findViewById(R.id.add_sample_log_rev_button).setOnClickListener(v -> {
 | 
			
		||||
            LacertaVcs lacertaVcs = lacertaVcsFactory.create("example_id");
 | 
			
		||||
            lacertaVcs.insertPage(1, "example_id");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
package one.nem.lacerta.feature.debug;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.feature.debug.common.adapter.DebugMenuListItemAdapter;
 | 
			
		||||
import one.nem.lacerta.feature.debug.common.model.DebugMenuListItem;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuVcsGeneralFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class DebugMenuVcsGeneralFragment extends Fragment {
 | 
			
		||||
    public DebugMenuVcsGeneralFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuVcsGeneralFragment newInstance() {
 | 
			
		||||
        DebugMenuVcsGeneralFragment fragment = new DebugMenuVcsGeneralFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_vcs_general, container, false);
 | 
			
		||||
 | 
			
		||||
        RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
 | 
			
		||||
        recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
 | 
			
		||||
        List<DebugMenuListItem> debugMenuListItems = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("General Action", "placeholder", R.id.action_debugMenuVcsGeneralFragment_to_debugMenuVcsGeneralActionFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Log Record", "placeholder", R.id.action_debugMenuVcsGeneralFragment_to_debugMenuVcsLogRecordFragment, true));
 | 
			
		||||
        debugMenuListItems.add(new DebugMenuListItem("Rev Record", "placeholder", R.id.action_debugMenuVcsGeneralFragment_to_debugMenuVcsRevRecordFragment, true));
 | 
			
		||||
 | 
			
		||||
        DebugMenuListItemAdapter adapter = new DebugMenuListItemAdapter(debugMenuListItems);
 | 
			
		||||
        recyclerView.setAdapter(adapter);
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
package one.nem.lacerta.feature.debug;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuVcsLogRecordFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class DebugMenuVcsLogRecordFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    public DebugMenuVcsLogRecordFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuVcsLogRecordFragment newInstance() {
 | 
			
		||||
        DebugMenuVcsLogRecordFragment fragment = new DebugMenuVcsLogRecordFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_vcs_log_record, container, false);
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -10,16 +10,16 @@ import android.view.ViewGroup;
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple {@link Fragment} subclass.
 | 
			
		||||
 * Use the {@link DebugMenuMetaDataFragment#newInstance} factory method to
 | 
			
		||||
 * Use the {@link DebugMenuVcsRevRecordFragment#newInstance} factory method to
 | 
			
		||||
 * create an instance of this fragment.
 | 
			
		||||
 */
 | 
			
		||||
public class DebugMenuMetaDataFragment extends Fragment {
 | 
			
		||||
    public DebugMenuMetaDataFragment() {
 | 
			
		||||
public class DebugMenuVcsRevRecordFragment extends Fragment {
 | 
			
		||||
    public DebugMenuVcsRevRecordFragment() {
 | 
			
		||||
        // Required empty public constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static DebugMenuMetaDataFragment newInstance() {
 | 
			
		||||
        DebugMenuMetaDataFragment fragment = new DebugMenuMetaDataFragment();
 | 
			
		||||
    public static DebugMenuVcsRevRecordFragment newInstance() {
 | 
			
		||||
        DebugMenuVcsRevRecordFragment fragment = new DebugMenuVcsRevRecordFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +34,8 @@ public class DebugMenuMetaDataFragment extends Fragment {
 | 
			
		|||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        // Inflate the layout for this fragment
 | 
			
		||||
        return inflater.inflate(R.layout.fragment_debug_menu_meta_data, container, false);
 | 
			
		||||
        View view = inflater.inflate(R.layout.fragment_debug_menu_vcs_rev_record, container, false);
 | 
			
		||||
 | 
			
		||||
        return view;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:theme="@style/Theme.Lacerta"
 | 
			
		||||
    tools:context=".DebugMenuDocProcessorTesterFragment" >
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginStart="1dp"
 | 
			
		||||
        android:layout_marginTop="1dp"
 | 
			
		||||
        android:layout_marginEnd="1dp"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
            <com.google.android.material.button.MaterialButton
 | 
			
		||||
                android:id="@+id/button_gen_random_img"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:text="Generate random image" />
 | 
			
		||||
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuLibraryItemListPageFragment">
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/item_recycler_view"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuMetaDataFragment">
 | 
			
		||||
 | 
			
		||||
    <!-- TODO: Update blank fragment layout -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuVcsGeneralFragment">
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/recycler_view"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuVcsGeneralActionFragment">
 | 
			
		||||
 | 
			
		||||
    <ScrollView
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:orientation="vertical" >
 | 
			
		||||
 | 
			
		||||
            <Button
 | 
			
		||||
                android:id="@+id/add_sample_log_rev_button"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:text="Add Sample log/Rev" />
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
    </ScrollView>
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuVcsGeneralFragment">
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/log_recycler_view"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DebugMenuVcsGeneralFragment">
 | 
			
		||||
 | 
			
		||||
    <androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
        android:id="@+id/rev_recycler_view"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="0dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -10,18 +10,19 @@
 | 
			
		|||
        android:name="one.nem.lacerta.feature.debug.DebugMenuTopFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_top"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_top" >
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuTopFragment_to_debugMenuMetaDataFragment"
 | 
			
		||||
            app:destination="@id/debugMenuMetaDataFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuTopFragment_to_debugMenuDocumentTesterTopFragment"
 | 
			
		||||
            app:destination="@id/debugMenuDocumentTesterTopFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuTopFragment_to_scannerDataManagerStubFragment"
 | 
			
		||||
            app:destination="@id/scannerDataManagerStubFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuTopFragment_to_debugMenuLibraryItemListPageFragment"
 | 
			
		||||
            app:destination="@id/debugMenuLibraryItemListPageFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuTopFragment_to_debugMenuVcsGeneralFragment"
 | 
			
		||||
            app:destination="@id/debugMenuVcsGeneralFragment" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuMetaDataFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuMetaDataFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_meta_data"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_meta_data" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuDocumentTesterTopFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuDocumentTesterTopFragment"
 | 
			
		||||
| 
						 | 
				
			
			@ -44,4 +45,43 @@
 | 
			
		|||
        android:name="one.nem.lacerta.feature.debug.DebugMenuDocumentTesterManageFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_document_tester_manage"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_document_tester_manage" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/scannerDataManagerStubFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.component.scanner.ScannerDataManagerStubFragment"
 | 
			
		||||
        android:label="ScannerDataManagerStubFragment" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuLibraryItemListPageFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuLibraryItemListPageFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_library_item_list_page"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_library_item_list_page" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuVcsGeneralFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuVcsGeneralFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_vcs_general"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_vcs_general" >
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuVcsGeneralFragment_to_debugMenuVcsGeneralActionFragment"
 | 
			
		||||
            app:destination="@id/debugMenuVcsGeneralActionFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuVcsGeneralFragment_to_debugMenuVcsRevRecordFragment"
 | 
			
		||||
            app:destination="@id/debugMenuVcsRevRecordFragment" />
 | 
			
		||||
        <action
 | 
			
		||||
            android:id="@+id/action_debugMenuVcsGeneralFragment_to_debugMenuVcsLogRecordFragment"
 | 
			
		||||
            app:destination="@id/debugMenuVcsLogRecordFragment" />
 | 
			
		||||
    </fragment>
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuVcsGeneralActionFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuVcsGeneralActionFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_vcs_general_action"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_vcs_general_action" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuVcsLogRecordFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuVcsLogRecordFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_vcs_log_record"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_vcs_log_record" />
 | 
			
		||||
    <fragment
 | 
			
		||||
        android:id="@+id/debugMenuVcsRevRecordFragment"
 | 
			
		||||
        android:name="one.nem.lacerta.feature.debug.DebugMenuVcsRevRecordFragment"
 | 
			
		||||
        android:label="fragment_debug_menu_vcs_rev_record"
 | 
			
		||||
        tools:layout="@layout/fragment_debug_menu_vcs_rev_record" />
 | 
			
		||||
</navigation>
 | 
			
		||||
| 
						 | 
				
			
			@ -36,4 +36,6 @@ dependencies {
 | 
			
		|||
    // JGit
 | 
			
		||||
    implementation 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
 | 
			
		||||
 | 
			
		||||
    implementation project(":shared:ui")
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
package one.nem.lacerta.model;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public class LibraryItemPage {
 | 
			
		||||
 | 
			
		||||
    String pageTitle;
 | 
			
		||||
    String pageId;
 | 
			
		||||
    ArrayList<ListItem> listItems;
 | 
			
		||||
 | 
			
		||||
    // Constructor
 | 
			
		||||
 | 
			
		||||
    public LibraryItemPage(String pageTitle, String pageId, ArrayList<ListItem> listItems) {
 | 
			
		||||
        this.pageTitle = pageTitle;
 | 
			
		||||
        this.pageId = pageId;
 | 
			
		||||
        this.listItems = listItems;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LibraryItemPage() {
 | 
			
		||||
        // Empty constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getter
 | 
			
		||||
 | 
			
		||||
    public String getPageTitle() {
 | 
			
		||||
        return pageTitle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPageId() {
 | 
			
		||||
        return pageId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<ListItem> getListItems() {
 | 
			
		||||
        return listItems;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Setter
 | 
			
		||||
 | 
			
		||||
    public void setPageTitle(String pageTitle) {
 | 
			
		||||
        this.pageTitle = pageTitle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPageId(String pageId) {
 | 
			
		||||
        this.pageId = pageId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setListItems(ArrayList<ListItem> listItems) {
 | 
			
		||||
        this.listItems = listItems;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								model/src/main/java/one/nem/lacerta/model/ListItem.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								model/src/main/java/one/nem/lacerta/model/ListItem.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
package one.nem.lacerta.model;
 | 
			
		||||
 | 
			
		||||
import android.graphics.drawable.Drawable;
 | 
			
		||||
 | 
			
		||||
public class ListItem {
 | 
			
		||||
 | 
			
		||||
    // Properties
 | 
			
		||||
 | 
			
		||||
    String title;
 | 
			
		||||
    String description;
 | 
			
		||||
    ListItemType itemType;
 | 
			
		||||
    String itemId;
 | 
			
		||||
 | 
			
		||||
    // Constructor
 | 
			
		||||
 | 
			
		||||
    public ListItem(String title, String description, ListItemType itemType, String itemId) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.description = description;
 | 
			
		||||
        this.itemType = itemType;
 | 
			
		||||
        this.itemId = itemId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ListItem() {
 | 
			
		||||
        // Empty constructor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getter
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDescription() {
 | 
			
		||||
        return description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ListItemType getItemType() {
 | 
			
		||||
        return itemType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getItemId() {
 | 
			
		||||
        return itemId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Setter
 | 
			
		||||
 | 
			
		||||
    public void setTitle(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDescription(String description) {
 | 
			
		||||
        this.description = description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setItemType(ListItemType itemType) {
 | 
			
		||||
        this.itemType = itemType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setItemId(String itemId) {
 | 
			
		||||
        this.itemId = itemId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								model/src/main/java/one/nem/lacerta/model/ListItemType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								model/src/main/java/one/nem/lacerta/model/ListItemType.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
package one.nem.lacerta.model;
 | 
			
		||||
 | 
			
		||||
public enum ListItemType {
 | 
			
		||||
 | 
			
		||||
    ITEM_TYPE_FOLDER(one.nem.lacerta.shared.ui.R.drawable.folder_24px),
 | 
			
		||||
    ITEM_TYPE_DOCUMENT(one.nem.lacerta.shared.ui.R.drawable.description_24px);
 | 
			
		||||
 | 
			
		||||
    private int iconId;
 | 
			
		||||
 | 
			
		||||
    ListItemType(int iconId) {
 | 
			
		||||
        this.iconId = iconId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getIconId() {
 | 
			
		||||
        return iconId;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								model/src/main/java/one/nem/lacerta/model/PublicPath.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								model/src/main/java/one/nem/lacerta/model/PublicPath.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
package one.nem.lacerta.model;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class PublicPath {
 | 
			
		||||
    /*
 | 
			
		||||
     * ユーザーが扱うパス(内部パスの代替)
 | 
			
		||||
     * (時間がないのでInjectされることは考慮しない)
 | 
			
		||||
     *
 | 
			
		||||
     * TODO-rca:
 | 
			
		||||
     *  - こわれたパスを検知する
 | 
			
		||||
     *  - バリデーション
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    List<String> path = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
    public PublicPath() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PublicPath(List<String> path) {
 | 
			
		||||
        this.path = path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void add(String path) {
 | 
			
		||||
        this.path.add(path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void resolveInternal(String path) {
 | 
			
		||||
        if (path.equals("..")) {
 | 
			
		||||
            this.path.remove(this.path.size() - 1);
 | 
			
		||||
        } else {
 | 
			
		||||
            add(path);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PublicPath resolve(String path) {
 | 
			
		||||
        resolveInternal(path);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PublicPath resolve(List<String> path) {
 | 
			
		||||
        for (String p : path) {
 | 
			
		||||
            resolveInternal(p);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PublicPath resolve(PublicPath path) {
 | 
			
		||||
        for (String p : path.getPath()) {
 | 
			
		||||
            resolveInternal(p);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PublicPath parent() {
 | 
			
		||||
        this.path.remove(this.path.size() - 1);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<String> getPath() {
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getStringPath() {
 | 
			
		||||
        return String.join("/", path);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
package one.nem.lacerta.model.document.internal;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public class XmlMetaModel {
 | 
			
		||||
 | 
			
		||||
    String title;
 | 
			
		||||
    String author;
 | 
			
		||||
    String description;
 | 
			
		||||
//    Date created;
 | 
			
		||||
//    Date updated;
 | 
			
		||||
    String defaultBranch;
 | 
			
		||||
    ArrayList<XmlMetaPageModel> pages;
 | 
			
		||||
 | 
			
		||||
    // Constructor
 | 
			
		||||
 | 
			
		||||
    public XmlMetaModel() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XmlMetaModel(String title, String author, String description, String defaultBranch, ArrayList<XmlMetaPageModel> pages) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.author = author;
 | 
			
		||||
        this.description = description;
 | 
			
		||||
        this.defaultBranch = defaultBranch;
 | 
			
		||||
        this.pages = pages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Getter
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAuthor() {
 | 
			
		||||
        return author;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDescription() {
 | 
			
		||||
        return description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDefaultBranch() {
 | 
			
		||||
        return defaultBranch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<XmlMetaPageModel> getPages() {
 | 
			
		||||
        return pages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Setter
 | 
			
		||||
 | 
			
		||||
    public void setTitle(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAuthor(String author) {
 | 
			
		||||
        this.author = author;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDescription(String description) {
 | 
			
		||||
        this.description = description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDefaultBranch(String defaultBranch) {
 | 
			
		||||
        this.defaultBranch = defaultBranch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPages(ArrayList<XmlMetaPageModel> pages) {
 | 
			
		||||
        this.pages = pages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
package one.nem.lacerta.model.document.internal;
 | 
			
		||||
 | 
			
		||||
public class XmlMetaPageModel {
 | 
			
		||||
 | 
			
		||||
    String filename;
 | 
			
		||||
 | 
			
		||||
    // Constructor
 | 
			
		||||
 | 
			
		||||
    public XmlMetaPageModel() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XmlMetaPageModel(String filename) {
 | 
			
		||||
        this.filename = filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getter
 | 
			
		||||
 | 
			
		||||
    public String getFilename() {
 | 
			
		||||
        return filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Setter
 | 
			
		||||
 | 
			
		||||
    public void setFilename(String filename) {
 | 
			
		||||
        this.filename = filename;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -32,4 +32,16 @@ dependencies {
 | 
			
		|||
    testImplementation libs.junit
 | 
			
		||||
    androidTestImplementation libs.androidx.test.ext.junit
 | 
			
		||||
    androidTestImplementation libs.androidx.test.espresso.core
 | 
			
		||||
 | 
			
		||||
    // DI
 | 
			
		||||
    implementation libs.com.google.dagger.hilt.android
 | 
			
		||||
    annotationProcessor libs.com.google.dagger.hilt.compiler
 | 
			
		||||
 | 
			
		||||
    // JGit
 | 
			
		||||
    implementation 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
 | 
			
		||||
 | 
			
		||||
    implementation project(':model')
 | 
			
		||||
    implementation project(':source')
 | 
			
		||||
    implementation project(':utils')
 | 
			
		||||
    implementation project(':data')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
package one.nem.lacerta.processor;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
 | 
			
		||||
public interface DocumentProcessor {
 | 
			
		||||
 | 
			
		||||
    // ページ操作
 | 
			
		||||
    void addNewPageToLast(Bitmap bitmap) throws Exception;
 | 
			
		||||
    void addNewPagesToLast(Bitmap[] bitmaps) throws Exception;
 | 
			
		||||
    void addNewPageAfterIndex(Bitmap bitmap, int index) throws Exception;
 | 
			
		||||
    void addNewPageBeforeIndex(Bitmap bitmap, int index) throws Exception;
 | 
			
		||||
    void removePageAtIndex(int index) throws Exception;
 | 
			
		||||
 | 
			
		||||
    // 更新
 | 
			
		||||
    void updatePageAtIndex(Bitmap bitmap, int index);
 | 
			
		||||
 | 
			
		||||
    // ページ取得
 | 
			
		||||
    Bitmap getPageAtIndex(int index);
 | 
			
		||||
    int getPageCount();
 | 
			
		||||
 | 
			
		||||
    void close() throws Exception;
 | 
			
		||||
    void init() throws Exception; // TODO-rca: 例外処理
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
package one.nem.lacerta.processor.factory;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.AssistedFactory;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
import one.nem.lacerta.processor.impl.DocumentProcessorImpl;
 | 
			
		||||
 | 
			
		||||
@AssistedFactory
 | 
			
		||||
public interface DocumentProcessorFactory {
 | 
			
		||||
    DocumentProcessorImpl create(DocumentDetail documentDetail);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,175 @@
 | 
			
		|||
package one.nem.lacerta.processor.impl;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.Assisted;
 | 
			
		||||
import dagger.assisted.AssistedInject;
 | 
			
		||||
import one.nem.lacerta.model.document.internal.XmlMetaPageModel;
 | 
			
		||||
import one.nem.lacerta.processor.DocumentProcessor;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.document.internal.XmlMetaModel;
 | 
			
		||||
import one.nem.lacerta.source.file.FileManager;
 | 
			
		||||
import one.nem.lacerta.source.file.factory.FileManagerFactory;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.XmlMetaParser;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class DocumentProcessorImpl implements DocumentProcessor{
 | 
			
		||||
 | 
			
		||||
    // Magic Numbers
 | 
			
		||||
    private static final String DEFAULT_SAVE_DIR = "raw";
 | 
			
		||||
 | 
			
		||||
    // Variables
 | 
			
		||||
    private final DocumentDetail documentDetail;
 | 
			
		||||
    private XmlMetaModel xmlMetaModel;
 | 
			
		||||
    private Path documentRootPath;
 | 
			
		||||
    private FileManager fileManager;
 | 
			
		||||
 | 
			
		||||
    // Injection
 | 
			
		||||
    private final FileManagerFactory fileManagerFactory;
 | 
			
		||||
    private final LacertaLogger logger;
 | 
			
		||||
    private final XmlMetaParser xmlMetaParser;
 | 
			
		||||
    @AssistedInject
 | 
			
		||||
    public DocumentProcessorImpl(FileManagerFactory fileManagerFactory, LacertaLogger logger, XmlMetaParser xmlMetaParser, @Assisted DocumentDetail documentDetail) {
 | 
			
		||||
        this.fileManagerFactory = fileManagerFactory;
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
        this.xmlMetaParser = xmlMetaParser;
 | 
			
		||||
        if (documentDetail == null) {
 | 
			
		||||
            throw new IllegalArgumentException("documentDetail must not be null");
 | 
			
		||||
        }
 | 
			
		||||
        this.documentDetail = documentDetail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void init() throws Exception{
 | 
			
		||||
        logger.debug("init", "called");
 | 
			
		||||
        // Init Variables
 | 
			
		||||
        this.documentRootPath = this.documentDetail.getPath().getFullPath();
 | 
			
		||||
        logger.debug("init", "documentRootPath: " + this.documentRootPath);
 | 
			
		||||
 | 
			
		||||
        this.fileManager = fileManagerFactory.create(this.documentRootPath).enableAutoCreateParent(); //Initialize FileManager
 | 
			
		||||
 | 
			
		||||
        FileManager initFileManager = this.fileManager.getNewInstance();
 | 
			
		||||
 | 
			
		||||
        logger.debug("init", "fileManager created");
 | 
			
		||||
 | 
			
		||||
        // xmlファイルの読み込み
 | 
			
		||||
        if (initFileManager.isExist("meta.xml")) {
 | 
			
		||||
            logger.debug("init", "meta.xml found");
 | 
			
		||||
            try {
 | 
			
		||||
                this.xmlMetaModel = xmlMetaParser.deserialize(this.fileManager.loadXml("meta.xml"));
 | 
			
		||||
                logger.debug("init", "meta.xml parsed");
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.debug("init", "meta.xml parse failed");
 | 
			
		||||
                logger.trace("init", e.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            logger.debug("init", "meta.xml not found");
 | 
			
		||||
            xmlMetaModel = new XmlMetaModel();
 | 
			
		||||
 | 
			
		||||
            xmlMetaModel.setTitle(this.documentDetail.getMeta().getTitle());
 | 
			
		||||
            xmlMetaModel.setAuthor(this.documentDetail.getAuthor());
 | 
			
		||||
            xmlMetaModel.setDescription(""); // FIXME-rca:
 | 
			
		||||
            xmlMetaModel.setDefaultBranch(this.documentDetail.getDefaultBranch());
 | 
			
		||||
            xmlMetaModel.setPages(new ArrayList<>());
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                initFileManager.createFileIfNotExist("meta.xml").saveXml(xmlMetaParser.serialize(xmlMetaModel), "meta.xml");
 | 
			
		||||
                logger.debug("init", "meta.xml saved");
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.error("init", "meta.xml save failed");
 | 
			
		||||
                logger.trace("init", e.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logger.info("init", "finished");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addNewPageToLast(Bitmap bitmap) throws Exception{
 | 
			
		||||
        logger.debug("addNewPageToLast", "called");
 | 
			
		||||
        String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
 | 
			
		||||
 | 
			
		||||
        this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
 | 
			
		||||
 | 
			
		||||
        XmlMetaPageModel xmlMetaPageModel = new XmlMetaPageModel();
 | 
			
		||||
        xmlMetaPageModel.setFilename(filename);
 | 
			
		||||
        xmlMetaModel.getPages().add(xmlMetaPageModel);
 | 
			
		||||
 | 
			
		||||
        logger.info("addNewPageToLast", "finished");
 | 
			
		||||
        logger.info("addNewPageToLast", "filename: " + filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addNewPagesToLast(Bitmap[] bitmaps) throws Exception{
 | 
			
		||||
        logger.debug("addNewPagesToLast", "called");
 | 
			
		||||
 | 
			
		||||
        for (Bitmap bitmap : bitmaps) {
 | 
			
		||||
            addNewPageToLast(bitmap);
 | 
			
		||||
        } // TODO-rca: 効率悪いので改善する
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addNewPageAfterIndex(Bitmap bitmap, int index) throws Exception {
 | 
			
		||||
        logger.debug("addNewPageAfterIndex", "called");
 | 
			
		||||
        String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
 | 
			
		||||
 | 
			
		||||
        this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
 | 
			
		||||
 | 
			
		||||
        XmlMetaPageModel xmlMetaPageModel = new XmlMetaPageModel();
 | 
			
		||||
        xmlMetaPageModel.setFilename(filename);
 | 
			
		||||
        xmlMetaModel.getPages().add(index, xmlMetaPageModel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addNewPageBeforeIndex(Bitmap bitmap, int index) throws Exception {
 | 
			
		||||
        logger.debug("addNewPageBeforeIndex", "called");
 | 
			
		||||
        String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
 | 
			
		||||
 | 
			
		||||
        this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
 | 
			
		||||
 | 
			
		||||
        XmlMetaPageModel xmlMetaPageModel = new XmlMetaPageModel();
 | 
			
		||||
        xmlMetaPageModel.setFilename(filename);
 | 
			
		||||
        xmlMetaModel.getPages().add(index - 1, xmlMetaPageModel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void removePageAtIndex(int index) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updatePageAtIndex(Bitmap bitmap, int index) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Bitmap getPageAtIndex(int index) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getPageCount() {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() throws Exception{
 | 
			
		||||
        logger.debug("close", "called");
 | 
			
		||||
        try {
 | 
			
		||||
            this.fileManager.getNewInstance().createFileIfNotExist("meta.xml").saveXml(xmlMetaParser.serialize(xmlMetaModel), "meta.xml");
 | 
			
		||||
            logger.debug("close", "meta.xml saved");
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("close", "meta.xml save failed");
 | 
			
		||||
            logger.trace("close", e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
package one.nem.lacerta.processor.module;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.Assisted;
 | 
			
		||||
import dagger.assisted.AssistedInject;
 | 
			
		||||
import one.nem.lacerta.model.document.DocumentDetail;
 | 
			
		||||
 | 
			
		||||
public class DocumentProcessorModule {
 | 
			
		||||
 | 
			
		||||
    private final DocumentDetail documentDetail;
 | 
			
		||||
 | 
			
		||||
    @AssistedInject
 | 
			
		||||
    public DocumentProcessorModule(@Assisted DocumentDetail documentDetail) {
 | 
			
		||||
        this.documentDetail = documentDetail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								processor/src/main/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								processor/src/main/res/values/strings.xml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<resources>
 | 
			
		||||
    <!-- TODO: Remove or change this placeholder text -->
 | 
			
		||||
    <string name="hello_blank_fragment">Hello blank fragment</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -31,3 +31,4 @@ include ':model'
 | 
			
		|||
include ':processor'
 | 
			
		||||
include ':shared:ui'
 | 
			
		||||
include ':shared:icon'
 | 
			
		||||
include ':vcs'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								shared/ui/src/main/res/drawable/description_24px.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								shared/ui/src/main/res/drawable/description_24px.xml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="960"
 | 
			
		||||
    android:viewportHeight="960"
 | 
			
		||||
    android:tint="?attr/colorControlNormal">
 | 
			
		||||
  <path
 | 
			
		||||
      android:fillColor="@android:color/white"
 | 
			
		||||
      android:pathData="M330,710L630,710L630,650L330,650L330,710ZM330,550L630,550L630,490L330,490L330,550ZM252.31,860Q222,860 201,839Q180,818 180,787.69L180,172.31Q180,142 201,121Q222,100 252.31,100L570,100L780,310L780,787.69Q780,818 759,839Q738,860 707.69,860L252.31,860ZM540,340L540,160L252.31,160Q247.69,160 243.85,163.85Q240,167.69 240,172.31L240,787.69Q240,792.31 243.85,796.15Q247.69,800 252.31,800L707.69,800Q712.31,800 716.15,796.15Q720,792.31 720,787.69L720,340L540,340ZM240,160L240,160L240,340L240,340L240,160L240,340L240,340L240,787.69Q240,792.31 240,796.15Q240,800 240,800L240,800Q240,800 240,796.15Q240,792.31 240,787.69L240,172.31Q240,167.69 240,163.85Q240,160 240,160Z"/>
 | 
			
		||||
</vector>
 | 
			
		||||
| 
						 | 
				
			
			@ -7,15 +7,21 @@ import androidx.room.RoomDatabase;
 | 
			
		|||
import one.nem.lacerta.source.database.entity.TagEntity;
 | 
			
		||||
import one.nem.lacerta.source.database.entity.DocumentEntity;
 | 
			
		||||
import one.nem.lacerta.source.database.entity.LibraryEntity;
 | 
			
		||||
import one.nem.lacerta.source.database.entity.VcsRevEntity;
 | 
			
		||||
import one.nem.lacerta.source.database.entity.VcsLogEntity;
 | 
			
		||||
 | 
			
		||||
// Daos
 | 
			
		||||
import one.nem.lacerta.source.database.dao.TagDao;
 | 
			
		||||
import one.nem.lacerta.source.database.dao.DocumentDao;
 | 
			
		||||
import one.nem.lacerta.source.database.dao.LibraryDao;
 | 
			
		||||
import one.nem.lacerta.source.database.dao.VcsRevDao;
 | 
			
		||||
import one.nem.lacerta.source.database.dao.VcsLogDao;
 | 
			
		||||
 | 
			
		||||
@Database(entities = {TagEntity.class, DocumentEntity.class, LibraryEntity.class}, version = 1)
 | 
			
		||||
@Database(entities = {TagEntity.class, DocumentEntity.class, LibraryEntity.class, VcsRevEntity.class, VcsLogEntity.class}, version = 2)
 | 
			
		||||
public abstract class LacertaDatabase extends RoomDatabase {
 | 
			
		||||
    public abstract TagDao tagDao();
 | 
			
		||||
    public abstract DocumentDao documentDao();
 | 
			
		||||
    public abstract LibraryDao libraryDao();
 | 
			
		||||
    public abstract VcsRevDao vcsRevDao();
 | 
			
		||||
    public abstract VcsLogDao vcsLogDao();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,8 @@ public class LacertaDatabaseModule {
 | 
			
		|||
                LacertaDatabase.class,
 | 
			
		||||
                "lacerta.db")
 | 
			
		||||
                .allowMainThreadQueries() // Debug
 | 
			
		||||
                .fallbackToDestructiveMigration() // Debug Only: マイグレーションがない場合などにデータベースを再生成する
 | 
			
		||||
                .fallbackToDestructiveMigrationOnDowngrade() // Debug Only: マイグレーションがない場合などにデータベースを再生成する
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import androidx.room.TypeConverter;
 | 
			
		|||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
public class TagArrayListConverter {
 | 
			
		||||
public class ArrayListConverter {
 | 
			
		||||
 | 
			
		||||
    @TypeConverter
 | 
			
		||||
    public static ArrayList<String> fromString(String value) {
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
package one.nem.lacerta.source.database.dao;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
import androidx.room.Insert;
 | 
			
		||||
import androidx.room.Query;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.source.database.entity.VcsLogEntity;
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
public interface VcsLogDao {
 | 
			
		||||
 | 
			
		||||
    // Select
 | 
			
		||||
    @Query("SELECT * FROM vcs_log WHERE id = :id")
 | 
			
		||||
    VcsLogEntity findById(String id);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_log")
 | 
			
		||||
    List<VcsLogEntity> findAll();
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_log WHERE id IN (:ids)")
 | 
			
		||||
    List<VcsLogEntity> findByIds(List<String> ids);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_log WHERE document_id = :documentId")
 | 
			
		||||
    List<VcsLogEntity> findByDocumentId(String documentId);
 | 
			
		||||
 | 
			
		||||
    // Insert
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insertAll(VcsLogEntity... vcsLogs);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insertAll(List<VcsLogEntity> vcsLogs);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(VcsLogEntity vcsLog);
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: Update, Deleteが必要か検討
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
package one.nem.lacerta.source.database.dao;
 | 
			
		||||
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
import androidx.room.Insert;
 | 
			
		||||
import androidx.room.Query;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.source.database.entity.VcsRevEntity;
 | 
			
		||||
 | 
			
		||||
@Dao
 | 
			
		||||
public interface VcsRevDao {
 | 
			
		||||
 | 
			
		||||
    // Select
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev WHERE id = :id")
 | 
			
		||||
    VcsRevEntity findById(String id);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev")
 | 
			
		||||
    List<VcsRevEntity> findAll();
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev WHERE id IN (:ids)")
 | 
			
		||||
    List<VcsRevEntity> findByIds(List<String> ids);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev WHERE document_id = :documentId")
 | 
			
		||||
    List<VcsRevEntity> findByDocumentId(String documentId);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev WHERE document_id = :documentId ORDER BY created_at DESC LIMIT 1")
 | 
			
		||||
    VcsRevEntity findLatestByDocumentId(String documentId);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM vcs_rev WHERE document_id = :documentId AND branch_name = :branchName ORDER BY created_at DESC LIMIT 1")
 | 
			
		||||
    VcsRevEntity findLatestByDocumentIdAndBranchName(String documentId, String branchName);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insertAll(VcsRevEntity... vcsRevs);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insertAll(List<VcsRevEntity> vcsRevs);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(VcsRevEntity vcsRev);
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: Update, Deleteが必要か検討
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ import androidx.room.TypeConverter;
 | 
			
		|||
import androidx.room.TypeConverters;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.source.database.common.DateTypeConverter;
 | 
			
		||||
import one.nem.lacerta.source.database.common.TagArrayListConverter;
 | 
			
		||||
import one.nem.lacerta.source.database.common.TagListConverter;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,4 +39,7 @@ public class DocumentEntity {
 | 
			
		|||
 | 
			
		||||
    @ColumnInfo(name = "tag_ids")
 | 
			
		||||
    public List<String> tagIds; // タグ
 | 
			
		||||
 | 
			
		||||
    @ColumnInfo(name = "public_path")
 | 
			
		||||
    public String publicPath; // 公開パス
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,10 +16,12 @@ public class LibraryEntity {
 | 
			
		|||
    @NonNull
 | 
			
		||||
    public String id; // ドキュメントID
 | 
			
		||||
 | 
			
		||||
    @ColumnInfo(name = "root_path")
 | 
			
		||||
    public String rootPath; // rootのパス
 | 
			
		||||
    // TODO-rca: 廃止?
 | 
			
		||||
 | 
			
		||||
    @ColumnInfo(name = "path")
 | 
			
		||||
    public String path; // パス
 | 
			
		||||
 | 
			
		||||
    @ColumnInfo(name = "root_path")
 | 
			
		||||
    public String rootPath; // ルートパス
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
package one.nem.lacerta.source.database.entity;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.room.ColumnInfo;
 | 
			
		||||
import androidx.room.Entity;
 | 
			
		||||
import androidx.room.PrimaryKey;
 | 
			
		||||
import androidx.room.TypeConverters;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.source.database.common.DateTypeConverter;
 | 
			
		||||
 | 
			
		||||
@Entity(tableName = "vcs_log")
 | 
			
		||||
@TypeConverters({DateTypeConverter.class})
 | 
			
		||||
public class VcsLogEntity {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * イベントID
 | 
			
		||||
     */
 | 
			
		||||
    @PrimaryKey
 | 
			
		||||
    @ColumnInfo(name = "id")
 | 
			
		||||
    @NonNull
 | 
			
		||||
    public String id;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ドキュメントID
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "document_id")
 | 
			
		||||
    public String documentId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ブランチ名
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "branch_name")
 | 
			
		||||
    public String branchName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 発生日時
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "created_at")
 | 
			
		||||
    public Date createdAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 発生アクション
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "action")
 | 
			
		||||
    public String action;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
package one.nem.lacerta.source.database.entity;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.room.ColumnInfo;
 | 
			
		||||
import androidx.room.Entity;
 | 
			
		||||
import androidx.room.PrimaryKey;
 | 
			
		||||
import androidx.room.TypeConverters;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.source.database.common.ArrayListConverter;
 | 
			
		||||
import one.nem.lacerta.source.database.common.DateTypeConverter;
 | 
			
		||||
 | 
			
		||||
@Entity(tableName = "vcs_rev")
 | 
			
		||||
@TypeConverters({DateTypeConverter.class, ArrayListConverter.class})
 | 
			
		||||
public class VcsRevEntity {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * リビジョンID
 | 
			
		||||
     */
 | 
			
		||||
    @PrimaryKey
 | 
			
		||||
    @ColumnInfo(name = "id")
 | 
			
		||||
    @NonNull
 | 
			
		||||
    public String id;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ドキュメントID
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "document_id")
 | 
			
		||||
    public String documentId;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ブランチ名
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "branch_name")
 | 
			
		||||
    public String branchName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * コミットメッセージ
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "commit_message")
 | 
			
		||||
    public String commitMessage;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * コミット日時
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "created_at")
 | 
			
		||||
    public Date createdAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 含まれるLogのID
 | 
			
		||||
     */
 | 
			
		||||
    @ColumnInfo(name = "log_ids")
 | 
			
		||||
    public ArrayList<String> logIds;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
package one.nem.lacerta.source.file;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
 | 
			
		||||
import org.w3c.dom.Document;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** @noinspection unused*/
 | 
			
		||||
public interface FileManager {
 | 
			
		||||
 | 
			
		||||
    File getFileRef();
 | 
			
		||||
    boolean isExist(String name) throws IOException;
 | 
			
		||||
    boolean isExist();
 | 
			
		||||
    boolean isDirectory();
 | 
			
		||||
    boolean isFile();
 | 
			
		||||
    boolean isWritable();
 | 
			
		||||
    boolean isReadable();
 | 
			
		||||
    // Get current instance
 | 
			
		||||
    FileManager getCurrentInstance();
 | 
			
		||||
    FileManager getNewInstance();
 | 
			
		||||
 | 
			
		||||
    // Configure
 | 
			
		||||
    FileManager enableAutoCreateParent();
 | 
			
		||||
    FileManager disableRootDirCheck();
 | 
			
		||||
 | 
			
		||||
    FileManager setRootDir(Path rootDir);
 | 
			
		||||
    FileManager setPath(Path path);
 | 
			
		||||
    FileManager resolve(String path) throws IOException;
 | 
			
		||||
 | 
			
		||||
    // Create
 | 
			
		||||
    FileManager createFile() throws IOException;
 | 
			
		||||
    FileManager createFile(String fileName) throws IOException;
 | 
			
		||||
    FileManager createFileIfNotExist() throws IOException;
 | 
			
		||||
    FileManager createFileIfNotExist(String fileName) throws IOException;
 | 
			
		||||
    FileManager createDirectory() throws IOException;
 | 
			
		||||
    FileManager createDirectory(String directoryName) throws IOException;
 | 
			
		||||
    FileManager createDirectoryIfNotExist() throws IOException;
 | 
			
		||||
    FileManager createDirectoryIfNotExist(String directoryName) throws IOException;
 | 
			
		||||
 | 
			
		||||
    // Save
 | 
			
		||||
    // XML
 | 
			
		||||
    void saveXml(Document document, String fileName) throws IOException;
 | 
			
		||||
    void saveXml(Document document) throws IOException;
 | 
			
		||||
 | 
			
		||||
    // Bitmap
 | 
			
		||||
    void saveBitmap(Bitmap bitmap, String fileName) throws IOException; // TODO-rca: パラメータに対応させる
 | 
			
		||||
    void saveBitmap(Bitmap bitmap) throws IOException; // TODO-rca: パラメータに対応させる
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Load
 | 
			
		||||
    // XML
 | 
			
		||||
    Document loadXml(String fileName) throws IOException;
 | 
			
		||||
    Document loadXml() throws IOException;
 | 
			
		||||
 | 
			
		||||
    // Bitmap
 | 
			
		||||
    Bitmap loadBitmap(String fileName) throws IOException;
 | 
			
		||||
    Bitmap loadBitmap() throws IOException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
package one.nem.lacerta.source.file.factory;
 | 
			
		||||
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.AssistedFactory;
 | 
			
		||||
import one.nem.lacerta.source.file.impl.FileManagerImpl;
 | 
			
		||||
 | 
			
		||||
@AssistedFactory
 | 
			
		||||
public interface FileManagerFactory {
 | 
			
		||||
    FileManagerImpl create(Path rootDir);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,364 @@
 | 
			
		|||
package one.nem.lacerta.source.file.impl;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
import android.graphics.BitmapFactory;
 | 
			
		||||
 | 
			
		||||
import org.w3c.dom.Document;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
 | 
			
		||||
import javax.xml.parsers.DocumentBuilder;
 | 
			
		||||
import javax.xml.parsers.DocumentBuilderFactory;
 | 
			
		||||
import javax.xml.transform.Transformer;
 | 
			
		||||
import javax.xml.transform.TransformerFactory;
 | 
			
		||||
import javax.xml.transform.dom.DOMSource;
 | 
			
		||||
import javax.xml.transform.stream.StreamResult;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.Assisted;
 | 
			
		||||
import dagger.assisted.AssistedInject;
 | 
			
		||||
import one.nem.lacerta.source.file.FileManager;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
public class FileManagerImpl implements FileManager {
 | 
			
		||||
 | 
			
		||||
    // variables
 | 
			
		||||
    private Path rootDir;
 | 
			
		||||
    private Path path;
 | 
			
		||||
    private boolean autoCreateParent = false;
 | 
			
		||||
    private boolean disableRootDirCheck = false;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Injection
 | 
			
		||||
    private final LacertaLogger logger;
 | 
			
		||||
    @AssistedInject
 | 
			
		||||
    public FileManagerImpl(LacertaLogger logger, @Assisted Path rootDir) {
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
        this.rootDir = rootDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for generate new instance
 | 
			
		||||
    public FileManagerImpl(LacertaLogger logger, Path rootDir, Path path, boolean autoCreateParent, boolean disableRootDirCheck) {
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
        this.rootDir = rootDir;
 | 
			
		||||
        this.path = path;
 | 
			
		||||
        this.autoCreateParent = autoCreateParent;
 | 
			
		||||
        this.disableRootDirCheck = disableRootDirCheck;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal
 | 
			
		||||
    private Path resolveStringPath(String path) throws IOException{
 | 
			
		||||
        String[] pathArray = path.split("/");
 | 
			
		||||
        Path resolvedPath = this.path;
 | 
			
		||||
        for (String pathPart : pathArray) {
 | 
			
		||||
            if (pathPart.equals("..")) {
 | 
			
		||||
                resolvedPath = resolvedPath.getParent();
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                resolvedPath = resolvedPath.resolve(pathPart);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                throw new IOException("Invalid path: " + path);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        logger.debug("resolveStringPath", "resolvedPath: " + resolvedPath);
 | 
			
		||||
        return resolvedPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private FileManager newInstance(Path rootDir, Path path, boolean autoCreateParent, boolean disableRootDirCheck) {
 | 
			
		||||
        logger.debug("newInstance", "Generating new instance");
 | 
			
		||||
        logger.debug("newInstance", "Path: " + path);
 | 
			
		||||
        return new FileManagerImpl(this.logger, rootDir, path, autoCreateParent, disableRootDirCheck);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public File getFileRef() {
 | 
			
		||||
        if (this.isExist()) {
 | 
			
		||||
            return this.path.toFile();
 | 
			
		||||
        } else {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isExist(String name) throws IOException {
 | 
			
		||||
        Path resolvedPath = this.resolveStringPath(name);
 | 
			
		||||
        return Files.exists(resolvedPath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isExist(){
 | 
			
		||||
        return Files.exists(this.path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isDirectory() {
 | 
			
		||||
        if (this.isExist()) {
 | 
			
		||||
            File file = this.path.toFile();
 | 
			
		||||
            return file.isDirectory();
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isFile() {
 | 
			
		||||
        if (this.isExist()) {
 | 
			
		||||
            File file = this.path.toFile();
 | 
			
		||||
            return file.isFile();
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isReadable() {
 | 
			
		||||
        if (this.isExist()) {
 | 
			
		||||
            File file = this.path.toFile();
 | 
			
		||||
            return file.canRead();
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isWritable() {
 | 
			
		||||
        if (this.isExist()) {
 | 
			
		||||
            File file = this.path.toFile();
 | 
			
		||||
            return file.canWrite();
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager getCurrentInstance() {
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager getNewInstance() {
 | 
			
		||||
        return this.newInstance(this.rootDir, this.rootDir, this.autoCreateParent, this.disableRootDirCheck);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager enableAutoCreateParent() {
 | 
			
		||||
        this.autoCreateParent = true;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager disableRootDirCheck() {
 | 
			
		||||
        this.disableRootDirCheck = true;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager setRootDir(Path rootDir) {
 | 
			
		||||
        return this.newInstance(rootDir, this.path, this.autoCreateParent, this.disableRootDirCheck);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager setPath(Path path) {
 | 
			
		||||
        Path resolvedPath;
 | 
			
		||||
        if (this.disableRootDirCheck) {
 | 
			
		||||
            resolvedPath = path;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (path.startsWith(this.rootDir)) {
 | 
			
		||||
                resolvedPath = path;
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException("path must be in rootDir");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        logger.debug("setPath", "resolvedPath: " + resolvedPath);
 | 
			
		||||
        return this.newInstance(this.rootDir, resolvedPath, this.autoCreateParent, this.disableRootDirCheck);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager resolve(String path) throws IOException{
 | 
			
		||||
        Path resolvedPath;
 | 
			
		||||
        try {
 | 
			
		||||
            resolvedPath = resolveStringPath(path);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            logger.error("resolve", e.getMessage());
 | 
			
		||||
            throw new IOException("Invalid path: " + path);
 | 
			
		||||
        }
 | 
			
		||||
        return this.setPath(resolvedPath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal
 | 
			
		||||
    private void createFileInternal(Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            if (this.autoCreateParent) {
 | 
			
		||||
                if (!path.getParent().toFile().exists()) {
 | 
			
		||||
                    Files.createDirectories(path.getParent());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Files.createFile(path);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("createFileInternal", e.getMessage());
 | 
			
		||||
            throw new IOException("Failed to create file");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createFile() throws IOException {
 | 
			
		||||
        this.createFileInternal(this.path);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createFile(String fileName) throws IOException { // pathが書き換わってしまうのは想像できない挙動かも?
 | 
			
		||||
        this.createFileInternal(this.resolveStringPath(fileName));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createFileIfNotExist() throws IOException {
 | 
			
		||||
        if (!this.isExist()) {
 | 
			
		||||
            this.createFile();
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createFileIfNotExist(String fileName) throws IOException {
 | 
			
		||||
        if (!this.isExist(fileName)) {
 | 
			
		||||
            this.createFile(fileName);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal
 | 
			
		||||
    private void createDirectoryInternal(Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            if (this.autoCreateParent) {
 | 
			
		||||
                if (!path.getParent().toFile().exists()) {
 | 
			
		||||
                    Files.createDirectories(path.getParent());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Files.createDirectory(path);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("createDirectoryInternal", e.getMessage());
 | 
			
		||||
            throw new IOException("Failed to create directory");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createDirectory() throws IOException {
 | 
			
		||||
        this.createDirectoryInternal(this.path);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createDirectory(String directoryName) throws IOException {
 | 
			
		||||
        this.createDirectoryInternal(this.resolveStringPath(directoryName));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createDirectoryIfNotExist() throws IOException {
 | 
			
		||||
        if (!this.isExist()) {
 | 
			
		||||
            this.createDirectory();
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FileManager createDirectoryIfNotExist(String directoryName) throws IOException {
 | 
			
		||||
        if (!this.isExist(directoryName)) {
 | 
			
		||||
            this.createDirectory(directoryName);
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal
 | 
			
		||||
    private void saveXmlInternal(Document document, Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
 | 
			
		||||
            Transformer transformer = transformerFactory.newTransformer();
 | 
			
		||||
            DOMSource source = new DOMSource(document);
 | 
			
		||||
 | 
			
		||||
            StreamResult result = new StreamResult(path.toFile());
 | 
			
		||||
 | 
			
		||||
            transformer.transform(source, result);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("saveXmlInternal", e.getMessage());
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            throw new IOException("Failed to save xml");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private void saveBitmapInternal(Bitmap bitmap, Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            logger.debug("saveBitmapInternal", "path: " + path);
 | 
			
		||||
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, Files.newOutputStream(path));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("saveBitmapInternal", e.getMessage());
 | 
			
		||||
            throw new IOException("Failed to save bitmap");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveXml(Document document, String fileName) throws IOException {
 | 
			
		||||
        this.saveXmlInternal(document, this.resolveStringPath(fileName));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveXml(Document document) throws IOException {
 | 
			
		||||
        this.saveXmlInternal(document, this.path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveBitmap(Bitmap bitmap, String fileName) throws IOException {
 | 
			
		||||
        this.saveBitmapInternal(bitmap, this.resolveStringPath(fileName));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveBitmap(Bitmap bitmap) throws IOException {
 | 
			
		||||
        this.saveBitmapInternal(bitmap, this.path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Internal
 | 
			
		||||
    private Document loadXmlInternal(Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 | 
			
		||||
            DocumentBuilder builder = factory.newDocumentBuilder();
 | 
			
		||||
            return builder.parse(Files.newInputStream(path));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("loadXmlInternal", e.getMessage());
 | 
			
		||||
            throw new IOException("Failed to load xml");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private Bitmap loadBitmapInternal(Path path) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            return BitmapFactory.decodeFile(path.toString());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("loadBitmapInternal", e.getMessage());
 | 
			
		||||
            throw new IOException("Failed to load bitmap");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Document loadXml(String fileName) throws IOException {
 | 
			
		||||
        return this.loadXmlInternal(this.resolveStringPath(fileName));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Document loadXml() throws IOException {
 | 
			
		||||
        return this.loadXmlInternal(this.path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Bitmap loadBitmap(String fileName) throws IOException {
 | 
			
		||||
        return this.loadBitmapInternal(this.resolveStringPath(fileName));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Bitmap loadBitmap() throws IOException {
 | 
			
		||||
        return this.loadBitmapInternal(this.path);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
package one.nem.lacerta.source.file.module;
 | 
			
		||||
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.Assisted;
 | 
			
		||||
import dagger.assisted.AssistedInject;
 | 
			
		||||
 | 
			
		||||
public class FileManagerModule {
 | 
			
		||||
 | 
			
		||||
    private final Path rootDir;
 | 
			
		||||
 | 
			
		||||
    @AssistedInject
 | 
			
		||||
    public FileManagerModule(@Assisted Path rootDir) {
 | 
			
		||||
        this.rootDir = rootDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Path getRootDir() {
 | 
			
		||||
        return rootDir;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -37,5 +37,6 @@ dependencies {
 | 
			
		|||
    implementation libs.com.google.dagger.hilt.android
 | 
			
		||||
    annotationProcessor libs.com.google.dagger.hilt.compiler
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // model
 | 
			
		||||
    implementation project(':model')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
package one.nem.lacerta.utils;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.model.KeyValueLog;
 | 
			
		||||
 | 
			
		||||
public interface LacertaLogger {
 | 
			
		||||
 | 
			
		||||
    void info(String tag, String message);
 | 
			
		||||
| 
						 | 
				
			
			@ -9,4 +11,7 @@ public interface LacertaLogger {
 | 
			
		|||
    void trace(String tag, String message);
 | 
			
		||||
    void fatal(String tag, String message);
 | 
			
		||||
 | 
			
		||||
    String buildKVMessage(KeyValueLog... logs);
 | 
			
		||||
    // With name
 | 
			
		||||
    String buildKVMessage(String name, KeyValueLog... logs);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								utils/src/main/java/one/nem/lacerta/utils/XmlMetaParser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								utils/src/main/java/one/nem/lacerta/utils/XmlMetaParser.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
package one.nem.lacerta.utils;
 | 
			
		||||
 | 
			
		||||
import org.w3c.dom.Document;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.document.internal.XmlMetaModel;
 | 
			
		||||
 | 
			
		||||
public interface XmlMetaParser {
 | 
			
		||||
 | 
			
		||||
    XmlMetaModel deserialize(Document document);
 | 
			
		||||
 | 
			
		||||
    Document serialize(XmlMetaModel meta);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,8 @@ import android.util.Log;
 | 
			
		|||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
import one.nem.lacerta.utils.model.KeyValueLog;
 | 
			
		||||
 | 
			
		||||
public class LacertaLoggerImpl implements LacertaLogger{
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
| 
						 | 
				
			
			@ -40,4 +42,30 @@ public class LacertaLoggerImpl implements LacertaLogger{
 | 
			
		|||
    public void fatal(String tag, String message) {
 | 
			
		||||
        Log.wtf(tag, message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String buildKVMessage(KeyValueLog... logs) {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        for (KeyValueLog log : logs) {
 | 
			
		||||
            builder.append(log.getKey());
 | 
			
		||||
            builder.append(": ");
 | 
			
		||||
            builder.append(log.getValue());
 | 
			
		||||
            builder.append("\n");
 | 
			
		||||
        }
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String buildKVMessage(String name, KeyValueLog... logs) {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        builder.append(name);
 | 
			
		||||
        builder.append("\n");
 | 
			
		||||
        for (KeyValueLog log : logs) {
 | 
			
		||||
            builder.append(log.getKey());
 | 
			
		||||
            builder.append(": ");
 | 
			
		||||
            builder.append(log.getValue());
 | 
			
		||||
            builder.append("\n");
 | 
			
		||||
        }
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
package one.nem.lacerta.utils.impl;
 | 
			
		||||
 | 
			
		||||
import org.w3c.dom.Document;
 | 
			
		||||
import org.w3c.dom.Element;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
import javax.xml.parsers.DocumentBuilder;
 | 
			
		||||
import javax.xml.parsers.DocumentBuilderFactory;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.model.document.internal.XmlMetaModel;
 | 
			
		||||
import one.nem.lacerta.model.document.internal.XmlMetaPageModel;
 | 
			
		||||
import one.nem.lacerta.utils.XmlMetaParser;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
 | 
			
		||||
public class XmlMetaParserImpl implements XmlMetaParser{
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    LacertaLogger logger;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    public XmlMetaParserImpl() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public XmlMetaModel deserialize(Document document) {
 | 
			
		||||
        logger.debug("deserialize", "called");
 | 
			
		||||
        try {
 | 
			
		||||
            Element rootElement = document.getDocumentElement();
 | 
			
		||||
 | 
			
		||||
            XmlMetaModel meta = new XmlMetaModel();
 | 
			
		||||
 | 
			
		||||
            meta.setTitle(rootElement.getElementsByTagName("title").item(0).getTextContent());
 | 
			
		||||
            meta.setAuthor(rootElement.getElementsByTagName("author").item(0).getTextContent());
 | 
			
		||||
            meta.setDescription(rootElement.getElementsByTagName("description").item(0).getTextContent());
 | 
			
		||||
            meta.setDefaultBranch(rootElement.getElementsByTagName("defaultBranch").item(0).getTextContent());
 | 
			
		||||
 | 
			
		||||
            ArrayList<XmlMetaPageModel> pages = new ArrayList<>();
 | 
			
		||||
            for(int i = 0; i < rootElement.getElementsByTagName("pages").getLength(); i++) {
 | 
			
		||||
                Element pageElement = (Element) rootElement.getElementsByTagName("page").item(i);
 | 
			
		||||
                XmlMetaPageModel page = new XmlMetaPageModel();
 | 
			
		||||
                page.setFilename(pageElement.getElementsByTagName("filename").item(0).getTextContent());
 | 
			
		||||
                pages.add(page);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            meta.setPages(pages);
 | 
			
		||||
 | 
			
		||||
            return meta;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("deserialize", "something wrong");
 | 
			
		||||
            logger.trace("deserialize", e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public Document serialize(XmlMetaModel meta) {
 | 
			
		||||
        logger.debug("serialize", "called");
 | 
			
		||||
        try {
 | 
			
		||||
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 | 
			
		||||
            DocumentBuilder builder = factory.newDocumentBuilder();
 | 
			
		||||
            Document document = builder.newDocument();
 | 
			
		||||
 | 
			
		||||
            Element rootElement = document.createElement("meta");
 | 
			
		||||
 | 
			
		||||
            appendElement(document, rootElement, "title", meta.getTitle());
 | 
			
		||||
            appendElement(document, rootElement, "author", meta.getAuthor());
 | 
			
		||||
            appendElement(document, rootElement, "description", meta.getDescription());
 | 
			
		||||
            appendElement(document, rootElement, "defaultBranch", meta.getDefaultBranch());
 | 
			
		||||
 | 
			
		||||
            Element pagesElement = document.createElement("pages");
 | 
			
		||||
            for(XmlMetaPageModel page : meta.getPages()) {
 | 
			
		||||
                Element pageElement = document.createElement("page");
 | 
			
		||||
                appendElement(document, pageElement, "filename", page.getFilename());
 | 
			
		||||
                pagesElement.appendChild(pageElement);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            rootElement.appendChild(pagesElement);
 | 
			
		||||
 | 
			
		||||
            document.appendChild(rootElement);
 | 
			
		||||
 | 
			
		||||
            return document;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error("serialize", "something wrong");
 | 
			
		||||
            logger.trace("serialize", e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    // Internal Methods
 | 
			
		||||
    private void appendElement(Document document, Element rootElement, String name, String textContent) {
 | 
			
		||||
        Element element = document.createElement(name);
 | 
			
		||||
        element.setTextContent(textContent);
 | 
			
		||||
        rootElement.appendChild(element);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
package one.nem.lacerta.utils.model;
 | 
			
		||||
 | 
			
		||||
public class KeyValueLog {
 | 
			
		||||
 | 
			
		||||
    String key;
 | 
			
		||||
    String value;
 | 
			
		||||
 | 
			
		||||
    public KeyValueLog(String key, String value) {
 | 
			
		||||
        this.key = key;
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getter
 | 
			
		||||
    public String getKey() {
 | 
			
		||||
        return key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Setter
 | 
			
		||||
    public void setKey(String key) {
 | 
			
		||||
        this.key = key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setValue(String value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
package one.nem.lacerta.utils.module;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import dagger.Binds;
 | 
			
		||||
import dagger.Module;
 | 
			
		||||
import dagger.hilt.InstallIn;
 | 
			
		||||
import dagger.hilt.components.SingletonComponent;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.utils.XmlMetaParser;
 | 
			
		||||
import one.nem.lacerta.utils.impl.XmlMetaParserImpl;
 | 
			
		||||
@Module
 | 
			
		||||
@InstallIn(SingletonComponent.class)
 | 
			
		||||
abstract public class XmlMetaParserModule {
 | 
			
		||||
 | 
			
		||||
    @Binds
 | 
			
		||||
    public abstract XmlMetaParser bindXmlMetaParser(XmlMetaParserImpl impl);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								vcs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vcs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
/build
 | 
			
		||||
							
								
								
									
										59
									
								
								vcs/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vcs/build.gradle
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
plugins {
 | 
			
		||||
    alias(libs.plugins.com.android.library)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    namespace 'one.nem.lacerta.vcs'
 | 
			
		||||
    compileSdk 34
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        minSdk 26
 | 
			
		||||
 | 
			
		||||
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
			
		||||
        consumerProguardFiles "consumer-rules.pro"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildTypes {
 | 
			
		||||
        release {
 | 
			
		||||
            minifyEnabled false
 | 
			
		||||
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    implementation libs.androidx.appcompat
 | 
			
		||||
    implementation libs.com.google.android.material
 | 
			
		||||
    testImplementation libs.junit
 | 
			
		||||
    androidTestImplementation libs.androidx.test.ext.junit
 | 
			
		||||
    androidTestImplementation libs.androidx.test.espresso.core
 | 
			
		||||
 | 
			
		||||
    // Hilt (DI)
 | 
			
		||||
    implementation libs.com.google.dagger.hilt.android
 | 
			
		||||
    annotationProcessor libs.com.google.dagger.hilt.compiler
 | 
			
		||||
 | 
			
		||||
    implementation project(':model')
 | 
			
		||||
    implementation project(':source')
 | 
			
		||||
    implementation project(':utils')
 | 
			
		||||
 | 
			
		||||
    // Jackson
 | 
			
		||||
    // TODO-rca: バージョンカタログにうつす
 | 
			
		||||
 | 
			
		||||
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
 | 
			
		||||
    implementation 'com.fasterxml.jackson.core:jackson-core:2.16.1'
 | 
			
		||||
 | 
			
		||||
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
 | 
			
		||||
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.1'
 | 
			
		||||
 | 
			
		||||
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
 | 
			
		||||
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.16.1'
 | 
			
		||||
 | 
			
		||||
    // Room
 | 
			
		||||
    implementation libs.androidx.room.runtime
 | 
			
		||||
    annotationProcessor libs.androidx.room.compiler
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										0
									
								
								vcs/consumer-rules.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vcs/consumer-rules.pro
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										21
									
								
								vcs/proguard-rules.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vcs/proguard-rules.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
# Add project specific ProGuard rules here.
 | 
			
		||||
# You can control the set of applied configuration files using the
 | 
			
		||||
# proguardFiles setting in build.gradle.
 | 
			
		||||
#
 | 
			
		||||
# For more details, see
 | 
			
		||||
#   http://developer.android.com/guide/developing/tools/proguard.html
 | 
			
		||||
 | 
			
		||||
# If your project uses WebView with JS, uncomment the following
 | 
			
		||||
# and specify the fully qualified class name to the JavaScript interface
 | 
			
		||||
# class:
 | 
			
		||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 | 
			
		||||
#   public *;
 | 
			
		||||
#}
 | 
			
		||||
 | 
			
		||||
# Uncomment this to preserve the line number information for
 | 
			
		||||
# debugging stack traces.
 | 
			
		||||
#-keepattributes SourceFile,LineNumberTable
 | 
			
		||||
 | 
			
		||||
# If you keep the line number information, uncomment this to
 | 
			
		||||
# hide the original source file name.
 | 
			
		||||
#-renamesourcefileattribute SourceFile
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
package one.nem.lacerta.vcs;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
import androidx.test.platform.app.InstrumentationRegistry;
 | 
			
		||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.runner.RunWith;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Instrumented test, which will execute on an Android device.
 | 
			
		||||
 *
 | 
			
		||||
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
			
		||||
 */
 | 
			
		||||
@RunWith(AndroidJUnit4.class)
 | 
			
		||||
public class ExampleInstrumentedTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    public void useAppContext() {
 | 
			
		||||
        // Context of the app under test.
 | 
			
		||||
        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 | 
			
		||||
        assertEquals("one.nem.lacerta.vcs.test", appContext.getPackageName());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								vcs/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vcs/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
							
								
								
									
										48
									
								
								vcs/src/main/java/one/nem/lacerta/vcs/ActionType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vcs/src/main/java/one/nem/lacerta/vcs/ActionType.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
package one.nem.lacerta.vcs;
 | 
			
		||||
 | 
			
		||||
public enum ActionType {
 | 
			
		||||
 | 
			
		||||
    INSERT_PAGE("insert_page"),
 | 
			
		||||
    UPDATE_PAGE("update_page"),
 | 
			
		||||
    DELETE_PAGE("delete_page"),
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: 実装----------------------------------------
 | 
			
		||||
    UPDATE_PAGE_ORDER("update_page_order"),
 | 
			
		||||
    INSERT_PAGE_CONTENT("insert_page_content"),
 | 
			
		||||
    UPDATE_PAGE_CONTENT("update_page_content"),
 | 
			
		||||
    DELETE_PAGE_CONTENT("delete_page_content"),
 | 
			
		||||
 | 
			
		||||
    CREATE_BRANCH("create_branch"),
 | 
			
		||||
    DROP_BRANCH("drop_branch"),
 | 
			
		||||
    REBASE_BRANCH("rebase_branch"),
 | 
			
		||||
 | 
			
		||||
    // -----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    CREATE_DOCUMENT("create_document"),
 | 
			
		||||
    DROP_DOCUMENT("drop_document"),
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: 実装----------------------------------------
 | 
			
		||||
    UPDATE_DOCUMENT_META("update_document_meta"),
 | 
			
		||||
    // -----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    OTHER("other");
 | 
			
		||||
 | 
			
		||||
    private final String value;
 | 
			
		||||
 | 
			
		||||
    ActionType(String value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ActionType fromValue(String value) {
 | 
			
		||||
        for (ActionType actionType : ActionType.values()) {
 | 
			
		||||
            if (actionType.getValue().equals(value)) {
 | 
			
		||||
                return actionType;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ActionType.OTHER;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								vcs/src/main/java/one/nem/lacerta/vcs/LacertaVcs.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vcs/src/main/java/one/nem/lacerta/vcs/LacertaVcs.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
package one.nem.lacerta.vcs;
 | 
			
		||||
 | 
			
		||||
public interface LacertaVcs {
 | 
			
		||||
 | 
			
		||||
    // Actions
 | 
			
		||||
    public void updatePage(int index, String fileName);
 | 
			
		||||
 | 
			
		||||
    public void insertPage(int index, String fileName);
 | 
			
		||||
 | 
			
		||||
    public void deletePage(int index);
 | 
			
		||||
 | 
			
		||||
    // debug
 | 
			
		||||
    public void printLog();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
package one.nem.lacerta.vcs.factory;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.AssistedFactory;
 | 
			
		||||
import one.nem.lacerta.vcs.impl.LacertaVcsImpl;
 | 
			
		||||
 | 
			
		||||
@AssistedFactory
 | 
			
		||||
public interface LacertaVcsFactory {
 | 
			
		||||
 | 
			
		||||
    LacertaVcsImpl create(String documentId);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
package one.nem.lacerta.vcs.impl;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
 | 
			
		||||
import dagger.assisted.Assisted;
 | 
			
		||||
import dagger.assisted.AssistedInject;
 | 
			
		||||
import one.nem.lacerta.source.database.LacertaDatabase;
 | 
			
		||||
import one.nem.lacerta.source.database.entity.VcsLogEntity;
 | 
			
		||||
import one.nem.lacerta.utils.LacertaLogger;
 | 
			
		||||
import one.nem.lacerta.vcs.LacertaVcs;
 | 
			
		||||
 | 
			
		||||
public class LacertaVcsImpl implements LacertaVcs {
 | 
			
		||||
 | 
			
		||||
    // TAG
 | 
			
		||||
    private static final String TAG = LacertaVcsImpl.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    String documentId;
 | 
			
		||||
 | 
			
		||||
    LacertaDatabase database;
 | 
			
		||||
 | 
			
		||||
    LacertaLogger logger;
 | 
			
		||||
 | 
			
		||||
    @AssistedInject
 | 
			
		||||
    public LacertaVcsImpl(LacertaLogger logger, LacertaDatabase database, @Assisted String documentId) {
 | 
			
		||||
        this.logger = logger;
 | 
			
		||||
        this.database = database;
 | 
			
		||||
        this.documentId = documentId;
 | 
			
		||||
        logger.debug(TAG, "LacertaVcsImpl constructor");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updatePage(int index, String fileName) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void insertPage(int index, String fileName) {
 | 
			
		||||
        logger.debug(TAG, "insertPage");
 | 
			
		||||
        VcsLogEntity vcsLogEntity = new VcsLogEntity();
 | 
			
		||||
        vcsLogEntity.id = UUID.randomUUID().toString();
 | 
			
		||||
        vcsLogEntity.documentId = documentId;
 | 
			
		||||
        vcsLogEntity.branchName = "master";
 | 
			
		||||
        vcsLogEntity.createdAt = new java.util.Date();
 | 
			
		||||
        vcsLogEntity.action = "placeholder";
 | 
			
		||||
        database.vcsLogDao().insert(vcsLogEntity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void deletePage(int index) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void printLog() {
 | 
			
		||||
        logger.debug(TAG, "printLog");
 | 
			
		||||
        database.vcsLogDao().findAll().forEach(vcsLog -> {
 | 
			
		||||
            logger.debug(TAG, vcsLog.id);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
package one.nem.lacerta.vcs.internal;
 | 
			
		||||
 | 
			
		||||
import android.provider.ContactsContract;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.vcs.ActionType;
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.DeletePage;
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.InsertPage;
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.UpdatePage;
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.common.ActionBase;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
 | 
			
		||||
public class JsonUtils {
 | 
			
		||||
 | 
			
		||||
    // TODO-rca: Injectionで実装しなおす
 | 
			
		||||
 | 
			
		||||
    // Public methods
 | 
			
		||||
 | 
			
		||||
    public static String toJson(Object object) {
 | 
			
		||||
        ActionBase converted;
 | 
			
		||||
        if (object == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        } else if (object instanceof ActionBase) {
 | 
			
		||||
            ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
            switch (((ActionBase) object).getActionType()) {
 | 
			
		||||
                case INSERT_PAGE:
 | 
			
		||||
                    converted = (InsertPage) object;
 | 
			
		||||
                    break;
 | 
			
		||||
                case UPDATE_PAGE:
 | 
			
		||||
                    converted = (UpdatePage) object;
 | 
			
		||||
                    break;
 | 
			
		||||
                case DELETE_PAGE:
 | 
			
		||||
                    converted = (DeletePage) object;
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new IllegalArgumentException("Unknown action type");
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                return mapper.writeValueAsString(converted);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new IllegalArgumentException("Unknown object type");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Object fromJson(String json, ActionType actionType) {
 | 
			
		||||
        ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
        try {
 | 
			
		||||
            switch (actionType) {
 | 
			
		||||
                case INSERT_PAGE:
 | 
			
		||||
                    return mapper.readValue(json, InsertPage.class);
 | 
			
		||||
                case UPDATE_PAGE:
 | 
			
		||||
                    return mapper.readValue(json, UpdatePage.class);
 | 
			
		||||
                case DELETE_PAGE:
 | 
			
		||||
                    return mapper.readValue(json, DeletePage.class);
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new IllegalArgumentException("Unknown action type");
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
package one.nem.lacerta.vcs.model.action;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.common.ActionBase;
 | 
			
		||||
 | 
			
		||||
public class DeletePage extends ActionBase {
 | 
			
		||||
 | 
			
		||||
        private int index;
 | 
			
		||||
 | 
			
		||||
        public DeletePage() {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public DeletePage(int index) {
 | 
			
		||||
            this.index = index;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int getIndex() {
 | 
			
		||||
            return index;
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
package one.nem.lacerta.vcs.model.action;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.common.ActionBase;
 | 
			
		||||
 | 
			
		||||
public class InsertPage extends ActionBase {
 | 
			
		||||
 | 
			
		||||
    private int index;
 | 
			
		||||
    private String fileName;
 | 
			
		||||
 | 
			
		||||
    public InsertPage() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public InsertPage(int index, String fileName) {
 | 
			
		||||
        this.index = index;
 | 
			
		||||
        this.fileName = fileName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getIndex() {
 | 
			
		||||
        return index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFileName() {
 | 
			
		||||
        return fileName;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
package one.nem.lacerta.vcs.model.action;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.vcs.model.action.common.ActionBase;
 | 
			
		||||
 | 
			
		||||
public class UpdatePage extends ActionBase {
 | 
			
		||||
 | 
			
		||||
    private int index;
 | 
			
		||||
    private String fileName;
 | 
			
		||||
 | 
			
		||||
    public UpdatePage() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public UpdatePage(int index, String fileName) {
 | 
			
		||||
        this.index = index;
 | 
			
		||||
        this.fileName = fileName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getIndex() {
 | 
			
		||||
        return index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFileName() {
 | 
			
		||||
        return fileName;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
package one.nem.lacerta.vcs.model.action.common;
 | 
			
		||||
 | 
			
		||||
import one.nem.lacerta.vcs.ActionType;
 | 
			
		||||
 | 
			
		||||
public class ActionBase {
 | 
			
		||||
    private ActionType actionType;
 | 
			
		||||
 | 
			
		||||
    public ActionBase() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ActionBase(ActionType actionType) {
 | 
			
		||||
        this.actionType = actionType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ActionType getActionType() {
 | 
			
		||||
        return actionType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setActionType(ActionType actionType) {
 | 
			
		||||
        this.actionType = actionType;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user