Skip to Content

Introduction

The Floorplan Manager (FPM) allows you to separate UI components into distinct building blocks which can be arranged to an entire application. These UI building blocks (UIBBs) may also be reusable in order to use them later on in another scenario. But without exchanging data, only few UIBBs can be properly used. So data sharing between certain UI components is a common requirement, not only in FPM based applications.

There are a lot of good guides in SCN which deal with the question of how data can be exchanged between UIBBs in the FPM.

So initially this blog post wouldn’t be necessary at all and I could have saved my time. The reason why I didn’t, is the fact that none of these blogs deal with the question, what the drawbacks of each approach are and what would be the specific difficulties to deal with in an evolving architecture during the implementation of large enterprise applications.

Options of sharing data between UIBBs

To share data between UIBBs in the FPM, there are mainly four options:

  • Singleton
  • Events
  • Wiring
  • Shared Data component (not usable for Generic UI Building Blocks)

Each of these options will be described below.

The Shared Data Component

Freestyle UIBBs can implement the Webdynpro Component interface IF_FPM_SHARED_DATA. The context of this component can be mapped in any other Freestyle UIBB. Since context mapping is not possible for the Generic UIBBs, I do not further investigate this possibility.

The Singleton-based approach

How does it work

This approach is quite easy to implement. Every UIBB or every OVP-/OIF-/GAF-Exit gets an instance of the application model by calling a static method of the class which implements this application model.

method IF_FPM_GUIBB~INITIALIZE.
mo_application_model = zcl_fpm_demo_application_model=>get_instance( ).
endmethod.

This call will return the same instance at every call. This means, any method and any data will be read from and written to the same instance. This approach is the easiest and one of the more dangerous approaches in terms of maintenance requirements.

Advantages

  • Easy to implement
  • Easy to implement also in dynamic scenarios, where UIBBs are registered at runtime
  • Sharing of a single Instance which offers both data and operations to its clients is quite easy, there is no need to share only internal tables or structures which offer no follow-up operations for the UIBBs dealing with these data structures / instead, UIBBs can get an object, retrieve data and also write some data back based on what the UIBBs was intended to do

Drawbacks

However, the outcome will be multiple classes whose dependencies would have to be managed separately in an extra FPM component, e.g. the application controller. To resolve dependencies, tools like IoC Container might help – but anyway, you need to be absolutely clear about the application model before starting with a singleton based approach. It is easy to implement at the beginning but might turn into a maintenance monster if you forget to care about it.

  • While in the standard FPM configuration editor, there is no transparency how an UIBB exchanges its data
  • All UIBBs which rely on the application model class will work only with this class, hence, show a strong association with that class. This threats the reusability of that components in scenarios which usually do not deal with this very application model class
  • This issue can be minimized by having multiple singleton instances (application models) which share some data between each other based on generic dependency injections. This could be achieved by using Constructor Injections or Setter Injections of the corresponding application models.
  • Specific UIBBs cannot be adressed conditionally this way. If you do not separately implement some logic which prevents certain UIBBs from getting updates based on the application model, all UIBBS which look for the corresponding model will get and write data from/to it or will not.

The Event-based approach

How does it work

Imagine a Search UIBB which works based on the table SFLIGHT needs to propagate its selection criteria to other UIBBs when the user pressed “Search”. If data exchange was implemented by a Singleton class, the method if_fpm_guibb_search~process_event would try to get the singleton instance and share the selection criteria by calling a method call which might look like this

lo_singleton->SET_FLIGHT_SELECTION_CRITERIA( lt_selopts )


In contrast to sharing the data using a singleton instance, the UIBB could also re-raise the event by actually triggering a new event with event parameters:

METHOD if_fpm_guibb_search~process_event.
...
  DATA lo_fpm_parameter TYPE REF TO if_fpm_parameter.
  DATA lo_fpm TYPE REF TO if_fpm.
* get FPM
  lo_fpm = cl_fpm_factory=>get_instance( ).
*       raise apply selection event
 lo_fpm_parameter = cl_fpm_parameter=>create_by_lpparam( it_parameter = lt_parameter ).
 lo_fpm_parameter->set_value( iv_key = 'SEARCH_CRITERIA_FLIGHTS' iv_value = IT_FPM_SEARCH_CRITERIA ).
 lo_fpm->raise_event_by_id(
 iv_event_id = 'ON_SEARCH_FLIGHTS'
          io_event_data = lo_fpm_parameter ).
...
ENDMETHOD.

Any UIBB which is interested in getting the selection criteria should handle this event in its own PROCESS_EVENT method. Any kind of the OVERRIDE-Methods which are used by certain exits are also welcome.

