• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

opensrp / opensrp-client-native-form / #65

21 Dec 2023 07:55AM UTC coverage: 66.139% (-0.05%) from 66.188%
#65

Pull #670

github

web-flow
Merge f3ea44e34 into f8c80cf2b
Pull Request #670: Round height weight for optibp

8444 of 12767 relevant lines covered (66.14%)

0.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.53
android-json-form-wizard/src/main/java/com/vijay/jsonwizard/utils/Utils.java
1
package com.vijay.jsonwizard.utils;
2

3
import static com.vijay.jsonwizard.constants.JsonFormConstants.KEY;
4
import static com.vijay.jsonwizard.constants.JsonFormConstants.OPENMRS_ENTITY;
5
import static com.vijay.jsonwizard.constants.JsonFormConstants.OPENMRS_ENTITY_ID;
6
import static com.vijay.jsonwizard.constants.JsonFormConstants.OPENMRS_ENTITY_PARENT;
7
import static com.vijay.jsonwizard.constants.JsonFormConstants.TEXT;
8
import static com.vijay.jsonwizard.constants.JsonFormConstants.TYPE;
9
import static com.vijay.jsonwizard.constants.JsonFormConstants.VALUE;
10
import static com.vijay.jsonwizard.utils.NativeFormLangUtils.getTranslatedString;
11
import static com.vijay.jsonwizard.widgets.RepeatingGroupFactory.REFERENCE_EDIT_TEXT_HINT;
12

13
import android.app.Activity;
14
import android.app.AlertDialog;
15
import android.app.Fragment;
16
import android.app.FragmentTransaction;
17
import android.app.ProgressDialog;
18
import android.content.Context;
19
import android.content.DialogInterface;
20
import android.content.res.AssetManager;
21
import android.os.Looper;
22
import android.text.TextUtils;
23
import android.view.View;
24
import android.view.ViewGroup;
25
import android.widget.Button;
26
import android.widget.ImageView;
27
import android.widget.LinearLayout;
28
import android.widget.RadioButton;
29
import android.widget.RelativeLayout;
30
import android.widget.Toast;
31

32
import androidx.annotation.NonNull;
33
import androidx.annotation.StringRes;
34
import androidx.core.util.TimeUtils;
35

36
import com.google.android.material.snackbar.Snackbar;
37
import com.vijay.jsonwizard.R;
38
import com.vijay.jsonwizard.constants.JsonFormConstants;
39
import com.vijay.jsonwizard.customviews.CompoundButton;
40
import com.vijay.jsonwizard.customviews.ExpansionPanelGenericPopupDialog;
41
import com.vijay.jsonwizard.domain.Form;
42
import com.vijay.jsonwizard.domain.WidgetArgs;
43
import com.vijay.jsonwizard.event.BaseEvent;
44
import com.vijay.jsonwizard.fragments.JsonFormFragment;
45
import com.vijay.jsonwizard.rules.RuleConstant;
46
import com.vijay.jsonwizard.views.CustomTextView;
47
import com.vijay.jsonwizard.widgets.DatePickerFactory;
48

49
import org.apache.commons.lang3.StringUtils;
50
import org.greenrobot.eventbus.EventBus;
51
import org.jetbrains.annotations.NotNull;
52
import org.jetbrains.annotations.Nullable;
53
import org.joda.time.LocalDate;
54
import org.json.JSONArray;
55
import org.json.JSONException;
56
import org.json.JSONObject;
57
import org.yaml.snakeyaml.Yaml;
58

59
import java.io.ByteArrayInputStream;
60
import java.io.ByteArrayOutputStream;
61
import java.io.Closeable;
62
import java.io.File;
63
import java.io.IOException;
64
import java.io.InputStream;
65
import java.net.URLDecoder;
66
import java.text.ParseException;
67
import java.text.SimpleDateFormat;
68
import java.util.ArrayList;
69
import java.util.Arrays;
70
import java.util.Calendar;
71
import java.util.Collection;
72
import java.util.Date;
73
import java.util.HashMap;
74
import java.util.HashSet;
75
import java.util.Iterator;
76
import java.util.List;
77
import java.util.Map;
78
import java.util.Scanner;
79
import java.util.Set;
80
import java.util.concurrent.TimeUnit;
81
import java.util.zip.GZIPInputStream;
82

83
import timber.log.Timber;
84

