SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Workflow Object Attributes and Macros



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> SAP Business Workflow
View previous topic :: View next topic  
Author Message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1639

PostPosted: Thu Dec 20, 2007 4:12 pm    Post subject: Workflow Object Attributes and Macros Reply with quote

Object Attributes
DB
Source: Database field
Macro: get_table_property <...>

DB/Object Ref
Source: Database field
Macro: get_table_property <...>

Virtual
Source: Virtual
Macro: get_property <...> changing container

Aggregate Attributes
BUS2105 (PurchaseRequisition) is the aggregate type of the object type BUS2009 (PurchaseReqItem).
BUS2105 has key PurchaseRequisition.Number
BUS2009 has key PurchaseReqItem.Number and PurchaseReqItem.Item
BUS2009 "is part of" BUS2105
PurchaseReqItem "is part of" PurchaseRequisition.

DB
SalesOrder.DocumentDate (Object VBAK)

Code:
* get_table_property is a macro that is the start of a database attribute
* implementation either referencing a database field or a database field and
* an object reference

get_table_property vbak.
DATA subrc LIKE sy-subrc.

PERFORM select_table_vbak USING subrc.
IF sy-subrc NE 0.
  exit_object_not_found.
ENDIF.
end_property.

FORM select_table_vbak USING subrc LIKE sy-subrc.

  IF object-_vbak-mandt IS INITIAL
  AND object-_vbak-vbeln IS INITIAL.
    SELECT SINGLE * FROM vbak CLIENT SPECIFIED
        WHERE mandt = sy-mandt
        AND vbeln = object-key-salesdocument.
    subrc = sy-subrc.
    IF subrc NE 0.
      EXIT.
    ENDIF.
    object-_vbak = vbak.
  ELSE.
    subrc = 0.
    vbak = object-_vbak.
  ENDIF.

ENDFORM.


DB/Object Ref
SalesOrder.OrderingParty (Object VBAK)
Same as DB example. Since it is a database source, the only code is the code populating the database row. So all database references to an attribute within this table will reference this same code. The difference is in the definition of the attribute it references the Object, KNA1, with the reference table/field being VBAK-KUNNR. Since this is the value to the single key in the object KNA1, it works.

Virtual
SalesOrder.CompanyCodeCurrency (Object VBAK)

Code:

* get_property <...> changing container is a macro that is the start of a virtual attribute
* implementation

get_property companycodecurrency changing container.

TABLES : tvko,
         t001.


DATA : BEGIN OF verkaufsorganisation,   " I don't think this is necessary
         vkorg LIKE vbak-vkorg,     
       END OF verkaufsorganisation.

DATA: salesorganization  TYPE swc_object.

* swc_get_property is a macro that retrieves a single value attribute of an object
* (This single value attribute can include another object)

swc_get_property self 'SalesOrganization' salesorganization. " self is an object
swc_get_property salesorganization                           " salesorganization is an object
                 'SalesOrganization'                         " SalesOrganization is an element
                 verkaufsorganisation-vkorg.                 " (actually it is the object key field)

* SalesOrganization is an object reference attribute in BUS2032
* "self" is a macro key word referring to the instantiation of
* the object within which this attribute is defined (BUS2032)
* The key for the object, SalesOrganization is
* SalesOrganization.SalesOrganization (vkorg)

SELECT SINGLE * FROM tvko WHERE vkorg = verkaufsorganisation-vkorg.
SELECT SINGLE * FROM t001 WHERE bukrs = tvko-bukrs.

object-companycodecurrency = t001-waers.

* swc_set_element <container> writes single value element from a
* variable to the container. The element is usually virtual but
* it can be database source

 swc_set_element container 'CompanyCodeCurrency'
     object-companycodecurrency.

end_property.

BEGIN_METHOD GETLIST CHANGING CONTAINER.
DATA:
      REQUISITIONER LIKE BAPIMMPARA-PREQ_NAME,
      ...

* swc_get_element is a macro that reads a single value element from the container
* It can be either virtual or from a database source
* 'Requisitioner' is an attribute (source db) in the object BUS2009. GETLIST is a method
* in this object.

  swc_get_element CONTAINER 'Requisitioner' REQUISITIONER.
      ...
END_METHOD.


Macro Instructions for Accessing Objects, Attributes and Methods

You can use these macros for simplifying access to Business Object Repository objects.

Prerequisites
The include file <OBJECT> must be incorporated into the program in order to use these macros.

Features
You must declare variables in which an object reference is to be stored with the following instruction:

DATA: <Object> TYPE SWC_OBJECT.

General macros
SWC_CREATE_OBJECT <Object> <ObjectType> <ObjectKey>.
Creates an object reference for an object key of an object type.

You must pass the object-specific key in <ObjectKey> and the ID of the object type in <ObjectType> . You must pass <ObjectType> either as a character string or as a variable declared with LIKE SWOTOBJID-OBJTYPE .

The object reference created is returned in the variable <Object> . You must declare <Object> with type SWC_OBJECT .

If the variable <ObjectKey> has the value SPACE , a reference to the object type is returned in <Object> . You can use this to query properties of the object type (attributes, methods, events).

SWC_REFRESH_OBJECT <Object>.
Object attributes that reference a database field are read from the database again when next accessed.

You must pass the object reference in <Object> . You must declare <Object> with type SWC_OBJECT .

You should use this macro instruction after execution of methods that can change attributes (for example Edit , Update , Change ).

SWC_GET_OBJECT_TYPE <Object> <ObjectType>.
The object type for the object reference is established.

You must pass the object reference in <Object> . You must declare <Object> with type SWC_OBJECT .

The object type is returned in the variable <ObjectType> . You can declare <ObjectType> with LIKE SWOTOBJID-OBJTYPE .

SWC_GET_OBJECT_KEY <Object> <ObjectKey>.
The object key for the object reference is established.

You must pass the object reference in <Object> . You must declare <Object> with type SWC_OBJECT .

The object key is returned in the variable <ObjectKey> . You can declare <ObjectKey> with LIKE SWOTOBJID-OBJKEY .

SWC_CALL_METHOD <Object> <Method> <Container>.
The method defined for an object type is executed on an object of this object type.

You must pass the object reference in <Object> and the method to be executed in <Method> . You must declare <Object> with type SWC_OBJECT .

The import parameters of the method are passed in the variable <Container> . The result and the export parameters of the method executed are also stored in <Container> . If the method called raises an exception, the number of the exception is stored in the system variable SY-SUBRC and any values in the variables SY-MSGV1 , ..., SY-MSGV4 .

An example of a call of this kind can be found in Programmed Call of Method.

If you pass SPACE for <Method> , the default method is executed.

You must pass a container even if no parameters are defined for the method called. Therefore you create and initialize an empty container with the following macro instructions:

SWC_CONTAINER <Container>.
SWC_CREATE_CONTAINER <Container>.

SWC_GET_PROPERTY <Object> <Attribute> <AttributeValue>.
SWC_GET_TABLE_PROPERTY <Object> <Attribute> <AttributeValue>.
The value of the specified attribute is established. If it is a virtual attribute, this is done dynamically.

You must pass the object reference in <Object> and the attribute or key field to be read in <Attribute> . You must declare <Object> with type SWC_OBJECT .

The value of the attribute or key field is returned in the variable <AttributeValue> . SWC_GET_PROPERTY returns a single value, SWC_GET_TABLE_PROPERTY returns a multiline value in an internal table.

An example of a call of this kind can be found in Programmed Access to an Attribute.

Executing macros on own object
All the macros in the section General macros can also be executed directly on the object itself in the implementation program. To do this, you replace <Object> with SELF in the macro calls.

Attribute values of the current object can be read by calling
SWC_GET_PROPERTY SELF <Attribute> <AttributeValue>.

Setting an object key
When implementing methods with which an object is created, the object key must be set. The typically applies to the methods Create and Find . Use the macro following macro instruction:

