diff --git a/.github/ISSUE_TEMPLATE/不具合用テンプレート.md b/.github/ISSUE_TEMPLATE/不具合用テンプレート.md
new file mode 100644
index 00000000..61724e36
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/不具合用テンプレート.md
@@ -0,0 +1,17 @@
+---
+name: 不具合用テンプレート
+about: 不具合用テンプレート
+title: "[BUG]: "
+labels: バグ
+assignees: ''
+
+---
+
+# 概要
+
+
+# 詳細
+
+
+# 影響箇所
+
diff --git a/.github/ISSUE_TEMPLATE/改善用テンプレート.md b/.github/ISSUE_TEMPLATE/改善用テンプレート.md
new file mode 100644
index 00000000..42d1256b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/改善用テンプレート.md
@@ -0,0 +1,17 @@
+---
+name: 改善用テンプレート
+about: 改善用テンプレート
+title: "[IMPROVE]"
+labels: ''
+assignees: ''
+
+---
+
+# 概要
+
+
+# 詳細
+
+
+# 影響箇所
+
diff --git a/.github/ISSUE_TEMPLATE/新機能用テンプレート.md b/.github/ISSUE_TEMPLATE/新機能用テンプレート.md
index 5518f596..c3d09e6f 100644
--- a/.github/ISSUE_TEMPLATE/新機能用テンプレート.md
+++ b/.github/ISSUE_TEMPLATE/新機能用テンプレート.md
@@ -1,10 +1,20 @@
---
name: 新機能用テンプレート
-about: 新規開発Issue用テンプレート
+about: 新規能用テンプレート
title: ''
-labels: ''
+labels: 新機能
assignees: ''
---
-WIP
+# 概要
+
+
+# 詳細
+
+
+# 関連Issue
+
+
+# 影響箇所
+
diff --git a/.github/PULL_REQUEST_TEMPLATE/general.md b/.github/PULL_REQUEST_TEMPLATE/general.md
new file mode 100644
index 00000000..2335a652
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE/general.md
@@ -0,0 +1,18 @@
+# 概要
+
+
+# 関連Issue
+- #000
+
+# 詳細
+
+
+# 影響箇所
+
+
+# チェック
+
+- [ ] 機能として完成している
+ - [ ] WIP(Work in progress: 作業中)
+- [ ] 正常にビルド/起動ができる
+- [ ] 既存の機能を壊していない
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index 0c0c3383..00000000
--- a/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 45c0ba13..b9fda1d9 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -26,10 +26,10 @@
-
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 773fe0fb..9f71c83d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,3 +1,4 @@
+
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..2335a652
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,18 @@
+# 概要
+
+
+# 関連Issue
+- #000
+
+# 詳細
+
+
+# 影響箇所
+
+
+# チェック
+
+- [ ] 機能として完成している
+ - [ ] WIP(Work in progress: 作業中)
+- [ ] 正常にビルド/起動ができる
+- [ ] 既存の機能を壊していない
diff --git a/README.md b/README.md
index 1146cd08..436e13a0 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,46 @@ WIP
![Untitled Diagram(2)](https://github.com/lacerta-doc/Lacerta/assets/66072112/9daabaca-5cdc-49f8-ac66-196c588a47c9)
+## メモ
+- アイコン: 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)
### 規則
diff --git a/app/build.gradle b/app/build.gradle
index e0a75c39..e6cbc668 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
@@ -61,8 +83,6 @@ dependencies {
implementation project(':shared:ui')
- implementation project(':shared:icon')
-
// Hilt (DI)
implementation libs.com.google.dagger.hilt.android
annotationProcessor libs.com.google.dagger.hilt.compiler
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6ad838c8..a5ae62e6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/provider_path.xml b/app/src/main/res/xml/provider_path.xml
new file mode 100644
index 00000000..d2e2c8de
--- /dev/null
+++ b/app/src/main/res/xml/provider_path.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/component/scanner/build.gradle b/component/scanner/build.gradle
index ee9a16a8..17887caf 100644
--- a/component/scanner/build.gradle
+++ b/component/scanner/build.gradle
@@ -1,5 +1,6 @@
plugins {
alias(libs.plugins.com.android.library)
+ id 'com.google.dagger.hilt.android'
}
android {
@@ -29,9 +30,26 @@ dependencies {
implementation libs.androidx.appcompat
implementation libs.com.google.android.material
+ implementation libs.androidx.activity
+ implementation libs.androidx.constraintlayout
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 'com.websitebeaver:documentscanner:1.0.0'
+
+ implementation project(':shared:ui')
+ implementation project(':model')
+
+ implementation project(':processor')
+
+ implementation project(':utils')
+
+ implementation project(':vcs')
+
+ implementation project(':data')
}
\ No newline at end of file
diff --git a/component/scanner/src/main/AndroidManifest.xml b/component/scanner/src/main/AndroidManifest.xml
index a5918e68..74cc7c29 100644
--- a/component/scanner/src/main/AndroidManifest.xml
+++ b/component/scanner/src/main/AndroidManifest.xml
@@ -1,4 +1,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CaptureResultAdapter.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CaptureResultAdapter.java
new file mode 100644
index 00000000..949e28d6
--- /dev/null
+++ b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CaptureResultAdapter.java
@@ -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 {
+ private final ArrayList results;
+
+ public CaptureResultAdapter(ArrayList 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CapturedData.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CapturedData.java
new file mode 100644
index 00000000..2b6441d5
--- /dev/null
+++ b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/CapturedData.java
@@ -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;
+ }
+}
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerDataManagerStubFragment.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerDataManagerStubFragment.java
new file mode 100644
index 00000000..9fd979b9
--- /dev/null
+++ b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerDataManagerStubFragment.java
@@ -0,0 +1,251 @@
+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 results = new ArrayList<>();
+
+ private Uri photoURI;
+
+ private DocumentDetail documentDetail;
+
+ private DocumentProcessor documentProcessor;
+
+ @Inject
+ DocumentProcessorFactory documentProcessorFactory;
+
+ @Inject
+ LacertaLogger logger;
+
+ @Inject
+ DeviceInfoUtils deviceInfoUtils;
+
+ private final ActivityResultLauncher 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");
+ return null;
+ }
+
+ @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));
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerActivity.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerActivity.java
new file mode 100644
index 00000000..b8ab64bf
--- /dev/null
+++ b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerActivity.java
@@ -0,0 +1,181 @@
+package one.nem.lacerta.component.scanner;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.annotation.AnimatorRes;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.google.android.material.appbar.MaterialToolbar;
+import com.websitebeaver.documentscanner.DocumentScanner;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+import javax.inject.Inject;
+
+import dagger.hilt.android.AndroidEntryPoint;
+import one.nem.lacerta.utils.LacertaLogger;
+import one.nem.lacerta.data.Document;
+
+@AndroidEntryPoint
+public class ScannerManagerActivity extends AppCompatActivity {
+
+ String TAG = "ScannerManagerActivity";
+
+ @Inject
+ LacertaLogger logger;
+
+ @Inject
+ Document document;
+
+
+ // Variables
+ private ArrayList croppedImages = new ArrayList<>();
+
+ View view;
+
+ DocumentScanner documentScanner = new DocumentScanner(
+ this,
+ (croppedImageResults) -> {
+ logger.debug(TAG, "croppedImage size: " + croppedImageResults.size());
+ ArrayList croppedImages = new ArrayList<>();
+ for (String result : croppedImageResults) {
+ croppedImages.add(BitmapFactory.decodeFile(result));
+ }
+ processResult(croppedImages);
+ return null;
+ },
+ (errorMessage) -> {
+ // an error happened
+ logger.error(TAG, "Error: " + errorMessage);
+ logger.e_code("543a230e-cb9a-47a2-8131-3beecfe1c458");
+ return null;
+ },
+ () -> {
+ // user canceled document scan
+ logger.debug(TAG, "User canceled document scan");
+ return null;
+ },
+ null,
+ null,
+ null
+ );
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_scanner_manager);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+
+ MaterialToolbar toolbar = findViewById(R.id.top_toolbar);
+ setSupportActionBar(toolbar);
+ Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
+
+ documentScanner.startScan();
+ // Init
+
+ this.view = findViewById(R.id.main); // TODO-rca:なんとかする
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(android.view.Menu menu) {
+ getMenuInflater().inflate(R.menu.scanner_result_toolbar, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(android.view.MenuItem item) {
+ if (item.getItemId() == R.id.action_save_new) {
+ // 新ドキュメントとして保存
+ Toast.makeText(this, "保存処理", Toast.LENGTH_SHORT).show();
+ saveNewDocument();
+ return true;
+ } else if (item.getItemId() == R.id.action_insert_exist) {
+ // 既存ドキュメントに挿入
+ Toast.makeText(this, "挿入処理", Toast.LENGTH_SHORT).show();
+ insertToExistDocument();
+ return true;
+ } else if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void processResult(ArrayList resultImages) {
+ logger.debug(TAG, "processResult");
+
+ if (resultImages.isEmpty()) {
+ logger.debug(TAG, "resultImages(arg) is empty");
+ if (this.croppedImages.isEmpty()) {
+ logger.debug(TAG, "this.resultImages is empty");
+ logger.e_code("7cb0584e-74ef-48ec-848a-c4d14e75e15a");
+ // TODO-rca: なんかする
+ } else {
+ logger.debug(TAG, "this.resultImages is not empty");
+ updateResultView(this.croppedImages);
+ }
+ } else {
+ logger.debug(TAG, "resultImages(arg) is not empty");
+ updateResultView(resultImages);
+ this.croppedImages = resultImages;
+ }
+
+ }
+
+ private void saveNewDocument() {
+ logger.debug(TAG, "saveNewDocument");
+
+ }
+
+ private void insertToExistDocument() {
+ logger.debug(TAG, "insertToExistDocument");
+ // TODO-rca: 実装
+ }
+
+ private void updateResultView(ArrayList resultImages) {
+ logger.debug(TAG, "updateResultView");
+
+ LinearLayout resultView = findViewById(R.id.result_list_container);
+ ImageView selectedImage = findViewById(R.id.selected_image);
+ resultView.removeAllViews();
+
+ for (Bitmap resultImage : resultImages) {
+ View resultImageView = getLayoutInflater().inflate(R.layout.result_image_container_item, null);
+ ImageView imageView = resultImageView.findViewById(R.id.result_image);
+ imageView.setImageBitmap(resultImage);
+ imageView.setOnClickListener(v -> {
+
+ selectedImage.setImageBitmap(resultImage);
+
+ for (int i = 0; i < resultView.getChildCount(); i++) {
+ View child = resultView.getChildAt(i).findViewById(R.id.result_image);
+ child.setSelected(false);
+ }
+
+ v.setSelected(true);
+ });
+
+ resultView.addView(resultImageView);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerFragment.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerFragment.java
new file mode 100644
index 00000000..b820111e
--- /dev/null
+++ b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerManagerFragment.java
@@ -0,0 +1,95 @@
+package one.nem.lacerta.component.scanner;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.fragment.app.Fragment;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.websitebeaver.documentscanner.DocumentScanner;
+import com.websitebeaver.documentscanner.DocumentScannerActivity;
+
+import java.util.Objects;
+
+import javax.inject.Inject;
+
+import dagger.hilt.android.AndroidEntryPoint;
+import one.nem.lacerta.utils.LacertaLogger;
+import one.nem.lacerta.vcs.LacertaVcs;
+import one.nem.lacerta.vcs.factory.LacertaVcsFactory;
+
+
+@AndroidEntryPoint
+public class ScannerManagerFragment extends Fragment {
+
+ String TAG = getClass().getSimpleName();
+
+ @Inject
+ LacertaLogger logger;
+
+ @Inject
+ LacertaVcsFactory vcsFactory;
+
+ private static final boolean DEFAULT_SINGLE_PAGE = false;
+ private boolean singlePage;
+
+ public ScannerManagerFragment() {
+ // Required empty public constructor
+ }
+
+// public static ScannerManagerFragment newInstance(boolean singlePage) {
+// ScannerManagerFragment fragment = new ScannerManagerFragment();
+// Bundle args = new Bundle();
+// args.putBoolean("singlePage", singlePage);
+// fragment.setArguments(args);
+// return fragment;
+// }
+
+ public static ScannerManagerFragment newInstance() {
+ ScannerManagerFragment fragment = new ScannerManagerFragment();
+ Bundle args = new Bundle();
+ args.putBoolean("singlePage", DEFAULT_SINGLE_PAGE);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ singlePage = getArguments().getBoolean("singlePage", DEFAULT_SINGLE_PAGE);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.fragment_scanner_manager, container, false);
+
+// ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+// ViewGroup.LayoutParams.MATCH_PARENT,
+// ViewGroup.LayoutParams.MATCH_PARENT
+// );
+// view.setLayoutParams(layoutParams);
+
+ return view;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ // Init
+ logger.debug(TAG, "called");
+
+ view.findViewById(R.id.button_intent_scanner_manager_activity).setOnClickListener(v -> {
+ // DocumentScannerActivityを起動する
+ Intent intent = new Intent(requireActivity().getApplicationContext(), ScannerManagerActivity.class);
+ startActivity(intent);
+ });
+ }
+}
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanFragment.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanFragment.java
deleted file mode 100644
index 54ba513e..00000000
--- a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanFragment.java
+++ /dev/null
@@ -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
- );
- }
-}
\ No newline at end of file
diff --git a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanResultFragment.java b/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanResultFragment.java
deleted file mode 100644
index beffe3d0..00000000
--- a/component/scanner/src/main/java/one/nem/lacerta/component/scanner/ScannerScanResultFragment.java
+++ /dev/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);
- }
-}
\ No newline at end of file
diff --git a/component/scanner/src/main/res/drawable/result_image_container_item_border.xml b/component/scanner/src/main/res/drawable/result_image_container_item_border.xml
new file mode 100644
index 00000000..e23fb7c8
--- /dev/null
+++ b/component/scanner/src/main/res/drawable/result_image_container_item_border.xml
@@ -0,0 +1,16 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/activity_scanner_manager.xml b/component/scanner/src/main/res/layout/activity_scanner_manager.xml
new file mode 100644
index 00000000..9e14218c
--- /dev/null
+++ b/component/scanner/src/main/res/layout/activity_scanner_manager.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/fragment_scanner_data_manager_stub.xml b/component/scanner/src/main/res/layout/fragment_scanner_data_manager_stub.xml
new file mode 100644
index 00000000..61753a90
--- /dev/null
+++ b/component/scanner/src/main/res/layout/fragment_scanner_data_manager_stub.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/fragment_scanner_manager.xml b/component/scanner/src/main/res/layout/fragment_scanner_manager.xml
new file mode 100644
index 00000000..c4909a49
--- /dev/null
+++ b/component/scanner/src/main/res/layout/fragment_scanner_manager.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/fragment_scanner_scan.xml b/component/scanner/src/main/res/layout/fragment_scanner_scan.xml
deleted file mode 100644
index cf20c76f..00000000
--- a/component/scanner/src/main/res/layout/fragment_scanner_scan.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/fragment_scanner_scan_result.xml b/component/scanner/src/main/res/layout/fragment_scanner_scan_result.xml
deleted file mode 100644
index 2ecaf967..00000000
--- a/component/scanner/src/main/res/layout/fragment_scanner_scan_result.xml
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/list_item_scanner_component_manager_stub.xml b/component/scanner/src/main/res/layout/list_item_scanner_component_manager_stub.xml
new file mode 100644
index 00000000..a7a91966
--- /dev/null
+++ b/component/scanner/src/main/res/layout/list_item_scanner_component_manager_stub.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/list_item_scanner_result.xml b/component/scanner/src/main/res/layout/list_item_scanner_result.xml
new file mode 100644
index 00000000..77d9ef65
--- /dev/null
+++ b/component/scanner/src/main/res/layout/list_item_scanner_result.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/layout/result_image_container_item.xml b/component/scanner/src/main/res/layout/result_image_container_item.xml
new file mode 100644
index 00000000..c0217701
--- /dev/null
+++ b/component/scanner/src/main/res/layout/result_image_container_item.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/component/scanner/src/main/res/menu/scanner_result_toolbar.xml b/component/scanner/src/main/res/menu/scanner_result_toolbar.xml
new file mode 100644
index 00000000..3321aadc
--- /dev/null
+++ b/component/scanner/src/main/res/menu/scanner_result_toolbar.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/data/build.gradle b/data/build.gradle
index 10a00015..8af2cd06 100644
--- a/data/build.gradle
+++ b/data/build.gradle
@@ -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
@@ -53,4 +56,6 @@ dependencies {
// データソースモジュール
implementation project(':source')
+
+ implementation project(':vcs')
}
\ No newline at end of file
diff --git a/data/src/main/java/one/nem/lacerta/data/Document.java b/data/src/main/java/one/nem/lacerta/data/Document.java
index eaa7b4bf..145a5905 100644
--- a/data/src/main/java/one/nem/lacerta/data/Document.java
+++ b/data/src/main/java/one/nem/lacerta/data/Document.java
@@ -13,38 +13,13 @@ import one.nem.lacerta.model.document.tag.DocumentTag;
*/
public interface Document {
- ArrayList getAllDocumentMetas(int limit);
+ DocumentDetail createDocument(DocumentMeta meta);
- ArrayList getAllDocumentMetas(int limit, int offset);
+ DocumentDetail createDocument();
- /**
- * 更新の新しいドキュメントから順に並べてlimit件取得する
- * @param limit 取得する上限数
- */
- ArrayList getRecentDocumentMetas(int limit);
+ void deleteDocument(String documentId);
- /**
- * 更新の新しいドキュメントから順に並べてoffset位置からlimit件取得する
- * @param limit 取得する上限数
- * @param offset 取得するオフセット
- */
- ArrayList getRecentDocumentMetas(int limit, int offset);
+ void updateDocument(DocumentMeta meta, DocumentDetail detail);
- /**
- * ドキュメントIDからDocumentDetailを取得する
- * @param id ドキュメントID
- */
- DocumentDetail getDocumentDetail(String id);
-
- /**
- * DocumentMetaからDocumentDetailを取得する
- * @param meta DocumentMeta
- */
- DocumentDetail getDocumentDetailByMeta(DocumentMeta meta); // 簡単に使えるように
-
- DocumentDetail createDocumentByMeta(DocumentMeta meta);
-
- Object getDocumentDetail();
-
- ArrayList getAllDocumentDetail(int i);
+ DocumentDetail getDocument(String documentId);
}
diff --git a/data/src/main/java/one/nem/lacerta/data/DocumentDebug.java b/data/src/main/java/one/nem/lacerta/data/DocumentDebug.java
deleted file mode 100644
index 94ae5b42..00000000
--- a/data/src/main/java/one/nem/lacerta/data/DocumentDebug.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package one.nem.lacerta.data;
-
-import one.nem.lacerta.model.document.DocumentMeta;
-import one.nem.lacerta.model.document.DocumentDetail;
-import one.nem.lacerta.model.document.path.DocumentPath;
-import one.nem.lacerta.model.document.tag.DocumentTag;
-
-public interface DocumentDebug {
-
- void insertDocument(DocumentMeta meta, DocumentDetail detail);
-
-}
diff --git a/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java b/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java
new file mode 100644
index 00000000..4748d7d0
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java
@@ -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); // TODO-rca: Documentに統合する
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/LacertaSearch.java b/data/src/main/java/one/nem/lacerta/data/LacertaSearch.java
new file mode 100644
index 00000000..04e27783
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/LacertaSearch.java
@@ -0,0 +1,13 @@
+package one.nem.lacerta.data;
+
+import java.util.ArrayList;
+
+import one.nem.lacerta.model.ListItem;
+
+public interface LacertaSearch {
+
+ ArrayList autoSearch(String query, int limit);
+
+ ArrayList autoSearch(String query, int limit, int offset);
+
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/impl/DocumentDebugImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/DocumentDebugImpl.java
deleted file mode 100644
index 0985436f..00000000
--- a/data/src/main/java/one/nem/lacerta/data/impl/DocumentDebugImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package one.nem.lacerta.data.impl;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import one.nem.lacerta.data.DocumentDebug;
-import one.nem.lacerta.model.document.DocumentDetail;
-import one.nem.lacerta.model.document.DocumentMeta;
-
-import one.nem.lacerta.source.database.entity.DocumentEntity;
-import one.nem.lacerta.source.database.entity.LibraryEntity;
-import one.nem.lacerta.source.database.entity.TagEntity;
-
-import one.nem.lacerta.source.database.LacertaDatabase;
-
-public class DocumentDebugImpl implements DocumentDebug{
-
- @Inject
- LacertaDatabase database;
-
- @Inject
- public DocumentDebugImpl() {
- }
-
-
- public void insertDocument(DocumentMeta meta, DocumentDetail detail) {
- DocumentEntity documentEntity = new DocumentEntity();
- LibraryEntity libraryEntity = new LibraryEntity();
-
- documentEntity.id = meta.getId();
- documentEntity.title = meta.getTitle();
- documentEntity.createdAt = meta.getCreatedAt();
- documentEntity.updatedAt = meta.getUpdatedAt();
- documentEntity.author = detail.getAuthor();
- documentEntity.defaultBranch = detail.getDefaultBranch();
- // ArrayListからListに変換
- documentEntity.tagIds = meta.getTagIds();
-
- libraryEntity.id = meta.getId();
- libraryEntity.path = "Placeholder";
- libraryEntity.rootPath = "Placeholder";
-
- database.documentDao().insert(documentEntity);
- database.libraryDao().insert(libraryEntity);
- }
-}
diff --git a/data/src/main/java/one/nem/lacerta/data/impl/DocumentImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/DocumentImpl.java
index 1740ef3c..10eb8265 100644
--- a/data/src/main/java/one/nem/lacerta/data/impl/DocumentImpl.java
+++ b/data/src/main/java/one/nem/lacerta/data/impl/DocumentImpl.java
@@ -1,151 +1,105 @@
package one.nem.lacerta.data.impl;
import java.util.ArrayList;
-import java.util.List;
+import java.util.Date;
+import java.util.UUID;
+// Hilt
import javax.inject.Inject;
+// Lacerta/data
import one.nem.lacerta.data.Document;
+// Lacerta/model
+import one.nem.lacerta.model.PublicPath;
import one.nem.lacerta.model.document.DocumentMeta;
import one.nem.lacerta.model.document.DocumentDetail;
-import one.nem.lacerta.model.document.path.DocumentPath;
-import one.nem.lacerta.model.document.tag.DocumentTag;
+// Lacerta/source
import one.nem.lacerta.source.database.LacertaDatabase;
-
import one.nem.lacerta.source.database.entity.DocumentEntity;
-import one.nem.lacerta.source.database.entity.LibraryEntity;
-import one.nem.lacerta.source.database.entity.TagEntity;
-import one.nem.lacerta.source.jgit.JGitRepository;
-import one.nem.lacerta.utils.repository.DeviceInfoUtils;
+// Lacerta/utils
+import one.nem.lacerta.utils.LacertaLogger;
+
+// Lacerta/vcs
+import one.nem.lacerta.vcs.LacertaVcs;
-public class DocumentImpl implements Document{
+public class DocumentImpl implements Document {
- private LacertaDatabase database;
+ String TAG = getClass().getSimpleName();
@Inject
- public DocumentImpl(LacertaDatabase database) {
- this.database = database;
- }
+ LacertaLogger logger;
@Inject
- JGitRepository jGitRepository;
+ LacertaDatabase database;
+
+// @Inject
+// LacertaVcs vcs;
+
@Inject
- DeviceInfoUtils deviceInfoUtils;
+ public DocumentImpl() {
+ // Init
+ logger.debug(TAG, "called");
+ }
+
@Override
- public ArrayList getAllDocumentMetas(int limit) {
- ArrayList documentMetas = new ArrayList<>();
- List documentEntities = database.documentDao().getAllWithLimit(limit);
+ public DocumentDetail createDocument(DocumentMeta meta) {
+ DocumentDetail detail = new DocumentDetail();
+ detail.setMeta(meta);
+ detail.setPages(new ArrayList<>());
- for (DocumentEntity documentEntity : documentEntities) {
- // タグ取得
- // TODO-rca: 切り出すべきかも?
- List tagEntities = database.tagDao().findByIds(documentEntity.tagIds);
- ArrayList documentTags = new ArrayList<>();
- for (TagEntity tagEntity : tagEntities) {
- documentTags.add(new DocumentTag(tagEntity.id, tagEntity.tagName, tagEntity.color));
- }
+ // TODO-rca: UIスレッドから追い出す
- // 組み立て処理
- // 可読性が終わるのでコンストラクタはつかわないほうがいいかも?
- DocumentMeta documentMeta = new DocumentMeta();
- documentMeta.setId(documentEntity.id);
- documentMeta.setTitle(documentEntity.title);
- documentMeta.setCreatedAt(documentEntity.createdAt);
- documentMeta.setUpdatedAt(documentEntity.updatedAt);
- documentMeta.setTags(documentTags);
+ // Create DocumentEntity
+ DocumentEntity documentEntity = new DocumentEntity();
+ documentEntity.id = meta.getId();
+ documentEntity.title = meta.getTitle();
+ documentEntity.author = meta.getAuthor();
+ documentEntity.defaultBranch = meta.getDefaultBranch();
+ documentEntity.updatedAt = meta.getUpdatedAt();
+ documentEntity.createdAt = meta.getCreatedAt();
+ documentEntity.publicPath = meta.getPath().getStringPath();
+ documentEntity.tagIds = meta.getTagIds();
- documentMetas.add(documentMeta);
- }
+ database.documentDao().insert(documentEntity);
- return documentMetas;
+ // Vcs
+// vcs.createDocument(meta.getId());
+
+ return detail;
}
@Override
- public ArrayList getAllDocumentMetas(int limit, int offset) {
- return null; // TODO-rca: 実装する
+ public DocumentDetail createDocument() {
+ DocumentMeta meta = new DocumentMeta();
+ meta.setId(UUID.randomUUID().toString());
+ meta.setTitle("New Document");
+ meta.setAuthor("author");
+ meta.setDefaultBranch("master");
+ meta.setUpdatedAt(new Date());
+ meta.setCreatedAt(new Date());
+ meta.setPath(new PublicPath().getRoot()); // TODO-rca: 2回インスタンスを生成していて無駄なのでなんとかする
+ meta.setTags(new ArrayList<>());
+ return createDocument(meta);
}
@Override
- public ArrayList getRecentDocumentMetas(int limit) {
-// ArrayList documentMetas = new ArrayList<>();
-// database.documentDao().
- // TODO-rca: 履歴取得するDao実装する
- return null;
+ public void deleteDocument(String documentId) {
+
}
@Override
- public ArrayList getRecentDocumentMetas(int limit, int offset) {
- return null;
+ public void updateDocument(DocumentMeta meta, DocumentDetail detail) {
+
}
@Override
- public DocumentDetail getDocumentDetail(String id) {
- DocumentDetail documentDetail = new DocumentDetail();
- DocumentEntity documentEntity = database.documentDao().findById(id);
-
- // タグ取得
- // TODO-rca: 切り出すべきかも?
- List tagEntities = database.tagDao().findByIds(documentEntity.tagIds);
- ArrayList documentTags = new ArrayList<>();
- for (TagEntity tagEntity : tagEntities) {
- documentTags.add(new DocumentTag(tagEntity.id, tagEntity.tagName, tagEntity.color));
- }
-
- // パス取得
- // TODO-rca: 切り出すべきかも?
- LibraryEntity libraryEntity = database.libraryDao().findById(id);
- DocumentPath documentPath = new DocumentPath(libraryEntity.rootPath, libraryEntity.path);
-
- // リポジトリ取得
- documentDetail.setRepository(jGitRepository.getRepository(id)); // TODO-rca: エラーハンドリング
-
- // 組み立て処理
- // 可読性が終わるのでコンストラクタはつかわないほうがいいかも?
- DocumentMeta documentMeta = new DocumentMeta();
- documentMeta.setId(documentEntity.id);
- documentMeta.setTitle(documentEntity.title);
- documentMeta.setCreatedAt(documentEntity.createdAt);
- documentMeta.setUpdatedAt(documentEntity.updatedAt);
- documentMeta.setTags(documentTags);
-
- documentDetail.setMeta(documentMeta);
- documentDetail.setAuthor(documentEntity.author);
- documentDetail.setPath(documentPath);
- documentDetail.setDefaultBranch(documentEntity.defaultBranch);
-
- return documentDetail;
- }
-
- @Override
- public DocumentDetail getDocumentDetailByMeta(DocumentMeta meta) {
- return getDocumentDetail(meta.getId()); // TODO-rca: 効率悪いのでMetaはもらった物を使うようにする(処理を切り分ける?)
- }
-
- @Override
- public DocumentDetail createDocumentByMeta(DocumentMeta meta) {
- DocumentDetail documentDetail = new DocumentDetail();
-
- documentDetail.setMeta(meta);
- documentDetail.setAuthor("author"); // TODO-rca: SharedPrefを扱う機能を作ってそこから取得するようにする or Gitの設定を参照するようにする
- documentDetail.setPath(new DocumentPath(deviceInfoUtils.getExternalStorageDirectoryString(), meta.getId()));
- documentDetail.setDefaultBranch("master"); // TODO-rca: SharedPrefを扱う機能を作ってそこから取得するようにする?
-
- return documentDetail;
- }
-
- @Override
- public Object getDocumentDetail() {
- return null;
- }
-
- @Override
- public ArrayList getAllDocumentDetail(int i) {
+ public DocumentDetail getDocument(String documentId) {
return null;
}
}
diff --git a/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java
new file mode 100644
index 00000000..49f7303a
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java
@@ -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;
+ }
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryStubImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryStubImpl.java
new file mode 100644
index 00000000..47d547f8
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryStubImpl.java
@@ -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 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 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 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);
+ }
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/impl/LacertaSearchStubImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/LacertaSearchStubImpl.java
new file mode 100644
index 00000000..b6076cfd
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/impl/LacertaSearchStubImpl.java
@@ -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 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 autoSearch(String query, int limit, int offset) {
+ logger.debug("SearchStub", "autoSearch");
+ logger.debug("SearchStub", "query: " + query);
+ return library.getLibraryPage(limit, offset).getListItems();
+ }
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/module/DocumentDebugModule.java b/data/src/main/java/one/nem/lacerta/data/module/DocumentDebugModule.java
deleted file mode 100644
index bcf5c7c5..00000000
--- a/data/src/main/java/one/nem/lacerta/data/module/DocumentDebugModule.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package one.nem.lacerta.data.module;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.hilt.InstallIn;
-import dagger.hilt.components.SingletonComponent;
-import one.nem.lacerta.data.DocumentDebug;
-import one.nem.lacerta.data.impl.DocumentDebugImpl;
-
-@Module
-@InstallIn(SingletonComponent.class) // TODO-rca: Singletonでいいのか検討する
-abstract public class DocumentDebugModule {
-
- @Binds
- public abstract DocumentDebug bindDocumentDebug(DocumentDebugImpl documentDebugImpl);
-}
diff --git a/data/src/main/java/one/nem/lacerta/data/module/LacertaLibraryModule.java b/data/src/main/java/one/nem/lacerta/data/module/LacertaLibraryModule.java
new file mode 100644
index 00000000..6c98e653
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/module/LacertaLibraryModule.java
@@ -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);
+
+}
diff --git a/data/src/main/java/one/nem/lacerta/data/module/LacertaSearchModule.java b/data/src/main/java/one/nem/lacerta/data/module/LacertaSearchModule.java
new file mode 100644
index 00000000..3357fb42
--- /dev/null
+++ b/data/src/main/java/one/nem/lacerta/data/module/LacertaSearchModule.java
@@ -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);
+}
diff --git a/feature/debug/build.gradle b/feature/debug/build.gradle
index 54afd119..aaa83e36 100644
--- a/feature/debug/build.gradle
+++ b/feature/debug/build.gradle
@@ -62,4 +62,13 @@ dependencies {
// Shared
implementation project(':shared:ui')
+ // Scanner
+ implementation project(':component:scanner')
+
+ // Processor
+ implementation project(':processor')
+
+ // LacertaVcs
+ implementation project(':vcs')
+
}
\ No newline at end of file
diff --git a/feature/debug/src/main/AndroidManifest.xml b/feature/debug/src/main/AndroidManifest.xml
index 4ae26da0..a5918e68 100644
--- a/feature/debug/src/main/AndroidManifest.xml
+++ b/feature/debug/src/main/AndroidManifest.xml
@@ -1,10 +1,4 @@
-
-
-
-
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocProcessorTesterFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocProcessorTesterFragment.java
new file mode 100644
index 00000000..c144a934
--- /dev/null
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocProcessorTesterFragment.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterListFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterListFragment.java
deleted file mode 100644
index a0d57399..00000000
--- a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterListFragment.java
+++ /dev/null
@@ -1,81 +0,0 @@
-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.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import dagger.hilt.android.AndroidEntryPoint;
-import one.nem.lacerta.data.Document;
-import one.nem.lacerta.feature.debug.common.adapter.DebugMenuDocumentListItemAdapter;
-import one.nem.lacerta.feature.debug.common.model.DebugMenuDocumentListItem;
-import one.nem.lacerta.model.document.DocumentMeta;
-import one.nem.lacerta.utils.LacertaLogger;
-
-/**
- * A simple {@link Fragment} subclass.
- * Use the {@link DebugMenuDocumentTesterListFragment#newInstance} factory method to
- * create an instance of this fragment.
- */
-
-@AndroidEntryPoint
-public class DebugMenuDocumentTesterListFragment extends Fragment {
-
- @Inject
- Document document;
-
- @Inject
- LacertaLogger logger;
-
- public DebugMenuDocumentTesterListFragment() {
- // Required empty public constructor
- }
-
- public static DebugMenuDocumentTesterListFragment newInstance() {
- DebugMenuDocumentTesterListFragment fragment = new DebugMenuDocumentTesterListFragment();
- 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_document_tester_list, container, false);
-
- RecyclerView recyclerView = view.findViewById(R.id.recycler_view_document_list);
- recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
-
- ArrayList documentMetas = document.getAllDocumentMetas(100);
-
- logger.debug("Debug/DocList", "Document count: " + documentMetas.size());
-
- List debugMenuDocumentListItems = new ArrayList<>();
-
- for (DocumentMeta documentMeta : documentMetas) {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- debugMenuDocumentListItems.add(new DebugMenuDocumentListItem(documentMeta.getTitle(), "Internal Id: " + documentMeta.getId(), simpleDateFormat.format(documentMeta.getUpdatedAt())));
- }
-
- DebugMenuDocumentListItemAdapter adapter = new DebugMenuDocumentListItemAdapter(debugMenuDocumentListItems);
- recyclerView.setAdapter(adapter);
-
- return view;
- }
-}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterManageFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterManageFragment.java
deleted file mode 100644
index b46ee40d..00000000
--- a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterManageFragment.java
+++ /dev/null
@@ -1,72 +0,0 @@
-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 com.google.android.material.textfield.TextInputEditText;
-
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import dagger.hilt.android.AndroidEntryPoint;
-import dagger.multibindings.IntKey;
-import one.nem.lacerta.data.DocumentDebug;
-
-import one.nem.lacerta.model.document.DocumentMeta;
-import one.nem.lacerta.model.document.DocumentDetail;
-
-import one.nem.lacerta.model.document.path.DocumentPath;
-import one.nem.lacerta.model.document.tag.DocumentTag;
-
-/**
- * A simple {@link Fragment} subclass.
- * Use the {@link DebugMenuDocumentTesterManageFragment#newInstance} factory method to
- * create an instance of this fragment.
- */
-@AndroidEntryPoint
-public class DebugMenuDocumentTesterManageFragment extends Fragment {
-
- @Inject
- DocumentDebug documentDebug;
-
- public DebugMenuDocumentTesterManageFragment() {
- // Required empty public constructor
- }
-
- public static DebugMenuDocumentTesterManageFragment newInstance() {
- DebugMenuDocumentTesterManageFragment fragment = new DebugMenuDocumentTesterManageFragment();
- 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_document_tester_manage, container, false);
-
- TextInputEditText editTextDocumentTitle = view.findViewById(R.id.edit_text_document_title);
- view.findViewById(R.id.button_insert_test_data).setOnClickListener( v -> {
-
- DocumentMeta meta = new DocumentMeta(editTextDocumentTitle != null ? editTextDocumentTitle.getText().toString() : "empty title"); // TODO-rca: Nullable
- DocumentPath path = new DocumentPath("root", "test_path");
- DocumentDetail detail = new DocumentDetail(meta, path, "test_author", "test_default_branch");
-
- documentDebug.insertDocument(meta, detail);
- });
-
- return view;
- }
-}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterTopFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterTopFragment.java
index 6d9bbe3e..369b41cc 100644
--- a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterTopFragment.java
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuDocumentTesterTopFragment.java
@@ -47,8 +47,8 @@ public class DebugMenuDocumentTesterTopFragment extends Fragment {
List debugMenuDocTesterListItems = new ArrayList<>();
- debugMenuDocTesterListItems.add(new DebugMenuListItem("DocumentListFragment", "DocumentListFragment", R.id.action_debugMenuDocumentTesterTopFragment_to_debugMenuDocumentTesterListFragment, true));
- debugMenuDocTesterListItems.add(new DebugMenuListItem("DocumentManagerFragment", "DocumentManagerFragment", R.id.action_debugMenuDocumentTesterTopFragment_to_debugMenuDocumentTesterManageFragment, true));
+// debugMenuDocTesterListItems.add(new DebugMenuListItem("DocumentListFragment", "DocumentListFragment", R.id.action_debugMenuDocumentTesterTopFragment_to_debugMenuDocumentTesterListFragment, true));
+// debugMenuDocTesterListItems.add(new DebugMenuListItem("DocumentManagerFragment", "DocumentManagerFragment", R.id.action_debugMenuDocumentTesterTopFragment_to_debugMenuDocumentTesterManageFragment, true));
DebugMenuListItemAdapter adapter = new DebugMenuListItemAdapter(debugMenuDocTesterListItems);
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuLibraryItemListPageFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuLibraryItemListPageFragment.java
new file mode 100644
index 00000000..a6be2bb4
--- /dev/null
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuLibraryItemListPageFragment.java
@@ -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 {
+ private ArrayList listItems;
+
+ public ItemAdapter(ArrayList 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);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuTopFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuTopFragment.java
index 26cb3c3b..c55914e8 100644
--- a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuTopFragment.java
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuTopFragment.java
@@ -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,11 @@ public class DebugMenuTopFragment extends Fragment {
recyclerView.setLayoutManager(new androidx.recyclerview.widget.LinearLayoutManager(getContext()));
List 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("ScannerStub", "placeholder", R.id.action_debugMenuTopFragment_to_scannerDataManagerStubFragment, true));
+ debugMenuListItems.add(new DebugMenuListItem("Scanner", "placeholder", R.id.action_debugMenuTopFragment_to_scannerManagerFragment, 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);
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralActionFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralActionFragment.java
new file mode 100644
index 00000000..6b97b63f
--- /dev/null
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralActionFragment.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralFragment.java
new file mode 100644
index 00000000..8437c82c
--- /dev/null
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsGeneralFragment.java
@@ -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 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;
+ }
+}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsLogRecordFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsLogRecordFragment.java
new file mode 100644
index 00000000..300a2475
--- /dev/null
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsLogRecordFragment.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuMetaDataFragment.java b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsRevRecordFragment.java
similarity index 62%
rename from feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuMetaDataFragment.java
rename to feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsRevRecordFragment.java
index 6427a262..c26b2fc2 100644
--- a/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuMetaDataFragment.java
+++ b/feature/debug/src/main/java/one/nem/lacerta/feature/debug/DebugMenuVcsRevRecordFragment.java
@@ -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;
}
}
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_doc_processor_tester.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_doc_processor_tester.xml
new file mode 100644
index 00000000..bb931a16
--- /dev/null
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_doc_processor_tester.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_manage.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_manage.xml
deleted file mode 100644
index e4b8b046..00000000
--- a/feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_manage.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_list.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_library_item_list_page.xml
similarity index 81%
rename from feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_list.xml
rename to feature/debug/src/main/res/layout/fragment_debug_menu_library_item_list_page.xml
index 65642307..0e184902 100644
--- a/feature/debug/src/main/res/layout/fragment_debug_menu_document_tester_list.xml
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_library_item_list_page.xml
@@ -4,11 +4,11 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".DebugMenuDocumentTesterListFragment" >
+ tools:context=".DebugMenuLibraryItemListPageFragment">
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general.xml
new file mode 100644
index 00000000..21cd13a8
--- /dev/null
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general_action.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general_action.xml
new file mode 100644
index 00000000..147a0424
--- /dev/null
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_general_action.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_log_record.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_log_record.xml
new file mode 100644
index 00000000..c8fcdc32
--- /dev/null
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_log_record.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_rev_record.xml b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_rev_record.xml
new file mode 100644
index 00000000..757f8d8a
--- /dev/null
+++ b/feature/debug/src/main/res/layout/fragment_debug_menu_vcs_rev_record.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/debug/src/main/res/navigation/feature_debug_internal_navigation.xml b/feature/debug/src/main/res/navigation/feature_debug_internal_navigation.xml
index 0a784b2b..cf7b1374 100644
--- a/feature/debug/src/main/res/navigation/feature_debug_internal_navigation.xml
+++ b/feature/debug/src/main/res/navigation/feature_debug_internal_navigation.xml
@@ -10,38 +10,69 @@
android:name="one.nem.lacerta.feature.debug.DebugMenuTopFragment"
android:label="fragment_debug_menu_top"
tools:layout="@layout/fragment_debug_menu_top" >
-
+
+
+
+
-
-
-
+ android:id="@+id/scannerDataManagerStubFragment"
+ android:name="one.nem.lacerta.component.scanner.ScannerDataManagerStubFragment"
+ android:label="ScannerDataManagerStubFragment" />
+ 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" />
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/library/build.gradle b/feature/library/build.gradle
index 8b5b1dcc..89087a45 100644
--- a/feature/library/build.gradle
+++ b/feature/library/build.gradle
@@ -1,5 +1,6 @@
plugins {
id 'com.android.library'
+ id 'com.google.dagger.hilt.android'
}
android {
@@ -29,6 +30,8 @@ dependencies {
implementation libs.androidx.appcompat
implementation libs.com.google.android.material
+ implementation 'androidx.navigation:navigation-fragment:2.7.5'
+ implementation 'androidx.navigation:navigation-ui:2.7.5'
testImplementation libs.junit
androidTestImplementation libs.androidx.test.ext.junit
androidTestImplementation libs.androidx.test.espresso.core
@@ -38,4 +41,15 @@ dependencies {
implementation libs.navigation.ui
implementation libs.navigation.dynamic.features.fragment
+ // Hilt (DI)
+ implementation libs.com.google.dagger.hilt.android
+ annotationProcessor libs.com.google.dagger.hilt.compiler
+
+ implementation project(':shared:ui')
+
+ implementation project(':model')
+
+ implementation project(':data')
+
+
}
\ No newline at end of file
diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentAdapter.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentAdapter.java
new file mode 100644
index 00000000..987dc903
--- /dev/null
+++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentAdapter.java
@@ -0,0 +1,55 @@
+package one.nem.lacerta.feature.library;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.List;
+
+import one.nem.lacerta.model.document.DocumentMeta;
+
+public class DocumentAdapter extends RecyclerView.Adapter {
+
+ private List documentMetas;
+
+ public DocumentAdapter(List documentMetas) {
+ // nullの場合に例外を発生させる
+ if (documentMetas == null) {
+ throw new IllegalArgumentException("DocumentMetas list cannot be null or empty");
+ }
+ this.documentMetas = documentMetas;
+ }
+
+ @NonNull
+ @Override
+ public DocumentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_library_menu, parent, false);
+ return new DocumentViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull DocumentViewHolder holder, int position) {
+ DocumentMeta documentMeta = documentMetas.get(position);
+ if (documentMeta != null) {
+ holder.title.setText(documentMeta.getTitle());
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return documentMetas.size();
+ }
+
+ class DocumentViewHolder extends RecyclerView.ViewHolder {
+ TextView title;
+
+ DocumentViewHolder(View itemView) {
+ super(itemView);
+ title = itemView.findViewById(R.id.debug_menu_item_title); // 適切な id に変更する
+ }
+ }
+}
diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryArchiveFragment.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryArchiveFragment.java
new file mode 100644
index 00000000..0867fa0e
--- /dev/null
+++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryArchiveFragment.java
@@ -0,0 +1,38 @@
+package one.nem.lacerta.feature.library;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+// LibraryArchiveFragment.java
+
+//画面変移用のコード
+//Fragmentへのデータの受け渡し機能
+public class LibraryArchiveFragment extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.fragment_library_top);
+
+ // ここに入力された内容を表示する機能
+ TextView textView = findViewById(R.id.document_list);
+
+ textView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // 文字をタップしたときの処理
+
+ // 移動先のアクティビティを指定
+ Intent intent = new Intent(LibraryArchiveFragment.this, LibraryDocFragment.class);
+
+ // データを付加する
+ intent.putExtra("key_name", "value_data");
+
+ startActivity(intent);
+ }
+ });
+ }
+}
diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryDocFragment.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryDocFragment.java
new file mode 100644
index 00000000..1fc09f28
--- /dev/null
+++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryDocFragment.java
@@ -0,0 +1,51 @@
+package one.nem.lacerta.feature.library;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.fragment.app.Fragment;
+
+//Fragmentにデータを受け渡す機能
+public class LibraryDocFragment extends Fragment {
+
+ private TextView textView; // フィールドとして TextView を定義
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_library_file, container, false);
+
+ textView = view.findViewById(R.id.textView);
+
+ return view;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // フラグメントに渡されたデータを取得
+ if (getArguments() != null) {
+ String receivedData = getArguments().getString("key_name");
+
+ // onCreateView メソッドで取得した TextView にデータをセットする
+ if (textView != null) {
+ textView.setText(receivedData);
+ }
+ }
+ }
+
+ // Factory method for creating a new instance of the fragment
+ public static LibraryDocFragment newInstance(String data) {
+ LibraryDocFragment fragment = new LibraryDocFragment();
+
+ // フラグメントにデータを渡す
+ Bundle args = new Bundle();
+ args.putString("key_name", data);
+ fragment.setArguments(args);
+
+ return fragment;
+ }
+}
diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java
index b08bfccc..cebe2f31 100644
--- a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java
+++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java
@@ -2,11 +2,28 @@ package one.nem.lacerta.feature.library;
import android.os.Bundle;
+import androidx.annotation.NonNull;
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.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import dagger.hilt.android.AndroidEntryPoint;
+import one.nem.lacerta.data.Document;
+import one.nem.lacerta.model.document.DocumentMeta;
+import one.nem.lacerta.model.document.tag.DocumentTag;
@@ -15,8 +32,12 @@ import android.view.ViewGroup;
* Use the {@link LibraryTopFragment#newInstance} factory method to
* create an instance of this fragment.
*/
+@AndroidEntryPoint
public class LibraryTopFragment extends Fragment {
+// @Inject
+// Document document;
+
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
@@ -57,10 +78,29 @@ public class LibraryTopFragment extends Fragment {
}
}
+
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_library_top, container, false);
+ View view = inflater.inflate(R.layout.fragment_library_top, container, false);
+
+ // Use view.findViewById instead of findViewById
+ RecyclerView documentRecyclerView = view.findViewById(R.id.document_list);
+
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
+ documentRecyclerView.setLayoutManager(layoutManager);
+
+ //データを取得
+
+// List metas = document.getAllDocumentMetas(100);
+
+// Toast.makeText(getContext(), "Documents: " + Integer.toString(metas.size()), Toast.LENGTH_LONG).show();
+
+// Create and set the adapter
+// DocumentAdapter adapter = new DocumentAdapter(metas);
+// documentRecyclerView.setAdapter(adapter);
+
+// Use a LinearLayoutManager to specify the layout
+ return view;
}
-}
\ No newline at end of file
+}
diff --git a/feature/library/src/main/res/layout/fragment_library_file.xml b/feature/library/src/main/res/layout/fragment_library_file.xml
new file mode 100644
index 00000000..973a133e
--- /dev/null
+++ b/feature/library/src/main/res/layout/fragment_library_file.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/library/src/main/res/layout/fragment_library_top.xml b/feature/library/src/main/res/layout/fragment_library_top.xml
index 46a6e596..b0d824e5 100644
--- a/feature/library/src/main/res/layout/fragment_library_top.xml
+++ b/feature/library/src/main/res/layout/fragment_library_top.xml
@@ -1,14 +1,32 @@
-
-
-
+ android:layout_height="wrap_content"
+ android:background="@color/colorPrimaryContainer"
+ android:minHeight="?attr/actionBarSize"
+ android:theme="?attr/actionBarTheme"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:title="Library"
+ app:titleTextColor="@color/colorOnPrimaryContainer" />
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/feature/library/src/main/res/layout/list_item_library_menu.xml b/feature/library/src/main/res/layout/list_item_library_menu.xml
new file mode 100644
index 00000000..277da422
--- /dev/null
+++ b/feature/library/src/main/res/layout/list_item_library_menu.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/library/src/main/res/values/strings.xml b/feature/library/src/main/res/values/strings.xml
index 6048840e..1049ca2d 100644
--- a/feature/library/src/main/res/values/strings.xml
+++ b/feature/library/src/main/res/values/strings.xml
@@ -1,4 +1,3 @@
-
- Hello blank fragment
+ Library
\ No newline at end of file
diff --git a/model/build.gradle b/model/build.gradle
index cfd215dc..8546adc4 100644
--- a/model/build.gradle
+++ b/model/build.gradle
@@ -36,4 +36,6 @@ dependencies {
// JGit
implementation 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
+ implementation project(":shared:ui")
+
}
\ No newline at end of file
diff --git a/model/src/main/java/one/nem/lacerta/model/LibraryItemPage.java b/model/src/main/java/one/nem/lacerta/model/LibraryItemPage.java
new file mode 100644
index 00000000..825c2396
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/LibraryItemPage.java
@@ -0,0 +1,51 @@
+package one.nem.lacerta.model;
+
+import java.util.ArrayList;
+
+public class LibraryItemPage {
+
+ String pageTitle;
+ String pageId;
+ ArrayList listItems;
+
+ // Constructor
+
+ public LibraryItemPage(String pageTitle, String pageId, ArrayList 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 getListItems() {
+ return listItems;
+ }
+
+ // Setter
+
+ public void setPageTitle(String pageTitle) {
+ this.pageTitle = pageTitle;
+ }
+
+ public void setPageId(String pageId) {
+ this.pageId = pageId;
+ }
+
+ public void setListItems(ArrayList listItems) {
+ this.listItems = listItems;
+ }
+
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/ListItem.java b/model/src/main/java/one/nem/lacerta/model/ListItem.java
new file mode 100644
index 00000000..323b6bdd
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/ListItem.java
@@ -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;
+ }
+
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/ListItemType.java b/model/src/main/java/one/nem/lacerta/model/ListItemType.java
new file mode 100644
index 00000000..65376a1c
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/ListItemType.java
@@ -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;
+ }
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/PublicPath.java b/model/src/main/java/one/nem/lacerta/model/PublicPath.java
new file mode 100644
index 00000000..47f68ca7
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/PublicPath.java
@@ -0,0 +1,74 @@
+package one.nem.lacerta.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PublicPath {
+ /*
+ * ユーザーが扱うパス(内部パスの代替)
+ * (時間がないのでInjectされることは考慮しない)
+ *
+ * TODO-rca:
+ * - こわれたパスを検知する
+ * - バリデーション
+ */
+
+ List path = new ArrayList();
+
+ public PublicPath() {
+ }
+
+ public PublicPath(List 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 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 getPath() {
+ return path;
+ }
+
+ public String getStringPath() {
+ return String.join("/", path);
+ }
+
+ public PublicPath getRoot() {
+ PublicPath root = new PublicPath();
+ root.add("/");
+ return root;
+ }
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/document/DocumentDetail.java b/model/src/main/java/one/nem/lacerta/model/document/DocumentDetail.java
index a9c696ee..a04764ba 100644
--- a/model/src/main/java/one/nem/lacerta/model/document/DocumentDetail.java
+++ b/model/src/main/java/one/nem/lacerta/model/document/DocumentDetail.java
@@ -3,11 +3,14 @@ package one.nem.lacerta.model.document;
import org.eclipse.jgit.lib.Repository;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Date;
import one.nem.lacerta.model.document.path.DocumentPath;
import one.nem.lacerta.model.document.DocumentMeta;
+import one.nem.lacerta.model.document.page.Page;
+
/**
* ドキュメントの詳細データ
*/
@@ -19,31 +22,21 @@ public class DocumentDetail {
DocumentMeta meta;
/**
- * ドキュメントのパス(DocumentPathインスタンス)
+ * ドキュメントのページ(Pageインスタンスのリスト)
*/
- DocumentPath path;
-
- /**
- * ドキュメントの作者(String)
- */
- String author;
-
- /**
- * ドキュメントのデフォルトブランチ(String)
- */
- String defaultBranch;
-
- Repository repository;
+ ArrayList pages;
// Constructor
public DocumentDetail() {
}
- public DocumentDetail(DocumentMeta meta, DocumentPath path, String author, String defaultBranch) {
+ public DocumentDetail(DocumentMeta meta) {
this.meta = meta;
- this.path = path;
- this.author = author;
- this.defaultBranch = defaultBranch;
+ }
+
+ public DocumentDetail(DocumentMeta meta, ArrayList pages) {
+ this.meta = meta;
+ this.pages = pages;
}
// Getter
@@ -56,34 +49,12 @@ public class DocumentDetail {
}
/**
- * ドキュメントのパス(DocumentPathインスタンス)を取得する
+ * ドキュメントのページ(Pageインスタンスのリスト)を取得する
*/
- public DocumentPath getPath() {
- return path;
+ public ArrayList getPages() {
+ return pages;
}
- /**
- * ドキュメントの作者(String)を取得する
- */
- public String getAuthor() {
- return author;
- }
-
- /**
- * ドキュメントのデフォルトブランチ(String)を取得する
- */
- public String getDefaultBranch() {
- return defaultBranch;
- }
-
- /**
- * ドキュメントのリポジトリを取得する
- */
- public Repository getRepository() {
- return repository;
- }
-
-
// Setter
/**
@@ -95,34 +66,11 @@ public class DocumentDetail {
}
/**
- * ドキュメントのパス(DocumentPathインスタンス)を設定する
- * @param path DocumentPathインスタンス
+ * ドキュメントのページ(Pageインスタンスのリスト)を設定する
+ * @param pages Pageインスタンスのリスト
*/
- public void setPath(DocumentPath path) {
- this.path = path;
- }
-
- /**
- * ドキュメントの作者(String)を設定する
- * @param author ドキュメントの作者
- */
- public void setAuthor(String author) {
- this.author = author;
- }
-
- /**
- * ドキュメントのデフォルトブランチ(String)を設定する
- * @param defaultBranch ドキュメントのデフォルトブランチ
- */
- public void setDefaultBranch(String defaultBranch) {
- this.defaultBranch = defaultBranch;
- }
-
- /**
- * ドキュメントのリポジトリを設定する
- */
- public void setRepository(Repository repository) {
- this.repository = repository;
+ public void setPages(ArrayList pages) {
+ this.pages = pages;
}
diff --git a/model/src/main/java/one/nem/lacerta/model/document/DocumentMeta.java b/model/src/main/java/one/nem/lacerta/model/document/DocumentMeta.java
index c191fcde..038b625e 100644
--- a/model/src/main/java/one/nem/lacerta/model/document/DocumentMeta.java
+++ b/model/src/main/java/one/nem/lacerta/model/document/DocumentMeta.java
@@ -1,6 +1,8 @@
package one.nem.lacerta.model.document;
import java.util.ArrayList;
+
+import one.nem.lacerta.model.PublicPath;
import one.nem.lacerta.model.document.tag.DocumentTag;
import java.util.Date;
import java.util.List;
@@ -9,7 +11,7 @@ import java.util.UUID;
/**
* ドキュメントのメタデータ
*/
-public class DocumentMeta {
+public class DocumentMeta { // TODO-rca: JavaDoc対応
/**
* ドキュメントのID(String)
*/
@@ -35,42 +37,52 @@ public class DocumentMeta {
*/
List tags;
+ PublicPath path;
+
+ String author;
+
+ String defaultBranch;
+
// Constructor
+
public DocumentMeta() {
}
- public DocumentMeta(String id, String title, Date updatedAt, Date createdAt, List tags) { // With all
+ public DocumentMeta(String title, List tags, String author, String defaultBranch) {
+ this.id = UUID.randomUUID().toString();
+ this.title = title;
+ this.tags = tags;
+ this.author = author;
+ this.defaultBranch = defaultBranch;
+ }
+
+ public DocumentMeta(String id, String title, List tags, String author, String defaultBranch) {
+ this.id = id;
+ this.title = title;
+ this.tags = tags;
+ this.author = author;
+ this.defaultBranch = defaultBranch;
+ }
+
+ public DocumentMeta(String id, String title, Date updatedAt, Date createdAt, List tags, String author, String defaultBranch) {
this.id = id;
this.title = title;
this.updatedAt = updatedAt;
this.createdAt = createdAt;
this.tags = tags;
+ this.author = author;
+ this.defaultBranch = defaultBranch;
}
- public DocumentMeta(String id, String title, Date updatedAt, Date createdAt) { // Without tags
+ public DocumentMeta(String id, String title, Date updatedAt, Date createdAt, List tags, PublicPath path, String author, String defaultBranch) {
this.id = id;
this.title = title;
this.updatedAt = updatedAt;
this.createdAt = createdAt;
- this.tags = new ArrayList<>();
- }
-
- public DocumentMeta(String id, String title) { // Without tags, updatedAt, createdAt
- this.id = id;
- this.title = title;
- // 現在時刻を設定
- this.updatedAt = new Date();
- this.createdAt = new Date();
- this.tags = new ArrayList<>();
- }
-
- public DocumentMeta(String title) { // title only
- this.id = UUID.randomUUID().toString(); // 新規作成時想定なのでコンストラクタで生成してしまう(使う人が楽なので)
- this.title = title;
- // 現在時刻を設定
- this.updatedAt = new Date();
- this.createdAt = new Date();
- this.tags = new ArrayList<>();
+ this.tags = tags;
+ this.path = path;
+ this.author = author;
+ this.defaultBranch = defaultBranch;
}
// Getter
@@ -121,6 +133,27 @@ public class DocumentMeta {
return tagIds;
}
+ /**
+ * PublicPathを取得する
+ */
+ public PublicPath getPath() {
+ return path;
+ }
+
+ /**
+ * ドキュメントの作者(String)を取得する
+ */
+ public String getAuthor() {
+ return author;
+ }
+
+ /**
+ * ドキュメントのデフォルトブランチ(String)を取得する
+ */
+ public String getDefaultBranch() {
+ return defaultBranch;
+ }
+
// Setter
/**
@@ -163,6 +196,30 @@ public class DocumentMeta {
this.tags = tags;
}
+ /**
+ * PublicPathを設定する
+ * @param path PublicPath
+ */
+ public void setPath(PublicPath path) {
+ this.path = path;
+ }
+
+ /**
+ * ドキュメントの作者(String)を設定する
+ * @param author ドキュメントの作者
+ */
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ /**
+ * ドキュメントのデフォルトブランチ(String)を設定する
+ * @param defaultBranch ドキュメントのデフォルトブランチ
+ */
+ public void setDefaultBranch(String defaultBranch) {
+ this.defaultBranch = defaultBranch;
+ }
+
/**
* updatedAtを現在時刻に設定する
*/
diff --git a/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaModel.java b/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaModel.java
new file mode 100644
index 00000000..55ae05d7
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaModel.java
@@ -0,0 +1,40 @@
+package one.nem.lacerta.model.document.internal;
+
+import java.util.ArrayList;
+
+public class XmlMetaModel {
+
+ String revisionId;
+
+ ArrayList pages;
+
+ // Constructor
+
+ public XmlMetaModel() {
+ }
+
+ public XmlMetaModel(String revisionId, ArrayList pages) {
+ this.revisionId = revisionId;
+ this.pages = pages;
+ }
+
+ // Getter
+
+ public String getRevisionId() {
+ return revisionId;
+ }
+
+ public ArrayList getPages() {
+ return pages;
+ }
+
+ // Setter
+
+ public void setRevisionId(String revisionId) {
+ this.revisionId = revisionId;
+ }
+
+ public void setPages(ArrayList pages) {
+ this.pages = pages;
+ }
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaPageModel.java b/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaPageModel.java
new file mode 100644
index 00000000..089aab2b
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/document/internal/XmlMetaPageModel.java
@@ -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;
+ }
+}
diff --git a/model/src/main/java/one/nem/lacerta/model/document/page/Page.java b/model/src/main/java/one/nem/lacerta/model/document/page/Page.java
new file mode 100644
index 00000000..97f65214
--- /dev/null
+++ b/model/src/main/java/one/nem/lacerta/model/document/page/Page.java
@@ -0,0 +1,39 @@
+package one.nem.lacerta.model.document.page;
+
+import android.graphics.Bitmap;
+
+public class Page {
+
+ String fileName;
+ Bitmap bitmap;
+
+ // Constructor
+
+ public Page() {
+ }
+
+ public Page(String fileName, Bitmap bitmap) {
+ this.fileName = fileName;
+ this.bitmap = bitmap;
+ }
+
+ // Getter
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public Bitmap getBitmap() {
+ return bitmap;
+ }
+
+ // Setter
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setBitmap(Bitmap bitmap) {
+ this.bitmap = bitmap;
+ }
+}
diff --git a/processor/build.gradle b/processor/build.gradle
index cc9c26a7..34829cc7 100644
--- a/processor/build.gradle
+++ b/processor/build.gradle
@@ -32,4 +32,17 @@ 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')
+ implementation project(':vcs')
}
\ No newline at end of file
diff --git a/processor/src/main/java/one/nem/lacerta/processor/DocumentProcessor.java b/processor/src/main/java/one/nem/lacerta/processor/DocumentProcessor.java
new file mode 100644
index 00000000..8a967ff0
--- /dev/null
+++ b/processor/src/main/java/one/nem/lacerta/processor/DocumentProcessor.java
@@ -0,0 +1,23 @@
+package one.nem.lacerta.processor;
+
+import android.graphics.Bitmap;
+
+import one.nem.lacerta.model.document.DocumentDetail;
+
+public interface DocumentProcessor {
+
+ // ページ操作
+ void addNewPageToLast(Bitmap bitmap) throws Exception;
+ void addNewPagesToLast(Bitmap[] bitmaps) throws Exception;
+ void insertPageAtIndex(Bitmap bitmap, int index) throws Exception;
+ void removePageAtIndex(int index) throws Exception;
+
+ // 更新
+ void updatePageAtIndex(Bitmap bitmap, int index);
+
+ // ページ取得
+ Bitmap getPageAtIndex(int index);
+ int getPageCount();
+
+ DocumentDetail getDocumentDetail();
+}
diff --git a/processor/src/main/java/one/nem/lacerta/processor/factory/DocumentProcessorFactory.java b/processor/src/main/java/one/nem/lacerta/processor/factory/DocumentProcessorFactory.java
new file mode 100644
index 00000000..2741a8a9
--- /dev/null
+++ b/processor/src/main/java/one/nem/lacerta/processor/factory/DocumentProcessorFactory.java
@@ -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);
+}
diff --git a/processor/src/main/java/one/nem/lacerta/processor/impl/DocumentProcessorImpl.java b/processor/src/main/java/one/nem/lacerta/processor/impl/DocumentProcessorImpl.java
new file mode 100644
index 00000000..90cc7cf7
--- /dev/null
+++ b/processor/src/main/java/one/nem/lacerta/processor/impl/DocumentProcessorImpl.java
@@ -0,0 +1,138 @@
+package one.nem.lacerta.processor.impl;
+
+import android.graphics.Bitmap;
+
+import java.nio.file.Path;
+import java.util.UUID;
+
+// Hilt
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedInject;
+
+// Lacerta/model
+import one.nem.lacerta.model.document.DocumentDetail;
+import one.nem.lacerta.model.document.internal.XmlMetaModel;
+import one.nem.lacerta.model.document.page.Page;
+
+// Lacerta/processor
+import one.nem.lacerta.processor.DocumentProcessor;
+
+// Lacerta/source
+import one.nem.lacerta.source.file.FileManager;
+import one.nem.lacerta.source.file.factory.FileManagerFactory;
+
+// Lacerta/utils
+import one.nem.lacerta.utils.LacertaLogger;
+import one.nem.lacerta.utils.XmlMetaParser;
+import one.nem.lacerta.utils.repository.DeviceInfoUtils;
+
+// Lacerta/vcs
+import one.nem.lacerta.vcs.LacertaVcs;
+import one.nem.lacerta.vcs.factory.LacertaVcsFactory;
+
+
+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;
+ private LacertaVcs lacertaVcs;
+
+ // Injection
+ private final FileManagerFactory fileManagerFactory;
+ private final LacertaLogger logger;
+ private final XmlMetaParser xmlMetaParser;
+ private final LacertaVcsFactory lacertaVcsFactory;
+ private final DeviceInfoUtils deviceInfoUtils;
+ @AssistedInject
+ public DocumentProcessorImpl(FileManagerFactory fileManagerFactory, LacertaLogger logger, XmlMetaParser xmlMetaParser, LacertaVcsFactory lacertaVcsFactory, DeviceInfoUtils deviceInfoUtils, @Assisted DocumentDetail documentDetail) {
+ this.fileManagerFactory = fileManagerFactory;
+ this.logger = logger;
+ this.xmlMetaParser = xmlMetaParser;
+ if (documentDetail == null) {
+ throw new IllegalArgumentException("documentDetail must not be null");
+ }
+ this.lacertaVcsFactory = lacertaVcsFactory;
+ this.documentDetail = documentDetail;
+ this.deviceInfoUtils = deviceInfoUtils;
+
+ // Init
+ this.documentRootPath = deviceInfoUtils.getExternalStorageDirectory().resolve(this.documentDetail.getMeta().getId());
+ logger.debug("init", "documentRootPath: " + this.documentRootPath);
+ this.fileManager = fileManagerFactory.create(this.documentRootPath).enableAutoCreateParent(); //Initialize FileManager
+ this.lacertaVcs = lacertaVcsFactory.create(this.documentDetail.getMeta().getId());
+ }
+
+
+ @Override
+ public void addNewPageToLast(Bitmap bitmap) throws Exception{
+ logger.debug("addNewPageToLast", "called");
+ String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
+
+ Page page = new Page();
+ page.setFileName(filename);
+ page.setBitmap(bitmap);
+ this.documentDetail.getPages().add(page);
+
+ lacertaVcs.insertPage(documentDetail.getPages().size(), filename);
+
+ this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
+
+ 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 insertPageAtIndex(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);
+
+ Page page = new Page();
+ page.setFileName(filename);
+ page.setBitmap(bitmap);
+ this.documentDetail.getPages().add(index, page);
+
+ lacertaVcs.insertPage(index, filename);
+ }
+
+ @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 DocumentDetail getDocumentDetail() {
+ return this.documentDetail;
+ }
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/impl/placeholder b/processor/src/main/java/one/nem/lacerta/processor/impl/placeholder
similarity index 100%
rename from source/src/main/java/one/nem/lacerta/source/jgit/impl/placeholder
rename to processor/src/main/java/one/nem/lacerta/processor/impl/placeholder
diff --git a/processor/src/main/java/one/nem/lacerta/processor/module/DocumentProcessorModule.java b/processor/src/main/java/one/nem/lacerta/processor/module/DocumentProcessorModule.java
new file mode 100644
index 00000000..b4456813
--- /dev/null
+++ b/processor/src/main/java/one/nem/lacerta/processor/module/DocumentProcessorModule.java
@@ -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;
+ }
+
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/module/placeholder b/processor/src/main/java/one/nem/lacerta/processor/module/placeholder
similarity index 100%
rename from source/src/main/java/one/nem/lacerta/source/jgit/module/placeholder
rename to processor/src/main/java/one/nem/lacerta/processor/module/placeholder
diff --git a/processor/src/main/java/one/nem/lacerta/processor/placeholder b/processor/src/main/java/one/nem/lacerta/processor/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/processor/src/main/res/values/strings.xml b/processor/src/main/res/values/strings.xml
new file mode 100644
index 00000000..6048840e
--- /dev/null
+++ b/processor/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Hello blank fragment
+
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 714f8785..0cc88262 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -30,4 +30,4 @@ include ':source'
include ':model'
include ':processor'
include ':shared:ui'
-include ':shared:icon'
+include ':vcs'
diff --git a/shared/ui/src/main/res/drawable/close_24px.xml b/shared/ui/src/main/res/drawable/close_24px.xml
new file mode 100644
index 00000000..0e4ce1a5
--- /dev/null
+++ b/shared/ui/src/main/res/drawable/close_24px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/shared/ui/src/main/res/drawable/description_24px.xml b/shared/ui/src/main/res/drawable/description_24px.xml
new file mode 100644
index 00000000..ca7e3ec8
--- /dev/null
+++ b/shared/ui/src/main/res/drawable/description_24px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/shared/ui/src/main/res/drawable/save_24px.xml b/shared/ui/src/main/res/drawable/save_24px.xml
new file mode 100644
index 00000000..5161a39b
--- /dev/null
+++ b/shared/ui/src/main/res/drawable/save_24px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabase.java b/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabase.java
index 68aea700..d009d8c0 100644
--- a/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabase.java
+++ b/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabase.java
@@ -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();
}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabaseModule.java b/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabaseModule.java
index f3e43f95..87da3dd5 100644
--- a/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabaseModule.java
+++ b/source/src/main/java/one/nem/lacerta/source/database/LacertaDatabaseModule.java
@@ -20,6 +20,8 @@ public class LacertaDatabaseModule {
LacertaDatabase.class,
"lacerta.db")
.allowMainThreadQueries() // Debug
+ .fallbackToDestructiveMigration() // Debug Only: マイグレーションがない場合などにデータベースを再生成する
+ .fallbackToDestructiveMigrationOnDowngrade() // Debug Only: マイグレーションがない場合などにデータベースを再生成する
.build();
}
}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/common/TagArrayListConverter.java b/source/src/main/java/one/nem/lacerta/source/database/common/ArrayListConverter.java
similarity index 94%
rename from source/src/main/java/one/nem/lacerta/source/database/common/TagArrayListConverter.java
rename to source/src/main/java/one/nem/lacerta/source/database/common/ArrayListConverter.java
index e9bd635b..7d5b0968 100644
--- a/source/src/main/java/one/nem/lacerta/source/database/common/TagArrayListConverter.java
+++ b/source/src/main/java/one/nem/lacerta/source/database/common/ArrayListConverter.java
@@ -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 fromString(String value) {
diff --git a/source/src/main/java/one/nem/lacerta/source/database/dao/VcsLogDao.java b/source/src/main/java/one/nem/lacerta/source/database/dao/VcsLogDao.java
new file mode 100644
index 00000000..cd15c89a
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/database/dao/VcsLogDao.java
@@ -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 findAll();
+
+ @Query("SELECT * FROM vcs_log WHERE id IN (:ids)")
+ List findByIds(List ids);
+
+ @Query("SELECT * FROM vcs_log WHERE document_id = :documentId")
+ List findByDocumentId(String documentId);
+
+ // Insert
+
+ @Insert
+ void insertAll(VcsLogEntity... vcsLogs);
+
+ @Insert
+ void insertAll(List vcsLogs);
+
+ @Insert
+ void insert(VcsLogEntity vcsLog);
+
+ // TODO-rca: Update, Deleteが必要か検討
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/dao/VcsRevDao.java b/source/src/main/java/one/nem/lacerta/source/database/dao/VcsRevDao.java
new file mode 100644
index 00000000..3213ca28
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/database/dao/VcsRevDao.java
@@ -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 findAll();
+
+ @Query("SELECT * FROM vcs_rev WHERE id IN (:ids)")
+ List findByIds(List ids);
+
+ @Query("SELECT * FROM vcs_rev WHERE document_id = :documentId")
+ List 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 vcsRevs);
+
+ @Insert
+ void insert(VcsRevEntity vcsRev);
+
+ // TODO-rca: Update, Deleteが必要か検討
+
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/entity/DocumentEntity.java b/source/src/main/java/one/nem/lacerta/source/database/entity/DocumentEntity.java
index 9f24e42e..90a17b1d 100644
--- a/source/src/main/java/one/nem/lacerta/source/database/entity/DocumentEntity.java
+++ b/source/src/main/java/one/nem/lacerta/source/database/entity/DocumentEntity.java
@@ -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 tagIds; // タグ
+
+ @ColumnInfo(name = "public_path")
+ public String publicPath; // 公開パス
}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/entity/LibraryEntity.java b/source/src/main/java/one/nem/lacerta/source/database/entity/LibraryEntity.java
index e8c45b09..33fffb3f 100644
--- a/source/src/main/java/one/nem/lacerta/source/database/entity/LibraryEntity.java
+++ b/source/src/main/java/one/nem/lacerta/source/database/entity/LibraryEntity.java
@@ -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; // ルートパス
+
}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/entity/VcsLogEntity.java b/source/src/main/java/one/nem/lacerta/source/database/entity/VcsLogEntity.java
new file mode 100644
index 00000000..de1ed13a
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/database/entity/VcsLogEntity.java
@@ -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;
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/database/entity/VcsRevEntity.java b/source/src/main/java/one/nem/lacerta/source/database/entity/VcsRevEntity.java
new file mode 100644
index 00000000..9c18a98c
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/database/entity/VcsRevEntity.java
@@ -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 logIds;
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/file/FileManager.java b/source/src/main/java/one/nem/lacerta/source/file/FileManager.java
new file mode 100644
index 00000000..41909906
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/file/FileManager.java
@@ -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;
+
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/file/factory/FileManagerFactory.java b/source/src/main/java/one/nem/lacerta/source/file/factory/FileManagerFactory.java
new file mode 100644
index 00000000..e5272020
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/file/factory/FileManagerFactory.java
@@ -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);
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/file/factory/placeholder b/source/src/main/java/one/nem/lacerta/source/file/factory/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/source/src/main/java/one/nem/lacerta/source/file/impl/FileManagerImpl.java b/source/src/main/java/one/nem/lacerta/source/file/impl/FileManagerImpl.java
new file mode 100644
index 00000000..6f8677db
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/file/impl/FileManagerImpl.java
@@ -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);
+ }
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/file/impl/placeholder b/source/src/main/java/one/nem/lacerta/source/file/impl/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/source/src/main/java/one/nem/lacerta/source/file/module/FileManagerModule.java b/source/src/main/java/one/nem/lacerta/source/file/module/FileManagerModule.java
new file mode 100644
index 00000000..68a35913
--- /dev/null
+++ b/source/src/main/java/one/nem/lacerta/source/file/module/FileManagerModule.java
@@ -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;
+ }
+}
diff --git a/source/src/main/java/one/nem/lacerta/source/file/module/placeholder b/source/src/main/java/one/nem/lacerta/source/file/module/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/ActionRepo.java b/source/src/main/java/one/nem/lacerta/source/jgit/ActionRepo.java
deleted file mode 100644
index 6bb6f830..00000000
--- a/source/src/main/java/one/nem/lacerta/source/jgit/ActionRepo.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package one.nem.lacerta.source.jgit;
-
-import org.eclipse.jgit.lib.Repository;
-
-public interface ActionRepo {
-
- // リポジトリをインスタンス変数に格納
- void setRepository(Repository repository);
-
- // リポジトリ取得
- Repository getRepository();
-
- // リポジトリ名取得
- String getRepositoryName();
-
- // ステージングされていないファイルの一覧を取得
- String[] getUnstagedFiles();
-
- // ステージングされているファイルの一覧を取得
- String[] getStagedFiles();
-
- // ファイルをステージング
- void stageFile(String path);
-
- // ファイルをアンステージング
- void unstageFile(String path);
-
- // ステージングされているファイルをコミット
- void commit(String message);
-
-}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/JGitRepository.java b/source/src/main/java/one/nem/lacerta/source/jgit/JGitRepository.java
deleted file mode 100644
index 09d04f17..00000000
--- a/source/src/main/java/one/nem/lacerta/source/jgit/JGitRepository.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package one.nem.lacerta.source.jgit;
-
-import org.eclipse.jgit.lib.Repository;
-
-public interface JGitRepository {
-
- // リポジトリ取得
- Repository getRepository(String id);
- // リポジトリ作成
- Repository createRepository(String id);
- // リポジトリ削除
- void deleteRepository(String id);
- // リポジトリ存在確認
- boolean repositoryExists(String id);
-
-
-}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/impl/ActionRepoImpl.java b/source/src/main/java/one/nem/lacerta/source/jgit/impl/ActionRepoImpl.java
deleted file mode 100644
index ac94b96f..00000000
--- a/source/src/main/java/one/nem/lacerta/source/jgit/impl/ActionRepoImpl.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package one.nem.lacerta.source.jgit.impl;
-
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Repository;
-
-import javax.inject.Inject;
-
-import one.nem.lacerta.source.jgit.ActionRepo;
-import one.nem.lacerta.utils.LacertaLogger;
-
-public class ActionRepoImpl implements ActionRepo{
-
- @Inject // Inject logger
- LacertaLogger logger;
-
- private final String TAG = "ActionRepoImpl";
-
- Repository repository;
-
- Git git;
-
- // Internal method
- private Git getGit() {
- if (this.git == null) {
- logger.debug(TAG, "getGit: git is null. Creating new Git instance");
- this.git = new Git(repository);
- }
- return this.git;
- }
-
- @Override
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- @Override
- public Repository getRepository() {
- if (repository == null) {
- logger.warn(TAG, "getRepository: repository is null. Throwing RuntimeException");
- throw new RuntimeException("リポジトリが設定されていません");
- }
- return repository;
- }
-
- @Override
- public String getRepositoryName() {
- return repository.getDirectory().getParentFile().getName();
- }
-
- @Override
- public String[] getUnstagedFiles() {
- Git git = getGit();
- try {
- return git.status().call().getUntracked().toArray(new String[0]);
- } catch (Exception e) { // TODO-rca: エラーハンドリング
- logger.error(TAG, "getUnstagedFiles: " + e.getMessage());
- return new String[0];
- }
- }
-
- @Override
- public String[] getStagedFiles() {
- Git git = getGit();
- try {
- return git.status().call().getAdded().toArray(new String[0]);
- } catch (Exception e) { // TODO-rca: エラーハンドリング
- logger.error(TAG, "getStagedFiles: " + e.getMessage());
- return new String[0];
- }
- }
-
- @Override
- public void stageFile(String path) {
- Git git = getGit();
- try {
- git.add().addFilepattern(path).call();
- } catch (Exception e) { // TODO-rca: エラーハンドリング
- logger.error(TAG, "stageFile: " + e.getMessage());
- }
- }
-
- @Override
- public void unstageFile(String path) {
- Git git = getGit();
- try {
- git.reset().addPath(path).call();
- } catch (Exception e) { // TODO-rca: エラーハンドリング
- logger.error(TAG, "unstageFile: " + e.getMessage());
- }
- }
-
- @Override
- public void commit(String message) {
- Git git = getGit();
- try {
- git.commit().setMessage(message).call();
- } catch (Exception e) { // TODO-rca: エラーハンドリング
- logger.error(TAG, "commit: " + e.getMessage());
- }
- }
-}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/impl/JGitRepositoryImpl.java b/source/src/main/java/one/nem/lacerta/source/jgit/impl/JGitRepositoryImpl.java
deleted file mode 100644
index fabcb0bb..00000000
--- a/source/src/main/java/one/nem/lacerta/source/jgit/impl/JGitRepositoryImpl.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package one.nem.lacerta.source.jgit.impl;
-
-import one.nem.lacerta.source.jgit.JGitRepository;
-
-import javax.inject.Inject;
-
-import one.nem.lacerta.utils.repository.DeviceInfoUtils;
-
-import org.eclipse.jgit.lib.Repository;
-
-import org.eclipse.jgit.lib.RepositoryBuilder;
-
-public class JGitRepositoryImpl implements JGitRepository {
-
- private final DeviceInfoUtils deviceInfoUtils;
-
- @Inject
- public JGitRepositoryImpl(DeviceInfoUtils deviceInfoUtils) {
- this.deviceInfoUtils = deviceInfoUtils;
- }
-
- @Override
- public Repository getRepository(String id) {
- RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
- repositoryBuilder.setGitDir(deviceInfoUtils.getExternalStorageDirectory().resolve(id).resolve(".git").toFile());
- repositoryBuilder.setMustExist(true);
- try {
- return repositoryBuilder.build();
- } catch (Exception e) {
- return null;
- }
- }
-
- @Override
- public Repository createRepository(String id) {
- RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
- repositoryBuilder.setGitDir(deviceInfoUtils.getExternalStorageDirectory().resolve(id).resolve(".git").toFile());
- repositoryBuilder.setMustExist(false);
- try {
- return repositoryBuilder.build();
- } catch (Exception e) {
- return null;
- }
- }
-
- @Override
- public void deleteRepository(String id) {
- // TODO-rca: 未実装
- }
-
- @Override
- public boolean repositoryExists(String id) {
- return false; // TODO-rca: 未実装
- }
-}
diff --git a/source/src/main/java/one/nem/lacerta/source/jgit/module/JGitRepositoryModule.java b/source/src/main/java/one/nem/lacerta/source/jgit/module/JGitRepositoryModule.java
deleted file mode 100644
index 4c9b8fde..00000000
--- a/source/src/main/java/one/nem/lacerta/source/jgit/module/JGitRepositoryModule.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package one.nem.lacerta.source.jgit.module;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.hilt.InstallIn;
-import dagger.hilt.components.SingletonComponent;
-import one.nem.lacerta.source.jgit.JGitRepository;
-
-@Module
-@InstallIn(SingletonComponent.class)
-abstract public class JGitRepositoryModule {
-
- @Binds
- public abstract JGitRepository bindManageRepo(one.nem.lacerta.source.jgit.impl.JGitRepositoryImpl manageRepoImpl);
-}
diff --git a/utils/build.gradle b/utils/build.gradle
index db7197a6..1aab90c9 100644
--- a/utils/build.gradle
+++ b/utils/build.gradle
@@ -37,5 +37,6 @@ dependencies {
implementation libs.com.google.dagger.hilt.android
annotationProcessor libs.com.google.dagger.hilt.compiler
- //
+ // model
+ implementation project(':model')
}
\ No newline at end of file
diff --git a/utils/src/main/java/one/nem/lacerta/utils/LacertaLogger.java b/utils/src/main/java/one/nem/lacerta/utils/LacertaLogger.java
index f49da584..15bbf2c9 100644
--- a/utils/src/main/java/one/nem/lacerta/utils/LacertaLogger.java
+++ b/utils/src/main/java/one/nem/lacerta/utils/LacertaLogger.java
@@ -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,9 @@ public interface LacertaLogger {
void trace(String tag, String message);
void fatal(String tag, String message);
+ void e_code(String errorId);
+
+ String buildKVMessage(KeyValueLog... logs);
+ // With name
+ String buildKVMessage(String name, KeyValueLog... logs);
}
diff --git a/utils/src/main/java/one/nem/lacerta/utils/XmlMetaParser.java b/utils/src/main/java/one/nem/lacerta/utils/XmlMetaParser.java
new file mode 100644
index 00000000..9aeac296
--- /dev/null
+++ b/utils/src/main/java/one/nem/lacerta/utils/XmlMetaParser.java
@@ -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);
+
+}
diff --git a/utils/src/main/java/one/nem/lacerta/utils/impl/LacertaLoggerImpl.java b/utils/src/main/java/one/nem/lacerta/utils/impl/LacertaLoggerImpl.java
index aba337d8..48b81cd8 100644
--- a/utils/src/main/java/one/nem/lacerta/utils/impl/LacertaLoggerImpl.java
+++ b/utils/src/main/java/one/nem/lacerta/utils/impl/LacertaLoggerImpl.java
@@ -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,35 @@ public class LacertaLoggerImpl implements LacertaLogger{
public void fatal(String tag, String message) {
Log.wtf(tag, message);
}
+
+ @Override
+ public void e_code(String errorId) {
+ Log.e("ErrorReport", "An error occurred. Searchable error ID: " + errorId);
+ }
+
+ @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();
+ }
}
diff --git a/utils/src/main/java/one/nem/lacerta/utils/impl/XmlMetaParserImpl.java b/utils/src/main/java/one/nem/lacerta/utils/impl/XmlMetaParserImpl.java
new file mode 100644
index 00000000..60263d68
--- /dev/null
+++ b/utils/src/main/java/one/nem/lacerta/utils/impl/XmlMetaParserImpl.java
@@ -0,0 +1,90 @@
+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.setRevisionId(rootElement.getElementsByTagName("revisionId").item(0).getTextContent());
+
+ ArrayList 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, "revisionId", meta.getRevisionId());
+
+ 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);
+ }
+}
diff --git a/utils/src/main/java/one/nem/lacerta/utils/model/KeyValueLog.java b/utils/src/main/java/one/nem/lacerta/utils/model/KeyValueLog.java
new file mode 100644
index 00000000..e33d0355
--- /dev/null
+++ b/utils/src/main/java/one/nem/lacerta/utils/model/KeyValueLog.java
@@ -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;
+ }
+
+}
diff --git a/utils/src/main/java/one/nem/lacerta/utils/module/XmlMetaParserModule.java b/utils/src/main/java/one/nem/lacerta/utils/module/XmlMetaParserModule.java
new file mode 100644
index 00000000..8e2f61f2
--- /dev/null
+++ b/utils/src/main/java/one/nem/lacerta/utils/module/XmlMetaParserModule.java
@@ -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);
+}
diff --git a/vcs/.gitignore b/vcs/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/vcs/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/vcs/build.gradle b/vcs/build.gradle
new file mode 100644
index 00000000..52036d31
--- /dev/null
+++ b/vcs/build.gradle
@@ -0,0 +1,60 @@
+plugins {
+ alias(libs.plugins.com.android.library)
+ id 'com.google.dagger.hilt.android'
+}
+
+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
+}
\ No newline at end of file
diff --git a/vcs/consumer-rules.pro b/vcs/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/vcs/proguard-rules.pro b/vcs/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/vcs/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/vcs/src/androidTest/java/one/nem/lacerta/vcs/ExampleInstrumentedTest.java b/vcs/src/androidTest/java/one/nem/lacerta/vcs/ExampleInstrumentedTest.java
new file mode 100644
index 00000000..949044c6
--- /dev/null
+++ b/vcs/src/androidTest/java/one/nem/lacerta/vcs/ExampleInstrumentedTest.java
@@ -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 Testing documentation
+ */
+@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());
+ }
+}
\ No newline at end of file
diff --git a/vcs/src/main/AndroidManifest.xml b/vcs/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..a5918e68
--- /dev/null
+++ b/vcs/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/ActionType.java b/vcs/src/main/java/one/nem/lacerta/vcs/ActionType.java
new file mode 100644
index 00000000..bc664a0d
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/ActionType.java
@@ -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;
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/LacertaVcs.java b/vcs/src/main/java/one/nem/lacerta/vcs/LacertaVcs.java
new file mode 100644
index 00000000..46640d37
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/LacertaVcs.java
@@ -0,0 +1,17 @@
+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);
+
+ public void createDocument(String documentId);
+
+ // debug
+ public void printLog();
+
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/factory/LacertaVcsFactory.java b/vcs/src/main/java/one/nem/lacerta/vcs/factory/LacertaVcsFactory.java
new file mode 100644
index 00000000..88a81bd0
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/factory/LacertaVcsFactory.java
@@ -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);
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/impl/LacertaVcsImpl.java b/vcs/src/main/java/one/nem/lacerta/vcs/impl/LacertaVcsImpl.java
new file mode 100644
index 00000000..15e343da
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/impl/LacertaVcsImpl.java
@@ -0,0 +1,67 @@
+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 createDocument(String documentId) {
+
+ }
+
+ @Override
+ public void printLog() {
+ logger.debug(TAG, "printLog");
+ database.vcsLogDao().findAll().forEach(vcsLog -> {
+ logger.debug(TAG, vcsLog.id);
+ });
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/internal/JsonUtils.java b/vcs/src/main/java/one/nem/lacerta/vcs/internal/JsonUtils.java
new file mode 100644
index 00000000..8925e51d
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/internal/JsonUtils.java
@@ -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);
+ }
+ }
+
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/DeletePage.java b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/DeletePage.java
new file mode 100644
index 00000000..e0b9f276
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/DeletePage.java
@@ -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;
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/InsertPage.java b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/InsertPage.java
new file mode 100644
index 00000000..b4e5ca58
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/InsertPage.java
@@ -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;
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/UpdatePage.java b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/UpdatePage.java
new file mode 100644
index 00000000..6a274bb5
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/UpdatePage.java
@@ -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;
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/common/ActionBase.java b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/common/ActionBase.java
new file mode 100644
index 00000000..28857183
--- /dev/null
+++ b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/common/ActionBase.java
@@ -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;
+ }
+}
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/common/placeholder b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/common/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/action/placeholder b/vcs/src/main/java/one/nem/lacerta/vcs/model/action/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/vcs/src/main/java/one/nem/lacerta/vcs/model/placeholder b/vcs/src/main/java/one/nem/lacerta/vcs/model/placeholder
new file mode 100644
index 00000000..e69de29b
diff --git a/vcs/src/test/java/one/nem/lacerta/vcs/ExampleUnitTest.java b/vcs/src/test/java/one/nem/lacerta/vcs/ExampleUnitTest.java
new file mode 100644
index 00000000..b99830ca
--- /dev/null
+++ b/vcs/src/test/java/one/nem/lacerta/vcs/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package one.nem.lacerta.vcs;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file