85
public class Utils {
1✔
86
    public final static List<String> PREFICES_OF_INTEREST = Arrays.asList(RuleConstant.PREFIX.GLOBAL, RuleConstant.STEP);
1✔
87
    public final static Set<Character> JAVA_OPERATORS = new HashSet<>(
1✔
88
            Arrays.asList('(', '!', ',', '?', '+', '-', '*', '/', '%', '+', '-', '.', '^', ')', '<', '>', '=', '{', '}', ':',
1✔
89
                    ';', '[', ']'));
1✔
90
    private static final FormUtils formUtils = new FormUtils();
1✔
91
    private static ProgressDialog progressDialog;
92

93
    public static void showToast(Context context, String message) {
94
        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
1✔
95
    }
1✔
96

97
    public static void showSnackBar(View view, String message) {
98
        Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
×
99
    }
×
100

101
    public static Date getDateFromString(String dtStart) {
102
        if (StringUtils.isNotBlank(dtStart) && !"0".equals(dtStart)) {
1✔
103
            try {
104
                return LocalDate.fromDateFields(DatePickerFactory.DATE_FORMAT.parse(dtStart)).toDate();
1✔
105
            } catch (Exception e) {
1✔
106
                Timber.e(e, " --> getDateFromString");
1✔
107
                return null;
1✔
108
            }
109
        } else {
110
            return null;
1✔
111
        }
112
    }
113

114
    public static String getStringFromDate(Date date) {
115
        try {
116
            return DatePickerFactory.DATE_FORMAT.format(date);
1✔
117
        } catch (Exception e) {
1✔
118
            Timber.e(e, " --> getStringFromDate");
1✔
119
            return null;
1✔
120
        }
121
    }
122

123
    public static String reverseDateString(String str, String delimiter) {
124
        String[] strr = str.split(delimiter);
1✔
125
        return strr[2] + "-" + strr[1] + "-" + strr[0];
1✔
126
    }
127

128
    public static String getDateFormattedForCalculation(String date, String datePickerDisplayFormat) {
129
        if (StringUtils.isNotBlank(datePickerDisplayFormat)) {
1✔
130
            return formatDateToPattern(date, datePickerDisplayFormat, DatePickerFactory.DATE_FORMAT.toPattern());
1✔
131
        } else
132
            return date;
1✔
133
    }
134

135
    public static String getDuration(String date) {
136
        return getDuration(date, null);
×
137
    }
138

139
    public static String getDuration(String date, String endDate) {
140
        if (!TextUtils.isEmpty(date)) {
1✔
141
            Calendar calendar = FormUtils.getDate(date);
1✔
142
            calendar.set(Calendar.HOUR_OF_DAY, 0);
1✔
143
            calendar.set(Calendar.MINUTE, 0);
1✔
144
            calendar.set(Calendar.SECOND, 0);
1✔
145
            calendar.set(Calendar.MILLISECOND, 0);
1✔
146

147
            Calendar now = Calendar.getInstance();
1✔
148
            if (endDate != null) {
1✔
149
                try {
150
                    now = FormUtils.getDate(endDate);
1✔
151
                } catch (Exception e) {
×
152
                    Timber.e(e, " --> getDuration");
×
153
                }
1✔
154
            }
155
            now.set(Calendar.HOUR_OF_DAY, 0);
1✔
156
            now.set(Calendar.MINUTE, 0);
1✔
157
            now.set(Calendar.SECOND, 0);
1✔
158
            now.set(Calendar.MILLISECOND, 0);
1✔
159

160
            long timeDiff = Math.abs(now.getTimeInMillis() - calendar.getTimeInMillis());
1✔
161
            StringBuilder builder = new StringBuilder();
1✔
162
            TimeUtils.formatDuration(timeDiff, builder);
1✔
163
            String duration = "";
1✔
164
            if (timeDiff >= 0 && timeDiff <= TimeUnit.MILLISECONDS.convert(13, TimeUnit.DAYS)) {
1✔
165
                // Represent in days
166
                long days = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS);
1✔
167
                duration = days + "d";
1✔
168
            } else if (timeDiff > TimeUnit.MILLISECONDS.convert(13, TimeUnit.DAYS) &&
1✔
169
                    timeDiff <= TimeUnit.MILLISECONDS.convert(97, TimeUnit.DAYS)) {
1✔
170
                // Represent in weeks and days
171
                int weeks = (int) Math.floor((float) timeDiff / TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS));
1✔
172
                int days = (int) Math.floor((float) (timeDiff - TimeUnit.MILLISECONDS.convert(weeks * 7, TimeUnit.DAYS)) /
1✔
173
                        TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
1✔
174

175
                if (days >= 7) {
1✔
176
                    days = 0;
×
177
                    weeks++;
×
178
                }
179

180
                duration = weeks + "w";
1✔
181
                if (days > 0) {
1✔
182
                    duration += " " + days + "d";
1✔
183
                }
184
            } else if (timeDiff > TimeUnit.MILLISECONDS.convert(97, TimeUnit.DAYS) &&
1✔
185
                    timeDiff <= TimeUnit.MILLISECONDS.convert(363, TimeUnit.DAYS)) {
1✔
186
                // Represent in months and weeks
187
                int months = (int) Math.floor((float) timeDiff / TimeUnit.MILLISECONDS.convert(30, TimeUnit.DAYS));
1✔
188
                int weeks = (int) Math.floor((float) (timeDiff - TimeUnit.MILLISECONDS.convert(months * 30, TimeUnit.DAYS)) /
1✔
189
                        TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS));
1✔
190

191
                if (weeks >= 4) {
1✔
192
                    weeks = 0;
×
193
                    months++;
×
194
                }
195

196
                if (months < 12) {
1✔
197
                    duration = months + "m";
1✔
198
                    if (weeks > 0 && months < 12) {
1✔
199
                        duration += " " + weeks + "w";
1✔
200
                    }
201
                } else if (months >= 12) {
×
202
                    duration = "1y";
×
203
                }
204
            } else {
1✔
205
                // Represent in years and months
206
                int years = (int) Math.floor((float) timeDiff / TimeUnit.MILLISECONDS.convert(365, TimeUnit.DAYS));
1✔
207
                int months = (int) Math
1✔
208
                        .floor((float) (timeDiff - TimeUnit.MILLISECONDS.convert(years * 365, TimeUnit.DAYS)) /
1✔
209
                                TimeUnit.MILLISECONDS.convert(30, TimeUnit.DAYS));
1✔
210

211
                if (months >= 12) {
1✔
212
                    months = 0;
×
213
                    years++;
×
214
                }
215

216
                duration = years + "y";
1✔
217
                if (months > 0) {
1✔
218
                    duration += " " + months + "m";
1✔
219
                }
220
            }
221

222
            return duration;
1✔
223
        }
224
        return null;
×
225
    }
226

227
    public static void showProgressDialog(@StringRes int title, @StringRes int message, Context context) {
228
        if (progressDialog != null && progressDialog.isShowing()) {
1✔
229
            return;
1✔
230
        }
231

232
        progressDialog = new ProgressDialog(context);
1✔
233
        progressDialog.setCancelable(true);
1✔
234
        progressDialog.setTitle(context.getString(title));
1✔
235
        progressDialog.setMessage(context.getString(message));
1✔
236
        progressDialog.show();
1✔
237
    }
1✔
238

239
    public static void hideProgressDialog() {
240
        if (progressDialog != null) {
1✔
241
            progressDialog.dismiss();
1✔
242
        }
243
    }
1✔
244

245
    public static ProgressDialog getProgressDialog() {
246
        return progressDialog;
1✔
247
    }
248

249
    public static int pixelToDp(int dpValue, Context context) {
250
        float dpRatio = context.getResources().getDisplayMetrics().density;
1✔
251
        float pixelForDp = dpValue * dpRatio;
1✔
252

253
        return (int) pixelForDp;
1✔
254
    }
255

256
    public static void postEvent(BaseEvent event) {
257
        EventBus.getDefault().post(event);
1✔
258
    }
1✔
259

260
    public static JSONObject getJsonObjectFromJsonArray(String key, JSONArray jsonArray) {
261
        JSONObject jsonObject = null;
1✔
262
        if (jsonArray != null) {
1✔
263
            for (int i = 0; i < jsonArray.length(); i++) {
1✔
264
                JSONObject tempJsonObject = jsonArray.optJSONObject(i);
1✔
265
                if (tempJsonObject != null && tempJsonObject.optString(KEY).equals(key)) {
1✔
266
                    jsonObject = tempJsonObject;
1✔
267
                    break;
1✔
268
                }
269
            }
270
        }
271
        return jsonObject;
1✔
272
    }
