Support > Repository > Business logic > Input check/Consistency check

I will explain how to implement complex input check and consistency check with script.

Input check processing can be described as script code.

Figure 1 Script description field

The process written here is a check of other (can be described by mandatory check, setting of character number check etc)laterIt will be executed.

To be exact, it is the last process of input check.

When you modify the script in Designer, it is immediately reflected in the application on the development machine.You can check the fix without building process.

In the script, "object" corresponding to the model name can be used.

In Wagby, the value entered from the Web form is "Presentation modelWe manage it.

In the operation of the presentation model, you can obtain the input string by assigning ".content" to the end of the item name.

The next example is a script that sets an error if the input of the date item sch_date of model schedule begins with "H25".

/* 日付を取り出す。*/
var s = 
    (schedule_p.schDate !== null) ? schedule_p.schDate.content : null; 
/* slice は JavaScript が提供する */
if (s !== null && s.slice(0,3)=="H25") { 
    var error = new Jfcerror();
    error.content = "平成25年はまだ入力できません。";
    p.errors.addJfcerror(error);
}

The following three types of messages can be displayed on the screen.

INFO

This message is displayed when processing is completed normally.A message appears in the blue frame.

var info = new Jfcinfo();
info.content="...";
p.errors.addJfcinfo(info);

ERROR

This is an error message.A message appears in the red frame.

var error = new Jfcerror();
error.content="...";
p.errors.addJfcerror(error);

Internationalization

It also supports internationalization of messages.

Write a message of "key = value" format in error message file $ (DEVHOME) \ customize \ resources \ myerrormsg_en.properties.UTF8.For details, please read "Change Messages/Internationalization> Edit Resource File".

Resource files are compatible with internationalization.For English version, prepare myerrormsg_en.properties.

The following code outputs the appropriate message corresponding to the locale.(In this example, we use the name "error.original" for the key.)

p.errors.addJfcerror(errorManager.getJfcerror("error.original", p.locale));

You can also specify a placeholder in the error message file.Specifically, it is as follows.

var arrayOfStrings = Java.type("java.lang.String[]");
var obj = new arrayOfStrings(1);
obj[0] = "テストです。";
p.errors.addJfcerror(errorManager.getJfcerror("error.original", obj, p.locale));
The above is an example of Java 8.Handling of arrays is different when using Java 6/7.For details, please read "Notes on using Java 6/7> Handling of arrays".

If you want to use warnings instead of errors, use the JFCHelperUtils class.Please do as follows.

var JFCHelperUtils = Java.type("jp.jasminesoft.jfc.JFCHelperUtils");

var s = model1.item1;
if (s != null && s == '(エラーとしたい値)') {
    var warn = new Jfcwarn();
    warn.content="..."; /*警告メッセージ*/
    JFCHelperUtils.checkWarnedError(
        p, s, warn, "model1.item1", 
        "model1.item1.error.input.generic");
}

The first argument of the JFCHelperUtils.checkWarnedError method is p.The second argument is "entered value".The third argument is a warning object (warn).The fourth argument should be "model ID. Item ID".The fifth argument becomes the key name of the resource of the error message when it is internationalized.As usual, please refer to "Model ID.Item ID.error.input.generic" as in the example above.

There is an attribute called errorcode in the input item of the presentation model.If some value is set here, the background of the input field will be red.

An example

The code that sets errorcode of the item "AAAM/item 1" included in the repeat container "AAAM" of model ID "AAA" is as follows.

var AAAMClass = Java.type("jp.jasminesoft.wagby.model.AAA_p.AAAM");
var Item1Class = Java.type("jp.jasminesoft.wagby.model.AAA_p.Item1");
var cont_ary = AAA_p.AAAM;
if (cont_ary !== null) {
  var values;
  for (var i=0; i<cont_ary.length; i++) {
    if (cont_ary[i].item1 === null) {
      values = new Item1Class();
      cont_ary[i].item1 = values;
    } else {
      values = cont_ary[i].item1;
    }
    values.errorcode = "ERROR";/* errorcode をセットする */
    var error = new Jfcerror();
    error.content = "ERROR";
    p.errors.addJfcerror(error);
  }
}

