Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- method create_inst.
- data:
- li_ifcl_items type mt_classlist_tt,
- lvc_ifcl_item type mt_classitem,
- li_tags type mt_taglist_tt,
- lr_tag type mt_tagitem,
- lr_map type mt_classmap,
- lcl_descr_ref type ref to cl_abap_refdescr,
- lcl_abap_typdscr type ref to cl_abap_typedescr.
- *Сначала мы получаем некоторую информацию о типах, используя систему SAP RTTI. Нам нужно определить тип передаваемой *переменной, убедиться, что она является ссылкой, и получить имя словаря базового интерфейса или класса.
- * determine the dictionary type of the reference that was passed in.
- lcl_descr_ref ?= cl_abap_refdescr=>describe_by_data( c_ref ).
- lcl_abap_typdscr = lcl_descr_ref->get_referenced_type( ).
- lvc_ifcl_item = lcl_abap_typdscr->get_relative_name( ).
- if lvc_ifcl_item is initial.
- raise nondictionary_type.
- endif.
- *Далее мы проверяем наш кеш ранее запрошенных экземпляров. Если класс для этой функциональности уже определен, то мы просто *создаем экземпляр класса и возвращаем экземпляр.
- * check our cache..
- read table mi_cache into lr_map
- with key source = lvc_ifcl_item.
- if sy-subrc eq 0.
- create object c_ref type (lr_map-target).
- return.
- endif.
- lr_map-source = lvc_ifcl_item.
- *Затем мы меняем поведение в зависимости от того, является ли переданная ссылка ссылкой на класс интерфейса. Мы создаем список *потенциальных кандидатов на экземпляры, поэтому, когда класс передается, мы просто добавляем его в список (и мы будем искать *потомков на более позднем этапе.) Если интерфейс был передан, мы выбираем список всех классов, которые реализуют интерфейс *(используя таблицу vseoimplem.)
- * input can be a class or an interface whose imp’ing classes we want.
- case lcl_abap_typdscr->type_kind.
- when cl_abap_typedescr=>typekind_class.
- append lvc_ifcl_item to li_ifcl_items.
- when cl_abap_typedescr=>typekind_intf.
- get_imp_classes( ” classes that implement the passed in interface
- exporting
- i_interface = lvc_ifcl_item
- importing
- e_classes = li_ifcl_items
- ).
- when others.
- raise not_a_reference.
- endcase.
- *Далее мы разбираем дерево зависимостей для классов, которые мы собрали (используя таблицу vseoextend.) Это необходимо, так *как методика, которую мы используем для выбора реализаторов интерфейса, возвращает только классы, непосредственно реализующие *интерфейс, а не потомки, которые не являются явно определить реализацию интерфейса. Кроме того, если передана ссылка на *класс, нам нужно выбрать потенциальных кандидатов, которые будут состоять из потомков класса.
- explode_descendents( ” get entire descendant tree.
- changing c_classlist = li_ifcl_items ).
- if li_ifcl_items is initial.
- raise no_implementing_classes.
- endif.
- *Затем мы анализируем список классов и определяем любые связанные с ними теги (используя таблицу seotypepls, которая содержит *список прямого объявления, который мы похитили для тегирования!) Возможные теги включают пометку как класс по умолчанию, *альтернативный класс или тестовый класс.
- fetch_class_tags(
- exporting
- i_classlist = li_ifcl_items
- importing
- e_taglist = li_tags
- ).
- *Далее мы применяем нашу логику выбора - если мы находимся в тестовом режиме, мы ищем тестовый класс; если мы находимся в *чистом режиме, мы ищем класс по умолчанию; в противном случае мы ищем альтернативный класс, если этот класс не задан по *умолчанию и первый класс в списке отсутствует.
- do.
- case mvb_mode.
- when mcc_mode_test.
- * if we’re in test mode, read first test class if exists.
- get_target_with_tag mcc_tag_tst.
- when mcc_mode_pure.
- * if we’re in pure mode, read first default class if exists.
- get_target_with_tag mcc_tag_def.
- endcase.
- * see if an alternative class exists.
- get_target_with_tag mcc_tag_alt.
- * see if we have a class marked as standard.
- get_target_with_tag mcc_tag_def.
- * fall through, when no keywords found just return first class.
- read table li_ifcl_items into lvc_ifcl_item
- index 1.
- exit.
- enddo.
- if lvc_ifcl_item is initial.
- raise no_implementing_classes.
- endif.
- *Затем мы создаем экземпляр класса, который хотим использовать, и помещаем ссылку в c_ref.
- try.
- create object c_ref type (lvc_ifcl_item).
- catch cx_sy_create_object_error.
- raise instantiation_failed.
- endtry.
- *Наконец, мы кешируем имя класса и сопоставляем его с именем типа ссылки, которая была передана.
- lr_map-target = lvc_ifcl_item.
- append lr_map to mi_cache.
- endmethod.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement