|
166 | 166 | properties (Access = private) |
167 | 167 | flags__ % additional options, will be passed to jsonlab utility functions such as savejson/loadjson |
168 | 168 | currentpath__ % internal variable tracking the current path when lookup embedded data at current depth |
| 169 | + root__ % reference to root jdict object for validated assignment |
169 | 170 | end |
170 | 171 | methods |
171 | 172 |
|
|
175 | 176 | obj.attr = containers.Map(); |
176 | 177 | obj.schema = []; |
177 | 178 | obj.currentpath__ = char(36); |
| 179 | + obj.root__ = obj; |
178 | 180 | if (nargin >= 1) |
179 | 181 | if (~isempty(varargin)) |
180 | 182 | allflags = [varargin(1:2:end); varargin(2:2:end)]; |
|
321 | 323 | newobj.attr = obj.attr; |
322 | 324 | newobj.schema = obj.schema; |
323 | 325 | newobj.currentpath__ = trackpath; |
| 326 | + newobj.root__ = obj.root__; |
324 | 327 | val = newobj; |
325 | 328 | i = i + 2; |
326 | 329 | continue |
|
381 | 384 | end |
382 | 385 | end |
383 | 386 | newobj.schema = obj.schema; |
384 | | - newobj.currentpath__ = char(36); |
| 387 | + newobj.currentpath__ = trackpath; |
| 388 | + newobj.root__ = obj.root__; |
385 | 389 | val = newobj; |
386 | 390 | end |
387 | 391 | varargout{1} = val; |
|
576 | 580 | opcell{i} = obj.call_('jsonpath', opcell{i}, idx.subs, opcell{i + 1}); |
577 | 581 | else |
578 | 582 | try |
579 | | - opcell{i} = subsasgn(opcell{i}, idx, opcell{i + 1}); |
| 583 | + if (exist('OCTAVE_VERSION', 'builtin') ~= 0) && (isa(opcell{i}, 'containers.Map') || isa(opcell{i}, 'dictionary')) |
| 584 | + opcell{i}(idx.subs) = opcell{i + 1}; |
| 585 | + else |
| 586 | + opcell{i} = subsasgn(opcell{i}, idx, opcell{i + 1}); |
| 587 | + end |
580 | 588 | catch |
581 | 589 | opcell{i}.(idx.subs) = opcell{i + 1}; |
582 | 590 | end |
|
793 | 801 |
|
794 | 802 | % validate data against JSON Schema |
795 | 803 | function errors = validate(obj, schemadata) |
796 | | - % determine which schema to use |
797 | | - if (nargin >= 2 && ~isempty(schemadata)) |
798 | | - useschema = schemadata; |
799 | | - else |
800 | | - useschema = obj.schema; |
| 804 | + if nargin >= 2 && ~isempty(schemadata) |
| 805 | + obj.setschema(schemadata); |
801 | 806 | end |
802 | 807 |
|
803 | | - if (isempty(useschema)) |
| 808 | + if isempty(obj.schema) |
804 | 809 | error('No schema available. Use setschema() first or provide schema as argument.'); |
805 | 810 | end |
806 | 811 |
|
807 | | - % use standalone jsonschema function |
808 | | - [valid, errors] = jsonschema(obj.data, useschema); |
| 812 | + subschema = jsonschema(obj.schema, [], 'getsubschema', obj.currentpath__); |
| 813 | + |
| 814 | + if isempty(subschema) |
| 815 | + errors = {}; |
| 816 | + return |
| 817 | + end |
| 818 | + |
| 819 | + [temp, errors] = jsonschema(obj.data, subschema, 'rootschema', obj.schema); |
809 | 820 | end |
810 | 821 |
|
811 | 822 | % convert attributes to JSON Schema |
|
922 | 933 | end |
923 | 934 | end |
924 | 935 |
|
| 936 | + % overload <= operator for schema-validated assignment |
| 937 | + function result = le(obj, value) |
| 938 | + % validate against schema if defined |
| 939 | + if ~isempty(obj.schema) |
| 940 | + subschema = jsonschema(obj.schema, [], 'getsubschema', obj.currentpath__); |
| 941 | + |
| 942 | + % if subschema found for this path, validate |
| 943 | + if ~isempty(subschema) |
| 944 | + [valid, errs] = jsonschema(value, subschema, 'rootschema', obj.schema); |
| 945 | + if ~valid |
| 946 | + errmsg = sprintf('Schema validation failed for "%s":', obj.currentpath__); |
| 947 | + for i = 1:length(errs) |
| 948 | + errmsg = [errmsg ' ' errs{i} ';']; |
| 949 | + end |
| 950 | + error(errmsg); |
| 951 | + end |
| 952 | + end |
| 953 | + end |
| 954 | + |
| 955 | + % assign via root object using JSONPath |
| 956 | + if strcmp(obj.currentpath__, char(36)) |
| 957 | + obj.root__.data = value; |
| 958 | + else |
| 959 | + idx.type = '.'; |
| 960 | + idx.subs = obj.currentpath__; |
| 961 | + subsasgn(obj.root__, idx, value); |
| 962 | + end |
| 963 | + result = obj; |
| 964 | + end |
| 965 | + |
925 | 966 | end |
926 | 967 | end |
0 commit comments