"Consistency check" using values ​​obtained by automatic calculation can be performed instead of input from the Web form.In this case, use the store model.The store model holds the value converted from the character string entered from the screen into the appropriate type (letter, number, date).It also holds the value obtained by automatic calculation.

In the following example, in the parent model Parent and the child model Child (related parent-child relationship with the foreign key), the number of Child models that are children (COUNT) and the maximum value of items (MAX) are defined in Parent on Parent side It shall be assumed.

Specifically, it is assumed that the calculation expression "COUNT ($ {child_lp})" is defined in the countOfChild item of the Parent model and the calculation expression "MAX ($ {child_lp.item 1})" is defined in the maxOfChildItem 1 item I will.

In this case, the rule that the countOfChild item is 2 or more and the maxOfChildItem 1 item is 100 or more is described as follows.

/* Parent はストアモデル */
if (Parent.countOfChild < 2) {
    var error = new Jfcerror();
    error.content = "子モデルの数は2以上です。";
    p.errors.addJfcerror(error);
}
if (Parent.maxOfChildItem1 < 100) {
    var error = new Jfcerror();
    error.content = "子モデルitem1の最大値は100以上です。";
    p.errors.addJfcerror(error);
}
In the above code, if it is expressed as Parent_p, we will use the presentation model.The presentation model holds the value (character string) entered from the screen, but the value of countOfChild item is not calculated because it is a calculation formula.Therefore, it is inappropriate to use the presentation model here.

In parent-child model relationship,Enable simultaneous updating of child models.

In this case, you can write an input check that "At least one child model is required in the parent model" as follows.Child model is defined as Child.

/* 子モデル名を Child と定義している */
var Child_ary = p.request.getAttribute("Child_ary");/*子モデル配列の取得*/
var count = Child_ary.length;
if (count < 1) {
    var error = new Jfcerror();
    error.content = "子モデルChildは1件以上、必要です。";
    p.errors.addJfcerror(error);
}

With the parent-child model simultaneous update function, the array of the child models to be targeted is stored in the p.request object at the timing of the input check processing.The key name is "child model name _ary".You can get an array with the key name appended with "_ary" at the end.

By getting this and checking the number of arrays we can know the number of child models.

The Child_ary obtained here isStore modelis.

In this example, Child starts with an uppercase letter.If the model name is child and the beginning is lowercase, it is p.request.getAttribute ("child_ary").

In parent-child model relationship,Enable simultaneous updating of child models.

In this case, you can write a script "Compare the shipping date of the parent model with the delivery date of each child model" as follows.

/*親モデルの出荷日と、子モデルの納期を比較する*/
var syukkabi = Parent.sdate;/*Parentはストアモデル*/
var Child_ary = p.request.getAttribute("Child_ary");
var count = Child_ary.length;
for (var i=0; i<count; i++) {
    var Child = Child_ary[i];/*Childもストアモデル*/
    var nouki = Child.nouki;/*syukkabiもnoukiもJavaScriptのDate型オブジェクトとして扱える*/
    if (syukkabi.getTime() > nouki.getTime()) {
        var error = new Jfcerror();
        error.content = (i+1)+"番目の納期は、出荷日よりも早い日になっています。";
        p.errors.addJfcerror(error);
    }
}

Parent and Child_ary are store models.Since the store model distinguishes between character strings, numbers, and date types, items sdate and nouki are recognized as date types.Therefore, it can operate as JavaScript date object.Specifically, comparison processing using the getTime () method can be performed.

In this example, Child starts with an uppercase letter.If the model name is child and the beginning is lowercase, it is p.request.getAttribute ("child_ary").

We assume the rule that customers model can be registered up to only 10 entries.For this check,"Number of cases" currently stored in the databaseIt is necessary to know.