273

274
    /**
275
     * Get the actual radio buttons on the parent view given
276
     *
277
     * @param parent {@link ViewGroup}
278
     * @return radioButtonList
279
     */
280
    public static List<RadioButton> getRadioButtons(ViewGroup parent) {
281
        List<RadioButton> radioButtonList = new ArrayList<>();
1✔
282
        for (int i = 0; i < parent.getChildCount(); i++) {
1✔
283
            View view = parent.getChildAt(i);
1✔
284
            if (view instanceof RadioButton) {
1✔
285
                radioButtonList.add((RadioButton) view);
1✔
286
            } else if (view instanceof ViewGroup) {
1✔
287
                List<RadioButton> nestedRadios = getRadioButtons((ViewGroup) view);
1✔
288
                radioButtonList.addAll(nestedRadios);
1✔
289
            }
290
        }
291
        return radioButtonList;
1✔
292
    }
293

294
    /**
295
     * Resets the radio buttons specify text in another option is selected
296
     *
297
     * @param button {@link CompoundButton}
298
     * @author kitoto
299
     */
300
    public static void resetRadioButtonsSpecifyText(RadioButton button) throws JSONException {
301
        CustomTextView specifyText = (CustomTextView) button.getTag(R.id.specify_textview);
1✔
302
        CustomTextView reasonsText = (CustomTextView) button.getTag(R.id.specify_reasons_textview);
1✔
303
        CustomTextView extraInfoTextView = (CustomTextView) button.getTag(R.id.specify_extra_info_textview);
1✔
304
        JSONObject optionsJson = (JSONObject) button.getTag(R.id.option_json_object);
1✔
305
        String radioButtonText = optionsJson.optString(TEXT);
1✔
306
        button.setText(radioButtonText);
1✔
307

308
        if (specifyText != null && optionsJson.has(JsonFormConstants.CONTENT_INFO)) {
1✔
309
            String specifyInfo = optionsJson.optString(JsonFormConstants.CONTENT_INFO);
1✔
310
            String newText = "(" + specifyInfo + ")";
1✔
311
            specifyText.setText(newText);
1✔
312
            optionsJson.put(JsonFormConstants.SECONDARY_VALUE, "");
1✔
313
        }
314

315
        if (reasonsText != null) {
1✔
316
            LinearLayout reasonTextViewParent = (LinearLayout) reasonsText.getParent();
1✔
317
            LinearLayout radioButtonParent = (LinearLayout) button.getParent().getParent();
1✔
318
            if (reasonTextViewParent.equals(radioButtonParent)) {
1✔
319
                reasonsText.setVisibility(View.GONE);
1✔
320
            }
321
        }
322
        if (extraInfoTextView != null) {
1✔
323
            extraInfoTextView.setVisibility(View.VISIBLE);
1✔
324
        }
325

326
    }
1✔
327

328
    private static String cleanConditionString(String conditionStringRaw) {
329
        String conditionString = conditionStringRaw;
1✔
330

331
        for (String token : PREFICES_OF_INTEREST) {
1✔
332

333
            conditionString = conditionString.replaceAll(token, " " + token);
1✔
334
        }
1✔
335

336
        return conditionString.replaceAll("  ", " ");
1✔
337
    }
338

339
    public static void buildRulesWithUniqueId(JSONObject element, String uniqueId, String ruleType,
340
                                              Context context, Map<String, List<Map<String, Object>>> rulesFileMap, String stepName) throws JSONException {
341
        JSONObject rules = element.optJSONObject(ruleType);
1✔
342
        if (rules != null) {
1✔
343
            if (rules.has(RuleConstant.RULES_ENGINE) && context != null) {
1✔
344
                JSONObject jsonRulesEngineObject = rules.optJSONObject(RuleConstant.RULES_ENGINE);
1✔
345
                JSONObject jsonExRules = jsonRulesEngineObject.optJSONObject(JsonFormConstants.JSON_FORM_KEY.EX_RULES);
1✔
346
                String fileName = JsonFormConstants.RULE + jsonExRules.optString(RuleConstant.RULES_DYNAMIC);
1✔
347

348
                if (!rulesFileMap.containsKey(fileName)) {
1✔
349
                    Iterable<Object> objectIterable = readYamlFile(fileName, context);
1✔
350
                    List<Map<String, Object>> arrayList = new ArrayList<>();
1✔
351
                    if (objectIterable != null) {
1✔
352
                        while (objectIterable.iterator().hasNext()) {
1✔
353
                            Map<String, Object> yamlRulesMap = (Map<String, Object>) objectIterable.iterator().next();
1✔
354
                            if (yamlRulesMap != null) {
1✔
355
                                arrayList.add(yamlRulesMap);
1✔
356
                            }
357
                        }
1✔
358
                    }
359
                    rulesFileMap.put(fileName, arrayList);
1✔
360
                }
361

362
                List<Map<String, Object>> mapArrayList = rulesFileMap.get(fileName);
1✔
363

364
                JSONArray jsonArrayRules = new JSONArray();
1✔
365
                JSONObject keyJsonObject = new JSONObject();
1✔
366
                keyJsonObject.put(KEY, ruleType + "/" + uniqueId);
1✔
367
                jsonArrayRules.put(keyJsonObject);
1✔
368
                for (Map<String, Object> map : mapArrayList) {
1✔
369
                    JSONObject jsonRulesDynamicObject = new JSONObject();
1✔
370
                    String strCondition = (String) map.get(RuleConstant.CONDITION);
1✔
371
                    List<String> conditionKeys = getConditionKeys(strCondition);
1✔
372

373
                    for (String conditionKey : conditionKeys) {
1✔
374
                        if (conditionKey.startsWith(stepName)) {
1✔
375
                            strCondition = strCondition.replace(conditionKey, conditionKey + "_" + uniqueId);
1✔
376
                        }
377
                    }
1✔
378

379
                    String action = ((ArrayList<String>) map.get(RuleConstant.ACTIONS)).get(0);
1✔
380
                    List<String> actionKeys = getConditionKeys(action);
1✔
381
                    String updatedAction = action;
1✔
382
                    for (String actionKey : actionKeys) {
1✔
383
                        if (actionKey.startsWith(stepName)) {
×
384
                            updatedAction = action.replace(actionKey, actionKey + "_" + uniqueId);
×
385
                        }
386
                    }
×
387

388
                    jsonRulesDynamicObject.put(RuleConstant.NAME, String.valueOf(map.get(RuleConstant.NAME)).concat("_").concat(uniqueId));
1✔
389
                    jsonRulesDynamicObject.put(RuleConstant.DESCRIPTION, String.valueOf(map.get(RuleConstant.DESCRIPTION)).concat("_").concat(uniqueId));
1✔
390
                    jsonRulesDynamicObject.put(RuleConstant.PRIORITY, map.get(RuleConstant.PRIORITY));
1✔
391
                    jsonRulesDynamicObject.put(RuleConstant.ACTIONS, updatedAction);
1✔
392
                    jsonRulesDynamicObject.put(RuleConstant.CONDITION, String.valueOf(strCondition));
1✔
393
                    jsonArrayRules.put(jsonRulesDynamicObject);
1✔
394
                }
1✔
395

396
                jsonExRules.put(RuleConstant.RULES_DYNAMIC, jsonArrayRules);
1✔
397

398
            } else {
1✔
399
                String currKey = rules.keys().next();
1✔
400
                JSONObject rulesObj = rules.getJSONObject(currKey);
1✔
401
                String newKey = currKey + "_" + uniqueId;
1✔
402
                rules.remove(currKey);
1✔
403
                rules.put(newKey, rulesObj);
1✔
404
            }
405
        }
406

407
    }
