Advertisement
isavchenko

Untitled

Dec 17th, 2018
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ABAP 6.23 KB | None | 0 0
  1. method create_inst.
  2.  
  3.   data:
  4.     li_ifcl_items    type mt_classlist_tt,
  5.     lvc_ifcl_item    type mt_classitem,
  6.     li_tags          type mt_taglist_tt,
  7.     lr_tag           type mt_tagitem,
  8.     lr_map           type mt_classmap,
  9.     lcl_descr_ref    type ref to cl_abap_refdescr,
  10.     lcl_abap_typdscr type ref to cl_abap_typedescr.
  11.  
  12.  
  13. *Сначала мы получаем некоторую информацию о типах, используя систему SAP RTTI. Нам нужно определить тип передаваемой *переменной, убедиться, что она является ссылкой, и получить имя словаря базового интерфейса или класса.
  14.  
  15.  
  16. * determine the dictionary type of the reference that was passed in.
  17.   lcl_descr_ref ?= cl_abap_refdescr=>describe_by_data( c_ref ).
  18.   lcl_abap_typdscr = lcl_descr_ref->get_referenced_type( ).
  19.  
  20.   lvc_ifcl_item = lcl_abap_typdscr->get_relative_name( ).
  21.  
  22.   if lvc_ifcl_item is initial.
  23.     raise nondictionary_type.
  24.   endif.
  25.  
  26.  
  27. *Далее мы проверяем наш кеш ранее запрошенных экземпляров. Если класс для этой функциональности уже определен, то мы просто *создаем экземпляр класса и возвращаем экземпляр.
  28.  
  29.  
  30. * check our cache..
  31.   read table mi_cache into lr_map
  32.     with key source = lvc_ifcl_item.
  33.  
  34.   if sy-subrc eq 0.
  35.     create object c_ref type (lr_map-target).
  36.     return.
  37.   endif.
  38.  
  39.   lr_map-source = lvc_ifcl_item.
  40.  
  41.  
  42. *Затем мы меняем поведение в зависимости от того, является ли переданная ссылка ссылкой на класс интерфейса. Мы создаем список *потенциальных кандидатов на экземпляры, поэтому, когда класс передается, мы просто добавляем его в список (и мы будем искать *потомков на более позднем этапе.) Если интерфейс был передан, мы выбираем список всех классов, которые реализуют интерфейс *(используя таблицу vseoimplem.)
  43.  
  44.  
  45. * input can be a class or an interface whose imp’ing classes we want.
  46.   case lcl_abap_typdscr->type_kind.
  47.  
  48.     when cl_abap_typedescr=>typekind_class.
  49.  
  50.       append lvc_ifcl_item to li_ifcl_items.
  51.  
  52.     when cl_abap_typedescr=>typekind_intf.
  53.  
  54.       get_imp_classes( ” classes that implement the passed in interface
  55.         exporting
  56.           i_interface = lvc_ifcl_item
  57.         importing
  58.           e_classes = li_ifcl_items
  59.       ).
  60.  
  61.     when others.
  62.       raise not_a_reference.
  63.   endcase.
  64.  
  65. *Далее мы разбираем дерево зависимостей для классов, которые мы собрали (используя таблицу vseoextend.) Это необходимо, так *как методика, которую мы используем для выбора реализаторов интерфейса, возвращает только классы, непосредственно реализующие *интерфейс, а не потомки, которые не являются явно определить реализацию интерфейса. Кроме того, если передана ссылка на *класс, нам нужно выбрать потенциальных кандидатов, которые будут состоять из потомков класса.
  66.  
  67. explode_descendents(get entire descendant tree.
  68.     changing c_classlist = li_ifcl_items ).
  69.  
  70.   if li_ifcl_items is initial.
  71.     raise no_implementing_classes.
  72.   endif.
  73.  
  74.  
  75. *Затем мы анализируем список классов и определяем любые связанные с ними теги (используя таблицу seotypepls, которая содержит *список прямого объявления, который мы похитили для тегирования!) Возможные теги включают пометку как класс по умолчанию, *альтернативный класс или тестовый класс.
  76.  
  77.  
  78. fetch_class_tags(
  79.     exporting
  80.       i_classlist = li_ifcl_items
  81.     importing
  82.       e_taglist = li_tags
  83.   ).
  84.  
  85.  
  86. *Далее мы применяем нашу логику выбора - если мы находимся в тестовом режиме, мы ищем тестовый класс; если мы находимся в *чистом режиме, мы ищем класс по умолчанию; в противном случае мы ищем альтернативный класс, если этот класс не задан по *умолчанию и первый класс в списке отсутствует.
  87.  
  88.  
  89.   do.
  90.     case mvb_mode.
  91.       when mcc_mode_test.
  92. * if we’re in test mode, read first test class if exists.
  93.         get_target_with_tag mcc_tag_tst.
  94.       when mcc_mode_pure.
  95. * if we’re in pure mode, read first default class if exists.
  96.         get_target_with_tag mcc_tag_def.
  97.     endcase.
  98.  
  99. * see if an alternative class exists.
  100.     get_target_with_tag mcc_tag_alt.
  101.  
  102. * see if we have a class marked as standard.
  103.     get_target_with_tag mcc_tag_def.
  104.  
  105. * fall through, when no keywords found just return first class.
  106.     read table li_ifcl_items into lvc_ifcl_item
  107.       index 1.
  108.     exit.
  109.   enddo.
  110.  
  111.   if lvc_ifcl_item is initial.
  112.     raise no_implementing_classes.
  113.   endif.
  114.  
  115.  
  116. *Затем мы создаем экземпляр класса, который хотим использовать, и помещаем ссылку в c_ref.
  117.  
  118.  
  119.   try.
  120.       create object c_ref type (lvc_ifcl_item).
  121.     catch cx_sy_create_object_error.
  122.       raise instantiation_failed.
  123.   endtry.
  124.  
  125.  
  126. *Наконец, мы кешируем имя класса и сопоставляем его с именем типа ссылки, которая была передана.
  127.  
  128.  
  129.   lr_map-target = lvc_ifcl_item.
  130.   append lr_map to mi_cache.
  131.  
  132. endmethod.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement