
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.
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 ).
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'
).
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' ).
*----------------------------------------------------------------------------------
* 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 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 does not have to be redefined. The last modified time stamp is evaluated based on the last coding change.