1✔
408

409
    public static NativeFormsProperties getProperties(Context context) {
410
        NativeFormsProperties properties = new NativeFormsProperties();
1✔
411

412
        try {
413
            AssetManager assetManager = context.getAssets();
1✔
414
            InputStream inputStream = assetManager.open(JsonFormConstants.APP_PROPERTIES_FILE);
1✔
415
            properties.load(inputStream);
1✔
416
        } catch (Exception exception) {
×
417
            Timber.e(exception);
×
418
        }
1✔
419

420
        return properties;
1✔
421
    }
422

423
    public static void removeDeletedViewsFromJsonForm(Collection<View> viewCollection, ArrayList<String> removeThisFields) {
424
        Iterator<View> viewIterator = viewCollection.iterator();
1✔
425
        while (viewIterator.hasNext()) {
1✔
426
            View view = viewIterator.next();
1✔
427
            String key = (String) view.getTag(R.id.key);
1✔
428
            if (removeThisFields.contains(key)) {
1✔
429
                viewIterator.remove();
1✔
430
            }
431
        }
1✔
432
    }
1✔
433

434
    public static void updateSubFormFields(JSONObject subForm, Form form) {
435
        for (int i = 0; i < subForm.optJSONArray(JsonFormConstants.CONTENT_FORM).length(); i++) {
×
436
            handleFieldBehaviour(subForm.optJSONArray(JsonFormConstants.CONTENT_FORM).optJSONObject(i), form);
×
437
        }
438
    }
×
439

440
    public static void handleFieldBehaviour(JSONObject fieldObject, Form form) {
441
        String key = fieldObject.optString(KEY);
1✔
442

443
        if (form != null && form.getHiddenFields() != null && form.getHiddenFields().contains(key)) {
1✔
444
            makeFieldHidden(fieldObject);
1✔
445
        }
446

447
        if (form != null && form.getDisabledFields() != null && form.getDisabledFields().contains(key)) {
1✔
448
            makeFieldDisabled(fieldObject);
1✔
449
        }
450

451
    }
1✔
452

453
    /**
454
     * Used to change type of field to hidden and put attribute disabled as true
455
     *
456
     * @param fieldObject
457
     */
458
    public static void makeFieldDisabled(JSONObject fieldObject) {
459
        try {
460
            makeFieldHidden(fieldObject);
1✔
461
            fieldObject.put(JsonFormConstants.DISABLED, true);
1✔
462
        } catch (JSONException e) {
×
463
            Timber.e(e);
×
464
        }
1✔
465
    }
1✔
466

467
    /**
468
     * Used to change type of field to hidden
469
     *
470
     * @param fieldObject
471
     */
472
    public static void makeFieldHidden(JSONObject fieldObject) {
473
        try {
474
            fieldObject.put(TYPE, JsonFormConstants.HIDDEN);
1✔
475
        } catch (JSONException e) {
×
476
            Timber.e(e);
×
477
        }
1✔
478
    }
1✔
479

480
    public static void removeDeletedInvalidFields(String fieldKeyPrefix, Map<String, ValidationStatus> invalidFields, ArrayList<String> fieldsToRemove) {
481
        for (String fieldToRemove : fieldsToRemove) {
1✔
482
            invalidFields.remove(fieldKeyPrefix + fieldToRemove);
1✔
483
        }
1✔
484
    }
1✔
485

486
    public static String getFieldKeyPrefix(String stepName, String stepTitle) {
487
        return stepName + "#" + stepTitle + ":";
1✔
488
    }
489

490
    /**
491
     * Returns the value string value for special translated fields like the Native Radio Button, Spinner, Check Box e.tc
492
     *
493
     * @param jsonObject -- Widget #JSONObject
494
     * @return
495
     */
496
    public static String returnValue(JSONObject jsonObject) {
497
        String value = "";
1✔
498
        if (enabledProperty(NativeFormsProperties.KEY.WIDGET_VALUE_TRANSLATED) && jsonObject.has(TYPE) && jsonObject.optString(TYPE).equals(JsonFormConstants.NATIVE_RADIO_BUTTON)) {
1✔
499
            JSONObject valueObject = jsonObject.optJSONObject(VALUE);
1✔
500
            if (valueObject != null) {
1✔
501
                value = valueObject.optString(VALUE, "");
1✔
502
            }
503
        } else {
1✔
504
            value = jsonObject.optString(VALUE, "");
1✔
505
        }
506
        return value;
1✔
507
    }
508

509
    @NonNull
510
    private static String cleanToken(String conditionTokenRaw) {
511
        String conditionToken = conditionTokenRaw.trim();
1✔
512

513
        for (int i = 0; i < conditionToken.length(); i++) {
1✔
514
            if (JAVA_OPERATORS.contains(conditionToken.charAt(i))) {
1✔
515
                if (i == 0) {
1✔
516
                    conditionToken = cleanToken(conditionToken.substring(1));
×
517
                } else {
518
                    conditionToken = conditionToken.substring(0, conditionToken.indexOf(conditionToken.charAt(i)));
1✔
519
                    break;
1✔
520
                }
521
            }
522
        }
523

524
        return conditionToken;
1✔
525
    }
526

