Skip to content

Commit 0d269e2

Browse files
feat(asset_policy_storage): add AssetPolicyStorage class for loading policies from Flutter assets
1 parent 1e51e91 commit 0d269e2

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import 'package:flutter/services.dart';
2+
import 'package:flutter_policy_engine/src/core/interfaces/i_policy_storage.dart';
3+
import 'package:flutter_policy_engine/src/utils/json_handler.dart';
4+
import 'package:flutter_policy_engine/src/utils/log_handler.dart';
5+
6+
/// A policy storage implementation that loads policies from Flutter assets.
7+
///
8+
/// This class implements the [IPolicyStorage] interface to provide policy
9+
/// storage functionality using Flutter's asset system. It loads policies
10+
/// from JSON files stored in the app's assets directory.
11+
///
12+
/// The asset file should contain a valid JSON object with policy definitions.
13+
/// If the asset file cannot be loaded or parsed, an empty map is returned
14+
/// and an error is logged.
15+
///
16+
/// Example usage:
17+
/// ```dart
18+
/// final storage = AssetPolicyStorage(assetPath: 'assets/policies.json');
19+
/// final policies = await storage.loadPolicies();
20+
/// ```
21+
class AssetPolicyStorage implements IPolicyStorage {
22+
/// Creates an [AssetPolicyStorage] instance.
23+
///
24+
/// The [assetPath] parameter specifies the path to the JSON asset file
25+
/// relative to the app's assets directory (e.g., 'assets/policies.json').
26+
///
27+
/// Throws an [ArgumentError] if [assetPath] is null or empty.
28+
AssetPolicyStorage({
29+
required String assetPath,
30+
}) : _assetPath = assetPath {
31+
if (assetPath.isEmpty) {
32+
throw ArgumentError('Asset path cannot be empty', 'assetPath');
33+
}
34+
}
35+
36+
/// The path to the asset file containing the policies.
37+
final String _assetPath;
38+
39+
/// Clears all stored policies.
40+
///
41+
/// This method is not implemented for asset-based storage since assets
42+
/// are read-only. Attempting to call this method will throw an
43+
/// [UnimplementedError].
44+
///
45+
/// Throws [UnimplementedError] - Asset storage is read-only.
46+
@override
47+
Future<void> clearPolicies() {
48+
// TODO: implement clearPolicies
49+
throw UnimplementedError();
50+
}
51+
52+
/// Loads policies from the specified asset file.
53+
///
54+
/// Reads the JSON content from the asset file specified in the constructor
55+
/// and parses it into a [Map&lt;String, dynamic&gt;]. The JSON should contain
56+
/// policy definitions in a structured format.
57+
///
58+
/// The method performs the following operations:
59+
/// 1. Loads the JSON string from the asset file using [rootBundle.loadString]
60+
/// 2. Parses the JSON string into a [Map&lt;String, dynamic&gt;] using [JsonHandler.parseJsonString]
61+
/// 3. Returns the parsed policies map
62+
///
63+
/// **Error Handling:**
64+
/// - If the asset file cannot be found or read, a [PlatformException] is thrown
65+
/// - If the JSON content is malformed, a [JsonParseException] is thrown
66+
/// - If any other error occurs during loading or parsing, the error is caught,
67+
/// logged via [LogHandler.error], and an empty map is returned
68+
///
69+
/// **Returns:** A [Map&lt;String, dynamic&gt;] containing the loaded policies.
70+
/// Returns an empty map if the asset file cannot be loaded or parsed.
71+
///
72+
/// **Example:**
73+
/// ```dart
74+
/// final storage = AssetPolicyStorage(assetPath: 'assets/policies.json');
75+
/// final policies = await storage.loadPolicies();
76+
/// print('Loaded ${policies.length} policies');
77+
/// ```
78+
///
79+
/// **Throws:**
80+
/// - [PlatformException] if the asset file cannot be found or read
81+
/// - [JsonParseException] if the JSON content is malformed
82+
@override
83+
Future<Map<String, dynamic>> loadPolicies() async {
84+
try {
85+
final jsonString = await rootBundle.loadString(_assetPath);
86+
return JsonHandler.parseJsonString(jsonString);
87+
} catch (e) {
88+
LogHandler.error(
89+
'Failed to load policies from asset: $_assetPath',
90+
error: e,
91+
);
92+
// Return an empty map with the correct type to satisfy the return type
93+
return <String, dynamic>{};
94+
}
95+
}
96+
97+
/// Saves policies to storage.
98+
///
99+
/// This method is not implemented for asset-based storage since assets
100+
/// are read-only. Attempting to call this method will throw an
101+
/// [UnimplementedError].
102+
///
103+
/// Throws [UnimplementedError] - Asset storage is read-only.
104+
@override
105+
Future<void> savePolicies(Map<String, dynamic> policies) {
106+
// TODO: implement savePolicies
107+
throw UnimplementedError();
108+
}
109+
}

0 commit comments

Comments
 (0)