xotcl.wu-wien.ac.at
Begin main content
Methods: Source: Variables:
[All Methods | Documented Methods | Hide Methods] [Display Source | Hide Source] [Show Variables | Hide Variables]

::xotcl::Class[i] ::xo::db::CrClass

Class Hierarchy of ::xo::db::CrClass

  • ::xotcl::Object[i]
    Meta-class:
    ::xotcl::Class[i]
    Methods for instances:
    __api_make_doc, __api_make_forward_doc, __timediff, abstract, ad_doc, ad_forward, ad_proc, appendC, arrayC, asHTML, autonameC, check, classC, cleanupC, configureC, containsC, copyC, db_0or1rowC, db_1rowC, debug, defaultmethodC, destroyC, destroy_on_cleanup, ds, evalC, existsC, extractConfigureArg, filterC, filterguardC, filtersearch, forward, hasclass, incrC, infoC, init, instvarC, invarC, isclass, ismetaclass, ismixin, isobject, istype, lappendC, log, method, mixinC, mixinguardC, moveC, msg, noinitC, objectparameter, parametercmdC, proc, procsearch, qn, requireNamespaceC, residualargsC, self, serialize, setC, set_instance_vars_defaults, show-object, substC, traceC, unknown, unsetC, uplevelC, upvarC, volatileC, vwait
    Methods to be applied on the class (in addition to the methods provided by the meta-class):
    getExitHandler, setExitHandler, unsetExitHandler

The meta class CrClass serves for a class of applications that mostly store information in the content repository and that use a few attributes adjoining this information. The class handles the open acs object_type creation and the automatic creation of the necessary tables based on instances of this meta-class.

The definition of new types is handled in the constructor of CrType through the method create_object_type, the removal of the object type is handled through the method drop_object_type (requires that all instances of this type are deleted).

Each content item can be retrieved either through the general method CrClass get_instance_from_db or through the "get_instance_from_db" method of every subclass of CrItem.

This Class is a meta-class providing methods for Classes managing CrItems.

Defined in packages/xotcl-core/tcl/cr-procs.tcl

Class Relations

  • superclass: ::xo::db::Class[i]
  • instmixin: ::xo::db::CrCache[i]
  • mixin: ::xo::db::CrCache::Class[i]
::xotcl::Class create ::xo::db::CrClass \
     -superclass ::xo::db::Class \
     -parameter {edit_form {folder_id -100} form {mime_type text/plain} {storage_type "text"} \
       {supertype content_revision}} \
     -instmixin ::xo::db::CrCache \
     -mixin ::xo::db::CrCache::Class

