Show TOC

Model Provider Class (MPC)Locate this document in the navigation structure

Method DEFINE
Declaration
                 DATA  lo_carrier_object         TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
  DATA  lo_carrier_entity_type    TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
  DATA  lo_carrier_entity_set     TYPE REF TO /iwbep/if_mgw_odata_entity_set.

  DATA  lo_flight_object          TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
  DATA  lo_flight_entity_type     TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
  DATA  lo_flight_entity_set      TYPE REF TO /iwbep/if_mgw_odata_entity_set.
  DATA  lo_flight_complex_type    TYPE REF TO /iwbep/if_mgw_odata_cmplx_type.

  DATA  lo_annotation             TYPE REF TO /iwbep/if_mgw_odata_annotation.
  DATA  lo_association            TYPE REF TO /iwbep/if_mgw_odata_assoc.
  DATA  lo_property               TYPE REF TO /iwbep/if_mgw_odata_property.
  DATA  lo_action                 TYPE REF TO /iwbep/if_mgw_odata_action.
  DATA  lo_parameter              TYPE REF TO /iwbep/if_mgw_odata_parameter.

            
Entity

Flight

               *----------------------------------------------------------------------------------
* Flight (Entity)
*----------------------------------------------------------------------------------

* first creating the flight data object
  lo_flight_object = model->create_entity_type( 'Flight' ).

* using the convinience interface for creating the properies in a bulk manner 
* instead of calling create_property for each property
  lo_property = lo_flight_object->create_property( 'carrid' ).
* set it as a key element
  lo_property->set_is_key( ).

* one could also use different names for the fields in the abap structure 
* (iv_abap_fieldname) and external representations (iv_property_name).
*  by default external names are converted to uppercase so that the following 
*  would have the same result when leaving out the
*  iv_abap_fieldname parameter. iv_abap_fieldname must be used according to the 
*  constraints of a fieldname in an abap structure: no spaces etc...
  lo_property = lo_flight_object->create_property(
    iv_property_name = 'connid'
    iv_abap_fieldname = 'CONNID'
  ).
  lo_property->set_is_key( ).

  lo_property = lo_flight_object->create_property( 'fldate' ).
  lo_property->set_is_key( ).

  lo_property = lo_flight_object->create_property( 'PRICE' ).
  lo_property->set_unit( 'CURRENCY' ).
  lo_property->set_sortable( ).

  lo_property = lo_flight_object->create_property( 'CURRENCY' ).
  lo_property->set_semantic( /iwbep/cl_mgw_abs_model=>gcs_sap_semantic-currency_code ).
  lo_property->set_sortable( abap_false ).

  lo_property = lo_flight_object->create_property( 'PLANETYPE' ).
* Set text type to class text element
  lo_property->set_label_from_text_element(
    iv_text_element_symbol = '000'
    io_object_ref = me
  ).


  lo_flight_object->create_property( 'SEATSMAX' ).
  lo_flight_object->create_property( 'SEATSOCC' ).
  lo_flight_object->create_property( 'PAYMENTSUM' ).
  lo_flight_object->create_property( 'SEATSMAX_B' ).
  lo_flight_object->create_property( 'SEATSOCC_B' ).
  lo_flight_object->create_property( 'SEATSMAX_F' ).
  lo_flight_object->create_property( 'SEATSOCC_F' ).

* a structure is bound to the data object, so all properties which are already defined or those
*  which were newly created were matched to the meta data of the ddic via the abap names. 
*  Texts, type info etc is gotten from the data elements
  lo_flight_object->bind_structure( '/IWBEP/CL_MGW_RT_SFLIGHT=>TY_S_SFLIGHT' ).
*  lo_flight_object->bind_structure( 'SFLIGHT' ).

* set it to read-only
  lo_flight_object->set_updatable( abap_false ).
  lo_flight_object->set_creatable( abap_false ).
  lo_flight_object->set_deletable( abap_false ).

             

Carrier

               *----------------------------------------------------------------------------------
* Carrier (Entity)
*----------------------------------------------------------------------------------
* carrier object gets defined
  lo_carrier_object = model->create_entity_type( 'Carrier' ).

  lo_property = lo_carrier_object->create_property( 'carrid' ).
  lo_property->set_is_key( ).
  lo_property->set_filterable( abap_true ).

  lo_carrier_object->create_property( 'CARRNAME' ).

  lo_carrier_object->create_property( 'CURRCODE' ).

  lo_property = lo_carrier_object->create_property( 'URL' ).