527
    public static List<String> getConditionKeys(String condition) {
528
        String cleanString = cleanConditionString(condition);
1✔
529
        String[] conditionTokens = cleanString.split(" ");
1✔
530
        Map<String, Boolean> conditionKeys = new HashMap<>();
1✔
531

532
        for (String token : conditionTokens) {
1✔
533
            if (token.contains(RuleConstant.STEP) || token.contains(RuleConstant.PREFIX.GLOBAL)) {
1✔
534
                String conditionToken = cleanToken(token);
1✔
535
                conditionKeys.put(conditionToken, true);
1✔
536
            }
537
        }
538

539
        return new ArrayList<>(conditionKeys.keySet());
1✔
540
    }
541

542
    public static Iterable<Object> readYamlFile(String fileName, Context context) {
543
        return new Yaml().loadAll(getTranslatedYamlFile(fileName, context));
1✔
544
    }
545

546
    /**
547
     * Translates a yaml file specified by {@param fileName} and returns its String representation
548
     *
549
     * @param fileName
550
     * @param context
551
     * @return Translated Yaml file in its String representation
552
     */
553
    public static String getTranslatedYamlFile(String fileName, Context context) {
554
        return getTranslatedString(getAssetFileAsString(fileName, context), context);
1✔
555
    }
556

557
    /**
558
     * Translates a yaml file specified by {@param fileName} using properties stored in the database
559
     * and returns its String representation
560
     *
561
     * @param fileName
562
     * @param context
563
     * @return Translated Yaml file in its String representation
564
     */
565
    public static String getTranslatedYamlFileWithDBProperties(String fileName, Context context) {
566
        return NativeFormLangUtils.getTranslatedStringWithDBResourceBundle(context, getAssetFileAsString(fileName, context), null);
×
567
    }
568

569
    /**
570
     * Gets the contents of a file specified by {@param fileName} from the assets folder as a {@link String}
571
     *
572
     * @param fileName
573
     * @param context
574
     * @return A file from the assets folder as a String
575
     */
576
    public static String getAssetFileAsString(String fileName, Context context) {
577
        InputStream inputStream = null;
1✔
578
        String fileContents = "";
1✔
579
        try {
580
            inputStream = context.getAssets().open(fileName);
1✔
581
            fileContents = convertStreamToString(inputStream);
1✔
582
        } catch (IOException e) {
×
583
            Timber.e(e);
×
584
        } finally {
585
            closeCloseable(inputStream);
1✔
586
        }
587
        return fileContents;
1✔
588
    }
589

590
    public static void closeCloseable(Closeable closeable) {
591
        try {
592
            if (closeable != null) {
1✔
593
                closeable.close();
1✔
594
            }
595
        } catch (IOException e) {
×
596
            Timber.e(e);
×
597
        }
1✔
598
    }
1✔
599

600
    private static void closeScanner(Scanner scanner) {
601
        if (scanner != null) {
1✔
602
            scanner.close();
1✔
603
        }
604
    }
1✔
605

606
    /**
607
     * Returns file contents for the file at {@param filePath} as a String
608
     * <p>
609
     * Defaults to an empty {@link String} if the file does not exist or is empty
610
     *
611
     * @param filePath
612
     * @return
613
     */
614
    public static String getFileContentsAsString(String filePath) {
615
        return getFileContentsAsString(new File(filePath));
1✔
616
    }
617

618
    public static String getFileContentsAsString(File file) {
619
        Scanner scanner = null;
1✔
620
        String fileContents = "";
1✔
621
        try {
622
            scanner = new Scanner(file);
1✔
623
            fileContents = scanner.useDelimiter("\\A").next();
1✔
624
        } catch (IOException e) {
×
625
            Timber.e(e);
×
626
        } finally {
627
            closeScanner(scanner);
1✔
628
        }
629
        return fileContents;
1✔
630
    }
631

632
    /**
633
     * Converts an {@link InputStream} into a {@link String}
634
     *
635
     * @param inputStream
636
     * @return String representation of an {@link InputStream}
637
     */
638
    public static String convertStreamToString(InputStream inputStream) {
639
        Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
1✔
640
        String data = scanner.hasNext() ? scanner.next() : "";
1✔
641
        closeScanner(scanner);
1✔
642
        return data;
1✔
643
    }
644

645
    /**
646
     * Gets form config entries as specified in json.form.config.json
647
     *
648
     * @param formName
649
     * @param configLocation
650
     * @param context
651
     * @return
652
     * @throws JSONException
653
     * @throws IOException
654
     */
655
    public static JSONObject getFormConfig(@NonNull String formName, @NonNull String configLocation, @NonNull Context context) throws JSONException, IOException {
656
        String fileContent = getAssetFileAsString(configLocation, context);
1✔
657
        JSONObject formConfig = null;
1✔
658
        if (StringUtils.isNotBlank(fileContent)) {
1✔
659
            JSONArray jsonArray = new JSONArray(fileContent);
1✔
660
            for (int i = 0; i < jsonArray.length(); i++) {
1✔
661
                JSONObject jsonObject = jsonArray.optJSONObject(i);
1✔
662
                if (formName.equals(jsonObject.optString(JsonFormConstants.FORM_NAME))) {
1✔
663
                    formConfig = jsonObject;
1✔
664
                    break;
1✔
665
                }
666
            }
667
        }
668
        return formConfig;
1✔
669
    }
670

671
    /**
672
     * Converts jsonArray to set
673
     *
674
     * @param jsonArray
675
     * @return
676
     */
677
    public static Set<String> convertJsonArrayToSet(@Nullable JSONArray jsonArray) {
678
        if (jsonArray != null) {
1✔
679
            Set<String> strings = new HashSet<>();
1✔
680
            for (int i = 0; i < jsonArray.length(); i++) {
1✔
681
                strings.add(jsonArray.optString(i));
1✔
682
            }
683
            return strings;
1✔
684
        }
685
        return null;
1✔
686
    }
687

688
    /***
689
     * Checks if step has no skip logic fields and that fields do not have type hidden
690
     * @param formFragment {@link JsonFormFragment}
691
     */