DATA: lr_data TYPE REF TO data.
FIELD-SYMBOLS <lt_selopts> TYPE FPMGB_T_SEARCH_CRITERIA.
  CASE io_tabbed->mo_event->mv_event_id.
    WHEN 'ON_SEARCH_FLIGHTS'.
 io_tabbed->mo_event->mo_event_data->get_value(
 EXPORTING iv_key = 'SEARCH_CRITERIA_FLIGHTS'
 IMPORTING er_value = lr_data ).
      ASSIGN lr_data->* TO <lt_selopts>.
...
ENDCASE.


Advantages

  • Easy to implement
  • Easy to implement also in dynamic scenarios, where UIBBs are registered at runtime
  • No extra class for the backend object needed

Drawbacks

  • No transparency while in the configuration editor, how an UIBB exchanges its data
  • Danger of creating endless loops caused by cascading event raisings without having a chance of knowing it when in a certain feeder class. Example: This could happen if UIBB 1 triggers an event which is handled by UIBB 2. UIBB 2 triggers another event itself which is handled by UIBB 3. This component could also trigger its own events, which could eventually cause UIBB 1 to start the event loop again.
  • only visible UIBB take part in the event loop, invisible UIBBs (e.g. in other tabs than the currently selected tab) do not receive the data
  • You cannot address specific UIBBs this way, instead all visible UIBBs take part in the event loop and will handle this event or ignore it
  • The parameter signature of the events might change without notice, or worse, another UIBB which raises the same event uses the same parameters but with another type. This ain’t fun for the clients of these events

The Wiring-based approach

How does it work

Wiring is the standard FPM-concept to share data. I’m not going to explain it here. Instead I refer to help.sap.com, the FPM developer guide, or the official book http://www.sap-press.de/katalog/buecher/titel/gp/titelID-2290

There are also good guides in SCN which describe wiring based on structures or tables.

Advantages

  • Since the connector classes and the data which they provide are defined at design time and used both on sender and receiver side, surprises are less certain than in the event-based approach. However, a sender might still decide to return different data via its outports which will cause an error at runtime
  • This little disadvantage brings us to the next advantage: Wiring can be configured in the FPM configuration editor. Errors can be found much quicker since every data exchange needs to be registered here
  • This also makes transparent, which data the UIBB you are currently configuring, really uses

Drawbacks

  • It is very difficult to implement wiring in dynamic scenarios, where UIBBs are added at runtime
  • This drawback is not mentioned because of the wiring concept, rather because of the way it is commonly used: Developers tend to share structures and tables between UIBBs without the possibility to support follow-up operations since these still remain simple data objects, but no object instances. Sharing  application models between UIBBs is a much more powerful possibility which I might demonstrate in an upcoming blog
  • Compared to the other options it is the most complicated approach and might be hard to follow and implement for someone who is new to FPM development

Conclusion

Every approach has its specific advantages. What we learned in real implementation projects, is, that there is always a mixture of these approaches depending on the scenario and the requirements in terms of reusability of UIBBs. If your UIBBs need to be reusable in various scenarios the approaches to exchange data should be (in order of relevance): Wiring before Singleton before Events.

To report this post you need to login first.

12 Comments

You must be Logged on to comment or reply to a post.

  1. Robin Vleeschhouwer

    Hi Uwe,

    Thanks for this good informative blog.

    What would you recommend to use in the following case:

    A GAF with 3 steps and at the last step the option want to save all the changes. The different GUIBB’s are dependent on eachother and also reusable for other applications.

    What I am missing in the Wires is the possibility to use a target several times. Now you can only use a target once, because the target has no option to determine what the source is. I think it would be nice if the connector class provided a method like: GET_OUTPUT_ID() so you could create a configuration for the target to handle several sources.

    Best regards,

    Robin Vleeschhouwer

    (0) 
    1. Uwe Kunath Post author

      Hi Robin,

      I think using a target once is fine since this restriction applies to only one configuration in one application at a time. Means, using another configuration of the feeder or in another application you should be able to wire the UIBB to another source.

      To solve the issue with the three UIBBs in a GAF, it should be sufficient to do the following:

      Define all of these three methods in every feeder the same way:

      METHOD if_fpm_feeder_model~get_outport_data.

      CASE iv_port_identifier.

      WHEN ZIF_YOUR_DATA_CONTAINER=>gc_name.

        IF mo_connector is NOT INITIAL.

            ro_data = mo_connector->get_output( ).

        ELSE.

      *create the data container in case the connector is not set

      *(this should only be the case if the current UIBB serves as a source only

      * and not as a target)

      *…

        ENDIF.

      ENDCASE.

      ENDMETHOD.

      METHOD if_fpm_feeder_model~get_outports.

        CLEAR: et_outport.

        DATA: ls_outport TYPE if_fpm_feeder_model=>ty_s_port.

        ls_outport-type = if_fpm_feeder_model=>cs_port_type-lead_selection.

        ls_outport-identifier = ZIF_YOUR_DATA_CONTAINER=>gc_name.

        ls_outport-description = ‘Data Container of type ZIF_YOUR_DATA_CONTAINER’.

        INSERT ls_outport INTO TABLE et_outport.

      ENDMETHOD.

      METHOD if_fpm_feeder_model~set_connector.

      * in case the UIBB serves as source only, IO_CONNECTOR will always be initial

        CHECK io_connector IS NOT INITIAL.

        mo_connector = io_connector.

      ENDMETHOD.

      This way, you should be able to wire UIBB 1 -> UIBB 2 and UIBB 1 -> UIBB 3, alternatively UIBB 1 -> UIBB 2 and UIBB 2 -> UIBB 3

      However, since the data container can be created by every UIBB feeder at runtime, if this very feeder serves as a source only, it’s up to you how to combine them. If the UIBB serves as a target instead, MO_CONNECTOR will be set and will be used in if_fpm_feeder_model~get_outport_data as the data container provider.

      In another application you might consider to provide different outports and also provide different data containers in method if_fpm_feeder_model~get_outport_data depending on the port identifier.

      Regards,

      Uwe

      (0) 
      1. Robin Vleeschhouwer

        Hi Uwe,

        Thanks for your quick response. I understand the wiring concept.

        I think i didn’t ask my question really clear.

        If we have a GAF with several steps and at the last step we want to save all the GUIBB’s. Some GUIBB’s have there own model.

        We have created a WD component with interface IF_FPM_TRANSACTION. We want to transfer all the GUIBB models to the transaction component.

        Wiring would be nice, but we have more sources to the transaction component. That is the reason why I would like to have more sources to a target. What would you do? We can always use a factory singleton, but if we do that then the wiring would not be needed anymore.

        Thanks in advance.

        Best regards,

        Robin Vleeschhouwer

        (0) 
        1. Uwe Kunath Post author

          Hi Robin,

          I see, this is in fact a problem which cannot be solved this way. What I tried in the past was the other way around: The AppController/transaction Handler serves as a wiring source and not as a target for a generic application model which contains several sub-models. But unfortunately an application controller/transaction handler may serve as a target only and not as a source. But I would give it another try and write what I found out.

          Regards,

          Uwe

          (0) 
  2. Rudy Clement

    Hi Uwe,

    I was getting up-to-date with the FPM blogs on SCN and found this one to be the most helpful for me. Thanks for sharing! It has always been a dilemma when defining the right data sharing technique. This list of pros and cons certainly helps!

    KR, Rudy.

    (0) 
  3. Marco Ustarroz

    Very clarifing blog! congrats!

    it would be nice to have a part II explaining different possibilities of data exchange but when using an AppCC implemented with an OO Abap class!!

    best regards,

    Marco.

    (0) 
  4. Glen Simpson

    Hi Uwe

    A very useful blog post. Thanks!

    I know your post is a few years old and I’m very late to the FPM party but I’ve reached the point that Marco was at… I’m trying to work out the best way to share data with an AppCC class when all the GUIBBs are connected via wiring (no singletons or shared data components).

    Any thoughts?

    Cheers

    Glen

    (0) 
    1. Uwe Kunath Post author

      Dear Glen,

      I guess you are referring to classes of type IF_FPM_APP_CONTROLLER.

      The only way we figured out here was to place a Freestyle UIBB with no visible view embedded in the FPM application.

      Then the AppCC Controller accesses the Freestyle UIBB via Singleton mechanisms. At least, the Freestyle Application Component is part of regular wiring this way…

      Regards,

      Uwe

      (0) 
  5. Siva Prasad Jena

    Hi Uwe,


    Is there any way to read/access the FPM screen personalization data ( like sorting of the fields on the list UIBB ) in the FPM feeder or appl controller class?

    Regards, Siva

    (0) 
    1. Uwe Kunath Post author

      Dear Siva,

      I don’t think that all of the data which you need is available in your feeder class. However, you may want to expose some data from the Parameters of the methods IF_FPM_GUIBB_LIST->GET_DATA or GET_DEFINITION and populate the data you Need via wiring. Using the invisible Freestyle UIBB I proposed to Glen might be a clean way to Exchange that data to a Feeder which serves as “Interface” to the AppCC.

      Regards,

      Uwe

      (0) 

Leave a Reply