* must be set when data object is a media type to mark the property which represents the url
  lo_property->set_fc_target_path(
    iv_keep_in_content = abap_true
    iv_fc_target_path = gcs_fc_target_path-media_content_src
  ).

  lo_carrier_object->bind_structure( 'SCARR' ).

* setting a data object as media type means that it gets a special semantic by having a url *  and allows streaming etc.
  lo_carrier_object->set_is_media( ).

  lo_property = lo_carrier_object->create_property(
    iv_property_name  = 'mimeType'
    iv_abap_fieldname = 'MIME_TYPE'
  ).
* must be set when data object is a media type to mark the property which represents the 
*  mime type information
  lo_property->set_fc_target_path(
    iv_keep_in_content = abap_true
    iv_fc_target_path  = gcs_fc_target_path-media_content_type
  ).

  lo_property->bind_data_element( 'SAEMIME' ).
  lo_property->set_filterable( abap_false ).

* set it to read-only
  lo_carrier_object->set_updatable( abap_false ).
  lo_carrier_object->set_creatable( abap_false ).
  lo_carrier_object->set_deletable( abap_false ).

            
Entity Collection

Flight Collection

A collection is created by default referencing to the <entity type>. The name is the <entity type>Collection. This means that the coding as listed below can be ignored.

               *----------------------------------------------------------------------------------
* FlightCollection (EntityCollection)
*----------------------------------------------------------------------------------

* create an entityset name, by default there is a entityset called <entity type>Collection, 
*  so the following could be also ignored
  lo_flight_entity_type = model->get_entity_type( 'Flight' ).
  lo_entity_set = lo_flight_entity_type->create_entity_set( 'FlightCollection' ).
  lo_entity_set->set_pageable( ).
  lo_entity_set->set_addressable( ).

* creating annotations generic extentions for entities by creating first a container 
*  with the proper namespace
  lo_annotation = lo_entity_set->create_annotation( iv_annotation_namespace = 'gp' ).
* and then adding key value pairs
  lo_annotation->add(
    iv_key   = 'collectionLayout'
    iv_value = ''
  ).
* there is also the possibility to create sub elements, but that's it so the result 
*  will be something like that <... gp:collectionLayout
  lo_annotation->add_child(
    iv_parent_key = 'collectionLayout'
    iv_key   = 'top-level'
    iv_value = 'true'
  ).

  lo_annotation->add_child(
    iv_parent_key = 'collectionLayout'
    iv_key   = 'display-order'
    iv_value = '0010'
  ).

            

Carrier Collection: Collections do not have to be defined explicitly, as stated above.

Complex Type

Flight Details

               *----------------------------------------------------------------------------------
* FlightDetails (Complex Type)
*----------------------------------------------------------------------------------

* defining now a complex type each property one by one with some of them having 
*  different external representations
  lo_flight_complex_type = model->create_complex_type( 'FlightDetails' ).

  lo_flight_complex_type->set_label_from_text_element(
    iv_text_element_symbol = '004'
    io_object_ref          = me
  ).

  lo_property = lo_flight_complex_type->create_property(
    iv_property_name  = 'countryFrom'
    iv_abap_fieldname = 'COUNTRYFR'
  ).
  lo_property->set_nullable( ).

  lo_property = lo_flight_complex_type->create_property( 'cityFrom' ).
  lo_property->set_conversion_exit( 'ZCITY' ).

  lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'AIRPFROM'
    iv_property_name  = 'airportFrom'
  ).

  lo_property = lo_flight_complex_type->create_property( 'countryTo' ).
  lo_property->set_nullable( ).

  lo_flight_complex_type->create_property( 'cityTo' ).

  lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'AIRPTO'
    iv_property_name  = 'airportTo'
  ).

  lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'FLTIME'
    iv_property_name  = 'flightTime'
  ).

  lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'DEPTIME'
    iv_property_name  = 'departureTime'
  ).

  lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'ARRTIME'
    iv_property_name  = 'arrivalTime'
  ).

  lo_property = lo_flight_complex_type->create_property( 'distance' ).
  lo_property->set_unit( 'distanceUnit' ).

  lo_property = lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'DISTID'
    iv_property_name  = 'distanceUnit'
  ).
  lo_property->set_nullable( ).
  lo_property->set_semantic( /iwbep/cl_mgw_abs_model=>gcs_sap_semantic-unit_of_measure ).

  lo_property = lo_flight_complex_type->create_property(
    iv_abap_fieldname = 'FLTYPE'
    iv_property_name  = 'flightType'
  ).
  lo_property->set_nullable( ).

  lo_flight_complex_type->create_property( 'period' ).

  lo_flight_complex_type->bind_structure( 'SPFLI' ).

* now the complex type is added to the data object which means that the flight gets an substructure
  lo_flight_object->create_complex_property(
    iv_property_name     = 'flightDetails'
    iv_complex_type_name = 'FlightDetails'
  ).

* annotation on complex type
  lo_annotation = lo_flight_complex_type->create_annotation( 'gp' ).
  lo_annotation->add(
    iv_key   = 'display-order'
    iv_value = '0010'
  ).

            
Function Import

Get Available Flights

               *----------------------------------------------------------------------------------
* GetAvailableFlights (Function Import)
*----------------------------------------------------------------------------------

* create an additional action GetAvailableFlights which has a special query semantic of only
* returning the available flights - the same can be done using the filter options in get_entityset
  lo_action = model->create_action( 'GetAvailableFlights' ).
  lo_action->set_return_entity_type( 'Flight' ).

* the http method which is used to execute the action.
  lo_action->set_http_method( 'GET' )."only GET method is allowed if return type is a feed

* the return multiplicity tells if it will be a feed/entity set or a single entity.
* For complex types only single entity is supported
  lo_action->set_return_multiplicity( cardinality_feed ).

* create also input parameters
  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'fromdate'
    iv_abap_fieldname = 'FROMDATE'
  ).
  lo_parameter->bind_data_element( 'S_DATE' ).

  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'todate'
    iv_abap_fieldname = 'TODATE'
  ).
  lo_parameter->bind_data_element( 'S_DATE' ).

  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'cityfrom'
    iv_abap_fieldname = 'CITYFROM'
  ).
  lo_parameter->bind_data_element( 'S_FROM_CIT' ).

  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'cityto'
    iv_abap_fieldname = 'CITYTO'
  ).
  lo_parameter->bind_data_element( 'S_TO_CITY' ).

            

Get Flight Details

               *----------------------------------------------------------------------------------
* GetFlightDetails (Function Import)
*----------------------------------------------------------------------------------

* create an additional action GetFlightDetails which has a special query semantic
* of only returning the flight details
  lo_action = model->create_action( 'GetFlightDetails' ).
  lo_action->set_return_complex_type( 'FlightDetails' ).

* mark the action for a specific entity type
  lo_action->set_action_for( 'Flight' ).

* the return multiplicity tells if it will be a feed/entity set or a single entity.
* For complex types only single entity is supported
  lo_action->set_return_multiplicity( /iwbep/if_mgw_med_odata_types=>gcs_cardinality-cardinality_1_1 ).

* create input parameters
  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'airlineid'
    iv_abap_fieldname = 'AIRLINEID'
  ).
  lo_parameter->bind_data_element( 'S_CARR_ID' ).

  lo_parameter = lo_action->create_input_parameter(
    iv_parameter_name = 'connectionid'
    iv_abap_fieldname = 'CONNECTIONID'
  ).
  lo_parameter->bind_data_element( 'S_CONN_ID' ).

            
Assocications
               *----------------------------------------------------------------------------------
* Carrier2Flight (Association)
*----------------------------------------------------------------------------------

* now create an association to connect carriers with flights:
  lo_association = model->create_association(
      iv_association_name = 'CarrierToFlight'
      iv_left_type        = 'Carrier'
      iv_right_type       = 'Flight'
      iv_left_card        = cardinality_entity
      iv_right_card       = cardinality_feed
  ).

* now create an association to connect carriers with flights:
  lo_association = model->create_association(
      iv_association_name = 'FlightToCarrier'
      iv_left_type        = 'Flight'
      iv_right_type       = 'Carrier'
      iv_left_card        = cardinality_feed
      iv_right_card       = cardinality_entity
  ).

            
Navigation Properties

Navigation properties can only be used if the corresponding association is available. This means, if one of the above associations is deleted and the corresponding navigation property is not the service is invalidated and will cause an error during runtime.

               *----------------------------------------------------------------------------------
* Carrier2Flight / Flight2Carrier (Navigation Properties)
*----------------------------------------------------------------------------------

* and now the navigations (in this case bidirectional) are defined based on the same association
  lo_carrier_object->create_navigation_property(
    iv_property_name    = 'CarrierFlights'
    iv_association_name = 'CarrierToFlight'
  ).

* and now the navigations (in this case bidirectional) are defined based on the same association
  lo_flight_object->create_navigation_property(
    iv_property_name    = 'FlightCarrier'
    iv_association_name = 'FlightToCarrier'
  ).

            
Method GET_LAST_MODIFIED

Method GET_LAST_MODIFIED does not have to be redefined. The last modified time stamp is evaluated based on the last coding change.