692
    public static void checkIfStepHasNoSkipLogic(JsonFormFragment formFragment) {
693
        String step = formFragment.getJsonApi().nextStep();
1✔
694
        if (formFragment.getJsonApi().stepSkipLogicPresenceMap().get(step) == null) {
1✔
695
            boolean hasNoSkipLogic = false;
1✔
696
            JSONObject jsonObject = formFragment.getJsonApi().getmJSONObject();
1✔
697
            if (StringUtils.isNotBlank(step)) {
1✔
698
                JSONObject jsonStepObject = jsonObject.optJSONObject(step);
1✔
699
                JSONArray fields = jsonStepObject.optJSONArray(JsonFormConstants.FIELDS);
1✔
700
                for (int i = 0; i < fields.length(); i++) {
1✔
701
                    JSONObject object = fields.optJSONObject(i);
1✔
702
                    if (object.has(TYPE)
1✔
703
                            && !object.optString(TYPE).equals(JsonFormConstants.HIDDEN)
1✔
704
                            && !object.has(JsonFormConstants.RELEVANCE)) {
1✔
705
                        hasNoSkipLogic = true;
1✔
706
                        break;
1✔
707
                    }
708
                }
709
                formFragment.getJsonApi().stepSkipLogicPresenceMap().put(step, hasNoSkipLogic);
1✔
710
            }
711
        }
712
    }
1✔
713

714
    /***
715
     * removes the generated dynamic rules by repeating group
716
     */
717
    public static void removeGeneratedDynamicRules(JsonFormFragment formFragment) {
718
        JSONObject form = formFragment.getJsonApi().getmJSONObject();
1✔
719
        JSONArray jsonArray = FormUtils.getMultiStepFormFields(form);
1✔
720
        for (int i = 0; i < jsonArray.length(); i++) {
1✔
721
            JSONObject jsonObject = jsonArray.optJSONObject(i);
1✔
722
            if (jsonObject.has(JsonFormConstants.RELEVANCE) &&
1✔
723
                    jsonObject.optJSONObject(JsonFormConstants.RELEVANCE).has(RuleConstant.RULES_ENGINE) &&
1✔
724
                    jsonObject.optJSONObject(JsonFormConstants.RELEVANCE).optJSONObject(RuleConstant.RULES_ENGINE)
1✔
725
                            .has(JsonFormConstants.JSON_FORM_KEY.EX_RULES) &&
1✔
726
                    jsonObject.optJSONObject(JsonFormConstants.RELEVANCE).optJSONObject(RuleConstant.RULES_ENGINE)
1✔
727
                            .optJSONObject(JsonFormConstants.JSON_FORM_KEY.EX_RULES).has(RuleConstant.RULES_DYNAMIC)) {
1✔
728
                jsonArray.optJSONObject(i).remove(JsonFormConstants.RELEVANCE);
1✔
729
            }
730
            if (jsonObject.has(JsonFormConstants.CALCULATION) &&
1✔
731
                    jsonObject.optJSONObject(JsonFormConstants.CALCULATION).has(RuleConstant.RULES_ENGINE) &&
×
732
                    jsonObject.optJSONObject(JsonFormConstants.CALCULATION).optJSONObject(RuleConstant.RULES_ENGINE)
×
733
                            .has(JsonFormConstants.JSON_FORM_KEY.EX_RULES) &&
×
734
                    jsonObject.optJSONObject(JsonFormConstants.CALCULATION).optJSONObject(RuleConstant.RULES_ENGINE)
×
735
                            .optJSONObject(JsonFormConstants.JSON_FORM_KEY.EX_RULES).has(RuleConstant.RULES_DYNAMIC)) {
×
736
                jsonArray.optJSONObject(i).remove(JsonFormConstants.CALCULATION);
×
737
            }
738
        }
739
    }
1✔
740

741
    public static final boolean isRunningOnUiThread() {
742
        return Looper.getMainLooper().getThread() == Thread.currentThread();
×
743
    }
744

745
    public static String formatDateToPattern(String date, String inputFormat, String outputFormat) {
746
        if (StringUtils.isEmpty(date)) return "";
1✔
747
        SimpleDateFormat sdf = new SimpleDateFormat(inputFormat);
1✔
748
        sdf.setLenient(false);
1✔
749
        Date newDate = null;
1✔
750
        try {
751
            newDate = sdf.parse(date);
1✔
752
        } catch (ParseException e) {
1✔
753
            Timber.e(e);
1✔
754
        }
1✔
755
        if (newDate == null) {
1✔
756
            return date;
1✔
757
        }
758
        sdf = new SimpleDateFormat(outputFormat);
1✔
759
        return sdf.format(newDate);
1✔
760
    }
761

762
    public static int getResourceId(Context context, String name, ResourceType resourceType) {
763
        try {
764
            return context.getResources().getIdentifier(name, resourceType.getType(), context.getPackageName());
×
765
        } catch (Exception e) {
×
766
            Timber.e(e);
×
767
            return -1;
×
768
        }
769
    }
770

771
    public static boolean isEmptyJsonArray(JSONArray jsonArray) {
772
        return jsonArray == null || jsonArray.length() == 0;
1✔
773
    }
774

775
    public static void showAlertDialog(Context context, String title, String message,
776
                                       String negativeBtnTxt, String positiveBtnTxt,
777
                                       DialogInterface.OnClickListener negativeBtnListener,
778
                                       DialogInterface.OnClickListener positiveBtnListener) {
779

780
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context, R.style.AppThemeAlertDialog).setTitle(title)
1✔
781
                .setMessage(message);
1✔
782

783
        if (negativeBtnListener != null) {
1✔
784
            alertDialogBuilder.setNegativeButton(negativeBtnTxt, negativeBtnListener);
1✔
785
        }
786

787
        if (positiveBtnListener != null) {
1✔
788
            alertDialogBuilder.setPositiveButton(positiveBtnTxt, positiveBtnListener);
1✔
789
        }
790

791
        alertDialogBuilder.create().show();
1✔
792
    }
1✔
793

794
    public static boolean isEmptyJsonObject(JSONObject jsonObject) {
795
        return jsonObject == null || jsonObject.length() == 0;
1✔
796
    }
797

798
    /**
799
     * Returns the object that holds the repeating group count
800
     *
801
     * @return
802
     * @throws JSONException
803
     */
804
    @Nullable