SWC_SET_OBJECTKEY <ObjectKey>.

The object key to be set is passed in the variable <ObjectKey> . An example of a call of this kind can be found in Programming Instance-Independent Methods.

Raising exceptions
Within the implementation program, you can raise the exceptions defined for a method. Use the macro following macro instruction:

EXIT_RETURN <Exception> <Var1> <Var2> <Var3> <Var4>.

Pass the number of the exception in <Exception> and the four task parameters displayed in <Var n> . The parameters can be SPACE . <Exception> must be declared with LIKE SWOTINVOKE-CODE .

INCLUDE <CNTN01>.
Code:

*************************** Macros *************************************
* Types
TYPES:
  SWC_OBJECT LIKE OBJ_RECORD.

* DATA Container
DEFINE SWC_CONTAINER.
DATA BEGIN OF &1 OCCURS 0.
  INCLUDE STRUCTURE SWCONT.
DATA END OF &1.
END-OF-DEFINITION.

*************************** Data Declaration ***************************
DATA BEGIN OF SWO_%RETURN.
  INCLUDE STRUCTURE SWOTRETURN.
DATA END OF SWO_%RETURN.
DATA SWO_%OBJID LIKE SWOTOBJID.
DATA SWO_%VERB LIKE SWOTLV-VERB.
SWC_CONTAINER SWO_%CONTAINER.

************************* Error Handling   *****************************
* set system error codes from structure SWOTRETURN
* P1    Returncode of structure SWOTRETURN
DEFINE SWC_%SYS_ERROR_SET.
  IF &1-CODE NE 0.
    SY-MSGID = &1-WORKAREA.
    SY-MSGNO = &1-MESSAGE.
    SY-MSGTY = 'E'.
    SY-MSGV1 = &1-VARIABLE1.
    SY-MSGV2 = &1-VARIABLE2.
    SY-MSGV3 = &1-VARIABLE3.
    SY-MSGV4 = &1-VARIABLE4.
  ENDIF.
  SY-SUBRC = &1-CODE.
END-OF-DEFINITION.

************************* Container Macros *****************************
*** for documentation see Online Documentation: Workflow Container
* Create Container
DEFINE SWC_CREATE_CONTAINER.
  CLEAR &1.
  REFRESH &1.
END-OF-DEFINITION.

* Release Container
DEFINE SWC_RELEASE_CONTAINER.
  CLEAR &1.
  REFRESH &1.
END-OF-DEFINITION.

* Clear Container
DEFINE SWC_CLEAR_CONTAINER.
  REFRESH &1.
  CLEAR &1.
END-OF-DEFINITION.

* Container Create Element
DEFINE SWC_CREATE_ELEMENT.
  CALL FUNCTION 'SWC_ELEMENT_CREATE'
       EXPORTING
            ELEMENT   = &2
       TABLES
            CONTAINER = &1
       EXCEPTIONS ALREADY_EXISTS = 4
                  OTHERS = 1.
END-OF-DEFINITION.

* Container Set Element
DEFINE SWC_SET_ELEMENT.
  CALL FUNCTION 'SWC_ELEMENT_SET'
       EXPORTING
            ELEMENT       = &2
            FIELD         = &3
       TABLES
            CONTAINER     = &1
       EXCEPTIONS OTHERS = 1.
END-OF-DEFINITION.

* Container Set Table
DEFINE SWC_SET_TABLE.
  CALL FUNCTION 'SWC_TABLE_SET'
       EXPORTING
            ELEMENT       = &2
       TABLES
            CONTAINER     = &1
            TABLE         = &3
       EXCEPTIONS OTHERS = 1.
END-OF-DEFINITION.

* Container Get Element
DEFINE SWC_GET_ELEMENT.
  CALL FUNCTION 'SWC_ELEMENT_GET'
       EXPORTING
            ELEMENT       = &2
       IMPORTING
            FIELD         = &3
       TABLES
            CONTAINER     = &1
       EXCEPTIONS NOT_FOUND = 8
                  IS_NULL   = 4
                  OTHERS = 1.
