Split validation and import.
Added validation for unused fields.
This commit is contained in:
parent
c9de7a0754
commit
fa05584827
3 changed files with 85 additions and 67 deletions
|
@ -72,10 +72,42 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
||||||
val PAUSE = ','
|
val PAUSE = ','
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
fun importConfig(intent: Intent) {
|
||||||
|
val errors = StringBuilder()
|
||||||
|
|
||||||
|
val tmp: Config? = try {
|
||||||
|
Gson().fromJson(InputStreamReader(contentResolver.openInputStream(intent.data)),
|
||||||
|
Config::class.java)
|
||||||
|
} catch (jse: JsonSyntaxException) {
|
||||||
|
val cause = jse.cause
|
||||||
|
if (cause != null) {
|
||||||
|
errors.append(cause.message)
|
||||||
|
} else {
|
||||||
|
errors.append(jse.message)
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp != null && validateConfig(tmp, errors)) {
|
||||||
|
config = tmp
|
||||||
|
saveConfig()
|
||||||
|
recreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length > 0) {
|
||||||
|
alert {
|
||||||
|
title(R.string.alert_config_error)
|
||||||
|
message(Html.fromHtml("$errors"))
|
||||||
|
cancelButton { }
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (requestCode == read_request_code && resultCode == Activity.RESULT_OK) {
|
if (requestCode == read_request_code && resultCode == Activity.RESULT_OK) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
MainActivityPermissionsDispatcher.validateConfigWithCheck(this, data)
|
MainActivityPermissionsDispatcher.importConfigWithCheck(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,6 +303,12 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
||||||
defaultConfigs.forEach {
|
defaultConfigs.forEach {
|
||||||
config = Gson().fromJson(InputStreamReader(resources.openRawResource(it)),
|
config = Gson().fromJson(InputStreamReader(resources.openRawResource(it)),
|
||||||
Config::class.java)
|
Config::class.java)
|
||||||
|
|
||||||
|
// val errors = StringBuilder()
|
||||||
|
// if (!validateConfig(config, errors)) {
|
||||||
|
// info("${config.params.name}: $errors")
|
||||||
|
// }
|
||||||
|
|
||||||
confs.configs.put(config.params.name, config)
|
confs.configs.put(config.params.name, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,91 +335,70 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
fun validateConfig(config: Config, errors: StringBuilder): Boolean {
|
||||||
fun validateConfig(intent: Intent) {
|
val len = errors.length
|
||||||
val errors = StringBuilder()
|
|
||||||
|
|
||||||
val tmp: Config? = try {
|
with(config) {
|
||||||
Gson().fromJson(InputStreamReader(contentResolver.openInputStream(intent.data)),
|
if (params.name.isBlank()) {
|
||||||
Config::class.java)
|
errors.append(getString(R.string.validate_missing_param, "name"))
|
||||||
} catch (jse: JsonSyntaxException) {
|
|
||||||
val cause = jse.cause
|
|
||||||
if (cause != null) {
|
|
||||||
errors.append(cause.message)
|
|
||||||
} else {
|
|
||||||
errors.append(jse.message)
|
|
||||||
}
|
}
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmp != null) {
|
if (params.size < 1) {
|
||||||
with(tmp) {
|
errors.append(getString(R.string.validate_invalid_param, "size"))
|
||||||
if (params.name.isBlank()) {
|
}
|
||||||
errors.append(getString(R.string.validate_missing_param, "name"))
|
|
||||||
|
if (params.star.isBlank()) {
|
||||||
|
errors.append(getString(R.string.validate_missing_param, "star"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.size == 0) {
|
||||||
|
errors.append(getString(R.string.validate_missing_opts))
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.forEachIndexed { i, option ->
|
||||||
|
if (option.fields.size == 0) {
|
||||||
|
errors.append(getString(R.string.validate_missing_fields, i + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size < 1) {
|
if (option.nosteps && option.nodial) {
|
||||||
errors.append(getString(R.string.validate_invalid_param, "size"))
|
errors.append(getString(R.string.validate_invalid_option, i + 1, "nodial/nosteps"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.star.isBlank()) {
|
if (option.dtmf.isBlank()) {
|
||||||
errors.append(getString(R.string.validate_missing_param, "star"))
|
errors.append(getString(R.string.validate_invalid_dtmf, i + 1, "''"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.size == 0) {
|
option.fields.forEachIndexed { j, field ->
|
||||||
errors.append(getString(R.string.validate_missing_opts))
|
if (field.size <= 0) {
|
||||||
}
|
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "size"))
|
||||||
|
|
||||||
opts.forEachIndexed { i, option ->
|
|
||||||
if (option.fields.size == 0) {
|
|
||||||
errors.append(getString(R.string.validate_missing_fields, i + 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.nosteps && option.nodial) {
|
if (!field.alpha) {
|
||||||
errors.append(getString(R.string.validate_invalid_option, i + 1, "nodial/nosteps"))
|
if (field.min >= 0 || field.max >= 0) {
|
||||||
}
|
if (field.max < 1) {
|
||||||
|
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "max"))
|
||||||
option.fields.forEachIndexed { j, field ->
|
} else if (field.min < 0) {
|
||||||
if (field.size <= 0) {
|
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "min"))
|
||||||
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "size"))
|
} else if (field.min > field.max) {
|
||||||
}
|
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "max/min"))
|
||||||
|
|
||||||
if (!field.alpha) {
|
|
||||||
if (field.min >= 0 || field.max >= 0) {
|
|
||||||
if (field.max < 1) {
|
|
||||||
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "max"))
|
|
||||||
} else if (field.min < 0) {
|
|
||||||
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "min"))
|
|
||||||
} else if (field.min > field.max) {
|
|
||||||
errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "max/min"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val blank = "\\0"
|
if (!option.dtmf.contains(Dtmf.DTMF_FIELD.format(j + 1))) {
|
||||||
val dtmf = Dtmf.mock(option, blank)
|
errors.append(getString(R.string.validate_unused_field, i + 1, j + 1))
|
||||||
if (!Dtmf.validate(dtmf, "${MainActivity.PAUSE}${params.star}${params.hash}$blank")) {
|
|
||||||
errors.append(getString(R.string.validate_invalid_dtmf, i + 1, dtmf.replace(blank, "✓")))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (errors.length == 0) {
|
val blank = "\\0"
|
||||||
config = tmp
|
val dtmf = Dtmf.mock(option, blank)
|
||||||
saveConfig()
|
if (!Dtmf.validate(dtmf, "${MainActivity.Companion.PAUSE}${params.star}${params.hash}$blank")) {
|
||||||
recreate()
|
errors.append(getString(R.string.validate_invalid_dtmf, i + 1, dtmf.replace(blank, "✓")))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors.length > 0) {
|
return errors.length == len
|
||||||
alert {
|
|
||||||
title(R.string.alert_config_error)
|
|
||||||
message(Html.fromHtml("$errors"))
|
|
||||||
cancelButton { }
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun validateFields(fields: ArrayList<EditText>, size: Int): Boolean {
|
fun validateFields(fields: ArrayList<EditText>, size: Int): Boolean {
|
||||||
|
|
|
@ -24,8 +24,8 @@ import java.util.*
|
||||||
|
|
||||||
class Dtmf {
|
class Dtmf {
|
||||||
companion object {
|
companion object {
|
||||||
private val DTMF_MASTER = "[MASTER]"
|
val DTMF_MASTER = "[MASTER]"
|
||||||
private val DTMF_FIELD = "[FIELD:%1\$d]"
|
val DTMF_FIELD = "[FIELD:%1\$d]"
|
||||||
|
|
||||||
private fun alphaToDigits(text: String, star: String): String {
|
private fun alphaToDigits(text: String, star: String): String {
|
||||||
val result = StringBuffer()
|
val result = StringBuffer()
|
||||||
|
|
|
@ -21,4 +21,5 @@
|
||||||
<string name="validate_missing_fields"><p><b>opts[<xliff:g id="opts">%1$d</xliff:g>]</b>: <font color=\"red\">fields</font> missing</string>
|
<string name="validate_missing_fields"><p><b>opts[<xliff:g id="opts">%1$d</xliff:g>]</b>: <font color=\"red\">fields</font> missing</string>
|
||||||
<string name="validate_missing_param"><p><p><b>params</b>: <font color=\"red\"><xliff:g id="param">%1$s</xliff:g></font> missing</p></string>
|
<string name="validate_missing_param"><p><p><b>params</b>: <font color=\"red\"><xliff:g id="param">%1$s</xliff:g></font> missing</p></string>
|
||||||
<string name="validate_missing_opts"><font color=\"red\">opts</font> missing.</string>
|
<string name="validate_missing_opts"><font color=\"red\">opts</font> missing.</string>
|
||||||
|
<string name="validate_unused_field"><b>opts[<xliff:g id="opts">%1$d</xliff:g>]</b>, <font color=\"red\">fields[<xliff:g id="field">%2$d</xliff:g>]</font>: unused</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue