Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MLS to native forms #373

Merged
merged 26 commits into from
Mar 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49dc519
Add util that replaces mls placeholders with a literal string
vincent-karuri Feb 20, 2020
8ecce94
Add mls test property and json files
vincent-karuri Feb 20, 2020
354972b
Move test files to test resources dir and add resource bundle propert…
vincent-karuri Feb 24, 2020
c229303
Modify regex to include enclosing quotation marks around interpolated…
vincent-karuri Feb 24, 2020
4ce15ca
Add test for en_US translation
vincent-karuri Feb 24, 2020
ce45822
Code clean-up
vincent-karuri Feb 24, 2020
7e4736a
Get the translations' property file name from the json form
vincent-karuri Feb 27, 2020
7028f0f
Enable translating native forms at launch
vincent-karuri Feb 27, 2020
3a07d8e
Rename method
vincent-karuri Mar 2, 2020
abbfba7
Add yaml file translation support
vincent-karuri Mar 2, 2020
bd98cf4
Rename form translation test files and modify interpolation regex to …
vincent-karuri Mar 2, 2020
2707dc9
Test yaml translation
vincent-karuri Mar 2, 2020
db8c3ec
Modify how yaml files are read to account for new line characters
vincent-karuri Mar 2, 2020
3430e70
Minor refactore
vincent-karuri Mar 2, 2020
f38d260
Return untranslated String if the translations property file is not s…
vincent-karuri Mar 2, 2020
4f0d3d4
Merge remote-tracking branch 'origin/master' into 367-add-mls-support…
vincent-karuri Mar 2, 2020
4bfc476
Add docstring
vincent-karuri Mar 2, 2020
e5ec6d4
:zap: Add the `ANC` registration forms to test translations, Update s…
dubdabasoduba Mar 5, 2020
ee81b40
Code clean-up
vincent-karuri Mar 2, 2020
cd8dbda
Merge branch '367-add-mls-support-to-native-forms' of github.com:Open…
vincent-karuri Mar 9, 2020
49f3263
Merge branch 'master' into 367-add-mls-support-to-native-forms
vincent-karuri Mar 9, 2020
dd9c85f
Fix failing test
vincent-karuri Mar 9, 2020
5ee3f0b
Merge branch '367-add-mls-support-to-native-forms' of github.com:Open…
vincent-karuri Mar 9, 2020
6ce3dd2
Merge branch 'master' into 367-add-mls-support-to-native-forms
ndegwamartin Mar 11, 2020
198d9ce
Bump lib version
vincent-karuri Mar 13, 2020
4c152c3
Merge branch '367-add-mls-support-to-native-forms' of github.com:Open…
vincent-karuri Mar 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.List;
import java.util.Map;

import static com.vijay.jsonwizard.utils.NativeFormLangUtils.getTranslatedString;