END-OF-DEFINITION.

* Container Get Table
DEFINE SWC_GET_TABLE.
  CALL FUNCTION 'SWC_TABLE_GET'
       EXPORTING
            ELEMENT       = &2
       TABLES
            CONTAINER     = &1
            TABLE         = &3
       EXCEPTIONS NOT_FOUND = 8
                  IS_NULL   = 4
                  OTHERS = 1.
END-OF-DEFINITION.

* Container Lіschen Element
DEFINE SWC_DELETE_ELEMENT.
  CALL FUNCTION 'SWC_ELEMENT_DELETE'
       EXPORTING
            ELEMENT   = &2
       TABLES
            CONTAINER = &1
       EXCEPTIONS OTHERS = 1.
END-OF-DEFINITION.

* Kopieren Container1/Element1 -> Container2/Element2
* Parameters:  P1  Quellcontainer
*              P2  Quellelement
*              P3  Zielcontainer
*              P4  Zielelement
DEFINE SWC_COPY_ELEMENT.
  CALL FUNCTION 'SWC_ELEMENT_COPY'
       EXPORTING
            SOURCE_ELEMENT   = &2
            TARGET_ELEMENT   = &4
       TABLES
            SOURCE_CONTAINER = &1
            TARGET_CONTAINER = &3
       EXCEPTIONS
            NOT_FOUND        = 1
            IS_NULL          = 2
            OTHERS           = 3.
END-OF-DEFINITION.


*************** Container Object Macros ********************************
* Create Object Reference
* Parameters: P1   Object Reference to be created,  Output
*             P2   Type of the Object, Input
*             P3   Key of the Object, Input
DEFINE SWC_CREATE_OBJECT.
  SWO_%OBJID-OBJTYPE = &2.
  SWO_%OBJID-OBJKEY = &3.
  &1-HEADER = 'OBJH'.
  &1-TYPE   = 'SWO '.
  CALL FUNCTION 'SWO_CREATE'
       EXPORTING
            OBJTYPE = SWO_%OBJID-OBJTYPE
            OBJKEY  = SWO_%OBJID-OBJKEY
       IMPORTING
            OBJECT  = &1-HANDLE
            RETURN  = SWO_%RETURN.
  IF SWO_%RETURN-CODE NE 0.
    &1-HANDLE = 0.
  ENDIF.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.

* Create Object Reference
* Parameters: P1   Object Reference to be created,  Output
*             P2   Type of the Object, Input
*             P3   Key of the Object, Input
*             P4   Object Location (logical system), Input
DEFINE SWC_CREATE_REMOTE_OBJECT.
  SWO_%OBJID-OBJTYPE = &2.
  SWO_%OBJID-OBJKEY  = &3.
  SWO_%OBJID-LOGSYS  = &4.
  &1-HEADER          = 'OBJH'.
  &1-TYPE            = 'SWO '.
  CALL FUNCTION 'SWO_CREATE'
       EXPORTING
            OBJTYPE        = SWO_%OBJID-OBJTYPE
            OBJKEY         = SWO_%OBJID-OBJKEY
            LOGICAL_SYSTEM = SWO_%OBJID-LOGSYS
       IMPORTING
            OBJECT         = &1-HANDLE
            RETURN         = SWO_%RETURN.
  IF SWO_%RETURN-CODE NE 0.
    &1-HANDLE = 0.
  ENDIF.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.

* Free Object Reference
* Parameters: P1   Object Reference to be freed,  Input
DEFINE SWC_FREE_OBJECT.
  CALL FUNCTION 'SWO_FREE'
       EXPORTING
            OBJECT  = &1-HANDLE
       IMPORTING
            RETURN  = SWO_%RETURN.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.

* Get Object Type
* Parameters: P1   Object Reference , Input
*             P2   Name of the Objecttype, Output
DEFINE SWC_GET_OBJECT_TYPE.
  CALL FUNCTION 'SWO_OBJECT_ID_GET'
       EXPORTING
            OBJECT  = &1-HANDLE
       IMPORTING
            RETURN  = SWO_%RETURN
            OBJID   = SWO_%OBJID.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
  &2 = SWO_%OBJID-OBJTYPE.
END-OF-DEFINITION.

* Get Object Key
* Parameters: P1   Object Reference,  Input
*             P2   Object Key, Output
DEFINE SWC_GET_OBJECT_KEY.
  CALL FUNCTION 'SWO_OBJECT_ID_GET'
       EXPORTING
            OBJECT  = &1-HANDLE
       IMPORTING
            RETURN  = SWO_%RETURN
            OBJID   = SWO_%OBJID.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
  &2 = SWO_%OBJID-OBJKEY.
END-OF-DEFINITION.

* Get Property
* Parameters: P1   Object Reference,  Input
*             P2   Attribute Name, Input
*             P3   Value of the attribute, Output
DEFINE SWC_GET_PROPERTY.
  SWC_CREATE_CONTAINER SWO_%CONTAINER.
  CALL FUNCTION 'SWO_INVOKE'
       EXPORTING
            ACCESS     = 'G'
            OBJECT     = &1-HANDLE
            VERB       = &2
            PERSISTENT = ' '
       IMPORTING
            RETURN     = SWO_%RETURN
            VERB       = SWO_%VERB
       TABLES
            CONTAINER  = SWO_%CONTAINER.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
  IF SY-SUBRC = 0.
    SWC_GET_ELEMENT SWO_%CONTAINER SWO_%VERB &3.
  ENDIF.
END-OF-DEFINITION.

* Get Table Property
* Parameters: P1   Object Reference,  Input
*             P2   Table Attribute Name, Input
*             P3   Value of the table attribute, Output
DEFINE SWC_GET_TABLE_PROPERTY.
  SWC_CREATE_CONTAINER SWO_%CONTAINER.
  CALL FUNCTION 'SWO_INVOKE'
       EXPORTING
            ACCESS     = 'G'
            OBJECT     = &1-HANDLE
            VERB       = &2
            PERSISTENT = ' '
       IMPORTING
            RETURN     = SWO_%RETURN
            VERB       = SWO_%VERB
       TABLES
            CONTAINER  = SWO_%CONTAINER.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
  IF SY-SUBRC = 0.
    SWC_GET_TABLE SWO_%CONTAINER SWO_%VERB &3.
  ENDIF.
END-OF-DEFINITION.

* Invoke Method
* Parameters: P1   Object Reference,  Input
*             P2   Method Name, Input
*             P3   Container with Import and Export parameters, In/Out
DEFINE SWC_CALL_METHOD.
  CALL FUNCTION 'SWO_INVOKE'
       EXPORTING
            ACCESS     = 'C'
            OBJECT     = &1-HANDLE
            VERB       = &2
            PERSISTENT = ' '
       IMPORTING
            RETURN     = SWO_%RETURN
       TABLES
            CONTAINER  = &3.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.

* Invoke Method asynchronously
* Parameters: P1   Object Reference,  Input
*             P2   Method Name, Input
*             P3   Container with Import and Export parameters, In/Out
DEFINE SWC_CALL_METHOD_ASYNC.
  CALL FUNCTION 'SWO_INVOKE'
       EXPORTING
            ACCESS     = 'C'
            OBJECT     = &1-HANDLE
            VERB       = &2
            PERSISTENT = ' '
            SYNCHRON   = ' '
            no_arfc    = 'X'
       importing
            RETURN     = SWO_%RETURN
       TABLES
            CONTAINER  = &3.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.

* Refresh Object Properties
* Parameters: P1   Object Reference,  Input
DEFINE SWC_REFRESH_OBJECT.
  CALL FUNCTION 'SWO_OBJECT_REFRESH'
       EXPORTING
            OBJECT       = &1
       EXCEPTIONS
            ERROR_CREATE = 02.
END-OF-DEFINITION.
***************** Events ***********************************************
* Raise Event
* Parameters: P1   Objectreference, Input
*             P2   Event Name, Input
*             P3   Event container with export parameters, Input
DEFINE SWC_RAISE_EVENT.
  IF &1-HANDLE > 0.
    SWC_CREATE_CONTAINER SWO_%CONTAINER.
    LOOP AT &3.
      SWO_%CONTAINER = &3.
      APPEND SWO_%CONTAINER.
    ENDLOOP.
*   Make container a persistent
    CALL FUNCTION 'SWC_CONT_PERSISTENT_CONVERT'
       EXPORTING
            FROM_PERSISTENT = ' '
            TO_PERSISTENT   = 'X'
       IMPORTING
            RETURN          = SWO_%RETURN
       TABLES
            CONTAINER       = SWO_%CONTAINER
       EXCEPTIONS
            OTHERS          = 1.
    IF SWO_%RETURN-CODE = 0.
*     Raise event
      SWC_GET_OBJECT_TYPE &1 SWO_%OBJID-OBJTYPE.
      SWC_GET_OBJECT_KEY &1 SWO_%OBJID-OBJKEY.
      CALL FUNCTION 'SWE_EVENT_CREATE'
         EXPORTING
              OBJTYPE              = SWO_%OBJID-OBJTYPE
              OBJKEY               = SWO_%OBJID-OBJKEY
              EVENT                = &2
         TABLES
              EVENT_CONTAINER      = SWO_%CONTAINER
         EXCEPTIONS
              OBJTYPE_NOT_FOUND    = 1
              OTHERS               = 2.
    ELSE.
      SWC_%SYS_ERROR_SET SWO_%RETURN.
    ENDIF.
  ELSE.
    SY-SUBRC = 4.
  ENDIF.
END-OF-DEFINITION.

************ Converting containers *************************************
* Convert persistent container to runtime format
* Parameters: P1   Container, In/Out
*             P2   from persistent,  In
*             P3   to persistent,    In
DEFINE SWC_CONTAINER_CONVERT.
  CALL FUNCTION 'SWC_CONT_PERSISTENT_CONVERT'
     EXPORTING
          FROM_PERSISTENT = &2
          TO_PERSISTENT   = &3
     IMPORTING
          RETURN          = SWO_%RETURN
     TABLES
          CONTAINER       = &1
     EXCEPTIONS
          OTHERS          = 1.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
END-OF-DEFINITION.
* Convert persistent container to runtime format
* Parameters: P1   Container, In/Out
DEFINE SWC_CONTAINER_TO_RUNTIME.
  SWC_CONTAINER_CONVERT &1 'X' ' '.
END-OF-DEFINITION.
* Make container persistent
* Parameters: P1   Container, In/Out
DEFINE SWC_CONTAINER_TO_PERSISTENT.
  SWC_CONTAINER_CONVERT &1 ' ' 'X'.
END-OF-DEFINITION.

* Convert handle to persistent object reference
* Parameters:   P1   object handle,   In
*               P2   persistent object reference (SWOTOBJID),   Out
DEFINE SWC_OBJECT_TO_PERSISTENT.
  CALL FUNCTION 'SWO_OBJECT_ID_GET'
       EXPORTING
            OBJECT  = &1-HANDLE
       IMPORTING
            RETURN  = SWO_%RETURN
            OBJID   = SWO_%OBJID.
  SWC_%SYS_ERROR_SET SWO_%RETURN.
  &2 = SWO_%OBJID.
END-OF-DEFINITION.

* Convert persistent object reference to runtime handle
* Parameters:   P1   persistent object reference (SWOTOBJID),   Out
*               P2   object handle,   In
DEFINE SWC_OBJECT_FROM_PERSISTENT.
  SWC_CREATE_OBJECT &2 &1-OBJTYPE &1-OBJKEY.
END-OF-DEFINITION.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> SAP Business Workflow All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.