1+ package org .densy .polyglot .core .provider ;
2+
3+ import org .densy .polyglot .api .language .Language ;
4+ import org .densy .polyglot .api .language .LanguageStandard ;
5+ import org .densy .polyglot .api .provider .TranslationProvider ;
6+
7+ import java .io .File ;
8+ import java .io .FileInputStream ;
9+ import java .io .IOException ;
10+ import java .io .InputStreamReader ;
11+ import java .nio .charset .StandardCharsets ;
12+ import java .util .HashMap ;
13+ import java .util .HashSet ;
14+ import java .util .Map ;
15+ import java .util .Properties ;
16+ import java .util .Set ;
17+
18+ /**
19+ * Properties file translation provider.
20+ */
21+ public class PropertiesFileProvider implements TranslationProvider {
22+ public static final Set <String > ALLOWED_EXTENSIONS = Set .of ("properties" , "props" , "ini" , "cfg" , "conf" , "env" , "lang" , "txt" );
23+
24+ private final File folder ;
25+ private final LanguageStandard languageStandard ;
26+ private final Map <Language , Map <String , String >> translations ;
27+ private final Set <String > allowedExtensions ;
28+
29+ public PropertiesFileProvider (File folder , LanguageStandard languageStandard ) {
30+ this (folder , languageStandard , ALLOWED_EXTENSIONS );
31+ }
32+
33+ public PropertiesFileProvider (File folder , LanguageStandard languageStandard , Set <String > allowedExtensions ) {
34+ this .folder = folder ;
35+ this .languageStandard = languageStandard ;
36+ this .allowedExtensions = new HashSet <>(allowedExtensions );
37+ this .translations = new HashMap <>();
38+ this .loadTranslationsFromFolder ();
39+ }
40+
41+ private void loadTranslationsFromFolder () {
42+ if (!folder .exists () || !folder .isDirectory ()) {
43+ return ;
44+ }
45+
46+ File [] propertiesFiles = folder .listFiles ((dir , name ) -> {
47+ String lowerName = name .toLowerCase ();
48+ int dotIndex = lowerName .lastIndexOf ('.' );
49+ if (dotIndex == -1 ) {
50+ return false ;
51+ }
52+ String extension = lowerName .substring (dotIndex + 1 );
53+ return allowedExtensions .contains (extension );
54+ });
55+
56+ if (propertiesFiles == null ) {
57+ return ;
58+ }
59+
60+ for (File file : propertiesFiles ) {
61+ try {
62+ String fileName = file .getName ();
63+ String languageString = fileName .substring (0 , fileName .lastIndexOf ('.' ));
64+
65+ if (languageStandard .matches (languageString )) {
66+ Language language = languageStandard .parseLanguage (languageString );
67+ Properties properties = new Properties ();
68+
69+ try (InputStreamReader reader = new InputStreamReader (new FileInputStream (file ), StandardCharsets .UTF_8 )) {
70+ properties .load (reader );
71+ }
72+
73+ Map <String , String > translationMap = new HashMap <>();
74+ for (String key : properties .stringPropertyNames ()) {
75+ translationMap .put (key , properties .getProperty (key ));
76+ }
77+
78+ this .translations .put (language , translationMap );
79+ }
80+ } catch (IOException e ) {
81+ throw new RuntimeException ("Error loading translation file: " + file .getName (), e );
82+ } catch (Exception e ) {
83+ throw new RuntimeException ("Error parsing translation file: " + file .getName (), e );
84+ }
85+ }
86+ }
87+
88+ @ Override
89+ public Map <Language , Map <String , String >> getTranslations () {
90+ return new HashMap <>(translations );
91+ }
92+
93+ @ Override
94+ public Set <Language > getSupportedLanguages () {
95+ return new HashSet <>(translations .keySet ());
96+ }
97+ }
0 commit comments