abstract class JsonFormBaseActivity extends MultiLanguageActivity implements OnFieldsInvalid {
protected static final String TAG = JsonFormActivity.class.getSimpleName();
protected static final String JSON_STATE = "jsonState";
Expand Down Expand Up @@ -69,7 +71,7 @@ protected void onCreate(Bundle savedInstanceState) {
lifeCycleListeners = new ArrayList<>();
isFormFragmentInitialized = false;
if (savedInstanceState == null) {
init(getIntent().getStringExtra(JsonFormConstants.JSON_FORM_KEY.JSON));
init(getForm());
initializeFormFragment();
onFormStart();
this.form = extractForm(getIntent().getSerializableExtra(JsonFormConstants.JSON_FORM_KEY.FORM));
Expand All @@ -82,6 +84,14 @@ protected void onCreate(Bundle savedInstanceState) {
}
}

private String getForm() {
String jsonForm = getIntent().getStringExtra(JsonFormConstants.JSON_FORM_KEY.JSON);
if (getIntent().getBooleanExtra(JsonFormConstants.PERFORM_FORM_TRANSLATION, false)) {
jsonForm = getTranslatedString(jsonForm);
}
return jsonForm;
}

public void init(String json) {
try {
setmJSONObject(new JSONObject(json));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,14 @@ public class JsonFormConstants {
public static final String FALSE = "false";
public static final String DISPLAY_SCROLL_BARS = "display_scroll_bars";
public static final String SKIP_BLANK_STEPS = "skip_blank_steps";
public static final String MULTI_SELECT_LIST ="multi_select_list" ;
public static final String MULTI_SELECT_LIST = "multi_select_list";
public static final String FORM_VERSION = "form_version";
public static final String LABEL_CONSTRAINT_LAYOUT = "label_constraint_layout";
public static final String STEP = "step";
public static final String RULE = "rule/";
public static final String REFERENCE_EDIT_TEXT = "reference_edit_text";
public static final String DISPLAY_LABEL = "display_label";
public static final String PERFORM_FORM_TRANSLATION = "perform_form_translation";

public interface MultiSelectUtils {
String IS_HEADER = "isHeader";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public JsonFormInteractor(@Nullable Map<String, FormWidgetFactory> additionalWid
}
}


public static JsonFormInteractor getInstance(@Nullable Map<String, FormWidgetFactory> additionalWidgetsMap) {
if (INSTANCE == null) {
INSTANCE = new JsonFormInteractor(additionalWidgetsMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Created by vijay on 24-05-2015.
*/
public interface FormWidgetFactory {

List<View> getViewsFromJson(String stepName, Context context, JsonFormFragment formFragment, JSONObject jsonObject, CommonListener listener, boolean popup) throws Exception;

List<View> getViewsFromJson(String stepName, Context context, JsonFormFragment formFragment, JSONObject jsonObject, CommonListener listener) throws Exception;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
import android.util.Log;

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import timber.log.Timber;

public class NativeFormLangUtils {

Expand All @@ -31,4 +36,44 @@ public static Context setAppLocale(Context ctx, String language) {

return context;
}

/**
* Performs translation on an interpolated {@param str}
* i.e. a String containing tokens in the format {{string_name}},
* replacing these tokens with their corresponding values for the current Locale
*
* @param str
* @return
*/
public static String getTranslatedString(String str) {
String translationsFileName = getTranslationsFileName(str);
if (translationsFileName.isEmpty()) {
Timber.e("Could not translate the String. Translation file name is not specified!");
return str;
}

ResourceBundle mlsResourceBundle = ResourceBundle.getBundle(getTranslationsFileName(str));

StringBuffer stringBuffer = new StringBuffer();
Pattern interpolatedStringPattern = Pattern.compile("\\{\\{([a-zA-Z_0-9\\.]+)\\}\\}");
Matcher matcher = interpolatedStringPattern.matcher(str);
while (matcher.find()) {
matcher.appendReplacement(stringBuffer, mlsResourceBundle.getString(matcher.group(1)));
}
matcher.appendTail(stringBuffer);

return stringBuffer.toString();
}

/**
* Gets the name of the translation file to be applied to the {@param str}
*
* @param str
* @return
*/
public static String getTranslationsFileName(String str) {
Pattern propertiesFileNamePattern = Pattern.compile("\"?properties_file_name\"?: ?\"([a-zA-Z_0-9\\.]+)\"");
Matcher matcher = propertiesFileNamePattern.matcher(str);
return matcher.find() ? matcher.group(1) : "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -52,12 +51,14 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import timber.log.Timber;

import static com.vijay.jsonwizard.constants.JsonFormConstants.KEY;
import static com.vijay.jsonwizard.utils.NativeFormLangUtils.getTranslatedString;

public class Utils {
private static ProgressDialog progressDialog;
Expand Down Expand Up @@ -482,18 +483,59 @@ private static String cleanConditionString(String conditionStringRaw) {

public static Iterable<Object> readYamlFile(String fileName, Context context) {
Yaml yaml = new Yaml();
InputStreamReader inputStreamReader;
Iterable<Object> objectIterable = null;
try {
inputStreamReader = new InputStreamReader(context.getAssets().open(fileName));
objectIterable = yaml.loadAll(inputStreamReader);
String translatedYamlStr = getTranslatedYamlFile(fileName, context);
objectIterable = yaml.loadAll(translatedYamlStr);
} catch (IOException e) {
Timber.e(e);
}

return objectIterable;
}

/**
* Translates a yaml file specified by {@param fileName} and returns its String representation
*
* @param fileName
* @param context
*
* @return Translated Yaml file in its String representation
*
* @throws IOException
*/
public static String getTranslatedYamlFile(String fileName, Context context) throws IOException {
return getTranslatedString(getAssetFileAsString(fileName, context));
}

/**
*
* Gets a file specified by {@param fileName} from the assets folder as a String
*
* @param fileName
* @param context
*
* @return A file from the assets folder as a String
*
* @throws IOException
*/
public static String getAssetFileAsString(String fileName, Context context) throws IOException {
InputStream inputStream = context.getAssets().open(fileName);
return convertStreamToString(inputStream);
}

/**
* Converts an {@link InputStream} into a String
*
* @param inputStream
*
* @return String representation of an {@link InputStream}
*/
public static String convertStreamToString(InputStream inputStream) {
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}

public static void buildRulesWithUniqueId(JSONObject element, String uniqueId, String ruleType, WidgetArgs widgetArgs, Map<String, List<Map<String, Object>>> rulesFileMap) throws JSONException {
JSONObject rules = element.optJSONObject(ruleType);
if (rules != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.vijay.jsonwizard.utils;

import android.content.Context;
import android.content.res.AssetManager;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

import static com.vijay.jsonwizard.utils.Utils.convertStreamToString;
import static com.vijay.jsonwizard.utils.Utils.getTranslatedYamlFile;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

/**
* Created by Vincent Karuri on 20/02/2020
*/
public class NativeFormLangUtilsTest {

@Test
public void testJsonFormTranslationShouldTranslateForm() {
Locale.setDefault(new Locale("id"));
String expectedJsonForm = getFileContentsAsString("test_form_translation_in");
String interpolatedJsonForm = getFileContentsAsString("test_form_translation_interpolated");
assertEquals(expectedJsonForm, NativeFormLangUtils.getTranslatedString(interpolatedJsonForm));

Locale.setDefault(new Locale("en", "US"));
expectedJsonForm = getFileContentsAsString("test_form_translation_en_US");
assertEquals(expectedJsonForm, NativeFormLangUtils.getTranslatedString(interpolatedJsonForm));
}

@Test
public void testYamlFileTranslationShouldTranslateYamlFile() throws IOException {
Context context = mockAssetManager("test_yaml_translation_interpolated");
Locale.setDefault(new Locale("en", "US"));
String translatedYamlStr = getTranslatedYamlFile("file_name", context);
assertEquals(getFileContentsAsString("test_yaml_translation_en_US"), translatedYamlStr);
}

@Test
public void testJsonFormTranslationShouldReturnUntranslatedForm() {
Locale.setDefault(new Locale("id"));
String interpolatedJsonForm = getFileContentsAsString("test_form_translation_interpolated_missing_translations");
assertEquals(interpolatedJsonForm, NativeFormLangUtils.getTranslatedString(interpolatedJsonForm));
}

@Test
public void testYamlFileTranslationShouldReturnUntranslatedYamlFile() throws IOException {
Context context = mockAssetManager("test_yaml_translation_interpolated_missing_translations");
Locale.setDefault(new Locale("en", "US"));
String translatedYamlStr = getTranslatedYamlFile("file_name", context);
assertEquals(getFileContentsAsString("test_yaml_translation_interpolated_missing_translations"), translatedYamlStr);
}

private Context mockAssetManager(String yamlFilePath) throws IOException {
Context context = mock(Context.class);
AssetManager assetManager = mock(AssetManager.class);
doReturn(getTestResource(yamlFilePath))
.when(assetManager)
.open(eq("file_name"));
doReturn(assetManager).when(context).getAssets();
return context;
}

private InputStream getTestResource(String filePath) {
return getClass().getClassLoader().getResourceAsStream(filePath);
}

private String getFileContentsAsString(String filePath) {
return convertStreamToString(getTestResource(filePath));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
step1.title = New client record
step1.previous_label = SAVE AND EXIT
step1.submit_label = SAVE
step1.patient_name_label.text = Name
step1.sex.label = Gender
step1.sex.options.Female.text = Female
step1.sex.options.Male.text = Male
step1.sex.v_required.err = Please specify gender
step1.patient_dob.hint = Patient's date of birth
step1.patient_dob.duration.label = Age
step1.patient_occupation_label.text = Occupation
step1.been_treated.label = Has been treated for malaria in the past 3 months?
step1.been_treated.options.Yes.text = Yes
step1.been_treated.options.No.text = No
step1.been_treated.options.not_answered.text = Not Answered
step1.been_treated.v_required.err = Has the patient been treated for malaria in the past 3 months?
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
step1.title = Data Pasien Baru
step1.previous_label = SIMPAN DAN KELUAR
step1.submit_label = SIMPAN
step1.patient_name_label.text = Nama
step1.sex.label = Jenis kelamin pasien
step1.sex.options.Female.text = Perempuan
step1.sex.options.Male.text = Laki-laki
step1.sex.v_required.err = Silakan sebutkan jenis kelamin
step1.patient_dob.hint = Tanggal lahir pasien
step1.patient_dob.duration.label = Usia
step1.patient_occupation_label.text = Pekerjaan pasien
step1.been_treated.label = Pernah dirawat karena Malaria dalam 3 bulan terakhir?
step1.been_treated.options.Yes.text = Ya
step1.been_treated.options.No.text = Tidak
step1.been_treated.options.not_answered.text = Tidak dijawab
step1.been_treated.v_required.err = Pernahkah pasien dirawat karena malaria dalam 3 bulan terakhir?
Loading