805
    public static JSONObject getRepeatingGroupCountObj(@NotNull WidgetArgs widgetArgs) throws JSONException {
806
        String repeatingGroupCountObjKey = widgetArgs.getJsonObject().get(KEY) + "_count";
1✔
807
        JSONObject stepJsonObject = widgetArgs.getFormFragment().getStep(widgetArgs.getStepName());
1✔
808
        if (stepJsonObject == null) {
1✔
809
            return null;
1✔
810
        }
811
        JSONArray stepFields = stepJsonObject.optJSONArray(JsonFormConstants.FIELDS);
1✔
812
        JSONObject repeatingGroupCountObj = FormUtils.getFieldJSONObject(stepFields, repeatingGroupCountObjKey);
1✔
813
        // prevents re-adding the count object during form traversals
814
        if (repeatingGroupCountObj != null) {
1✔
815
            return repeatingGroupCountObj;
1✔
816
        }
817

818
        repeatingGroupCountObj = new JSONObject();
1✔
819
        repeatingGroupCountObj.put(KEY, repeatingGroupCountObjKey);
1✔
820
        repeatingGroupCountObj.put(OPENMRS_ENTITY_PARENT, "");
1✔
821
        repeatingGroupCountObj.put(OPENMRS_ENTITY, "");
1✔
822
        repeatingGroupCountObj.put(OPENMRS_ENTITY_ID, "");
1✔
823
        repeatingGroupCountObj.put(TYPE, "");
1✔
824
        repeatingGroupCountObj.put(VALUE, "0");
1✔
825
        repeatingGroupCountObj.put(TEXT, widgetArgs.getJsonObject().get(REFERENCE_EDIT_TEXT_HINT));
1✔
826
        stepFields.put(repeatingGroupCountObj);
1✔
827
        return repeatingGroupCountObj;
1✔
828
    }
829

830

831
    /**
832
     * @param This     function is to return JSON Object of i.e {"value":"widget_item_key","text":"translated_text_value"} for translatable_widgets_keys. It's not specific to the widget_type
833
     * @param item
834
     * @param itemType
835
     * @return
836
     * @throws JSONException
837
     */
838

839
    public static JSONObject generateTranslatableValue(String value, JSONObject item) throws JSONException {
840
        JSONObject newValue = new JSONObject();
1✔
841
        if (item.has(JsonFormConstants.OPTIONS_FIELD_NAME)) {
1✔
842
            JSONArray options = item.getJSONArray(JsonFormConstants.OPTIONS_FIELD_NAME);
1✔
843
            JSONObject selectedOption = formUtils.getOptionFromOptionsUsingKey(options, value);
1✔
844
            newValue.put(VALUE, value);
1✔
845
            newValue.put(TEXT, selectedOption.optString(JsonFormConstants.TRANSLATION_TEXT));
1✔
846
            return newValue;
1✔
847
        }
848
        newValue.put(VALUE, value);
1✔
849
        newValue.put(TEXT, item.optString(JsonFormConstants.TRANSLATION_TEXT));
1✔
850
        return newValue;
1✔
851
    }
852

853
    public static boolean enabledProperty(String appPropName) {
854
        NativeFormsProperties nativeFormsProperties = JsonFormFragment.getNativeFormProperties();
1✔
855
        return nativeFormsProperties != null && nativeFormsProperties.isTrue(appPropName);
1✔
856
    }
857

858
    public static String getValueAfterTranslation(JSONObject item) {
859
        try {
860
            if (item != null && item.has(VALUE)) {
×
861
                if (item.opt(VALUE) != null && item.opt(VALUE).toString().length() > 0 && item.opt(VALUE).toString().charAt(0) == '{') {
×
862
                    return new JSONObject(item.opt(VALUE).toString()).optString(VALUE);
×
863
                }
864
                return item.opt(VALUE) + "";
×
865
            }
866
            return "";
×
867
        } catch (Exception e) {
×
868
            Timber.e(e);
×
869
            return "";
×
870
        }
871
    }
872

873
    public List<String> createExpansionPanelChildren(JSONArray jsonArray) throws JSONException {
874
        List<String> stringList = new ArrayList<>();
1✔
875
        String label;
876
        for (int i = 0; i < jsonArray.length(); i++) {
1✔
877
            if (!jsonArray.isNull(i)) {
1✔
878
                JSONObject jsonObject = jsonArray.getJSONObject(i);
1✔
879
                if (jsonObject.has(JsonFormConstants.VALUES) && jsonObject.has(JsonFormConstants.LABEL) &&
1✔
880
                        !"".equals(jsonObject.getString(JsonFormConstants.LABEL))) {
1✔
881
                    //Get label and replace any colon in some labels. Not needed at this point
882
                    label = jsonObject.getString(JsonFormConstants.LABEL).replace(":", "");
1✔
883
                    stringList.add(label + ":" + getStringValue(jsonObject));
1✔
884
                }
885
            }
886
        }
887

888
        return stringList;
1✔
889
    }
890

891
    private String getStringValue(JSONObject jsonObject) throws JSONException {
892
        StringBuilder value = new StringBuilder();
1✔
893
        if (jsonObject != null) {
1✔
894
            JSONArray jsonArray = jsonObject.getJSONArray(JsonFormConstants.VALUES);
1✔
895
            for (int i = 0; i < jsonArray.length(); i++) {
1✔
896
                String stringValue = jsonArray.getString(i);
1✔
897
                value.append(getValueFromSecondaryValues(stringValue));
1✔
898
                value.append(", ");
1✔
899
            }
900
        }
901

902
        return value.toString().replaceAll(", $", "");
1✔
903
    }
904

905
    private String getValueFromSecondaryValues(String itemString) {
906
        String[] strings = itemString.split(":");
1✔
907
        return strings.length > 1 ? strings[1] : strings[0];
1✔
908
    }
909

910
    protected String getKey(JSONObject object) throws JSONException {
911
        return object.has(RuleConstant.IS_RULE_CHECK) && object.getBoolean(RuleConstant.IS_RULE_CHECK) ?
1✔
912
                object.get(RuleConstant.STEP) + "_" + object.get(KEY) : VALUE;
1✔
913
    }
914

915
    protected Object getValue(JSONObject object) throws JSONException {
916
        Object value;
917
        if (object.has(VALUE)) {
1✔
918
            value = returnValue(object);
1✔
919
            if (isNumberWidget(object)) {
1✔
920
                value = TextUtils.isEmpty(object.optString(VALUE)) ? 0 :
×
921
                        processNumberValues(object.optString(VALUE));
×
922
            } else if (value != null && !TextUtils.isEmpty(object.getString(VALUE)) &&
1✔
923
                    canHaveNumber(object)) {
1✔
924
                value = processNumberValues(value);
×
925
            }
926

927
        } else {
928
            value = isNumberWidget(object) ? 0 : "";
×
929
        }
930

931
        return value;
1✔
932
    }
933

934
    protected boolean isNumberWidget(JSONObject object) throws JSONException {
935
        return object.has(JsonFormConstants.EDIT_TYPE) &&
1✔
936
                object.getString(JsonFormConstants.EDIT_TYPE).equals(JsonFormConstants.EDIT_TEXT_TYPE.NUMBER) ||
1✔
937
                object.getString(TYPE).equals(JsonFormConstants.NUMBER_SELECTOR);
1✔
938
    }
