Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_object_view.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Object View
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
15 /* __AFW_OBJECT_VIEW_DEBUG__ causes debug log messages to be produced. */
16 // #define __AFW_OBJECT_VIEW_DEBUG__
17 
18 #include "afw_internal.h"
19 
20 
21 
22 #define impl_afw_object_get_meta \
23  afw_object_impl_internal_get_meta
24 
25 #define impl_afw_object_get_property_meta \
26  afw_object_impl_internal_get_property_meta
27 
28 #define impl_afw_object_get_next_property_meta \
29  afw_object_impl_internal_get_next_property_meta
30 
31 /* Object view object implementation. */
32 #define AFW_IMPLEMENTATION_ID "afw_object_view"
34 
35 /*--- Macros. ---*/
36 
37 
38 /* Set meta.properties property. */
39 #define impl_meta_property_type_get(self, property_name, xctx) \
40 afw_object_meta_get_property_type( \
41  ((const afw_object_t *)self), \
42  property_name, xctx)
43 
44 /*--- Static declares. ---*/
45 
46 static const afw_value_t *
47 impl_shared_string_value(
49  const afw_utf8_t *string,
50  afw_xctx_t *xctx);
51 
52 
53 static const afw_value_t *
54 impl_shared_path_value(
56  const afw_utf8_t *path,
57  afw_xctx_t *xctx);
58 
59 
60 static void
61 impl_set_property(
63  const afw_object_t *origin,
64  const afw_utf8_t *original_name,
65  const afw_value_t *original_value,
66  afw_xctx_t *xctx);
67 
68 
70 impl_get_property(
72  const afw_utf8_t *property_name);
73 
74 
75 /* Add requested meta properties. */
76 static void
77 impl_additional_object_option_processing(
79  afw_xctx_t *xctx);
80 
81 
82 static void
83 impl_add_origin_properties(
85  afw_xctx_t *xctx);
86 
87 
88 static void
89 impl_merge_properties(
92  afw_xctx_t *xctx);
93 
94 
95 static void
96 impl_resolve_parents(
98  afw_xctx_t *xctx);
99 
100 
101 static void
102 impl_add_inherited_properties(
104  afw_xctx_t *xctx);
105 
106 
108 impl_get_object_by_uri(
109  const afw_utf8_t *uri,
111  afw_xctx_t *xctx);
112 
113 
115 impl_object_create_entity(
117  const afw_object_t *origin,
118  const afw_uri_parsed_t *uri_parsed,
119  afw_xctx_t *xctx);
120 
121 
123 impl_object_create(
125  afw_object_view_internal_object_self_t *embedding_object,
126  const afw_utf8_t *property_name,
127  const afw_object_t *origin,
128  const afw_uri_parsed_t *uri_parsed,
129  afw_xctx_t *xctx);
130 
131 
132 /*--- impl function defines. ---*/
133 
134 
135 static void
136 impl_meta_set_property(
138  const afw_utf8_t *property_name,
139  const afw_value_t *value,
140  afw_xctx_t *xctx)
141 {
143  ((const afw_object_t *)self),
144  property_name, value, xctx);
145 }
146 
147 static void
148 impl_meta_set_property_type_property(
150  const afw_utf8_t *property_type_id,
151  const afw_utf8_t *property_name,
152  const afw_value_t *value,
153  afw_xctx_t *xctx)
154 {
156  ((const afw_object_t *)self),
157  property_type_id, property_name, value, xctx);
158 }
159 
160 
161 static const afw_value_t *
162 impl_shared_string_value(
164  const afw_utf8_t *string,
165  afw_xctx_t *xctx)
166 {
167  afw_value_string_t *value;
168 
169  if (!view->string_values) {
170  view->string_values = apr_hash_make(afw_pool_get_apr_pool(view->p));
171  }
172 
173  value = apr_hash_get(view->string_values, string->s, string->len);
174  if (!value) {
175  value = afw_value_allocate_string(view->p, xctx);
176  value->internal.s = string->s;
177  value->internal.len = string->len;
178  apr_hash_set(view->string_values,
179  value->internal.s, value->internal.len, value);
180  }
181 
182  return (const afw_value_t *)value;
183 }
184 
185 
186 static const afw_value_t *
187 impl_shared_path_value(
189  const afw_utf8_t *path,
190  afw_xctx_t *xctx)
191 {
192  afw_object_view_internal_view_t *view = self->view;
193  const afw_pool_t *p = view->p;
194  afw_value_anyURI_t *value;
195  const afw_utf8_octet_t *c;
196  afw_size_t len;
197  const afw_uri_parsed_t *parsed;
198  const afw_utf8_t *current_path;
199 
200  if (!view->path_values) {
201  view->path_values = apr_hash_make(afw_pool_get_apr_pool(p));
202  }
203 
204  value = apr_hash_get(view->path_values, path->s, path->len);
205  if (!value) {
206  for (c = path->s, len = path->len; len > 0; c++, len--) {
207  if (*c == '*') {
208  current_path = afw_object_meta_get_path(
209  (const afw_object_t *)self, xctx);
210  parsed = afw_uri_parse(path, true, current_path,
211  p, xctx);
212  value = apr_hash_get(view->path_values,
213  parsed->normalized_uri.s, parsed->normalized_uri.len);
214  if (!value) {
215  value = afw_value_allocate_anyURI(p, xctx);
216  value->internal.s = parsed->normalized_uri.s;
217  value->internal.len = parsed->normalized_uri.len;
218  apr_hash_set(view->path_values,
219  value->internal.s, value->internal.len, value);
220  }
221  apr_hash_set(view->path_values,
222  path->s, path->len, value);
223  break;
224  }
225  }
226  }
227 
228  if (!value) {
229  value = afw_value_allocate_anyURI(p, xctx);
230  value->internal.s = path->s;
231  value->internal.len = path->len;
232  apr_hash_set(view->path_values,
233  path->s, path->len, value);
234  }
235 
236  return (const afw_value_t *)value;
237 }
238 
239 
240 static const afw_value_t *
241 impl_make_value(
243  const afw_object_t *origin,
244  const afw_utf8_t *property_name,
245  const afw_value_t *original_value,
246  afw_xctx_t *xctx)
247 {
248  const afw_value_t *result;
249  const afw_value_t *original_entry_value;
250  const afw_value_t *value;
252  const afw_pool_t *p;
253  const afw_list_t *list;
254  const afw_data_type_t *data_type;
255  const afw_iterator_t *iterator;
257 
258  view = self->view;
259  p = view->p;
260 
261  /* Default result will be original value. */
262  result = original_value;
263 
264  /* If single object, create copy. */
265  if (afw_value_is_object(original_value)) {
266  embedded_object = impl_object_create(
267  view, self, property_name,
268  ((const afw_value_object_t *)original_value)->internal,
269  NULL, xctx);
270  result = afw_value_create_object(
271  (const afw_object_t *)embedded_object, p, xctx);
272  }
273 
274  /* If single list, make new list with entries using impl_make_value(). */
275  else if (afw_value_is_list(original_value)) {
276  data_type = afw_list_get_data_type(
277  ((const afw_value_list_t *)original_value)->internal,
278  xctx);
279  list = afw_list_of_create(data_type, p, xctx);
280  for (iterator = NULL;;) {
281  original_entry_value = afw_list_get_next_value(
282  ((afw_value_list_t *)original_value)->internal,
283  &iterator, p, xctx);
284  if (!original_entry_value) {
285  break;
286  }
287  value = impl_make_value(self, origin, property_name,
288  original_entry_value, xctx);
289  afw_list_add_value(list, value, xctx);
290  }
291  result = afw_value_create_list(list, p, xctx);
292  }
293 
294  /* Return result. */
295  return result;
296 }
297 
298 
300 impl_get_property(
302  const afw_utf8_t *property_name)
303 {
305 
306  for (prop = self->first_property;
307  prop && !afw_utf8_equal(prop->name, property_name);
308  prop = prop->next_property);
309 
310  return prop;
311 }
312 
313 
314 
315 static void
316 impl_set_property(
318  const afw_object_t *origin,
319  const afw_utf8_t *property_name,
320  const afw_value_t *original_value,
321  afw_xctx_t *xctx)
322 {
324  const afw_pool_t *p;
326 
327  view = self->view;
328  p = view->p;
329 
331  prop->origin = origin;
332  prop->name = property_name;
333  prop->value = impl_make_value(self, origin,
334  prop->name, original_value, xctx);
335  prop->next_property = self->first_property;
336  self->first_property = prop;
337 }
338 
339 
340 
341 /* Update property value. */
342 static void
343 impl_update_property_value(
345  const afw_utf8_t *property_name,
346  const afw_value_t *value,
347  afw_xctx_t *xctx)
348 {
350 
351  prop = impl_get_property(self, property_name);
352  if (!prop) {
353  AFW_THROW_ERROR_Z(general,
354  "Internal error - impl_update_property_value()",
355  xctx);
356  }
357 
358  prop->value = value;
359 }
360 
361 
362 
363 static const afw_value_t *
364 impl_normalize_value(
367  const afw_utf8_t *property_name,
368  const afw_value_t *value,
369  afw_xctx_t *xctx)
370 {
371  afw_object_view_internal_view_t *view = self->view;
372  const afw_pool_t *p = view->p;
373  const afw_value_t *result = NULL;
374 
375  AFW_TRY {
377  pt, value, p, xctx);
378  }
379 
382  (const afw_object_t *)self,
383  property_name, -1, AFW_ERROR_THROWN, xctx);
384  }
385 
386  AFW_ENDTRY;
387 
388  return result;
389 }
390 
391 
392 
393 /* Add objectTypeMetaDelta/objectTypeMetaFull */
394 static void
395 impl_object_type_related_object_option_processing(
397  afw_xctx_t *xctx)
398 {
399  afw_object_view_internal_view_t *view = self->view;
400  const afw_object_t *instance = (const afw_object_t *)self;
401  const afw_object_options_t *options = view->options;
402 
403  const afw_utf8_t *object_type_id;
404  const afw_object_type_t *object_type;
405  const afw_iterator_t *iterator;
406  const afw_value_t *value;
407  const afw_utf8_t *property_name;
408  const afw_utf8_t *s;
409  const afw_value_t *s_value;
410  const afw_value_t *new_value;
411  const afw_object_t *object;
413  afw_boolean_t check_required;
414  afw_boolean_t include_defaults;
415  const afw_data_type_t *value_data_type;
416 
417  /* Convenience */
418  check_required = AFW_OBJECT_OPTION_IS(options, checkRequired);
419  include_defaults = AFW_OBJECT_OPTION_IS(options, includeDefaultValues);
420 
421  /* Get object type id. Default is _AdaptiveObject_. */
422  object_type_id = afw_object_meta_get_object_type_id(instance, xctx);
423  if (!object_type_id) {
424  object_type_id = &afw_s__AdaptiveObject_;
425  }
426 
427  /* Get object type object. */
428  object_type = afw_adaptor_get_object_type(view->adaptor_id,
429  object_type_id, view->journal_entry, xctx);
430  if (!object_type) {
431  afw_object_meta_add_error_fz(instance, xctx,
432  "objectType %" AFW_UTF8_FMT
433  " needed for normalize object option is not found",
434  AFW_UTF8_FMT_ARG(object_type_id));
435  return;
436  }
437  if (AFW_OBJECT_OPTION_IS(options, metaFull)) {
438  afw_object_meta_set_object_type(instance, object_type, xctx);
439  }
440 
441  /* If requested, check required and include default values. */
442  if (check_required || include_defaults) {
443  for (iterator = NULL;;) {
445  object_type, &iterator, &property_name, xctx);
446  if (!pt) break;
447 
448  value = afw_object_get_property(instance, property_name, xctx);
449  if (value) {
450  value_data_type = afw_value_get_data_type(value, xctx);
451 
453  if (afw_utf8_equal(&value_data_type->cType,
454  &afw_s_afw_utf8_t))
455  {
456  if (((afw_value_string_t *)value)
457  ->internal.len == 0)
458  {
459  value = NULL;
460  }
461  }
462  else if (afw_utf8_equal(&value_data_type->cType,
463  &afw_s_afw_memory_t))
464  {
465  if (((afw_value_base64Binary_t *)value)
466  ->internal.size == 0)
467  {
468  value = NULL;
469  }
470  }
471  }
472  if (!value)
473  {
474  if (include_defaults) {
475  value = pt->default_value;
476  if (value) {
477  impl_set_property(self, pt->property_type_object,
478  property_name, value, xctx);
479  }
480  }
481  if (!value && check_required && pt->required) {
483  property_name, "value required", xctx);
484  }
485  }
486  }
487  }
488 
491  /* Normalize values. */
492  for (iterator = NULL;;) {
493  value = afw_object_get_next_property(instance,
494  &iterator, &property_name, xctx);
495  if (!value) break;
496 
497  /* Get property type. */
498  pt = afw_object_type_property_type_get(object_type,
499  property_name, xctx);
500  if (!pt) {
501  afw_object_meta_add_property_error_z(instance, property_name,
502  "no property type", xctx);
503  continue;
504  }
505 
506  /* If property value needed normalization, update it in instance. */
507  new_value = impl_normalize_value(self, pt,
508  property_name, value, xctx);
509  if (new_value != value) {
510  impl_update_property_value(self, property_name, new_value, xctx);
511  }
512  }
513 
514 
515  /*
516  * If objectTypes is true, add it to the objectTypes object of the
517  * entity's meta.
518  */
519  if (AFW_OBJECT_OPTION_IS(options, objectTypes))
520  {
522  object_type->object_type_object,
523  xctx);
524  }
525 
526  /*
527  * Fix up dataType, and if object, objectType in propertyTypes based on
528  * actual property values in self.
529  */
530  for (iterator = NULL;;) {
531  value = afw_object_get_next_property(instance,
532  &iterator, &property_name, xctx);
533  if (!value) break;
534 
535  AFW_TRY {
536 
537  value_data_type = afw_value_get_data_type(value, xctx);
538 
539  /* Get property type from object type object. May be NULL. */
540  pt = afw_object_type_property_type_get(object_type,
541  property_name, xctx);
542 
543  /* Set dataType if different. */
544  if (value_data_type && (!pt || value_data_type != pt->data_type))
545  {
546  s_value = impl_shared_string_value(view,
547  &value_data_type->data_type_id, xctx);
549  property_name, &afw_s_dataType, s_value, xctx);
550  }
551 
552  /* If object, set dataTypeParameter if different */
553  if (afw_value_is_object(value)) {
554  object =
555  ((const afw_value_object_t *)value)->internal;
556  object_type_id = afw_object_meta_get_object_type_id(object,
557  xctx);
558  if (object_type_id)
559  {
560  s = NULL;
561  if (pt) {
563  pt->property_type_object,
564  &afw_s_dataTypeParameter,
565  xctx);
566  }
567  if (s && !afw_utf8_equal(s, object_type_id)) {
568  s_value = impl_shared_string_value(view,
569  object_type_id, xctx);
571  property_name, &afw_s_dataTypeParameter, s_value, xctx);
572  }
573  }
574  }
575  }
576 
579  property_name, -1, AFW_ERROR_THROWN, xctx);
580  }
581 
582  AFW_ENDTRY;
583 
584  }
585 }
586 
587 
588 /* Add requested meta properties. */
589 static void
590 impl_additional_object_option_processing(
592  afw_xctx_t *xctx)
593 {
594  afw_object_view_internal_view_t *view = self->view;
595  const afw_object_options_t *options = view->options;
596  const afw_pool_t *p = view->p;
597 
598  const afw_value_t *v;
599  const afw_utf8_t *path;
601  const afw_value_list_t *parent_paths;
602  afw_value_list_t *resolved_parent_paths;
603  const afw_iterator_t *iterator;
604 
605  /*NOTE
606  *
607  * objectId, objectType, path, and pathEmbedded are honored even though
608  * content types will provide them if they are passed options. There were
609  * situations where content types do not have the options available, or in
610  * the case of perform, where there may be multiple actions with different
611  * options.
612  */
613 
614  /* normalize related options */
615  if (AFW_OBJECT_OPTION_IS(options, normalize)) {
616  impl_object_type_related_object_option_processing(self, xctx);
617  }
618 
619  /* objectId */
620  if (AFW_OBJECT_OPTION_IS(options, objectId) &&
621  !self->pub.meta.embedding_object)
622  {
623  if (self->pub.meta.id) {
624  v = impl_shared_string_value(self->view, self->pub.meta.id, xctx);
625  impl_meta_set_property(self, &AFW_OBJECT_S_PN_OBJECT_ID, v,
626  xctx);
627  }
628  }
629 
630  /* objectType */
631  if (AFW_OBJECT_OPTION_IS(options, objectType))
632  {
633  if (afw_object_meta_get_object_type_id(&self->pub, xctx)) {
634  v = impl_shared_string_value(self->view,
635  afw_object_meta_get_object_type_id(&self->pub, xctx),
636  xctx);
637  impl_meta_set_property(self, &afw_s_objectType, v, xctx);
638  }
639  }
640 
641  /* path and pathEmbedded */
642  if ((AFW_OBJECT_OPTION_IS(options, path) &&
643  !self->pub.meta.embedding_object) ||
644  (AFW_OBJECT_OPTION_IS(options, pathEmbedded) &&
645  self->pub.meta.embedding_object))
646  {
647  if (!self->pub.meta.object_uri) {
648  self->pub.meta.object_uri = afw_object_meta_get_path(
649  (const afw_object_t *)self, xctx);
650  }
651  if (self->pub.meta.object_uri) {
652  v = impl_shared_path_value(self, self->pub.meta.object_uri, xctx);
653  impl_meta_set_property(self, &afw_s_path, v, xctx);
654  }
655  }
656 
657  /*
658  * If parentPaths, resolve. If composite option, change name of
659  * parentPaths to resolvedParentPaths.
660  */
662  (const afw_object_t *)self, xctx);
663  if (parent_paths) {
664 
665  resolved_parent_paths = afw_value_allocate_list(p, xctx);
666  resolved_parent_paths->internal = afw_list_of_create(
667  afw_data_type_anyURI, p, xctx);
668  for (iterator = NULL;;) {
669  path = afw_list_of_utf8_get_next(parent_paths->internal,
670  &iterator, xctx);
671  if (!path) break;
672 
673  v = impl_shared_path_value(self, path, xctx);
674  afw_list_add_value(resolved_parent_paths->internal, v, xctx);
675  }
676 
677  if (AFW_OBJECT_OPTION_IS(options, composite)) {
678  if (AFW_OBJECT_OPTION_IS(options, resolvedParentPaths)) {
679  impl_meta_set_property(self, &afw_s_resolvedParentPaths,
680  (const afw_value_t *)resolved_parent_paths, xctx);
681  }
683  &afw_s_parentPaths, NULL, xctx);
684  }
685 
686  else {
687  impl_meta_set_property(self, &afw_s_parentPaths,
688  (const afw_value_t *)resolved_parent_paths, xctx);
689  }
690  }
691 
692  /* inheritedFrom */
693  if (AFW_OBJECT_OPTION_IS(options, inheritedFrom))
694  {
695  for (prop = self->first_property; prop; prop = prop->next_property)
696  {
697  if (prop->origin != self->origin) {
698  path = afw_object_meta_get_path(prop->origin, xctx);
699  if (!path) {
700  AFW_THROW_ERROR_FZ(general, xctx,
701  "Property %" AFW_UTF8_FMT " is missing path for inheritedFrom",
702  AFW_UTF8_FMT_ARG(prop->name));
703  }
704  v = impl_shared_path_value(self, path, xctx);
705  impl_meta_set_property_type_property(self,
706  prop->name, &afw_s_inheritedFrom,
707  v, xctx);
708  }
709  }
710  }
711 
712  /* Add requested meta for any embedded object properties. */
713  for (prop = self->first_property; prop; prop = prop->next_property)
714  {
715  if (afw_value_is_object(prop->value)) {
716  impl_additional_object_option_processing(
718  ((const afw_value_object_t *)prop->value)->internal,
719  xctx);
720  }
721  }
722 }
723 
724 
725 static void
726 impl_resolve_parents(
728  afw_xctx_t *xctx)
729 {
730  const afw_pool_t *p;
732  const afw_object_t *origin;
734  const afw_utf8_t *path;
735  const afw_iterator_t *iterator;
736  const afw_value_list_t *parent_paths;
737  afw_size_t count;
738 
739  view = self->view;
740  p = view->p;
741  origin = self->origin;
742 
743  parent_paths = afw_object_meta_get_parent_paths_value(origin, xctx);
744  if (!parent_paths) return;
745 
746  /* Allocate memory for parents. */
747  count = afw_list_get_count(parent_paths->internal, xctx);
748  self->parents = parent = afw_pool_malloc(p,
749  (count + 1) *
751  xctx);
752 
753  AFW_TRY {
754  for (iterator = NULL;;) {
755  path = afw_list_of_utf8_get_next(parent_paths->internal,
756  &iterator, xctx);
757  if (!path) break;
758 
759  *parent++ = impl_get_object_by_uri(path, self, xctx);
760  }
761  *parent = NULL;
762  }
763 
765  *parent = NULL;
767  xctx, "Error resolving parentPaths - %s",
768  AFW_ERROR_THROWN->message_z);
769  }
770 
771  AFW_ENDTRY;
772 }
773 
774 
775 static void
776 impl_merge_properties(
779  afw_xctx_t *xctx)
780 {
781  afw_object_view_property_t *parent_prop;
782  afw_object_view_property_t *self_prop;
785  afw_size_t count;
786  afw_size_t count2;
787 
788  /*
789  * Determine then number of ancestors that need to have inherited
790  * properties added.
791  */
792  for (count = 0, ancestor = parent;
793 
794  ancestor &&
795  !ancestor->inherited_properties_being_added &&
796  !ancestor->inherited_properties_added;
797 
798  count++)
799  {
801  ancestor->pub.meta.embedding_object;
802  }
803 
804  /*
805  * Add inherited properties to ancestors that need it from most distant
806  * to closest.
807  */
808  for (ancestor = parent; count > 0; count--)
809  {
810  for (obj = ancestor, count2 = count; count2 > 1; count2--)
811  {
813  obj->pub.meta.embedding_object;
814  }
815  impl_add_inherited_properties(obj, xctx);
816  }
817 
818  /*
819  * Merge properties from parent to self.
820  *
821  * If an object property is exists in both self and parent, the parent's
822  * property is merged into self's property.
823  *
824  * Object properties that are lists are not merged.
825  */
826  for (parent_prop = parent->first_property;
827  parent_prop;
828  parent_prop = parent_prop->next_property)
829  {
830  self_prop = impl_get_property(self, parent_prop->name);
831  if (!self_prop) {
832  impl_set_property(self,
833  parent_prop->origin, parent_prop->name, parent_prop->value, xctx);
834  }
835  else if (
836  afw_value_is_object(self_prop->value) &&
837  afw_value_is_object(parent_prop->value))
838  {
839  impl_merge_properties(
841  ((afw_value_object_t *)self_prop->value)->internal,
843  ((afw_value_object_t *)parent_prop->value)->internal,
844  xctx);
845  }
846  }
847 }
848 
849 
850 
851 static void
852 impl_add_inherited_properties(
854  afw_xctx_t *xctx)
855 {
857  const afw_utf8_t *path;
859 
860 
861  /* If inherited properties already added, just return. */
862  if (self->inherited_properties_added) {
863 
864 #ifdef __AFW_OBJECT_VIEW_DEBUG__
865  path = afw_object_meta_get_path((const afw_object_t *)self, xctx);
866  AFW_LOG_FZ(debug, xctx,
867  "Properties already added - %" AFW_UTF8_FMT, AFW_UTF8_FMT_ARG(path));
868 #endif
869 
870  return;
871  }
872 
873 #ifdef __AFW_OBJECT_VIEW_DEBUG__
874  path = afw_object_meta_get_path((const afw_object_t *)self, xctx);
875  AFW_LOG_FZ(debug, xctx,
876  "Starting to add properties - %" AFW_UTF8_FMT, AFW_UTF8_FMT_ARG(path));
877 #endif
878 
879  /* Check for recursion loop. */
880  if (self->inherited_properties_being_added) {
881  path = afw_object_meta_get_path((const afw_object_t *)self, xctx);
882  AFW_THROW_ERROR_FZ(general, xctx,
883  "parentPaths recursion loop while processing %" AFW_UTF8_FMT,
884  AFW_UTF8_FMT_ARG(path));
885  }
886  self->inherited_properties_being_added = true;
887 
888  /* Process direct parents first. */
889  impl_resolve_parents(self, xctx);
890  if (self->parents) {
891  for (parent = self->parents; *parent; parent++) {
892  impl_merge_properties(self, *parent, xctx);
893  }
894  }
895 
896  /* Add inherited to any object properties properties and children. */
897  for (prop = self->first_property; prop; prop = prop->next_property)
898  {
899  if (afw_value_is_object(prop->value)) {
900  impl_add_inherited_properties(
902  ((const afw_value_object_t *)prop->value)->internal,
903  xctx);
904  }
905  }
906 
907  /* Indicate that inherited properties have been added. */
908  self->inherited_properties_being_added = false;
909  self->inherited_properties_added = true;
910 
911 
912 #ifdef __AFW_OBJECT_VIEW_DEBUG__
913  AFW_LOG_FZ(debug, xctx,
914  "Finished adding properties - %" AFW_UTF8_FMT, AFW_UTF8_FMT_ARG(path));
915 #endif
916 }
917 
918 
919 
920 static void
921 impl_add_origin_properties(
923  afw_xctx_t *xctx)
924 {
925  const afw_value_t *value;
926  const afw_utf8_t *name;
927  const afw_iterator_t *iterator;
928 
929  /* Make array of properties. */
930  for (iterator = NULL;;) {
931  value = afw_object_get_next_property(self->origin, &iterator, &name, xctx);
932  if (!value) break;
933 
934  if (!afw_utf8_equal(name, &afw_s__meta_)) {
935  impl_set_property(self, self->origin, name, value, xctx);
936  }
937  }
938 }
939 
940 
941 
943 impl_get_object_by_uri(
944  const afw_utf8_t *uri,
946  afw_xctx_t *xctx)
947 {
948  const afw_uri_parsed_t *uri_parsed;
949  const afw_uri_parsed_t *entity_uri_parsed;
950  const afw_object_path_parsed_t *path_parsed;
951  const afw_utf8_t *current_path;
953  const afw_pool_t *p;
955  const afw_object_t *object;
958 
959  view = current->view;
960  p = view->p;
961 
962  /* Get current path. */
963  current_path = afw_object_meta_get_path((afw_object_t *)current, xctx);
964 
965  /* Parse URI. */
966  uri_parsed = afw_uri_parse(uri, true, current_path, p, xctx);
967  path_parsed = uri_parsed->path_parsed;
968 
969  /* See if entity has already been loaded. */
970  for (entity = view->main_entity; entity; entity = entity->next_entity) {
971  if (afw_utf8_equal(&entity->uri_parsed->normalized_uri,
972  &uri_parsed->normalized_uri))
973  {
974  break;
975  }
976  if (entity->uri_parsed->path_parsed &&
977  uri_parsed->path_parsed &&
979  &entity->uri_parsed->path_parsed->entity_path,
980  &uri_parsed->path_parsed->entity_path))
981  {
982  break;
983  }
984  }
985 
986  /* If entity not already loaded, try to load it. */
987  if (!entity) {
988 
989  /* If local path, call adaptor directly. */
990  if (path_parsed) {
991  object = afw_adaptor_get_object(
992  &path_parsed->adaptor_id,
993  &path_parsed->object_type_id,
994  &path_parsed->entity_object_id,
995  NULL,
996  NULL,
997  view->journal_entry,
998  NULL, view->p, xctx);
999  if (!object) goto error;
1000  entity_uri_parsed = uri_parsed;
1001  if (path_parsed && path_parsed->first_property_name) {
1002  entity_uri_parsed = afw_uri_parse(
1003  &uri_parsed->path_parsed->entity_path, true, current_path, p, xctx);
1004  }
1005  entity = impl_object_create_entity(view, object, entity_uri_parsed, xctx);
1006  }
1007 
1008  /* If full URI, call resolver. */
1009  else {
1010  AFW_THROW_ERROR_Z(general,
1011  "Not implemented - only local path supported", xctx);
1012  }
1013  }
1014 
1015  /* If entity not loaded, not found error. */
1016  if (!entity) {
1017  goto error;
1018  }
1019 
1020  /* Result is entity or an embedded object of entity. */
1021  result = entity;
1022  if (path_parsed) {
1023  for (name = path_parsed->first_property_name; name; name = name->next) {
1026  (const afw_object_t *)result, &name->property_name, xctx);
1027  if (!result) {
1028  goto error;
1029  }
1030  }
1031  }
1032 
1033  /* Return result. */
1034  return result;
1035 
1036 error:
1037  AFW_THROW_ERROR_FZ(general, xctx, "%" AFW_UTF8_FMT
1038  " not found or invalid",
1039  AFW_UTF8_FMT_ARG(uri));
1040 }
1041 
1042 
1044 impl_object_create_entity(
1046  const afw_object_t *origin,
1047  const afw_uri_parsed_t *uri_parsed,
1048  afw_xctx_t *xctx)
1049 {
1051 
1052 #ifdef __AFW_OBJECT_VIEW_DEBUG__
1053  const afw_utf8_t *path;
1054 #endif
1055 
1056  self = impl_object_create(view, NULL, NULL, origin, uri_parsed, xctx);
1057  if (AFW_OBJECT_OPTION_IS(view->options, composite)) {
1058 
1059 #ifdef __AFW_OBJECT_VIEW_DEBUG__
1060  path = afw_object_meta_get_path((const afw_object_t *)self, xctx);
1061  AFW_LOG_FZ(debug, xctx,
1062  "Starting composite view - %" AFW_UTF8_FMT,
1063  AFW_UTF8_FMT_ARG(path));
1064 #endif
1065 
1066  impl_add_inherited_properties(self, xctx);
1067 
1068 #ifdef __AFW_OBJECT_VIEW_DEBUG__
1069  path = afw_object_meta_get_path((const afw_object_t *)self, xctx);
1070  AFW_LOG_FZ(debug, xctx,
1071  "Finished composite view - %" AFW_UTF8_FMT,
1072  AFW_UTF8_FMT_ARG(path));
1073 #endif
1074 
1075  }
1076 
1077  return self;
1078 }
1079 
1080 
1081 /* uri_parsed required for entities. */
1083 impl_object_create(
1085  afw_object_view_internal_object_self_t *embedding_object,
1086  const afw_utf8_t *property_name,
1087  const afw_object_t *origin,
1088  const afw_uri_parsed_t *uri_parsed,
1089  afw_xctx_t *xctx)
1090 {
1092  const afw_pool_t *p;
1093  const afw_value_t *value;
1094 
1095  p = view->p;
1096  value = NULL;
1097 
1098  /* Allocate and initialize self. */
1100  xctx);
1101  self->pub.inf = &impl_afw_object_inf;
1102  self->pub.p = p;
1103  self->view = view;
1104  self->pub.meta.embedding_object = (const afw_object_t *)embedding_object;
1105  self->pub.meta.id = property_name;
1106  self->pub.meta.object_type_uri = origin->meta.object_type_uri;
1107  self->origin = origin;
1108  self->uri_parsed = uri_parsed;
1109 
1110  /*
1111  * If a uri_parsed is passed with a parsed uri path, use it's path,
1112  * object_type_id, and object_id. If not, these will be determined
1113  * by the corresponding get_*() method. This is so the they will not
1114  * be produced unnecessarily.
1115  */
1116  if (uri_parsed && uri_parsed->path_parsed) {
1117  self->pub.meta.object_type_uri =
1118  &uri_parsed->path_parsed->object_type_id;
1119  self->pub.meta.id = &uri_parsed->path_parsed->entity_object_id;
1120  if (uri_parsed->path_parsed->first_property_name) {
1121  AFW_THROW_ERROR_Z(general,
1122  "Dotted property names in object id not allowed here",
1123  xctx);
1124  }
1125  self->pub.meta.object_uri = &uri_parsed->path_parsed->normalized_path;
1126 
1127  value = afw_value_create_anyURI(self->pub.meta.object_uri,
1128  p, xctx);
1129  }
1130 
1131  /* If this is entity object, add to list of loaded entity objects. */
1132  if (!embedding_object) {
1133  if (!view->main_entity) {
1134  view->main_entity = self;
1135  } else {
1136  self->next_entity = view->main_entity->next_entity;
1137  view->main_entity->next_entity = self;
1138  }
1139  }
1140 
1141  /* Set meta using clone of origin's meta and set path if entity. */
1142  afw_object_meta_clone_and_set((const afw_object_t *)self, origin, xctx);
1143  if (uri_parsed && uri_parsed->path_parsed) {
1144  impl_meta_set_property(self, &afw_s_path, value, xctx);
1145  }
1146 
1147  /* Add self properties from origin. */
1148  impl_add_origin_properties(self, xctx);
1149 
1150  /* Return instance. */
1151  return self;
1152 }
1153 
1154 /*--- Object implementation for internal view objects. ---*/
1155 
1156 
1157 
1158 /*
1159  * Implementation of method release of interface afw_object.
1160  */
1161 void
1163  const afw_object_t * instance,
1164  afw_xctx_t *xctx)
1165 {
1167  const afw_object_t *entity;
1168 
1169  /* Methods release and add_reference act on the entity. */
1170  AFW_OBJECT_GET_ENTITY(entity, instance);
1171  self = (afw_object_view_internal_object_self_t *)entity;
1172 
1173  /* Decrement count and release object's pool if zero. */
1174  if (afw_atomic_integer_decrement(&self->view->reference_count) == 0) {
1175  afw_pool_release(instance->p, xctx);
1176  }
1177 }
1178 
1179 
1180 
1181 /*
1182  * Implementation of method add_reference of interface afw_object.
1183  */
1184 void
1186  const afw_object_t * instance,
1187  afw_xctx_t *xctx)
1188 {
1190  const afw_object_t *entity;
1191 
1192  /* Methods release and add_reference act on the entity. */
1193  AFW_OBJECT_GET_ENTITY(entity, instance);
1194  self = (afw_object_view_internal_object_self_t *)entity;
1195 
1196  /* Increment reference count. */
1197  afw_atomic_integer_increment(&self->view->reference_count);
1198 }
1199 
1200 /*
1201  * Implementation of method get_count for interface afw_object.
1202  */
1203 afw_size_t
1205  const afw_object_t * instance,
1206  afw_xctx_t * xctx)
1207 {
1208 // <afwdev {prefixed_interface_name}>_self_t *self =
1209 // (<afwdev {prefixed_interface_name}>_self_t *)instance;
1210 
1212  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
1213 
1214 }
1215 
1216 /*
1217  * Implementation of method get_property of interface afw_object.
1218  */
1219 const afw_value_t *
1221  const afw_object_t * instance,
1222  const afw_utf8_t * property_name,
1223  afw_xctx_t *xctx)
1224 {
1228 
1229  prop = impl_get_property(self, property_name);
1230 
1231  return (prop) ? prop->value : NULL;
1232 }
1233 
1234 
1235 
1236 /*
1237  * Implementation of method get_next_property of interface afw_object.
1238  */
1239 const afw_value_t *
1241  const afw_object_t * instance,
1242  const afw_iterator_t * * iterator,
1243  const afw_utf8_t * * property_name,
1244  afw_xctx_t *xctx)
1245 {
1248  const afw_value_t *result;
1250 
1251  /* If iterator is NULL, point iterator to first property. */
1252  if (!*iterator) {
1253  prop = self->first_property;
1254  }
1255  else {
1256  prop = ((afw_object_view_property_t *)*iterator)->next_property;
1257  }
1258  *iterator = (afw_iterator_t *)prop;
1259 
1260  /*
1261  * If there are no more properties, return NULL for result and property
1262  * name.
1263  */
1264  if (!prop)
1265  {
1266  if (property_name) {
1267  *property_name = NULL;
1268  }
1269  result = NULL;
1270  }
1271 
1272  /* If there is another value, return it. */
1273  else {
1274  result = prop->value;
1275  if (property_name) {
1276  *property_name = prop->name;
1277  }
1278  }
1279 
1280  /* Return result. */
1281  return result;
1282 }
1283 
1284 
1285 
1286 /*
1287  * Implementation of method has_property of interface afw_object.
1288  */
1291  const afw_object_t * instance,
1292  const afw_utf8_t * property_name,
1293  afw_xctx_t *xctx)
1294 {
1295  return (impl_afw_object_get_property(instance,
1296  property_name, xctx) != NULL);
1297 }
1298 
1299 
1300 
1301 /*
1302  * Implementation of method get_setter of interface afw_object.
1303  */
1304 const afw_object_setter_t *
1306  const afw_object_t * instance,
1307  afw_xctx_t *xctx)
1308 {
1309  /* Views are immutable. */
1310  return NULL;
1311 }
1312 
1313 
1314 
1315 /*--- Public function defines. ---*/
1316 
1317 
1318 
1319 /* Create an object view of an object in specified pool. */
1320 AFW_DEFINE(const afw_object_t *)
1322  const afw_object_t *instance,
1323  const afw_utf8_t *entity_path,
1324  const afw_object_options_t *options,
1325  const afw_pool_t *p, afw_xctx_t *xctx)
1326 {
1329  const afw_utf8_t *reconcilable;
1330  afw_value_object_t self_value;
1331  const afw_value_t *value;
1332 
1333  /*
1334  * Add reference to instance. Instance most have lifetime at least as
1335  * long as returned view object since uncloned values are used.
1336  */
1337  afw_object_add_reference(instance, xctx);
1338 
1339  /* If no options specified, just return instance asis. */
1340  if (!options || options->mask == 0)
1341  {
1342  return instance;
1343  }
1344 
1345  /* Create view common. */
1346  p = afw_pool_create(p, xctx);
1348  view->p = p;
1349  view->reference_count = 1;
1350  view->options = afw_object_options_create(NULL, options, p, xctx);
1351 
1352  /* Parse entity path and adaptor id. */
1353  if (!entity_path) {
1354  entity_path = afw_object_meta_get_path(instance, xctx);
1355  }
1356  if (entity_path) {
1357  view->uri_parsed = afw_uri_parse(entity_path, true, NULL, p, xctx);
1358  }
1359  if (!entity_path || !view->uri_parsed || !view->uri_parsed->path_parsed ||
1360  view->uri_parsed->path_parsed->adaptor_id.len == 0)
1361  {
1362  AFW_THROW_ERROR_Z(general,
1363  "Entity path required for afw_object_view_create()",
1364  xctx);
1365  }
1366  view->adaptor_id = &view->uri_parsed->path_parsed->adaptor_id;
1367 
1369  view->journal_entry = afw_object_create_managed(p, xctx);
1370 
1371  /* Create view object. */
1372  self = impl_object_create_entity(view, instance, view->uri_parsed, xctx);
1373 
1374  /* Add requested meta. */
1375  impl_additional_object_option_processing(self, xctx);
1376 
1377  /* If reconcilable option, add reconcilable meta. */
1378  if (AFW_OBJECT_OPTION_IS(options, reconcilable)) {
1379  self_value.inf = &afw_value_evaluated_object_inf;
1380  self_value.internal = (const afw_object_t *)self;
1381  reconcilable = afw_json_from_value(
1382  (const afw_value_t *)&self_value,
1384  p, xctx);
1385  value = afw_value_create_string(reconcilable, p, xctx);
1386  impl_meta_set_property(self, &afw_s_reconcilable, value, xctx);
1387  }
1388 
1389  /* Return view. */
1390  return (const afw_object_t *)self;
1391 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
afw_adaptor_get_object_type(const afw_utf8_t *adaptor_id, const afw_utf8_t *object_type_id, const afw_object_t *journal_entry, afw_xctx_t *xctx)
Get and cache AdaptiveObjectType object.
Definition: afw_adaptor.c:437
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_integer_t afw_atomic_integer_decrement(AFW_ATOMIC afw_integer_t *mem)
Integer atomic decrement.
Definition: afw_atomic.h:96
afw_integer_t afw_atomic_integer_increment(AFW_ATOMIC afw_integer_t *mem)
Integer atomic increment.
Definition: afw_atomic.h:127
afw_value_create_anyURI(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type anyURI value.
afw_data_type_anyURI
Data type struct for anyURI.
afw_value_allocate_anyURI(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type anyURI value.
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.
afw_value_allocate_list(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type list value.
#define afw_value_is_list(A_VALUE)
Macro to determine if value is evaluated list.
#define afw_value_is_object(A_VALUE)
Macro to determine if value is evaluated object.
#define afw_object_old_get_property_as_object(object, property_name, xctx)
Get property function for data type object value.
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.
afw_value_evaluated_object_inf
Unmanaged evaluated value inf for data type object.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
afw_value_allocate_string(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type string value.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
struct afw_iterator_s afw_iterator_t
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
Definition: afw_common.h:236
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#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
const afw_utf8_t * afw_json_from_value(const afw_value_t *value, const afw_object_options_t *options, const afw_pool_t *p, afw_xctx_t *xctx)
Convert an adaptive value to JSON.
#define afw_list_get_next_value(instance, iterator, p, xctx)
Call method get_next_value of interface afw_list.
#define afw_list_get_data_type(instance, xctx)
Call method get_data_type of interface afw_list.
#define afw_list_get_count(instance, xctx)
Call method get_count of interface afw_list.
afw_list_of_utf8_get_next(const afw_list_t *instance, const afw_iterator_t **iterator, afw_xctx_t *xctx)
Get next value from list whose data type cType is afw_utf8_t.
Definition: afw_list.c:19
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
#define afw_list_of_create(data_type, p, xctx)
Create an list of a specific data type in memory.
Definition: afw_list.h:64
#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
const afw_object_setter_t * impl_afw_object_get_setter(const afw_object_t *instance, afw_xctx_t *xctx)
void impl_afw_object_add_reference(const afw_object_t *instance, afw_xctx_t *xctx)
const afw_value_t * impl_afw_object_get_next_property(const afw_object_t *instance, const afw_iterator_t **iterator, const afw_utf8_t **property_name, afw_xctx_t *xctx)
void impl_afw_object_release(const afw_object_t *instance, afw_xctx_t *xctx)
const afw_value_t * impl_afw_object_get_property(const afw_object_t *instance, const afw_utf8_t *property_name, afw_xctx_t *xctx)
afw_boolean_t impl_afw_object_has_property(const afw_object_t *instance, const afw_utf8_t *property_name, afw_xctx_t *xctx)
afw_size_t impl_afw_object_get_count(const afw_object_t *instance, afw_xctx_t *xctx)
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
#define afw_object_add_reference(instance, xctx)
Call method add_reference 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_meta_add_error_fz(instance, xctx, format_z,...)
Add a formatted error message to instance's meta.
afw_object_meta_set_object_type(const afw_object_t *instance, const afw_object_type_t *object_type, afw_xctx_t *xctx)
Set object's object type id.
#define afw_object_meta_get_object_type_id(instance, xctx)
Get object's object_type_id.
afw_object_meta_get_path(const afw_object_t *instance, afw_xctx_t *xctx)
Get an object's path.
#define afw_object_meta_set_property_type_property(instance, property_name, property_type_property_name, value, xctx)
Set a property type property for a property in the meta of an object.
afw_object_meta_clone_and_set(const afw_object_t *instance, const afw_object_t *from, afw_xctx_t *xctx)
Set object's meta using a clone of the meta of another object.
afw_object_meta_get_parent_paths_value(const afw_object_t *instance, afw_xctx_t *xctx)
Get meta parentPaths property value.
#define afw_object_meta_add_property_error_z(instance, property_name, message_z, xctx)
Add a null terminate error message for a property to instance's meta.
afw_object_meta_add_needed_object_type(const afw_object_t *instance, const afw_object_t *object_type, afw_xctx_t *xctx)
Add a needed object type object.
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.
#define afw_object_meta_set_property(instance, property_name, value, xctx)
Set a property in the meta of an object.
#define AFW_OBJECT_OPTION_IS(_options, _option)
Test mask.
afw_object_options_create(const afw_object_options_t *initial_options, const afw_object_options_t *options, const afw_pool_t *p, afw_xctx_t *xctx)
Create a options.
afw_object_options_reconcilable_meta_property
Object processing options to produce reconcilable meta property.
afw_object_type_property_type_get(const afw_object_type_t *object_type, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Get property type object for property.
afw_object_type_property_type_get_next(const afw_object_type_t *object_type, const afw_iterator_t **iterator, const afw_utf8_t **property_name, afw_xctx_t *xctx)
Get next property type for object type.
afw_object_type_property_type_normalize(const afw_object_type_property_type_t *pt, const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Normalize a value based on property type.
afw_object_view_create(const afw_object_t *instance, const afw_utf8_t *entity_path, const afw_object_options_t *options, const afw_pool_t *p, afw_xctx_t *xctx)
Create an object view of an object in specified pool.
#define AFW_OBJECT_GET_ENTITY(entity, object)
Macro to get entity for object.
Definition: afw_object.h:406
#define AFW_OBJECT_S_PN_OBJECT_ID
String pseudo meta property name for objectId.
Definition: afw_object.h:87
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
Definition: afw_object.h:913
#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
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_uri_parse(const afw_utf8_t *uri, afw_boolean_t is_value_path, const afw_utf8_t *current_path, const afw_pool_t *p, afw_xctx_t *xctx)
Parse a URI in specific pool.
Definition: afw_uri.c:1470
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.
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
Interface afw_data_type public struct.
Interface afw_list public struct.
const afw_object_t * embedding_object
Embedding object.
Definition: afw_common.h:768
const afw_utf8_t * object_type_uri
Object type object URI or NULL.
Definition: afw_common.h:796
Struct for object processing options.
Typedef for parsed object path.
Property name path struct.
Interface afw_object public struct.
Interface afw_object_setter public struct.
Struct for afw_object_type_property_type_t.
Struct for afw_object_type_t.
apr_hash_t * string_values
Shared string values.
afw_object_view_internal_object_self_t * main_entity
First loaded entity.
const afw_object_t * journal_entry
Journal entry used during path resolution.
const afw_uri_parsed_t * uri_parsed
Parsed URI for view entity.
const afw_pool_t * p
Pool used for all resources in view.
const afw_object_options_t * options
View options.
apr_hash_t * path_values
Shared path values.
const afw_utf8_t * adaptor_id
Parsed URI for view entity.
Interface afw_pool public struct.
Typedef for parsed URI returned from afw_uri_parse().
Definition: afw_uri.h:133
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type anyURI values.
struct for data type base64Binary values.
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.