In order to operate the database with the input check script, the developer gets "session".

For scripts of input checking, developers need to acquire sessions themselves.

Here is an example of a script.

var HibernateUtil = Java.type("jp.jasminesoft.jfc.app.HibernateUtil");
var session = HibernateUtil.openSession();
try {
    var o = session.createSQLQuery(
           "SELECT COUNT(*) FROM \"customer\"").uniqueResult();
    if (o > 10) {
        var error = new Jfcerror();
        error.content = "10件以上のデータを登録することはできません。";
        p.errors.addJfcerror(error);
    }
} catch (e) {
    e.printStackTrace();
} finally {
    if (session !== null) {
        session.close();/*忘れないこと*/
    }
}
  • The session object for database operation is obtained using HibernateUtil.openSession ().
  • Be sure to close the acquired session.If you forget to close it, you will run out of available database sessions, resulting in a runtime error during operation.
  • In the above script we enclose the front and back of the table customer in double quotes.Depending on your database, use either single quote or double quote.(When using HSQLDB which is the built-in DB, enclose it in double quotation marks.)For this reason,If you use different databases for the development machine and the production machine, you may also need to change the script filePlease note that.
  • Please use SQL only in the search system.(*1)
  • Since the sample code above uses the uniqueResult method, the return value must always be one.If you write SQL that returns multiple records, use the list method.(For details, please learn Hibernate programming.) In the next section, we will explain an example of handling multiple items using EntityService.
1. It is safe to assume that update processing will not occur because input checking is handled here.Wagby uses its own lock manager when updating.Ignoring it and directly updating it with SQL will not guarantee data integrity.When updating is involved, please use EntityService provided by Wagby instead of SQL.

We will assume a product model.Assume that the primary key field pkey is automatically numbered in order and has an item "product code (pcode)" which is not a primary key.Here, we will introduce a script that preliminarily checks the duplicate item codes and displays an error message if there is a duplication.

var screentype = p.request.getAttribute("__jfc_screen_type");/* SCREENTYPE 関数のこと */

var service = p.appctx.getBean("ProductEntityService");
var criteriaConverter = p.appctx.getBean("ProductCriteriaConverter");
var criteria = criteriaConverter.defaultCriteria();
var metaClass = Java.type("jp.jasminesoft.wagby.model.product.ProductMeta");
var meta = new metaClass();

criteria.eq(meta.pcode, product.pcode);/* pcode の重複を確認する。*/

var list = service.find(criteria);
if (list !== null && list.size() >= 1) {
    if (screentype === "update" && list.size() === 1) {
        var o = list.get(0);
        if (o.pkey === product.pkey) {
            /* 自分自身なのでエラーとしない */
            return;
        }
    }
    var error = new Jfcerror();
    error.content = "商品コード '"+product.pcode+"' が重複しています。";
    p.errors.addJfcerror(error);
}
  • Criteria deals with search criteria.For details, please read "Using Criteria".
  • "Unique constraintYou can do the same with the setting ".Unique constraints are a way to have the database determine the error.Since the above script method is judged by the application, it has extensibility such as complicated condition setting and arbitrary error message can be prepared.

Call script with "Input check" prepared on the list maintenance screen.Only the number of rows whose values ​​have changed is eligible.(The script will not be called even if you press the "Check Input" button without changing it.)

Figure 2 Input Check of List Maintenance Screen

Prepare "script> helper> input check (list update)".Here is an example.

stdout.println("入力チェック "+customer+" "+customer_ulp);

if (customer.customername == "aaa") {
    var error = new Jfcerror();
    error.content = "顧客名に aaa は利用できません。";
    p.errors.addJfcerror(error);
    return error.content;
}

Within the script, you can refer to the presentation model with the suffix "_ulp", which can only be used on the list update screen, in addition to the store model.

Values ​​can not be rewritten here.Because it is an input check script, please only refer to the value.