This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 248917

Summary: Validation for Knockout.js property types
Product: platform Reporter: tulach
Component: Html4jAssignee: Jaroslav Tulach <jtulach>
Status: STARTED ---    
Severity: normal CC: apireviews
Priority: P4 Keywords: API_REVIEW_FAST
Version: 8.1   
Hardware: PC   
OS: Windows 7   
Issue Type: ENHANCEMENT Exception Reporter:
Bug Depends on:    
Bug Blocks: 249691    
Attachments: PropertyBinding.type()

Description tulach 2014-11-26 10:15:26 UTC
It will be nice if property types can be determined in wrapModel function.
Comment 1 Jaroslav Tulach 2014-11-26 19:00:47 UTC
The type of property[1] is certainly known internally. It is just a matter of making it available to technology implementators. Most likely it would be addition of 

Class<?> type();

method into PropertyBinding[2] class.


[1] http://bits.netbeans.org/html+java/1.0/net/java/html/json/Property.html
[2] http://bits.netbeans.org/html+java/1.0/org/netbeans/html/json/spi/PropertyBinding.html
Comment 2 Jaroslav Tulach 2014-11-26 21:24:55 UTC
Created attachment 150739 [details]
PropertyBinding.type()

Reporter, please confirm this change satisfies your needs.
Comment 3 Jaroslav Tulach 2014-12-03 08:59:01 UTC
The review period is over, so I plan to integrate as soon as reporter confirms the change satisfies his needs.
Comment 4 tulach 2014-12-03 13:48:03 UTC
It seems that property types are not enough :(. Because of limited number of (hardcoded) usable types. My intention was to add validated types. Maybe some kind of optional attributes propagated to wrapModel could solve this problem.
Comment 5 Jaroslav Tulach 2014-12-04 09:45:50 UTC
OK. Let's step back. What kind of validators do you have in mind? I can imagine one working on int.class and requesting a range rather than all 32-bit values. Can you share other examples?
Comment 6 tulach 2014-12-04 10:20:30 UTC
We support following basic attributes:
- Size
- Precision
- Required
- MinValue
- MaxValue
- Enum
- NullIfEmpty
- AutoTrim
- ReadOnly
- DisplayName
- DefaultValue
- PrivateField

But this attributes could be extended. Also if you use different type of property it can validate if string is e-mail, url, phone number, ...

My original intention was to create some classes which will represent our property types and if user use this classes our wrapModel will know how to map them to JavaScript model. Also there can be possibility to inherit from this basic classes and set some attributes. The wrapModel then could realize that class type is derived from class that he knows how to map to JavaScript and in this case he could create instance of this class and read values of its attributes.

Example:

Some basic class (defined in controls4j):
public final class ngFieldDef_String extends ngFieldDef {
  ...
}

User-defined class:

public final class ngFieldDef_StringMax10 extends ngFieldDef_String {
  public ngFieldDef_StringMax10() {
    Size=10;
  }
}

Use:
    @Model(className = "AppModel", properties = {
        
      /* Application's ViewModel properties */
      @Property(name = "FirstName", type = ngFieldDef_String.class),
      @Property(name = "Message", type = ngFieldDef_StringMax10.class),
    })
    static class AppModelImpl {
...
Comment 7 Jaroslav Tulach 2015-01-08 10:33:09 UTC
OK, here is the plan. If you want to define new class that has some constraints over for example String you would:

@Convertor.Registration(from=String.class) 
class StringMax10 {
  public static StringMax10 fromJSON(String from) throws IllegalArgumentException 
  {....}
  public String toJSON() { .... }
}

and then you could use StringMax10.class in @Model annotations. This would work well for newly defined types. For existing types (like Date as issue 249691 requests) one could implement Convertor manually:

@Serviceprovider(service=Convertor.class)
public class DateConvertor extends Convertor<Date,String> {
  public DataConvertor() { super(Date.class, String.class); }
  protected String toJSON(Date d) { .... }
  protected Date fromJSON(String json) throws IllegalArgumentException { ... }
}