Methods

  • proc delete (public)

    ::xo::db::CrClass[i] delete [ -item_id item_id ]
    Delete a CrItem in the database

    Switches:
    -item_id (optional)
    ::1034086 proc delete -item_id {
        set object_type [my get_object_type -item_id $item_id]
        $object_type delete -item_id $item_id
      }
    
  • proc get_child_item_ids (public)

    ::xo::db::CrClass[i] get_child_item_ids -item_id item_id 
    Return a list of content items having the provided item_id as direct or indirect parent. The method returns recursively all item_ids.

    Switches:
    -item_id (required)
    Returns:
    list of item_ids
    ::1034086 proc get_child_item_ids -item_id:required {
        set items [list]
        foreach item_id [::xo::db_list get_child_items  "select item_id from cr_items where parent_id = :item_id"] {
          lappend items $item_id {*}[my [self proc] -item_id $item_id]
        }
        return $items
      }
    
  • proc get_instance_from_db (public)

    ::xo::db::CrClass[i] get_instance_from_db [ -item_id item_id ] \
        [ -revision_id revision_id ]
    Instantiate the live revision or the specified revision of an CrItem. The XOTcl object is destroyed automatically on cleanup (end of a connection request).

    Switches:
    -item_id (defaults to "0") (optional)
    -revision_id (defaults to "0") (optional)
    Returns:
    fully qualified object containing the attributes of the CrItem
    ::1034086 proc get_instance_from_db {{-item_id 0} {-revision_id 0}} { 
        set object_type [my get_object_type -item_id $item_id -revision_id $revision_id]
        set class [::xo::db::Class object_type_to_class $object_type]
        return [$class get_instance_from_db -item_id $item_id -revision_id $revision_id]
      }
    
  • proc get_name (public)

    ::xo::db::CrClass[i] get_name -item_id item_id 
    Get the name of a content item either from an already instantiated object or from the database without instantiating it. If item_id is not a valid item_id, we throw an error.

    Switches:
    -item_id (required)
    Returns:
    parent_id
    ::1034086 proc get_name -item_id:required { 
        # TODO: the following line is deactivated, until we get rid of the "folder object" in xowiki
        #if {[my isobject ::$item_id]} {return [::$item_id parent_id]}
        ::xo::db_1row get_name "select name from cr_items where item_id = :item_id"
        return $name
      }
    
  • proc get_object_type (public)

    ::xo::db::CrClass[i] get_object_type [ -item_id item_id ] \
        [ -revision_id revision_id ]
    Return the object type for an item_id or revision_id.

    Switches:
    -item_id (optional)
    -revision_id (defaults to "0") (optional)
    Returns:
    object_type typically an XOTcl class
    ::1034086 proc get_object_type {-item_id {-revision_id 0}} {
        set object_type [ns_cache eval xotcl_object_type_cache  [expr {$item_id ? $item_id : $revision_id}] {
          if {$item_id} {
            ::xo::db_1row get_class_from_item_id  "select content_type as object_type from cr_items where item_id=$item_id"
          } else {
            ::xo::db_1row get_class_from_revision_id  "select object_type from acs_objects where object_id=$revision_id"
          }
          return $object_type
        }]
      }
    
  • proc get_parent_id (public)

    ::xo::db::CrClass[i] get_parent_id -item_id item_id 
    Get the parent_id of a content item either from an already instantiated object or from the database without instantiating it. If item_id is not a valid item_id, we throw an error.

    Switches:
    -item_id (required)
    Returns:
    parent_id
    ::1034086 proc get_parent_id -item_id:required { 
        # TODO: the following line is deactivated, until we get rid of the "folder object" in xowiki
        #if {[my isobject ::$item_id]} {return [::$item_id parent_id]}
        ::xo::db_1row get_parent "select parent_id from cr_items where item_id = :item_id"
        return $parent_id
      }
    
  • proc lookup (public)

    ::xo::db::CrClass[i] lookup -name name  [ -parent_id parent_id ]
    Check, whether an content item with the given name exists. If the item exists, return its item_id, otherwise 0.

    Switches:
    -name (required)
    -parent_id (defaults to "-100") (optional)
    Returns:
    item_id
    ::1034086 proc lookup {-name:required {-parent_id -100}} {
        return [::xo::db_string entry_exists_select {
          select item_id from cr_items where name = :name and parent_id = :parent_id
        } 0]
      }
    
  • proc require_folder_object (public)

    ::xo::db::CrClass[i] require_folder_object [ -folder_id folder_id ] \
        [ -package_id package_id ]
    Dummy stub; let specializations define it

    Switches:
    -folder_id (optional)
    -package_id (optional)
    ::1034086 proc require_folder_object {-folder_id -package_id} {
      }
    
  • instproc create_object_type (public)

    <instance of ::xo::db::CrClass[i]> create_object_type
    Create an oacs object_type and a table for keeping the additional attributes.

    ::1034086 instproc create_object_type {} {
        my instvar object_type supertype pretty_name pretty_plural  table_name id_column name_method
    
        my check_table_atts
    
        set supertype [my info superclass]
        switch -- $supertype {
          ::xotcl::Object -
          ::xo::db::CrItem {set supertype content_revision}
        }
        if {![info exists pretty_plural]} {set pretty_plural $pretty_name}
    
        db_transaction {
          ::xo::db::sql::content_type create_type  -content_type $object_type  -supertype $supertype  -pretty_name $pretty_name  -pretty_plural $pretty_plural  -table_name $table_name  -id_column $id_column  -name_method $name_method
          
          my folder_type register
        }
      }
    
  • instproc delete (public)

    <instance of ::xo::db::CrClass[i]> delete -item_id item_id 
    Delete a content item from the content repository.

    Switches:
    -item_id (required)
    id of the item to be deleted
    ::1034086 instproc delete -item_id:required {
        ::xo::db::sql::content_item del -item_id $item_id
      }
    
  • instproc drop_object_type (public)

    <instance of ::xo::db::CrClass[i]> drop_object_type
    Delete the object type and remove the table for the attributes. This method should be called when all instances are deleted. It undoes everying what create_object_type has produced.

    ::1034086 instproc drop_object_type {} {
        my instvar object_type table_name
        db_transaction {
          my folder_type unregister
          ::xo::db::sql::content_type drop_type  -content_type $object_type  -drop_children_p t  -drop_table_p t
        }
      }
    
  • instproc edit_atts

    ::1034086 instproc edit_atts {} {
        # TODO remove, when name and text are slots (only for generic)
        my array names db_slot
      }
    
  • instproc fetch_object (public)

    <instance of ::xo::db::CrClass[i]> fetch_object -item_id item_id  \
        [ -revision_id revision_id ] -object object  \
        [ -initialize initialize ]
    Load a content item into the specified object. If revision_id is provided, the specified revision is returned, otherwise the live revision of the item_id. If the object does not exist, we create it.

    Switches:
    -item_id (required)
    -revision_id (defaults to "0") (optional)
    -object (required)
    -initialize (defaults to "true") (optional)
    Returns:
    cr item object
    ::1034086 instproc fetch_object {-item_id:required {-revision_id 0} -object:required {-initialize true}} {
        #my log "-- [self args]"
        if {![::xotcl::Object isobject $object]} {
          # if the object does not yet exist, we have to create it
          my create $object
        }
        set raw_atts [::xo::db::CrClass set common_query_atts]
        #my log "-- raw_atts = '$raw_atts'"
    
        set atts [list]
        foreach v $raw_atts {
          switch -glob -- $v {
            publish_status {set fq i.$v}
            creation_date  {set fq o.$v}
            creation_user  {set fq o.$v}
            package_id     {set fq o.$v}
            default        {set fq n.$v}
          }
          lappend atts $fq
        }
        foreach {slot_name slot} [my array get db_slot] {
          switch -- $slot {
    	::xo::db::CrItem::slot::text {
    	  # We need the rule, since insert the handling of the sql
    	  # attribute "text" is somewhat magic. On insert, one can use the
    	  # automatic view with column_name "text, on queries, one has to use
    	  # "data". Therefore, we cannot use simply -column_name for the slot.
    	  lappend atts "n.data AS text"
    	}
    	::xo::db::CrItem::slot::name {
    	  lappend atts i.[$slot column_name]
    	}
    	default {
    	  lappend atts n.[$slot column_name]
    	}
          }
        }
        if {$revision_id} {
          $object db_1row [my qn fetch_from_view_revision_id] " select [join $atts ,], i.parent_id  from   [my set table_name]i n, cr_items i,acs_objects o  where  n.revision_id = $revision_id  and    i.item_id = n.item_id  and    o.object_id = $revision_id"
        } else {
          # We fetch the creation_user and the modifying_user by returning the 
          # creation_user of the automatic view as modifying_user. In case of
          # troubles, comment next line out.
          lappend atts "n.creation_user as modifying_user"
          
          $object db_1row [my qn fetch_from_view_item_id] " select [join $atts ,], i.parent_id  from   [my set table_name]i n, cr_items i, acs_objects o  where  i.item_id = $item_id  and    n.[my id_column] = coalesce(i.live_revision, i.latest_revision)  and    o.object_id = i.item_id"
        }
        # db_1row treats all newly created variables as instance variables,
        # so we can see vars like __db_sql, __db_lst that we do not want to keep
        foreach v [$object info vars __db_*] {$object unset $v}
    
        if {[apm_version_names_compare [ad_acs_version] 5.2] <= -1} {
          $object set package_id [::xo::db_string get_pid  "select package_id from cr_folders where folder_id = [$object set parent_id]"]
        }
    
        #my log "--AFTER FETCH\n[$object serialize]"
        if {$initialize} {$object initialize_loaded_object}
        return $object
      }
    
  • instproc folder_type (public)

    <instance of ::xo::db::CrClass[i]> folder_type \
        [ -include_subtypes include_subtypes ] [ -folder_id folder_id ] \
        operation
    register the current object type for folder_id. If folder_id is not specified, use the instvar of the class instead.

    Switches:
    -include_subtypes (defaults to "t") (optional)
    Boolean value (t/f) to flag whether the operation should be applied on subtypes as well
    -folder_id (optional)
    Parameters:
    operation
    ::1034086 instproc folder_type {{-include_subtypes t} -folder_id operation} {
        if {$operation ne "register" && $operation ne "unregister"} {
          error "[self] operation for folder_type must be 'register' or 'unregister'"
        }
        my instvar object_type
        if {![info exists folder_id]} {
          my instvar folder_id
        }
        ::xo::db::sql::content_folder ${operation}_content_type  -folder_id $folder_id  -content_type $object_type  -include_subtypes $include_subtypes
      }
    
  • instproc folder_type_unregister_all (public)

    <instance of ::xo::db::CrClass[i]> folder_type_unregister_all \
        [ -include_subtypes include_subtypes ]
    Unregister the object type from all folders on the system

    Switches:
    -include_subtypes (defaults to "t") (optional)
    Boolean value (t/f) to flag whether the operation should be applied on subtypes as well
    ::1034086 instproc folder_type_unregister_all {{-include_subtypes t}} {
        my instvar object_type
        db_foreach [my qn all_folders] { 
          select folder_id from cr_folder_type_map 
          where content_type = :object_type
        } {
          ::xo::db::sql::content_folder unregister_content_type  -folder_id $folder_id  -content_type $object_type  -include_subtypes $include_subtypes
          }
      }
    
  • instproc getFormClass

    ::1034086 instproc getFormClass -data:required {
        if {[$data exists item_id] && [$data set item_id] != 0 && [my exists edit_form]} {
          return [my edit_form]
        } else {
          return [my form]
        }
      }
    
  • instproc get_instance_from_db (public)

    <instance of ::xo::db::CrClass[i]> get_instance_from_db \
        [ -item_id item_id ] [ -revision_id revision_id ]
    Retrieve either the live revision or a specified revision of a content item with all attributes into a newly created object. The retrieved attributes are strored in the instance variables in class representing the object_type. The XOTcl object is destroyed automatically on cleanup (end of a connection request)

    Switches:
    -item_id (defaults to "0") (optional)
    id of the item to be retrieved.
    -revision_id (defaults to "0") (optional)
    revision-id of the item to be retrieved.
    Returns:
    fully qualified object
    ::1034086 instproc get_instance_from_db {{-item_id 0} {-revision_id 0}} {
        set object ::[expr {$revision_id ? $revision_id : $item_id}]
        if {![my isobject $object]} {
          my fetch_object -object $object  -item_id $item_id -revision_id $revision_id
          $object destroy_on_cleanup
        }
        return $object
      }
    
  • instproc get_instances_from_db (public)

    <instance of ::xo::db::CrClass[i]> get_instances_from_db \
        [ -select_attributes select_attributes ] \
        [ -from_clause from_clause ] [ -where_clause where_clause ] \
        [ -orderby orderby ] [ -with_subtypes on|off ] \
        [ -folder_id folder_id ] [ -page_size page_size ] \
        [ -page_number page_number ] [ -base_table base_table ]
    Returns a set (ordered composite) of the answer tuples of an 'instance_select_query' with the same attributes. The tuples are instances of the class, on which the method was called.

    Switches:
    -select_attributes (optional)
    -from_clause (optional)
    -where_clause (optional)
    -orderby (optional)
    -with_subtypes (boolean) (defaults to "true") (optional)
    -folder_id (optional)
    -page_size (defaults to "20") (optional)
    -page_number (optional)
    -base_table (defaults to "cr_revisions") (optional)
    ::1034086 instproc get_instances_from_db {{-select_attributes ""} {-from_clause ""} {-where_clause ""} {-orderby ""} {-with_subtypes:boolean true} -folder_id {-page_size 20} {-page_number ""} {-base_table "cr_revisions"}} {
        set s [my instantiate_objects -sql  [my instance_select_query  -select_attributes $select_attributes  -from_clause $from_clause  -where_clause $where_clause  -orderby $orderby  -with_subtypes $with_subtypes  -folder_id $folder_id  -page_size $page_size  -page_number $page_number  -base_table $base_table  ]]
        return $s
      }
    
  • instproc init

    ::1034086 instproc init {} {
        my instvar object_type db_slot
        # first, do whatever ::xo::db::Class does for initialization ...
        next
        # We want to be able to define for different CrClasses different
        # default mime-types. Therefore, we define attribute slots per 
        # application class with the given default for mime_type. 
        if {[self] ne "::xo::db::CrItem"} {
          my slots {
    	::xotcl::Attribute create mime_type -default [my mime_type]
          }
          my db_slots
        }
        # ... then we do the CrClass specific initialization.
        #if {[my info superclass] ne "::xo::db::CrItem"} {
        #  my set superclass [[my info superclass] set object_type]
        #}
    
        # CrClasses store all attributes of the class hierarchy in
        # db_slot. This is due to the usage of the
        # automatically created views. Note, that classes created with
        # ::xo::db::Class keep only the class specific db slots.
        #
        foreach {slot_name slot} [[my info superclass] array get db_slot] {
          # don't overwrite slots, unless the object_title (named title)
          if {![info exists db_slot($slot_name)] ||
    	  $slot eq "::xo::db::Object::slot::object_title"} {
    	set db_slot($slot_name) $slot
          }
        }
        my remember_long_text_slots
        
        if {![::xo::db::Class object_type_exists_in_db -object_type $object_type]} {
          my create_object_type
        }
      }
    
  • instproc insert_statement

    ::1034086 instproc insert_statement {atts vars} {
          return "insert into [my set table_name]i ([join $atts ,])  values (:[join $vars ,:])"
        }
    
  • instproc instance_select_query (public)

    <instance of ::xo::db::CrClass[i]> instance_select_query \
        [ -select_attributes select_attributes ] [ -orderby orderby ] \
        [ -where_clause where_clause ] [ -from_clause from_clause ] \
        [ -with_subtypes on|off ] [ -with_children on|off ] \
        [ -publish_status publish_status ] [ -count on|off ] \
        [ -folder_id folder_id ] [ -parent_id parent_id ] \
        [ -page_size page_size ] [ -page_number page_number ] \
        [ -base_table base_table ]
    returns the SQL-query to select the CrItems of the specified object_type

    Switches:
    -select_attributes (optional)
    -orderby (optional)
    for ordering the solution set
    -where_clause (optional)
    clause for restricting the answer set
    -from_clause (optional)
    -with_subtypes (boolean) (defaults to "true") (optional)
    return subtypes as well
    -with_children (boolean) (defaults to "false") (optional)
    return immediate child objects of all objects as well
    -publish_status (optional)
    one of 'live', 'ready', or 'production'
    -count (boolean) (defaults to "false") (optional)
    return the query for counting the solutions
    -folder_id (optional)
    parent_id
    -parent_id (optional)
    -page_size (defaults to "20") (optional)
    -page_number (optional)
    -base_table (defaults to "cr_revisions") (optional)
    typically automatic view, must contain title and revision_id
    Returns:
    sql query
    ::1034086 instproc instance_select_query {{-select_attributes ""} {-orderby ""} {-where_clause ""} {-from_clause ""} {-with_subtypes:boolean true} {-with_children:boolean false} -publish_status {-count:boolean false} -folder_id -parent_id {-page_size 20} {-page_number ""} {-base_table "cr_revisions"}} {
        if {![info exists folder_id]} {my instvar folder_id}
        if {![info exists parent_id]} {set parent_id $folder_id}
    
        if {$base_table eq "cr_revisions"} {
          set attributes [list ci.item_id ci.name ci.publish_status acs_objects.object_type acs_objects.package_id] 
        } else {
          set attributes [list bt.item_id ci.name ci.publish_status bt.object_type "bt.object_package_id as package_id"] 
        }
        foreach a $select_attributes {
          if {$a eq "title"} {set a bt.title}
          lappend attributes $a
        }
        set type_selection_clause [my type_selection_clause -base_table $base_table -with_subtypes $with_subtypes]
        #my log "type_selection_clause -with_subtypes $with_subtypes returns $type_selection_clause"
        if {$count} {
          set attribute_selection "count(*)"
          set orderby ""      ;# no need to order when we count
          set page_number  ""      ;# no pagination when count is used
        } else {
          set attribute_selection [join $attributes ,]
        }
        
        set cond [list]
        if {$type_selection_clause ne ""} {lappend cond $type_selection_clause}
        if {$where_clause ne ""}          {lappend cond $where_clause}
        if {[info exists publish_status]} {lappend cond "ci.publish_status eq '$publish_status'"}
        if {$base_table eq "cr_revisions"} {
          lappend cond "acs_objects.object_id = bt.revision_id"
          set acs_objects_table "acs_objects, "
        } else {
          lappend cond "ci.item_id = bt.item_id"
          set acs_objects_table ""
        }
        lappend cond "coalesce(ci.live_revision,ci.latest_revision) = bt.revision_id"
        if {$parent_id ne ""} {
          if {$with_children} {
            lappend cond "ci.parent_id in (select $parent_id from dual union select item_id from cr_items where parent_id = $parent_id)"
          } else {
            lappend cond "ci.parent_id = $parent_id"
          }
        }
    
        if {$page_number ne ""} {
          set limit $page_size
          set offset [expr {$page_size*($page_number-1)}]
        } else {
          set limit ""
          set offset ""
        }
    
        set sql [::xo::db::sql select  -vars $attribute_selection  -from "$acs_objects_table cr_items ci, $base_table bt $from_clause"  -where [join $cond " and "]  -orderby $orderby  -limit $limit -offset $offset]
        #my log "--sql=$sql"
        return $sql
      }
    
  • instproc lock

    ::1034086 instproc lock {tablename mode} {;}
    
  • instproc mk_insert_method

    ::1034086 instproc mk_insert_method {} {;}
    
  • instproc mk_save_method

    ::1034086 instproc mk_save_method {} {;}
    
  • instproc new_persistent_object (public)

    <instance of ::xo::db::CrClass[i]> new_persistent_object \
        [ -package_id package_id ] [ -creation_user creation_user ] \
        [ -creation_ip creation_ip ] args [ args... ]
    Create a new content item of the actual class, configure it with the given arguments and insert it into the database. The XOTcl object is destroyed automatically on cleanup (end of a connection request).

    Switches:
    -package_id (optional)
    -creation_user (optional)
    -creation_ip (optional)
    Parameters:
    args
    Returns:
    fully qualified object
    ::1034086 instproc new_persistent_object {-package_id -creation_user -creation_ip args} {
        my get_context package_id creation_user creation_ip
        my log "ID [self] create $args"
        if {[catch {set p [eval my create ::0 $args]} errorMsg]} {
    	my log "Error: $errorMsg, $::errorInfo"
        }
        my log "ID [::0 serialize]"
        set item_id [::0 save_new  -package_id $package_id  -creation_user $creation_user  -creation_ip $creation_ip]
        ::0 move ::$item_id
        ::$item_id destroy_on_cleanup
        return ::$item_id
      }
    
  • instproc remember_long_text_slots

    ::1034086 instproc remember_long_text_slots {} {
        #
        # keep long_text_slots in a separate array (for Oracle)
        #
        my array unset long_text_slots
        foreach {slot_name slot} [my array get db_slot] {
          if {[$slot sqltype] eq "long_text"} {
            my set long_text_slots($slot_name) $slot
          }
        }
        #my log "--long_text_slots = [my array names long_text_slots]"
      }
    
  • instproc type_selection_clause

    ::1034086 instproc type_selection_clause {{-base_table cr_revisions} {-with_subtypes:boolean false}} {
        my instvar object_type
        if {$with_subtypes} {
          if {$base_table eq "cr_revisions"} {
            # do type selection manually
            return "acs_objects.object_type in ([my object_types_query])"
          }
          # the base-table defines contains the subtypes
          return ""
        } else {
          if {$base_table eq "cr_revisions"} {
            return "acs_objects.object_type = '$object_type'"
          } else {
            return "bt.object_type = '$object_type'"
          }
        }
      }
    
  • instproc unknown

    ::1034086 instproc unknown {obj args} {
        # When this happens, this is most likely an error. Ease debugging
        # by writing the call stack to the error log.
        ::xo::show_stack
        my log "::xo::db::CrClass: unknown called with $obj $args"
      }
    

Instances

::xo::db::CrFolder[i], ::xo::db::CrItem[i], ::xo::db::image[i], ::xowiki::File[i], ::xowiki::Form[i], ::xowiki::FormPage[i], ::xowiki::Object[i], ::xowiki::Page[i], ::xowiki::PageInstance[i], ::xowiki::PageTemplate[i], ::xowiki::PlainPage[i], ::xowiki::PodcastItem[i]

Methods: Source: Variables:
[All Methods | Documented Methods | Hide Methods] [Display Source | Hide Source] [Show Variables | Hide Variables]