Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_model_adaptor.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Model Adaptor
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 /* Declares and rti/inf defines for interface afw_adaptor */
19 #define AFW_IMPLEMENTATION_ID "model"
24 
25 
26 static const afw_utf8_t *
27 impl_on_object_type_ids[] = {
28 #define XX(id) \
29  &afw_s_ ## id,
30  AFW_MODEL_ON_MAP(XX)
31 #undef XX
32  NULL
33 };
34 
35 static afw_utf8_t
36 impl_on_paths[] = {
37 #define XX(id) \
38  AFW_UTF8_LITERAL( "/afw/" #id "/current"),
39  AFW_MODEL_ON_MAP(XX)
40 #undef XX
41  { NULL }
42 };
43 
45 
47  const afw_query_criteria_filter_entry_t *old_entry;
48  impl_filter_entry_t *next_entry;
50 };
51 
52 
53 typedef struct {
54  impl_filter_entry_t *anchor;
55  const afw_model_object_type_t *model_object_type;
56  const afw_pool_t *p;
57  afw_xctx_t *xctx;
59 
60 static const afw_utf8_t impl_factory_description =
61 AFW_UTF8_LITERAL("Adaptor type for using models to access objects.");
62 
63 
64 /* Model adaptor factory instance. */
67 {
68  &impl_afw_adaptor_factory_inf,
69  AFW_UTF8_LITERAL("model"),
70  &impl_factory_description
71 };
72 
73 
74 static const afw_object_t *
75 impl_adapt_object_from_adaptor(
77  const afw_adaptor_impl_request_t *impl_request,
78  const afw_model_object_type_t *object_type,
79  const afw_utf8_t *object_id,
80  const afw_object_t *mapped_object,
81  const afw_query_criteria_t *criteria,
82  const afw_pool_t *p, afw_xctx_t *xctx);
83 
84 
85 static void
86 impl_get_property_type_by_mapped_property_name(
87  const afw_model_property_type_t * *pt,
88  const afw_utf8_t * *property_name,
89  const afw_model_object_type_t *object_type,
90  const afw_utf8_t *mapped_property_name,
91  afw_xctx_t *xctx);
92 
93 
94 static void
95 impl_add_adapted_properties_from_adaptor(
96  const afw_object_t *result,
97  const afw_model_object_type_t *model_object_type,
98  const afw_object_t *mapped_object,
100  afw_xctx_t *xctx);
101 
102 
103 static void
104 impl_get_property_type_by_property_name(
105  const afw_model_property_type_t * *pt,
106  const afw_utf8_t * *mapped_property_name,
107  const afw_model_object_type_t *object_type,
108  const afw_utf8_t *property_name,
109  afw_xctx_t *xctx);
110 
111 
112 static afw_boolean_t
113 impl_model_object_cb(
114  const afw_object_t *mapped_object,
115  void *context,
116  afw_xctx_t *xctx);
117 
118 
119 void
120 impl_get_property_type_by_mapped_property_name(
121  const afw_model_property_type_t * *property_type,
122  const afw_utf8_t * *property_name,
123  const afw_model_object_type_t *object_type,
124  const afw_utf8_t *mapped_property_name,
125  afw_xctx_t *xctx)
126 {
127  const afw_model_property_type_t * *pt;
128 
129  /* Check for matching property name. */
130  for (pt = &object_type->property_type[0]; *pt; pt++)
131  {
132  if (afw_utf8_equal((*pt)->mapped_property_name,
133  mapped_property_name))
134  {
135  *property_type = *pt;
136  *property_name = (*pt)->property_name;
137  return;
138  }
139  }
140 
141  /* Return otherProperties property type or NULL. */
142  *property_type = object_type->property_type_other;
143  *property_name = (object_type->property_type_other)
144  ? mapped_property_name
145  : NULL;
146 }
147 
148 
149 
150 void
151 impl_get_property_type_by_property_name(
152  const afw_model_property_type_t * *property_type,
153  const afw_utf8_t * *mapped_property_name,
154  const afw_model_object_type_t *object_type,
155  const afw_utf8_t *property_name,
156  afw_xctx_t *xctx)
157 {
158  const afw_model_property_type_t * *pt;
159 
160  /* Check for matching property name. */
161  for (pt = &object_type->property_type[0]; *pt; pt++)
162  {
163  if (afw_utf8_equal((*pt)->property_name, property_name)) {
164  *property_type = *pt;
165  *mapped_property_name = (*pt)->mapped_property_name;
166  return;
167  }
168  }
169 
170  /* Return otherProperties property type or NULL. */
171  *property_type = object_type->property_type_other;
172  *mapped_property_name = (object_type->property_type_other)
173  ? property_name
174  : NULL;
175 }
176 
177 
178 
179 void
180 impl_add_adapted_properties_from_adaptor(
181  const afw_object_t *result,
182  const afw_model_object_type_t *model_object_type,
183  const afw_object_t *mapped_object,
185  afw_xctx_t *xctx)
186 {
187  const afw_value_t *value;
188  const afw_model_property_type_t * *pt;
189  afw_boolean_t use_default_processing;
190 
191  /* Process each property in object_type that is not in object. */
192  for (pt = &model_object_type->property_type[0]; *pt; pt++)
193  {
194  AFW_TRY {
195 
196  /* If onGetProperty for this property, set it to value. */
197  afw_memory_clear(&ctx->property_level);
198  ctx->property_level.model_property_type = *pt;
199  ctx->property_level.mapped_value = afw_object_get_property(
200  mapped_object, (*pt)->mapped_property_name, xctx);
201 
202  use_default_processing = true;
203  if ((*pt)->onGetProperty) {
204  value = afw_value_evaluate((*pt)->onGetProperty,
205  ctx->p, xctx);
206  if (value != ctx->useDefaultProcessing_value) {
207  value = afw_value_convert(value, (*pt)->data_type,
208  true, ctx->p, xctx);
209  use_default_processing = false;
210  }
211  }
212 
213  if (use_default_processing) {
214  value = ctx->property_level.mapped_value;
215  if (!value && (*pt)->default_value) {
216  value = afw_value_evaluate((*pt)->default_value,
217  result->p, xctx);
218  }
219  }
220 
221  if (!afw_value_is_nullish(value)) {
223  (*pt)->property_name,
224  value, xctx);
225  }
226  else if ((*pt)->required) {
227  afw_object_meta_add_error_fz(result, xctx,
228  "Missing property %" AFW_UTF8_FMT,
229  AFW_UTF8_FMT_ARG((*pt)->property_name));
230  }
231  }
232 
235  (*pt)->property_name, -1, AFW_ERROR_THROWN,
236  xctx);
237  }
238 
239  AFW_ENDTRY;
240  }
241 
242  afw_memory_clear(&ctx->property_level);
243 }
244 
245 
246 
247 const afw_object_t *
248 impl_adapt_object_from_adaptor(
250  const afw_adaptor_impl_request_t *impl_request,
251  const afw_model_object_type_t *model_object_type,
252  const afw_utf8_t *object_id,
253  const afw_object_t *mapped_object,
254  const afw_query_criteria_t *criteria,
255  const afw_pool_t *p, afw_xctx_t *xctx)
256 {
257  const afw_value_list_t *parent_paths;
259  const afw_object_t *object;
260  int top;
261 
262  /* Add a variable qualifier and remove it when finished. */
265  p, xctx);
266  AFW_TRY {
267 
268  /* Prime context. */
269  ctx = afw_model_internal_create_skeleton_context(
270  &self->adaptor->
271  instance_skeleton__AdaptiveModelCurrentOnGetProperty_,
272  &afw_model_internal_context_current_property_from_mapped[0],
273  self, impl_request, model_object_type, p, xctx);
274  ctx->criteria = criteria;
275  ctx->mapped_object = mapped_object;
276  ctx->from_adaptor = true;
277 
278  /* Set ids in result object. */
279  ctx->object_id = object_id;
280  if (!object_id) {
281  ctx->object_id = afw_object_meta_get_object_id(mapped_object, xctx);
282  }
284  &self->adaptor->pub.adaptor_id,
285  model_object_type->object_type_id,
286  ctx->object_id, xctx);
287 
288 
295  /* Set parent path in result object. */
296  parent_paths = afw_object_meta_get_parent_paths_value(mapped_object,
297  xctx);
298  if (parent_paths) {
299  afw_object_meta_set_parent_paths(object, parent_paths, xctx);
300  }
301 
302  /* Add adapted properties to result object. */
303  impl_add_adapted_properties_from_adaptor(object,
304  model_object_type, mapped_object, ctx, xctx);
305  }
306 
307  AFW_FINALLY{
309  }
310 
311  AFW_ENDTRY;
312 
313  return object;
314 }
315 
316 
317 
318 /* Convert a property based on object_type and adapt_type. */
320 afw_model_internal_convert_property(
321  const afw_model_object_type_t *object_type,
322  afw_model_adapt_t adapt_type,
323  const afw_utf8_t * *to_property_name,
324  const afw_value_t * *to_value,
325  const afw_utf8_t * from_property_name,
326  const afw_value_t * from_value,
327  const afw_object_t * const *variable_objects,
328  const afw_pool_t *p, afw_xctx_t *xctx)
329 {
330  const afw_model_property_type_t *property_type;
331 
332  /* Default mapped to unmapped and return if object_type NULL. */
333  *to_property_name = from_property_name;
334  *to_value = from_value;
335  if (!object_type) return;
336 
337  /* Process based on adapt_type. */
338  switch (adapt_type) {
339 
340  case afw_model_adapt_to_adaptor:
341  case afw_model_adapt_to_requestor:
342  impl_get_property_type_by_property_name(
343  &property_type, to_property_name,
344  object_type, from_property_name, xctx);
345  if (!property_type) {
346  goto error;
347  }
348  *to_value = afw_value_convert(from_value,
349  property_type->data_type, false, p, xctx);
350  break;
351 
352  case afw_model_adapt_from_adaptor:
353  case afw_model_adapt_from_requestor:
354  impl_get_property_type_by_mapped_property_name(
355  &property_type, to_property_name,
356  object_type, from_property_name, xctx);
357  if (!property_type) {
358  goto error;
359  }
360  *to_value = afw_value_convert(from_value,
361  property_type->data_type, false, p, xctx);
362  break;
363 
364  default:
365  AFW_THROW_ERROR_Z(general, "Invalid adapt_type", xctx);
366  }
367 
368  return;
369 
370 error:
371  AFW_THROW_ERROR_FZ(general, xctx,
372  "Invalid property %" AFW_UTF8_FMT,
373  AFW_UTF8_FMT_ARG(from_property_name));
374 }
375 
376 
377 
378 /* Convert a property name based on object_type and adapt_type. */
380 afw_model_internal_convert_property_name(
381  const afw_model_object_type_t *object_type,
382  afw_model_adapt_t adapt_type,
383  const afw_utf8_t * *to_property_name,
384  const afw_utf8_t * from_property_name,
385  const afw_object_t * const *variable_objects,
386  const afw_pool_t *p, afw_xctx_t *xctx)
387 {
388  const afw_model_property_type_t *property_type;
389 
390  /* Default mapped to unmapped and return if object_type NULL. */
391  *to_property_name = from_property_name;
392  if (!object_type) return;
393 
394  /* Process based on adapt_type. */
395  switch (adapt_type) {
396 
397  case afw_model_adapt_to_adaptor:
398  case afw_model_adapt_to_requestor:
399  impl_get_property_type_by_property_name(
400  &property_type, to_property_name,
401  object_type, from_property_name, xctx);
402  if (!property_type) goto error;
403  break;
404 
405  case afw_model_adapt_from_adaptor:
406  case afw_model_adapt_from_requestor:
407  impl_get_property_type_by_mapped_property_name(
408  &property_type, to_property_name,
409  object_type, from_property_name, xctx);
410  if (!property_type) goto error;
411  break;
412 
413  default:
414  AFW_THROW_ERROR_Z(general, "Invalid adapt_type", xctx);
415  }
416 
417  return;
418 
419 error:
420  AFW_THROW_ERROR_FZ(general, xctx,
421  "Invalid property %" AFW_UTF8_FMT,
422  AFW_UTF8_FMT_ARG(from_property_name));
423 
424 }
425 
426 
427 static const afw_utf8_t * const *
428 impl_convert_select(
429  const afw_model_object_type_t *model_object_type,
430  const afw_utf8_t * const *select,
431  const afw_pool_t *p,
432  afw_xctx_t *xctx)
433 {
434  const afw_utf8_t * *result;
435  afw_size_t i;
436 
437  /* Return NULL if no select. */
438  if (!select || !*select) {
439  return NULL;
440  }
441 
442  /* Return converted select. */
443  for (i = 0; select[i]; i++);
444  result = afw_pool_malloc(p, sizeof(const afw_utf8_t *) * i, xctx);
445  result[i] = NULL;
446  for (i = 0; select[i]; i++) {
447  afw_model_internal_convert_property_name(
448  model_object_type,
449  afw_model_adapt_to_adaptor,
450  &result[i],
451  select[i],
452  NULL ,
453  p, xctx);
454  }
455  return result;
456 }
457 
458 
462  const afw_query_criteria_filter_entry_t *old_entry)
463 {
464  impl_filter_entry_t *entry;
465 
466  if (!old_entry || old_entry == (void *)1) {
467  return old_entry;
468  }
469 
470  for (entry = wa->anchor;
471  entry && old_entry != entry->old_entry;
472  entry = entry->next_entry);
473 
474  if (!entry) {
475  entry = afw_pool_calloc_type(wa->p, impl_filter_entry_t, wa->xctx);
476  entry->old_entry = old_entry;
477  entry->next_entry = wa->anchor;
478  wa->anchor = entry;
479  entry->converted.next = impl_get_converted_entry(wa,
480  old_entry->next);
481  entry->converted.op_name = old_entry->op_name;
482  entry->converted.op_id = old_entry->op_id;
483  entry->converted.alt_not = old_entry->alt_not;
484  entry->converted.alt_op_id = old_entry->alt_op_id;
485  entry->converted.property_name = old_entry->property_name;
486  entry->converted.value = old_entry->value;
487  entry->converted.op_specific = old_entry->op_specific;
488 
489  entry->converted.first_conjunctive_child = impl_get_converted_entry(wa,
490  old_entry->first_conjunctive_child);
491  entry->converted.next_conjunctive_sibling = impl_get_converted_entry(wa,
492  old_entry->next_conjunctive_sibling);
493  entry->converted.on_true = impl_get_converted_entry(wa,
494  old_entry->on_true);
495  entry->converted.on_false = impl_get_converted_entry(wa,
496  old_entry->on_false);
497 
498  /* If contains, just convert property name. */
499  if (!entry->converted.value)
500  {
501  if (old_entry->property_name) {
502  afw_model_internal_convert_property_name(
503  wa->model_object_type,
504  afw_model_adapt_to_adaptor,
505  &entry->converted.property_name,
506  old_entry->property_name,
507  NULL ,
508  wa->p, wa->xctx);
509  }
510  }
511 
512  /* Else, convert property name and value based on object type. */
513  else {
514  afw_model_internal_convert_property(
515  wa->model_object_type,
516  afw_model_adapt_to_adaptor,
517  &entry->converted.property_name, &entry->converted.value,
518  old_entry->property_name, old_entry->value,
519  NULL , wa->p, wa->xctx);
520  if (afw_value_is_list(entry->converted.value)) {
521  entry->converted.value = afw_value_one_and_only(
522  entry->converted.value,
523  wa->p, wa->xctx);
524  }
525  }
526  }
527 
528  return &entry->converted;
529 }
530 
531 
532 static const afw_query_criteria_sort_entry_t *
533 impl_convert_first_sort(
534  const afw_model_object_type_t *model_object_type,
535  const afw_query_criteria_sort_entry_t *first_sort,
536  const afw_pool_t *p,
537  afw_xctx_t *xctx)
538 {
539  const afw_query_criteria_sort_entry_t *from_entry;
540  const afw_query_criteria_sort_entry_t *result = NULL;
543 
544  /* Return NULL if no first_sort. */
545  if (!first_sort) {
546  return NULL;
547  }
548 
549  /* Convert. */
550  for (
551  from_entry = first_sort,
552  prev_entry = NULL;
553  from_entry;
554  prev_entry = new_entry,
555  from_entry = from_entry->next)
556  {
557  new_entry = afw_pool_calloc_type(p,
559  if (prev_entry) {
560  prev_entry->next = new_entry;
561  }
562  else {
563  result = new_entry;
564  }
565  new_entry->descending = from_entry->descending;
566  afw_model_internal_convert_property_name(
567  model_object_type,
568  afw_model_adapt_to_adaptor,
569  &new_entry->property_name,
570  from_entry->property_name,
571  NULL ,
572  p, xctx);
573  }
574  return result;
575 }
576 
577 
578 
579 /*
580  * Execute function for function thunk custom::mapBackObject
581  *
582  * Like adaptive function: model_mapBackObject_signature
583  *
584  * Parameters:
585  * mappedObject - (object) This is the object to map back.
586  *
587  * Returns:
588  * (object) This is the mapped back object.
589  */
590 const afw_value_t *
592  const afw_value_function_thunk_t *thunk,
593  afw_size_t argc, const afw_value_t *const *argv,
594  const afw_pool_t *p, afw_xctx_t *xctx)
595 {
597  const afw_value_t *mapped_object_value;
598  const afw_object_t *mapped_object;
599  const afw_object_t *object;
600 
602  afw_function_execute_t modified_x;
604  afw_memory_clear(&modified_x);
605  modified_x.p = p;
606  modified_x.xctx = xctx;
607  modified_x.function = NULL;
608  modified_x.argc = argc;
609  modified_x.argv = argv;
610  x = &modified_x;
611  /*---------------------------------- */
612 
613 
614  mapped_object = NULL;
615  if (x->argc == 1) {
616  mapped_object_value = afw_value_evaluate(argv[1], p, xctx);
617  if (afw_value_is_object(mapped_object_value)) {
618  mapped_object =
619  ((const afw_value_object_t *)mapped_object_value)->internal;
620  }
621  }
622  if (!mapped_object) {
623  AFW_THROW_ERROR_FZ(general, xctx,
624  "%" AFW_UTF8_FMT " expects 1 object parameter",
625  AFW_UTF8_FMT_ARG(thunk->name));
626  }
627 
628  object = impl_adapt_object_from_adaptor(
629  cb_ctx->session, cb_ctx->impl_request,
630  cb_ctx->model_object_type, cb_ctx->object_id,
631  mapped_object,
632  cb_ctx->criteria,
633  cb_ctx->p, xctx);
634 
635  return afw_value_create_object(object, p, xctx);
636 }
637 
638 
639 
640 /*
641  * Execute function for function thunk custom::returnObject
642  *
643  * Like adaptive function: model_returnObject_signature
644  *
645  * See afw_function_bindings.h for more information.
646  *
647  * Parameters:
648  * object - (object) This is the object to return.
649  * userData? - (binary) If this is present and true, the object will be
650  * mapped its mapped adaptor's object type to the model adaptor's
651  * object type.
652  *
653  * Returns:
654  * (boolean) This will return true if no more objects can be returned for
655  * any reason including a limit exceeded, connection closed, or server
656  * stopping.
657  */
658 const afw_value_t *
660  const afw_value_function_thunk_t *thunk,
661  afw_size_t argc, const afw_value_t *const *argv,
662  const afw_pool_t *p, afw_xctx_t *xctx)
663 {
665  const afw_value_t *object_value;
666  const afw_object_t *object;
667  const afw_value_t *mapback_value;
668  afw_boolean_t abort;
669 
671  afw_function_execute_t modified_x;
673  afw_memory_clear(&modified_x);
674  modified_x.p = p;
675  modified_x.xctx = xctx;
676  modified_x.function = NULL;
677  modified_x.argc = argc;
678  modified_x.argv = argv;
679  x = &modified_x;
680  /*---------------------------------- */
681 
682 
683  /* Can have at most 2 parameters. */
684  object = NULL;
685  if (x->argc > 2) {
686  AFW_THROW_ERROR_FZ(general, xctx,
687  "%" AFW_UTF8_FMT " expects at most 2 parameters",
689  }
690 
691  if (x->argc >= 1) {
692  object_value = afw_value_evaluate(argv[1], p, xctx);
693  if (afw_value_is_object(object_value)) {
694  object = ((const afw_value_object_t *)object_value)->internal;
695  }
696  }
697  if (!object) {
698  AFW_THROW_ERROR_FZ(general, xctx,
699  "%" AFW_UTF8_FMT " expects 1 object parameter",
701  }
702 
703  /* If second parameter is specified and true, mapback object. */
704  if (x->argc == 2) {
705  mapback_value = afw_value_evaluate(argv[2], p, xctx);
706  if (mapback_value) {
707  if (!afw_value_is_boolean(mapback_value)) {
708  AFW_THROW_ERROR_FZ(general, xctx,
709  "%" AFW_UTF8_FMT " expects parameter 2 to be boolean",
710  AFW_UTF8_FMT_ARG(thunk->name));
711  }
712  if (((afw_value_boolean_t *)mapback_value)->internal) {
713  object = impl_adapt_object_from_adaptor(
714  cb_ctx->session, cb_ctx->impl_request,
715  cb_ctx->model_object_type, cb_ctx->object_id,
716  object,
717  cb_ctx->criteria,
718  cb_ctx->p, xctx);
719  }
720  }
721  }
722 
723  /* Call original callback. */
724  abort = cb_ctx->original_callback(object, cb_ctx->original_context, xctx);
725 
726  return abort ? afw_value_true : afw_value_false;
727 }
728 
729 
730 
731 /* Convert query criteria based on model. */
734  const afw_model_object_type_t *model_object_type,
735  const afw_query_criteria_t *criteria,
736  const afw_pool_t *p, afw_xctx_t *xctx)
737 {
738  afw_query_criteria_t *result;
740 
741  result = afw_pool_calloc_type(p, afw_query_criteria_t, xctx);
742 
743  wa.anchor = NULL;
744  wa.model_object_type = model_object_type;
745  wa.p = p;
746  wa.xctx = xctx;
747  result->filter = impl_get_converted_entry(&wa, criteria->filter);
748  result->tree = impl_get_converted_entry(&wa, criteria->tree);
749 
750  result->select =
751  impl_convert_select(model_object_type, criteria->select,
752  p, xctx);
753 
754  result->first_sort =
755  impl_convert_first_sort(model_object_type, criteria->first_sort,
756  p, xctx);
757 
758  return result;
759 }
760 
761 
762 /* Create an instance of the adaptor. */
763 AFW_DEFINE(const afw_adaptor_t *)
765  const afw_object_t *properties,
766  const afw_pool_t *p, afw_xctx_t *xctx)
767 {
769  afw_adaptor_t *adaptor;
770  const afw_adaptor_t *model_location_adaptor;
771  const afw_utf8_t *source_location;
773  const afw_runtime_object_type_meta_t *meta;
774  int i;
775 
776  /* Create adaptor and process common properties. */
778  &impl_afw_adaptor_inf,
780  properties, p, xctx);
781  self = (afw_model_internal_adaptor_self_t *)adaptor;
782 
783  source_location = adaptor->impl->source_location;
784 
785  /* Get signature functions for current:: thunks. */
786  self->mapBackObject_signature = (const afw_value_t *)
788  &afw_s_model_mapBackObject_signature, xctx);
789  self->mapObject_signature = (const afw_value_t *)
791  &afw_s_model_mapObject_signature, xctx);
792  self->returnObject_signature = (const afw_value_t *)
794  &afw_s_model_returnObject_signature, xctx);
795 
796  /* Don't allow model to be updated view a model adaptor. */
797  //afw_adaptor_impl_set_supported_core_object_type(adaptor,
798  // &afw_s__AdaptiveModelObjectType_, true, false, xctx);
799  //afw_adaptor_impl_set_supported_core_object_type(adaptor,
800  // &afw_s__AdaptiveModelPropertyType_, false, false, xctx);
801 
802  /* Get modelLocationAdaptorId. It can not be the same as adaptorId. */
803  self->model_location_adaptor_id = afw_object_old_get_property_as_utf8(properties,
804  &afw_s_modelLocationAdaptorId, p, xctx);
805  if (afw_utf8_equal(self->model_location_adaptor_id, &adaptor->adaptor_id)) {
806  AFW_THROW_ERROR_FZ(general, xctx,
808  "modelLocationAdaptorId can not be the same as adaptorId",
809  AFW_UTF8_FMT_ARG(source_location));
810  }
811 
812  /* Prime on* instance skeletons */
813  for (obj = &self->instance_skeleton[0], i = 0;
814  i < afw_model_on_map_count;
815  obj++, i++)
816  {
818  impl_on_object_type_ids[i], xctx);
819  if (!obj->pub.inf) {
820  AFW_THROW_ERROR_Z(general,
821  "Internal error afw_model_adaptor_create_cede_p()",
822  xctx);
823  }
824  meta = obj->pub.inf->rti.implementation_specific;
825  obj->pub.meta.id = &afw_s_current;
826  obj->pub.meta.object_type_uri = meta->object_type_id;
827  obj->pub.meta.object_uri = &impl_on_paths[i];
828  }
829 
830  /* Make sure model location adaptor is started and modelId is loaded. */
831  model_location_adaptor = NULL;
832  AFW_TRY {
833  AFW_LOG_FZ(debug, xctx,
834  "Adaptor %" AFW_UTF8_FMT
835  " specified modelLocationAdaptorId %" AFW_UTF8_FMT
836  ".",
837  AFW_UTF8_FMT_ARG(&adaptor->adaptor_id),
838  AFW_UTF8_FMT_ARG(self->model_location_adaptor_id));
839  model_location_adaptor = afw_adaptor_get_reference(
840  self->model_location_adaptor_id, xctx);
841  if (!model_location_adaptor->impl || !model_location_adaptor->impl->model_location) {
842  AFW_THROW_ERROR_FZ(general, xctx,
844  "the specified modelLocationAdaptorId %" AFW_UTF8_FMT
845  " does not hold _AdaptiveModel_ objects",
846  AFW_UTF8_FMT_ARG(source_location),
847  AFW_UTF8_FMT_ARG(self->model_location_adaptor_id));
848  }
849 
851  self->model_id = afw_object_old_get_property_as_utf8(properties,
852  &afw_s_modelId, p, xctx);
853  }
854 
855  AFW_FINALLY{
856  if (model_location_adaptor) {
857  afw_adaptor_release(model_location_adaptor, xctx);
858  }
859  }
860 
861  AFW_ENDTRY;
862 
863  /* mappedAdaptorId */
864  self->mappedAdaptorId_value = afw_object_get_property(properties,
865  &afw_s_mappedAdaptorId, xctx);
866  if (!self->mappedAdaptorId_value) {
868  &afw_s_mappedAdaptorId, xctx);
869  }
870  if (!afw_value_is_string(self->mappedAdaptorId_value)) {
872  &afw_s_mappedAdaptorId, xctx);
873  }
874  self->mapped_adaptor_id =
875  &((const afw_value_string_t *)self->mappedAdaptorId_value)->internal;
876  if (afw_utf8_equal(self->mapped_adaptor_id, &self->pub.adaptor_id)) {
878  &afw_s_mappedAdaptorId, xctx);
879  }
880 
881  /* Return adaptor. */
882  return adaptor;
883 }
884 
885 
886 /*
887  * Implementation of method create_adaptor_cede_p of interface afw_adaptor_factory.
888  */
889 const afw_adaptor_t *
890 impl_afw_adaptor_factory_create_adaptor_cede_p (
891  const afw_adaptor_factory_t * instance,
892  const afw_object_t * properties,
893  const afw_pool_t * p,
894  afw_xctx_t *xctx)
895 {
896  return afw_model_adaptor_create_cede_p(properties, p, xctx);
897 }
898 
899 
900 /*
901  * Implementation of method destroy of interface afw_adaptor.
902  */
903 void
905  const afw_adaptor_t * instance,
906  afw_xctx_t *xctx)
907 {
908  /* Release pool. */
909  afw_pool_release(instance->p, xctx);
910 }
911 
912 
913 
914 /*
915  * Implementation of method create_adaptor_session of interface afw_adaptor.
916  */
917 const afw_adaptor_session_t *
919  const afw_adaptor_t * instance,
920  afw_xctx_t *xctx)
921 {
925 
927  xctx);
928  session->pub.inf = &impl_afw_adaptor_session_inf;
929  session->pub.adaptor = instance;
930  session->pub.p = xctx->p;
931  session->adaptor = self;
932 
933  session->model_location_adaptor = afw_adaptor_get_reference(
934  self->model_location_adaptor_id, xctx);
935  if (!session->model_location_adaptor) {
936  AFW_THROW_ERROR_FZ(general, xctx,
937  "Model adaptor %" AFW_UTF8_FMT " is not available",
938  AFW_UTF8_FMT_ARG(self->model_location_adaptor_id));
939  }
940  session->model = afw_model_location_get_model(
941  session->model_location_adaptor, self->model_id, xctx);
942  if (!session->model) {
943  AFW_THROW_ERROR_FZ(general, xctx,
944  "Model adaptor %" AFW_UTF8_FMT
945  " model %" AFW_UTF8_FMT
946  " not found",
947  AFW_UTF8_FMT_ARG(self->model_location_adaptor_id),
948  AFW_UTF8_FMT_ARG(self->model_id));
949  }
950 
951  return (const afw_adaptor_session_t *)session;
952 }
953 
954 
955 
956 /*
957  * Implementation of method get_additional_metrics of interface afw_adaptor.
958  */
959 const afw_object_t *
961  const afw_adaptor_t * instance,
962  const afw_pool_t * p,
963  afw_xctx_t *xctx)
964 {
966  return NULL;
967 }
968 
969 
970 
971 /*
972  * Implementation of method destroy of interface afw_adaptor_session.
973  */
974 void
976  const afw_adaptor_session_t * instance,
977  afw_xctx_t *xctx)
978 {
981 
982  if (self->model_location_adaptor) {
983  afw_adaptor_release(self->model_location_adaptor, xctx);
984  }
985 }
986 
987 
988 /* _AdaptiveObjectType_ callback */
989 static afw_boolean_t
990 impl_AdaptiveObjectType_cb(
991  const void *value,
992  void *context,
993  afw_xctx_t *xctx)
994 {
996  const afw_model_object_type_t *object_type = value;
997  const afw_object_t *object;
998 
999  object = (object_type) ? object_type->object_type_object : NULL;
1000 
1001  if (object && ctx->criteria) {
1002  if (!afw_query_criteria_test_object(object, ctx->criteria,
1003  ctx->p, xctx))
1004  {
1005  return false;
1006  }
1007  }
1008 
1009  return ctx->original_callback(object, ctx->original_context, xctx);
1010 }
1011 
1012 
1013 
1014 /* Map object callback. */
1015 static afw_boolean_t
1016 impl_model_object_cb(
1017  const afw_object_t *mapped_object,
1018  void *context,
1019  afw_xctx_t *xctx)
1020 {
1022  const afw_object_t *object;
1023 
1024  /* Process object from adaptor. */
1025  object = mapped_object;
1026  if (object) {
1027  object = impl_adapt_object_from_adaptor(
1028  ctx->session, ctx->impl_request,
1029  ctx->model_object_type, ctx->object_id,
1030  mapped_object,
1031  ctx->criteria,
1032  ctx->p, xctx);
1033  }
1034 
1035  /* Callback with view or NULL. Callback will release view. */
1036  return ctx->original_callback(object, ctx->original_context, xctx);
1037 }
1038 
1039 
1040 /*
1041  * Implementation of method retrieve_objects for interface
1042  * afw_adaptor_session.
1043  */
1044 void
1046  const afw_adaptor_session_t *instance,
1047  const afw_adaptor_impl_request_t *impl_request,
1048  const afw_utf8_t *object_type_id,
1049  const afw_query_criteria_t *criteria,
1050  void *context,
1051  afw_object_cb_t callback,
1052  const afw_object_t *adaptor_type_specific,
1053  const afw_pool_t *p,
1054  afw_xctx_t *xctx)
1055 {
1059  (afw_model_internal_adaptor_self_t *)instance->adaptor;
1062  apr_hash_index_t *hi;
1063  afw_model_object_type_t *model_object_type;
1064  afw_utf8_t id;
1065  afw_boolean_t use_default_processing;
1066 
1067  afw_memory_clear(&cb_ctx);
1068  cb_ctx.p = p;
1069  cb_ctx.session = self;
1070  cb_ctx.original_context = context;
1071  cb_ctx.original_callback = callback;
1072  cb_ctx.criteria = criteria;
1073 
1074  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1075 
1076  /* Process other object types and return. */
1077  for (hi = apr_hash_first(afw_pool_get_apr_pool(p),
1078  self->model->model_object_types);
1079  hi;
1080  hi = apr_hash_next(hi))
1081  {
1083  apr_hash_this(hi, (const void **)&id.s, (apr_ssize_t *)&id.len,
1084  (void **)&model_object_type);
1085  impl_AdaptiveObjectType_cb(model_object_type, &cb_ctx, xctx);
1086  }
1087  callback(NULL, context, xctx);
1088  return;
1089  }
1090 
1091  cb_ctx.model_object_type = afw_model_get_object_type(self->model,
1092  object_type_id, xctx);
1093  if (!cb_ctx.model_object_type) {
1094  callback(NULL, context, xctx);
1095  return;
1096  }
1097 
1098  use_default_processing = true;
1099  if (cb_ctx.model_object_type->onRetrieveObjects) {
1100  const afw_value_t *result;
1101  int top;
1102 
1103  use_default_processing = false;
1105  AFW_TRY{
1106 
1107  /* Prime context for "onRetrieveObjects". */
1108  ctx = afw_model_internal_create_skeleton_context(
1109  &self->adaptor->
1110  instance_skeleton__AdaptiveModelCurrentOnRetrieveObjects_,
1111  &afw_model_internal_context_current_retrieve_objects[0],
1112  self, impl_request, cb_ctx.model_object_type, p, xctx);
1113  ctx->mapBackObject_value = afw_value_function_thunk_create(
1114  &afw_s_a_current_colon_colon_mapBackObject,
1115  adaptor->mapBackObject_signature,
1116  impl_execute_mapBackObject_thunk, &cb_ctx, p, xctx);
1117  ctx->returnObject_value = afw_value_function_thunk_create(
1118  &afw_s_a_current_colon_colon_returnObject,
1119  adaptor->returnObject_signature,
1120  impl_execute_returnObject_thunk, &cb_ctx, p, xctx);
1121  ctx->mapped_object_type_id_value =
1122  ctx->model_object_type->mapped_object_type_id_value;
1123  ctx->criteria = criteria;
1124 
1125  result = afw_value_evaluate(
1126  cb_ctx.model_object_type->onRetrieveObjects,
1127  p, xctx);
1128  if (result == ctx->useDefaultProcessing_value) {
1129  use_default_processing = true;
1130  break;
1131  }
1132  callback(NULL, context, xctx);
1133  }
1134 
1135  /* Always restore top for qualifier stack to entry value. */
1136  AFW_FINALLY{
1138  }
1139 
1140  AFW_ENDTRY;
1141  }
1142 
1143  if (use_default_processing) {
1144  if (criteria) {
1146  cb_ctx.model_object_type, criteria, p, xctx);
1147  }
1148 
1149  afw_adaptor_retrieve_objects(self->adaptor->mapped_adaptor_id,
1150  cb_ctx.model_object_type->mapped_object_type_id,
1151  impl_request->options, cb_ctx.criteria,
1152  afw_object_create_managed(p, xctx),
1153  &cb_ctx, impl_model_object_cb,
1154  adaptor_type_specific,
1155  p, xctx);
1156  }
1157 }
1158 
1159 
1160 
1161 /*
1162  * Implementation of method get_object for interface afw_adaptor_session.
1163  */
1164 void
1166  const afw_adaptor_session_t *instance,
1167  const afw_adaptor_impl_request_t *impl_request,
1168  const afw_utf8_t *object_type_id,
1169  const afw_utf8_t *object_id,
1170  void *context,
1171  afw_object_cb_t callback,
1172  const afw_object_t *adaptor_type_specific,
1173  const afw_pool_t *p,
1174  afw_xctx_t *xctx)
1175 {
1179  (afw_model_internal_adaptor_self_t *)instance->adaptor;
1182  const afw_object_t *object;
1183  const afw_object_t *mapped_object;
1184  afw_boolean_t use_default_processing;
1185 
1186  afw_memory_clear(&cb_ctx);
1187  cb_ctx.p = p;
1188  cb_ctx.session = self;
1189  cb_ctx.original_context = context;
1190  cb_ctx.original_callback = callback;
1191 
1192  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1193  cb_ctx.model_object_type = afw_model_get_object_type(self->model,
1194  object_id, xctx);
1195  object = (cb_ctx.model_object_type)
1196  ? cb_ctx.model_object_type->object_type_object
1197  : NULL;
1198  callback(object, context, xctx);
1199  return;
1200  }
1201 
1202  cb_ctx.model_object_type = afw_model_get_object_type(self->model,
1203  object_type_id, xctx);
1204  cb_ctx.object_id = object_id;
1205  if (!cb_ctx.model_object_type) {
1206  callback(NULL, context, xctx);
1207  return;
1208  }
1209 
1210  /* Get object via onGet. */
1211  use_default_processing = true;
1212  if (cb_ctx.model_object_type->onGetObject) {
1213  const afw_value_t *object_value;
1214  const afw_object_t *object;
1215  int top;
1216 
1217  use_default_processing = false;
1219  AFW_TRY{
1220 
1221  /* Prime context for onGetObject. */
1222  ctx = afw_model_internal_create_skeleton_context(
1223  &self->adaptor->
1224  instance_skeleton__AdaptiveModelCurrentOnGetObject_,
1225  &afw_model_internal_context_current_get_object[0],
1226  self, impl_request, cb_ctx.model_object_type, p, xctx);
1227  ctx->mapBackObject_value = afw_value_function_thunk_create(
1228  &afw_s_a_current_colon_colon_mapBackObject,
1229  adaptor->mapBackObject_signature,
1230  impl_execute_mapBackObject_thunk, &cb_ctx, p, xctx);
1231  ctx->mapped_object_type_id_value =
1232  ctx->model_object_type->mapped_object_type_id_value;
1233  ctx->object_id = object_id;
1234 
1235  object_value = afw_value_evaluate(
1236  cb_ctx.model_object_type->onGetObject,
1237  p, xctx);
1238  if (object_value == ctx->useDefaultProcessing_value) {
1239  use_default_processing = true;
1240  break;
1241  }
1242  if (afw_value_is_nullish(object_value)) {
1243  object = NULL;
1244  }
1245  else if (afw_value_is_object(object_value)) {
1246  object = ((const afw_value_object_t *)object_value)->internal;
1247  }
1248  else {
1249  AFW_THROW_ERROR_Z(general,
1250  "onGetObject returned invalid value", xctx);
1251  }
1252 
1253  callback(object, context, xctx);
1254  }
1255 
1256  /* Always restore top for qualifier stack to entry value. */
1257  AFW_FINALLY{
1259  }
1260 
1261  AFW_ENDTRY;
1262  }
1263 
1264  /* Get object and map. */
1265  if (use_default_processing) {
1266  mapped_object = afw_adaptor_get_object(
1267  self->adaptor->mapped_adaptor_id,
1268  cb_ctx.model_object_type->mapped_object_type_id,
1269  object_id, NULL, NULL,
1270  afw_object_create_managed(p, xctx),
1271  adaptor_type_specific, p, xctx);
1272  cb_ctx.p = p;
1273  cb_ctx.session = self;
1274  cb_ctx.original_context = context;
1275  cb_ctx.original_callback = callback;
1276  impl_model_object_cb(mapped_object, &cb_ctx, xctx);
1277  }
1278 }
1279 
1280 
1281 /*
1282  * This is used by add and replace to create basic mapped object. Each
1283  * does further appropriated processing on returned object. ctx must be
1284  * initialized before call.
1285  */
1289  afw_xctx_t *xctx)
1290 {
1291  const afw_pool_t *p = ctx->p;
1292  const afw_object_t *result;
1293  const afw_utf8_t *property_name;
1294  const afw_utf8_t *mapped_property_name;
1295  const afw_value_t *value;
1296  const afw_value_t *mapped_value;
1297  const afw_model_property_type_t *pt;
1298  const afw_model_property_type_t * const *pts;
1299  const afw_iterator_t *iterator;
1300 
1301  /* */
1302  result = afw_object_create(p, xctx);
1303 
1304  /* Loop processing object. */
1305  iterator = NULL;
1306  while ((value = afw_object_get_next_property(ctx->object,
1307  &iterator, &property_name, xctx)))
1308  {
1309  impl_get_property_type_by_property_name(
1310  &pt, &mapped_property_name,
1311  ctx->model_object_type, property_name, xctx);
1312 
1313  if (!pt) {
1315  ctx->impl_request->request,
1316  property_name, xctx,
1317  "Invalid property %" AFW_UTF8_FMT,
1318  AFW_UTF8_FMT_ARG(property_name));
1319  }
1320  else if (pt->allow_write)
1321  {
1322  mapped_value = value;
1323  if (pt->onSetProperty) {
1324  ctx->property_level.model_property_type = pt;
1325  ctx->property_level.value = value;
1326  mapped_value = afw_value_evaluate(
1327  pt->onSetProperty, p, xctx);
1328  if (mapped_value == ctx->useDefaultProcessing_value) {
1329  mapped_value = value;
1330  }
1331  ctx->property_level.model_property_type = NULL;
1332  ctx->property_level.value = NULL;
1333  }
1334  if (!afw_value_is_nullish(mapped_value)) {
1335  afw_object_set_property(result,
1336  mapped_property_name, mapped_value, xctx);
1337  }
1338  }
1339  }
1340 
1343  /* If processing initial values or general onset??? */
1344  if (ctx->process_initial_values) {
1345  pts = ctx->model_object_type->property_type;
1346  if (pts) for (; *pts; pts++) {
1347  pt = *pts;
1348  if (pt->onGetInitialValue &&
1350  xctx))
1351  {
1352  mapped_value = afw_value_evaluate(
1353  pt->onGetInitialValue, p, xctx);
1354  afw_object_set_property(result,
1355  pt->mapped_property_name, mapped_value,
1356  xctx);
1357  }
1358  }
1359  }
1360 
1363  return result;
1364 }
1365 
1366 
1367 
1368 AFW_DEFINE_INTERNAL(void)
1369 afw_model_internal_complete_ctx_default_add_object(
1371  afw_xctx_t *xctx)
1372 {
1373  const afw_value_t *value;
1374 
1375  /* Create basic mapped object. */
1376  ctx->mapped_object =
1378 
1379  /* If onGetInitialObjectId, evaluate it. */
1380  if (ctx->model_object_type->onGetInitialObjectId) {
1381  ctx->current_variables =
1382  &afw_model_internal_context_current_for_initial_object_id[0];
1383  value = afw_value_evaluate(
1384  ctx->model_object_type->onGetInitialObjectId,
1385  xctx->p, xctx);
1386  ctx->mapped_object_id = afw_value_as_utf8(value, ctx->p, xctx);
1387  }
1388 }
1389 
1390 
1391 
1392 /*
1393  * Implementation of method add_object for interface afw_adaptor_session.
1394  */
1395 const afw_utf8_t *
1397  const afw_adaptor_session_t *instance,
1398  const afw_adaptor_impl_request_t *impl_request,
1399  const afw_utf8_t *object_type_id,
1400  const afw_utf8_t *suggested_object_id,
1401  const afw_object_t *object,
1402  const afw_object_t *adaptor_type_specific,
1403  afw_xctx_t *xctx)
1404 {
1408  const afw_utf8_t *mapped_object_id;
1409  const afw_object_t *journal_entry;
1410  const afw_value_t *value;
1411  int top;
1412  afw_boolean_t use_default_processing;
1413 
1414  /* _AdaptiveObjectType_ objects are immutable in model adaptor. */
1415  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1416  AFW_OBJECT_ERROR_OBJECT_IMMUTABLE;
1417  }
1418 
1419  /* Save top for qualifier stack. */
1421  mapped_object_id = NULL;
1422  AFW_TRY {
1423 
1424  /* Prime context for "to adaptor" (current property to mapped is superset). */
1425  ctx = afw_model_internal_create_to_adaptor_skeleton_context(
1426  self,
1427  &self->adaptor->instance_skeleton__AdaptiveModelCurrentOnAddObject_,
1428  self->model,
1429  impl_request,
1430  object_type_id,
1431  suggested_object_id,
1432  xctx);
1433  ctx->object = object;
1434  ctx->process_initial_values = true;
1435 
1436  /* If onAddObject, evaluate it. */
1437  use_default_processing = true;
1438  if (ctx->model_object_type->onAddObject) {
1439  use_default_processing = false;
1440  value = afw_value_evaluate(ctx->model_object_type->onAddObject,
1441  ctx->p, xctx);
1442  if (value == ctx->useDefaultProcessing_value) {
1443  use_default_processing = true;
1444  }
1445  else {
1446  if (!afw_value_is_string(value)) {
1447  AFW_THROW_ERROR_Z(general, "onAddObject must return string", xctx);
1448  }
1449  mapped_object_id = &((const afw_value_string_t *)value)->internal;
1450  }
1451  }
1452 
1453  /* If no onAddObject or it returned undefined, do default processing. */
1454  if (use_default_processing) {
1455  afw_model_internal_complete_ctx_default_add_object(ctx, xctx);
1456  journal_entry = afw_object_create_managed(ctx->p, xctx);
1457  mapped_object_id = afw_adaptor_add_object(
1458  self->adaptor->mapped_adaptor_id,
1459  ctx->mapped_object_type_id,
1460  ctx->mapped_object_id,
1461  ctx->mapped_object,
1462  journal_entry,
1463  adaptor_type_specific,
1464  xctx);
1465  }
1466 
1467  }
1468 
1469  /* Always restore top for qualifier stack to entry value. */
1470  AFW_FINALLY{
1472  }
1473 
1474  AFW_ENDTRY;
1475 
1476  /* Return object id. */
1477  return mapped_object_id;
1478 }
1479 
1480 
1481 
1482 AFW_DEFINE_INTERNAL(void)
1485  afw_xctx_t *xctx)
1486 {
1487  const afw_list_t *mapped_entry;
1488  const afw_adaptor_modify_entry_t * const * entry;
1489  const afw_object_path_property_name_entry_t *first_property_name_entry;
1490  const afw_utf8_t *mapped_property_name;
1491  const afw_model_property_type_t *model_property_type;
1492  const afw_value_t *value;
1493 
1494  /* Make a mapped entries list. */
1495  ctx->mapped_entries = afw_list_create_with_options(
1496  0, afw_data_type_list, ctx->p, xctx);
1497 
1498  /* Process all entries. */
1499  for (entry = ctx->modify_entries; *entry; entry++, mapped_entry++)
1500  {
1501  first_property_name_entry = ((*entry)->first_property_name_entry);
1502  if (!first_property_name_entry ||
1503  first_property_name_entry->next)
1504  {
1505  AFW_THROW_ERROR_Z(general,
1506  "Model adaptor only supports modify at the entity level",
1507  xctx);
1508  }
1509 
1510  /* Make a skeleton modify entry list and add it. */
1511  mapped_entry = afw_list_create_generic(ctx->p, xctx);
1512  value = afw_value_create_list(mapped_entry, ctx->p, xctx);
1513  afw_list_add_value(ctx->mapped_entries, value, xctx);
1514 
1515  /* Add type to entry. */
1516  if ((*entry)->type < 0 ||
1517  (*entry)->type >= afw_adaptor_modify_entry_type_invalid)
1518  {
1519  AFW_THROW_ERROR_FZ(general, xctx, "Invalid modify type %d",
1520  (*entry)->type);
1521  }
1522  afw_list_add_value(mapped_entry,
1523  afw_adaptor_modify_entry_type_value((*entry)->type), xctx);
1524 
1525  /* Add mapped name to entry. */
1526  impl_get_property_type_by_property_name(
1527  &model_property_type, &mapped_property_name, ctx->model_object_type,
1528  &(*entry)->first_property_name_entry->property_name, xctx);
1529  if (!model_property_type) {
1530  AFW_THROW_ERROR_FZ(general, xctx,
1531  "Property name %" AFW_UTF8_FMT " invalid",
1532  AFW_UTF8_FMT_ARG(&(*entry)->first_property_name_entry->property_name));
1533  }
1534  afw_list_add_value(mapped_entry,
1535  model_property_type->mapped_property_name_value, xctx);
1536 
1537  /* Add value if there is one. */
1539  if ((*entry)->value) {
1540  value = (*entry)->value;
1541  if (model_property_type->onSetProperty) {
1542  ctx->property_level.model_property_type =
1543  model_property_type;
1544  ctx->property_level.value = value;
1545  value = afw_value_evaluate(
1546  model_property_type->onSetProperty,
1547  ctx->p, xctx);
1548  afw_memory_clear(&ctx->property_level);
1549  }
1550  afw_list_add_value(mapped_entry, value, xctx);
1551  }
1552  }
1553 }
1554 
1555 
1556 
1557 /*
1558  * Implementation of method modify_object for interface afw_adaptor_session.
1559  */
1560 void
1562  const afw_adaptor_session_t *instance,
1563  const afw_adaptor_impl_request_t *impl_request,
1564  const afw_utf8_t *object_type_id,
1565  const afw_utf8_t *object_id,
1566  const afw_adaptor_modify_entry_t *const *entry,
1567  const afw_object_t *adaptor_type_specific,
1568  afw_xctx_t *xctx)
1569 {
1573  const afw_value_t *value;
1574  const afw_object_t *journal_entry;
1575  const afw_list_t *entries_list;
1576  int top;
1577  afw_boolean_t use_default_processing;
1578 
1579  /* _AdaptiveObjectType_ objects are immutable in model adaptor. */
1580  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1581  AFW_OBJECT_ERROR_OBJECT_IMMUTABLE;
1582  }
1583 
1584  /* Save top for qualifier stack. */
1586  AFW_TRY {
1587 
1588  /* Prime context for "to adaptor". */
1589  ctx = afw_model_internal_create_to_adaptor_skeleton_context(
1590  self,
1591  &self->adaptor->instance_skeleton__AdaptiveModelCurrentOnModifyObject_,
1592  self->model,
1593  impl_request,
1594  object_type_id,
1595  object_id,
1596  xctx);
1597  ctx->modify_entries = entry;
1598 
1599  /* If onModifyObject, evaluate it to modify object. */
1600  use_default_processing = true;
1601  if (ctx->model_object_type->onModifyObject) {
1602  use_default_processing = false;
1603  entries_list = afw_adaptor_modify_entries_to_list(entry,
1604  ctx->p, xctx);
1605  ctx->modify_entries_value = afw_value_create_list(entries_list,
1606  ctx->p, xctx);
1607  value = afw_value_evaluate(ctx->model_object_type->onModifyObject,
1608  ctx->p, xctx);
1609  if (value == ctx->useDefaultProcessing_value) {
1610  use_default_processing = true;
1611  }
1612  }
1613 
1614  /* If no onModifyObject or it returned undefined, do default processing. */
1615  if(use_default_processing) {
1617  journal_entry = afw_object_create_managed(ctx->p, xctx);
1619  self->adaptor->mapped_adaptor_id,
1620  ctx->mapped_object_type_id,
1621  ctx->mapped_object_id,
1622  ctx->mapped_entries,
1623  journal_entry, adaptor_type_specific,
1624  xctx);
1625  }
1626 
1628  }
1629 
1630  /* Always restore top for qualifier stack to entry value. */
1631  AFW_FINALLY{
1633  }
1634 
1635  AFW_ENDTRY;
1636 }
1637 
1638 
1639 
1640 AFW_DEFINE_INTERNAL(void)
1641 afw_model_internal_complete_ctx_default_replace_object(
1643  afw_xctx_t *xctx)
1644 {
1645  /* Create basic mapped object. */
1646  ctx->mapped_object = afw_model_internal_create_basic_to_adaptor_mapped_object(ctx, xctx);
1647 }
1648 
1649 
1650 
1651 /*
1652  * Implementation of method replace_object for interface afw_adaptor_session.
1653  */
1654 void
1656  const afw_adaptor_session_t *instance,
1657  const afw_adaptor_impl_request_t *impl_request,
1658  const afw_utf8_t *object_type_id,
1659  const afw_utf8_t *object_id,
1660  const afw_object_t *replacement_object,
1661  const afw_object_t *adaptor_type_specific,
1662  afw_xctx_t *xctx)
1663 {
1667  const afw_object_t *journal_entry;
1668  const afw_value_t *value;
1669  int top;
1670  afw_boolean_t use_default_processing;
1671 
1672  /* _AdaptiveObjectType_ objects are immutable in model adaptor. */
1673  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1674  AFW_OBJECT_ERROR_OBJECT_IMMUTABLE;
1675  }
1676 
1677  /* Save top for qualifier stack. */
1679  AFW_TRY {
1680 
1681  /* Prime context for "to adaptor". */
1682  ctx = afw_model_internal_create_to_adaptor_skeleton_context(
1683  self,
1684  &self->adaptor->instance_skeleton__AdaptiveModelCurrentOnReplaceObject_,
1685  self->model,
1686  impl_request,
1687  object_type_id,
1688  object_id,
1689  xctx);
1690  ctx->object = replacement_object;
1691 
1692  /* If onReplaceObject, evaluate it. */
1693  use_default_processing = true;
1694  if (ctx->model_object_type->onReplaceObject) {
1695  use_default_processing = false;
1696  value = afw_value_evaluate(ctx->model_object_type->onReplaceObject,
1697  ctx->p, xctx);
1698  if (value == ctx->useDefaultProcessing_value) {
1699  use_default_processing = true;
1700  }
1701  }
1702 
1703  /* If no onReplaceObject or it returned undefined, do default processing. */
1704  if (use_default_processing) {
1705  journal_entry = afw_object_create_managed(ctx->p, xctx);
1706  afw_model_internal_complete_ctx_default_replace_object(ctx, xctx);
1708  self->adaptor->mapped_adaptor_id,
1709  ctx->mapped_object_type_id,
1710  ctx->mapped_object_id,
1711  ctx->mapped_object,
1712  journal_entry, adaptor_type_specific,
1713  xctx);
1714  }
1715 
1717  }
1718 
1719  /* Always restore top for qualifier stack to entry value. */
1720  AFW_FINALLY{
1722  }
1723 
1724  AFW_ENDTRY;
1725 }
1726 
1727 
1728 
1729 AFW_DEFINE_INTERNAL(void)
1730 afw_model_internal_complete_ctx_default_delete_object(
1732  afw_xctx_t *xctx)
1733 {
1734  /* Nothing currently to do. */
1735 }
1736 
1737 
1738 
1739 /*
1740  * Implementation of method delete_object for interface afw_adaptor_session.
1741  */
1742 void
1744  const afw_adaptor_session_t *instance,
1745  const afw_adaptor_impl_request_t *impl_request,
1746  const afw_utf8_t *object_type_id,
1747  const afw_utf8_t *object_id,
1748  const afw_object_t *adaptor_type_specific,
1749  afw_xctx_t *xctx)
1750 {
1754  const afw_object_t *journal_entry;
1755  const afw_value_t *value;
1756  int top;
1757  afw_boolean_t use_default_processing;
1758 
1759  /* _AdaptiveObjectType_ objects are immutable in model adaptor. */
1760  if (afw_utf8_equal(object_type_id, &afw_s__AdaptiveObjectType_)) {
1761  AFW_OBJECT_ERROR_OBJECT_IMMUTABLE;
1762  }
1763 
1764  /* Save top for qualifier stack. */
1766  AFW_TRY {
1767 
1768  /* Prime context for "to adaptor". */
1769  ctx = afw_model_internal_create_to_adaptor_skeleton_context(
1770  self,
1771  &self->adaptor->instance_skeleton__AdaptiveModelCurrentOnDeleteObject_,
1772  self->model,
1773  impl_request,
1774  object_type_id,
1775  object_id,
1776  xctx);
1777 
1778  /* If onDeleteObject, evaluate it. */
1779  use_default_processing = true;
1780  if (ctx->model_object_type->onDeleteObject) {
1781  use_default_processing = false;
1782  value = afw_value_evaluate(ctx->model_object_type->onDeleteObject,
1783  ctx->p, xctx);
1784  if (value == ctx->useDefaultProcessing_value) {
1785  use_default_processing = true;
1786  }
1787  }
1788 
1789  /* If no onDeleteObjector or it returned undefined, do default processing. */
1790  if (use_default_processing) {
1791  journal_entry = afw_object_create(ctx->p, xctx);
1792  afw_model_internal_complete_ctx_default_delete_object(ctx, xctx);
1793  afw_adaptor_delete_object(self->adaptor->mapped_adaptor_id,
1794  ctx->mapped_object_type_id, ctx->mapped_object_id,
1795  journal_entry, /*FIXME */ NULL, xctx);
1796  }
1797  }
1798 
1799  /* Always restore top for qualifier stack to entry value. */
1800  AFW_FINALLY{
1802  }
1803 
1804  AFW_ENDTRY;
1805 }
1806 
1807 
1808 
1809 /*
1810  * Implementation of method begin_transaction of interface afw_adaptor_session.
1811  */
1814  const afw_adaptor_session_t * instance,
1815  afw_xctx_t *xctx)
1816 {
1818  (afw_model_internal_adaptor_self_t *)instance->adaptor;
1819 
1820  /* Get cached session with begin_transaction. Ignore result. */
1821  afw_adaptor_session_get_cached(adaptor->mapped_adaptor_id,
1822  true, xctx);
1823 
1824  /* Return NULL since cached mapped adaptor session handle cleanup. */
1825  return NULL;
1826 }
1827 
1828 
1829 
1830 /*
1831  * Implementation of method get_journal_interface of interface afw_adaptor_session.
1832  */
1833 const afw_adaptor_journal_t *
1834 impl_afw_adaptor_session_get_journal_interface (
1835  const afw_adaptor_session_t * instance,
1836  afw_xctx_t *xctx)
1837 {
1838  /* There is no journal interface for model adaptor. */
1839  return NULL;
1840 }
1841 
1842 
1843 
1844 /*
1845  * Implementation of method get_key_value_interface of interface afw_adaptor_session.
1846  */
1849  const afw_adaptor_session_t * instance,
1850  afw_xctx_t *xctx)
1851 {
1852  /* There is no key_value interface for model adaptor. */
1853  return NULL;
1854 }
1855 
1856 
1857 
1858 /*
1859  * Implementation of method get_index_interface of interface afw_adaptor_session.
1860  */
1863  const afw_adaptor_session_t * instance,
1864  afw_xctx_t *xctx)
1865 {
1866  /* There is no index interface for model adaptor. */
1867  return NULL;
1868 }
1869 
1870 
1871 
1872 /*
1873  * Implementation of method get_object_type_cache_interface for interface
1874  * afw_adaptor_session.
1875  */
1877 impl_afw_adaptor_session_get_object_type_cache_interface(
1878  const afw_adaptor_session_t * instance,
1879  afw_xctx_t *xctx)
1880 {
1883 
1885  &self->object_type_cache,
1886  &impl_afw_adaptor_object_type_cache_inf,
1887  instance, true, xctx);
1888 
1889  return &self->object_type_cache;
1890 }
1891 
1892 
1893 
1894 /*
1895  * Implementation of method get for interface afw_adaptor_object_type_cache.
1896  */
1897 const afw_object_type_t *
1898 impl_afw_adaptor_object_type_cache_get(
1899  const afw_adaptor_object_type_cache_t * instance,
1900  const afw_utf8_t * object_type_id,
1901  afw_boolean_t * final_result,
1902  afw_xctx_t *xctx)
1903 {
1905  (afw_model_internal_adaptor_session_self_t *)instance->session;
1906  const afw_object_type_t *result;
1907  afw_model_t *model = (afw_model_t *)session->model;
1908 
1909  *final_result = false;
1910 
1911  if (!model->object_types_ht) {
1912  return NULL;
1913  }
1914 
1915  AFW_ADAPTOR_IMPL_LOCK_READ_BEGIN(session->model_location_adaptor)
1916  {
1917  result = apr_hash_get(model->object_types_ht,
1918  object_type_id->s, object_type_id->len);
1919  }
1921 
1922  return result;
1923 }
1924 
1925 
1926 
1927 /*
1928  * Implementation of method set for interface afw_adaptor_object_type_cache.
1929  */
1930 void
1931 impl_afw_adaptor_object_type_cache_set(
1932  const afw_adaptor_object_type_cache_t * instance,
1933  const afw_object_type_t * object_type,
1934  afw_xctx_t *xctx)
1935 {
1937  (afw_model_internal_adaptor_session_self_t *)instance->session;
1938  afw_model_t *model = (afw_model_t *)session->model;
1939 
1940  AFW_ADAPTOR_IMPL_LOCK_WRITE_BEGIN(session->model_location_adaptor)
1941  {
1942 
1943  if (!model->object_types_ht) {
1944  model->object_types_ht = apr_hash_make(
1945  afw_pool_get_apr_pool(session->adaptor->pub.p));
1946  }
1947 
1948  apr_hash_set(model->object_types_ht,
1949  object_type->object_type_id->s,
1950  object_type->object_type_id->len,
1951  object_type);
1952  }
1954 }
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
AFW_DEFINE(const afw_object_t *)
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
#define AFW_DEFINE_CONST_DATA(type)
Define a public afw variable.
Adaptive Framework Core Internal.
const afw_query_criteria_filter_entry_t * impl_get_converted_entry(impl_convert_entry_wa_t *wa, const afw_query_criteria_filter_entry_t *old_entry)
const afw_value_t * impl_execute_mapBackObject_thunk(const afw_value_function_thunk_t *thunk, afw_size_t argc, const afw_value_t *const *argv, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_value_t * impl_execute_returnObject_thunk(const afw_value_function_thunk_t *thunk, afw_size_t argc, const afw_value_t *const *argv, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_object_t * impl_afw_adaptor_get_additional_metrics(const afw_adaptor_t *instance, const afw_pool_t *p, afw_xctx_t *xctx)
void impl_afw_adaptor_destroy(const afw_adaptor_t *instance, afw_xctx_t *xctx)
const afw_adaptor_session_t * impl_afw_adaptor_create_adaptor_session(const afw_adaptor_t *instance, afw_xctx_t *xctx)
afw_adaptor_impl_throw_property_invalid(const afw_adaptor_t *adaptor, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Developers should call this for configuration property errors.
afw_adaptor_impl_throw_property_required(const afw_adaptor_t *adaptor, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Developers should call this for missing required configuration property.
#define AFW_ADAPTOR_IMPL_LOCK_WRITE_END
Macro to end an adaptor write lock section.
afw_adaptor_impl_object_type_cache_initialize(afw_adaptor_object_type_cache_t *object_type_cache, const afw_adaptor_object_type_cache_inf_t *inf, const afw_adaptor_session_t *session, afw_boolean_t all_object_types_immutable, afw_xctx_t *xctx)
Initialize object type cache instance.
#define AFW_ADAPTOR_IMPL_LOCK_READ_END
Macro to end an adaptor read lock section.
afw_adaptor_impl_create_cede_p(const afw_adaptor_inf_t *inf, afw_size_t instance_size, const afw_object_t *properties, const afw_pool_t *p, afw_xctx_t *xctx)
Developers should call this in all create functions for afw_adaptor.
#define AFW_ADAPTOR_IMPL_LOCK_READ_BEGIN(adaptor)
Macro to begin an adaptor read lock section.
#define AFW_ADAPTOR_IMPL_LOCK_WRITE_BEGIN(adaptor)
Macro to begin an adaptor write lock section.
void impl_afw_adaptor_session_modify_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_adaptor_modify_entry_t *const *entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_replace_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *replacement_object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_delete_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_retrieve_objects(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_query_criteria_t *criteria, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_transaction_t * impl_afw_adaptor_session_begin_transaction(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
void impl_afw_adaptor_session_destroy(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_adaptor_impl_index_t * impl_afw_adaptor_session_get_index_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_utf8_t * impl_afw_adaptor_session_add_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *suggested_object_id, const afw_object_t *object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_get_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_key_value_t * impl_afw_adaptor_session_get_key_value_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
afw_adaptor_modify_entry_type_value(afw_adaptor_modify_entry_type_t type)
Convert entry type enum to value.
afw_adaptor_retrieve_objects(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_object_options_t *options, const afw_query_criteria_t *criteria, const afw_object_t *journal_entry, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
Retrieve objects.
afw_adaptor_replace_object(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *replacement_object, const afw_object_t *journal_entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
Replace object and remove from cache.
afw_adaptor_add_object(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *suggested_object_id, const afw_object_t *object, const afw_object_t *journal_entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
Call adaptor to add object and remove from cache.
afw_adaptor_release(const afw_adaptor_t *instance, afw_xctx_t *xctx)
Release an adaptor accessed by afw_adaptor_get_reference().
Definition: afw_adaptor.c:221
afw_adaptor_session_get_cached(const afw_utf8_t *adaptor_id, afw_boolean_t begin_transaction, afw_xctx_t *xctx)
Get/create an active cached session for adaptor_id.
Definition: afw_adaptor.c:375
afw_adaptor_modify_object(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_list_t *entries, const afw_object_t *journal_entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
Modify object and remove from cache.
afw_adaptor_get_reference(const afw_utf8_t *adaptor_id, afw_xctx_t *xctx)
Get an adaptor and make sure it is started.
Definition: afw_adaptor.c:143
afw_adaptor_get_object(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_options_t *options, const afw_query_criteria_t *criteria, const afw_object_t *journal_entry, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
Get and cache object.
afw_adaptor_delete_object(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *journal_entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
Delete object from cache and via adaptor.
afw_adaptor_modify_entries_to_list(const afw_adaptor_modify_entry_t *const *entries, const afw_pool_t *p, afw_xctx_t *xctx)
Create a list from modify entries in specified pool.
#define afw_value_is_boolean(A_VALUE)
Macro to determine if value is evaluated boolean.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
#define afw_value_is_list(A_VALUE)
Macro to determine if value is evaluated list.
afw_data_type_list
Data type struct for list.
#define afw_value_is_object(A_VALUE)
Macro to determine if value is evaluated object.
afw_value_create_object(const afw_object_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type object value.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
afw_boolean_t(* afw_object_cb_t)(const afw_object_t *object, void *context, afw_xctx_t *xctx)
Typedef for afw_adaptor_session_object callback.
Definition: afw_common.h:1176
#define AFW_UTF8_LITERAL(A_STRING)
String literal initializer.
Definition: afw_common.h:582
#define AFW_UTF8_CONTEXTUAL_LABEL_FMT
Format string used for source location.
Definition: afw_common.h:595
struct afw_iterator_s afw_iterator_t
#define AFW_UTF8_FMT_OPTIONAL_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify optional arg.
Definition: afw_common.h:616
_Bool afw_boolean_t
Definition: afw_common.h:373
struct afw_model_internal_s afw_model_t
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
const afw_value_function_definition_t * afw_environment_get_function(const afw_utf8_t *function_id, afw_xctx_t *xctx)
Get the function instance associated with function id.
const afw_object_inf_t * afw_environment_get_runtime_object_map_inf(const afw_utf8_t *object_type_id, afw_xctx_t *xctx)
Get the interface associated with a runtime object map.
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#define AFW_ERROR_THROWN
Access the thrown error. See AFW_TRY.
Definition: afw_error.h:554
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define afw_list_create_generic(p, xctx)
Create an value list in memory.
Definition: afw_list.h:81
afw_list_add_value(const afw_list_t *instance, const afw_value_t *value, afw_xctx_t *xctx)
Call method add_value of interface afw_list_setter.
Definition: afw_list.c:104
const afw_list_t * afw_list_create_with_options(int options, const afw_data_type_t *data_type, const afw_pool_t *p, afw_xctx_t *xctx)
Create an list in memory with options.
#define AFW_LOG_FZ(priority, xctx, format_z,...)
Log an message to environment's log using a printf style format and parameters.
Definition: afw_log.h:192
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
afw_model_internal_create_basic_to_adaptor_mapped_object(afw_model_internal_context_t *ctx, afw_xctx_t *xctx)
afw_model_internal_complete_ctx_default_modify_object(afw_model_internal_context_t *ctx, afw_xctx_t *xctx)
afw_model_internal_convert_query_criteria(const afw_model_object_type_t *model_object_type, const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Convert query criteria based on model.
afw_model_adaptor_create_cede_p(const afw_object_t *properties, const afw_pool_t *p, afw_xctx_t *xctx)
Create a model adaptor.
afw_adaptor_factory_model
Definition: afw_model.h:33
afw_model_get_object_type(const afw_model_t *model, const afw_utf8_t *object_type_id, afw_xctx_t *xctx)
Get the model object type for an object type id from model.
Definition: afw_model.c:21
enum afw_model_adapt_e afw_model_adapt_t
Typedef for model adapt type enum.
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
#define afw_object_has_property(instance, property_name, xctx)
Call method has_property of interface afw_object.
#define afw_object_meta_add_error_fz(instance, xctx, format_z,...)
Add a formatted error message to instance's meta.
afw_object_meta_set_parent_paths(const afw_object_t *instance, const afw_value_list_t *parent_paths, afw_xctx_t *xctx)
Set meta parentPaths property.
#define afw_object_meta_add_property_error_fz(instance, property_name, xctx, format_z,...)
Add a formatted error message for a property to instance's meta.
afw_object_meta_get_parent_paths_value(const afw_object_t *instance, afw_xctx_t *xctx)
Get meta parentPaths property value.
afw_object_meta_add_thrown_property_error(const afw_object_t *instance, const afw_utf8_t *property_name, afw_integer_t index, const afw_error_t *error, afw_xctx_t *xctx)
Add a thrown error for a property to instance's meta.
afw_object_meta_set_ids(const afw_object_t *instance, const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, afw_xctx_t *xctx)
Set object's ids.
afw_object_meta_get_object_id(const afw_object_t *instance, afw_xctx_t *xctx)
Get entity object's object id.
afw_object_old_get_property_as_utf8(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_pool_t *p, afw_xctx_t *xctx)
Get an object's property value as a string in specified pool.
Definition: afw_object.c:531
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
Definition: afw_object.h:913
#define afw_object_create(p, xctx)
Create an empty unmanaged object in memory.
Definition: afw_object.h:948
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
Definition: afw_object.c:46
#define afw_object_create_and_cede_p(p, xctx)
Create an empty entity object in memory in specified pool and cede control of the pool to the object.
Definition: afw_object.h:898
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
afw_query_criteria_test_object(const afw_object_t *obj, const afw_query_criteria_t *criteria, const afw_pool_t *p, afw_xctx_t *xctx)
Test object against query criteria.
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_value_one_and_only(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Return value from one entry list or single value.
Definition: afw_value.c:407
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
afw_value_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:456
afw_value_false
Adaptive value false.
Definition: afw_value.h:354
#define afw_value_is_nullish(A_VALUE)
Determine if value is undefined or null.
Definition: afw_value.h:422
afw_value_convert(const afw_value_t *value, const afw_data_type_t *to_data_type, afw_boolean_t required, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a value to a value/data type.
Definition: afw_value.c:584
#define afw_value_function_thunk_create(name, like_function_value, execute, ctx, p, xctx)
Create a function thunk value.
Definition: afw_value.h:1338
afw_value_true
Adaptive value true.
Definition: afw_value.h:348
afw_xctx_get_qualifier_stack_top(afw_xctx_t *xctx)
Get qualifier stack top.
Definition: afw_xctx.c:316
afw_xctx_set_qualifier_stack_top(int top, afw_xctx_t *xctx)
Set stack top index.
Definition: afw_xctx.c:325
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Definition: afw_xctx.h:199
Interface afw_adaptor_factory public struct.
Interface afw_adaptor_impl_index public struct.
Internal request info used by afw_adaptor_impl*() functions.
const afw_object_options_t * options
Object options.
const afw_model_location_t * model_location
Model location struct if this adaptor is a model location.
const afw_utf8_t * source_location
Source location associated with this adaptor.
Interface afw_adaptor_journal public struct.
Interface afw_adaptor_key_value public struct.
Adaptor modify entry.
Interface afw_adaptor_object_type_cache public struct.
Interface afw_adaptor public struct.
Interface afw_adaptor_session public struct.
Interface afw_adaptor_transaction public struct.
Function execute parameter.
Definition: afw_function.h:53
const afw_value_t *const * argv
This is the function parameters.
Definition: afw_function.h:86
afw_xctx_t * xctx
The execution context (xctx) of caller.
Definition: afw_function.h:62
const afw_value_function_definition_t * function
The evaluated function definition.
Definition: afw_function.h:71
const afw_pool_t * p
Pool for result.
Definition: afw_function.h:59
afw_size_t argc
This is the argv count not counting argv[0].
Definition: afw_function.h:89
Interface afw_list public struct.
Internal struct used by afw_model* functions.
const afw_list_t * mapped_entries
Mapped entries for modify.
const afw_value_t * modify_entries_value
Original entries for modify as list value.
const afw_adaptor_modify_entry_t *const * modify_entries
Original entries for modify.
Struct for afw_model_object_type_t property_type_other member.
const afw_utf8_t * object_type_id
Object type id.
const afw_model_property_type_t ** property_type
NULL terminated list of property types for this object type.
const afw_value_t * mapped_object_type_id_value
mappedObjectType value.
const afw_object_t * object_type_object
Property type object.
const afw_value_t * onReplaceObject
onReplaceObject or NULL.
const afw_value_t * onGetInitialObjectId
onGetInitialObjectId or NULL.
const afw_value_t * onDeleteObject
onDeleteObject or NULL.
const afw_value_t * onAddObject
onAddObject or NULL.
const afw_value_t * onModifyObject
onModifyObject or NULL.
const afw_model_property_type_t * property_type_other
Property type for other properties.
const afw_value_t * onSetProperty
onSetProperty value or NULL if value from object used asis.
const afw_value_t * onGetInitialValue
initial value or NULL if value from object used asis.
const afw_data_type_t * data_type
Data type or NULL if not restricted.
const afw_utf8_t * mapped_property_name
Mapped property name.
const afw_value_t * mapped_property_name_value
Mapped property name as adaptive value.
const afw_utf8_t * id
Object id or property name.
Definition: afw_common.h:782
const afw_utf8_t * object_uri
Object path or NULL.
Definition: afw_common.h:811
const afw_utf8_t * object_type_uri
Object type object URI or NULL.
Definition: afw_common.h:796
Property name path struct.
Interface afw_object public struct.
Struct for afw_object_type_t.
Interface afw_pool public struct.
Parsed filter entry from query string.
Parsed query criteria.
Struct for runtime objects.
Definition: afw_runtime.h:174
const afw_utf8_t * object_type_id
Object Type Id.
Definition: afw_runtime.h:61
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type boolean values.
Struct for function thunk value.
void * ctx
ctx passed on create.
const afw_utf8_t * name
name.
struct for data type list values.
struct for data type object values.
Interface afw_value public struct.
struct for data type string values.
Interface afw_xctx public struct.