939

940
    protected Object processNumberValues(Object object) {
941
        Object value = object;
1✔
942
        try {
943
            if (value.toString().contains(".")) {
1✔
944
                value = String.valueOf((float) Math.round(Float.valueOf(value.toString()) * 100) / 100);
1✔
945
            } else {
946
                value = Integer.valueOf(value.toString());
1✔
947
            }
948
        } catch (NumberFormatException e) {
1✔
949
            Timber.e(e);
1✔
950
        }
1✔
951
        return value;
1✔
952
    }
953

954
    protected boolean canHaveNumber(JSONObject object) throws JSONException {
955
        return isNumberWidget(object) || object.getString(TYPE).equals(JsonFormConstants.HIDDEN) ||
1✔
956
                object.getString(TYPE).equals(JsonFormConstants.SPINNER);
1✔
957
    }
958

959
    public void setChildKey(View view, String type, ExpansionPanelGenericPopupDialog genericPopupDialog) {
960
        String childKey;
961
        if (type != null && (type.equals(JsonFormConstants.CHECK_BOX) || type.equals(JsonFormConstants.NATIVE_RADIO_BUTTON) || type.equals(JsonFormConstants.EXTENDED_RADIO_BUTTON))) {
1✔
962
            childKey = (String) view.getTag(com.vijay.jsonwizard.R.id.childKey);
×
963
            genericPopupDialog.setChildKey(childKey);
×
964
        }
965
    }
1✔
966

967
    public void setExpansionPanelDetails(String type, String toolbarHeader, String container, ExpansionPanelGenericPopupDialog genericPopupDialog) {
968
        if (type != null && type.equals(JsonFormConstants.EXPANSION_PANEL)) {
1✔
969
            genericPopupDialog.setHeader(toolbarHeader);
1✔
970
            genericPopupDialog.setContainer(container);
1✔
971
        }
972
    }
1✔
973

974
    /**
975
     * Gets the {@link android.support.v4.app.FragmentTransaction} from the {@link Context} and removes any {@link android.support.v4.app.Fragment} with the tag `GenericPopup` from the transaction.
976
     * Then nullifies the stack by calling {@link android.support.v4.app.FragmentTransaction#addToBackStack(String)} with a null value.
977
     *
978
     * @param context {@link Activity} The activity context where this transaction called from
979
     * @return fragmentTransaction {@link android.support.v4.app.FragmentTransaction}
980
     */
981
    @NotNull
982
    public FragmentTransaction getFragmentTransaction(Activity context) {
983
        FragmentTransaction fragmentTransaction = context.getFragmentManager().beginTransaction();
1✔
984
        Fragment fragment = context.getFragmentManager().findFragmentByTag("GenericPopup");
1✔
985
        if (fragment != null) {
1✔
986
            fragmentTransaction.remove(fragment);
×
987
        }
988

989
        fragmentTransaction.addToBackStack(null);
1✔
990
        return fragmentTransaction;
1✔
991
    }
992

993
    /**
994
     * Enabling the expansion panel views after they were disabled on sub form opening.
995
     *
996
     * @param linearLayout {@link LinearLayout}
997
     */
998
    public void enableExpansionPanelViews(LinearLayout linearLayout) {
999
        RelativeLayout layoutHeader = (RelativeLayout) linearLayout.getChildAt(0);
×
1000
        RelativeLayout expansionHeaderLayout = layoutHeader.findViewById(R.id.expansion_header_layout);
×
1001
        expansionHeaderLayout.setEnabled(true);
×
1002
        expansionHeaderLayout.setClickable(true);
×
1003

1004
        ImageView statusImageView = expansionHeaderLayout.findViewById(R.id.statusImageView);
×
1005
        statusImageView.setEnabled(true);
×
1006
        statusImageView.setClickable(true);
×
1007

1008
        CustomTextView topBarTextView = expansionHeaderLayout.findViewById(R.id.topBarTextView);
×
1009
        topBarTextView.setClickable(true);
×
1010
        topBarTextView.setEnabled(true);
×
1011

1012
        LinearLayout contentLayout = (LinearLayout) linearLayout.getChildAt(1);
×
1013
        LinearLayout buttonLayout = contentLayout.findViewById(R.id.accordion_bottom_navigation);
×
1014
        Button okButton = buttonLayout.findViewById(R.id.ok_button);
×
1015
        okButton.setEnabled(true);
×
1016
        okButton.setClickable(true);
×
1017
    }
×
1018
    /***
1019
     *
1020
     * @param jsonArrayString
1021
     * @return
1022
     */
1023
    public static boolean checkIfValidJsonArray(String jsonArrayString) {
1024
        if (StringUtils.isNotBlank(jsonArrayString)) {
1✔
1025
            try {
1026
                return new JSONArray(jsonArrayString).length() > 0;
×
1027
            } catch (Exception e) {
×
1028
                return false;
×
1029
            }
1030
        }
1031
        return false;
1✔
1032
    }
1033
    public static String extractValueFromJson(String value)
1034
    {
1035
        try{
1036
            if(!StringUtils.isEmpty(value) && value.startsWith("{") && value.endsWith("}")) {
1✔
1037
                JSONObject object = new JSONObject(value);
1✔
1038
                return object.optString(VALUE);
1✔
1039
            }
1040
        }
1041
        catch (Exception e)
×
1042
        {
1043
            Timber.e(e);
×
1044
        }
1✔
1045
        return  value;
1✔
1046
    }
1047

1048
    public static String decompress(String str, String outEncoding) {
1049
        if (str == null || str.length() == 0) {
×
1050
            return str;
×
1051
        }
1052

1053
        try {
1054
            String decode = URLDecoder.decode(str, "UTF-8");
×
1055

1056
            ByteArrayOutputStream out = new ByteArrayOutputStream();
×
1057
            ByteArrayInputStream in = new ByteArrayInputStream(decode.getBytes("ISO-8859-1"));
×
1058
            GZIPInputStream gunzip = new GZIPInputStream(in);
×
1059
            byte[] buffer = new byte[256];
×
1060
            int n;
1061
            while ((n = gunzip.read(buffer)) >= 0) {
×
1062
                out.write(buffer, 0, n);
×
1063
            }
1064
            return out.toString(outEncoding);
×
1065
        } catch (IOException e) {
×
1066
            e.printStackTrace();
×
1067
        }
1068
        return null;
×
1069
    }
1070

1071
}
1072

1073

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc