Index: ClientSide.tcl ================================================================== --- ClientSide.tcl +++ ClientSide.tcl @@ -45,11 +45,11 @@ package require tdom 0.8 package require http 2 package require log package require uri -package provide WS::Client 2.4.4 +package provide WS::Client 2.4.5 namespace eval ::WS::Client { # register https only if not yet registered if {[catch { http::unregister https } lPortCmd]} { # not registered -> register on my own @@ -115,11 +115,32 @@ suppressNS {} useTypeNs {} nsOnChangeOnly {} noTargetNs 0 errorOnRedefine 0 + inlineElementNS 1 } + ## + ## List of options which are copied to the service array + ## + set ::WS::Client::serviceLocalOptionsList { + skipLevelWhenActionPresent + skipLevelOnReply + skipHeaderLevel + suppressTargetNS + allowOperOverloading + contentType + UseNS + parseInAttr + genOutAttr + valueAttrCompatiblityMode + suppressNS + useTypeNs + nsOnChangeOnly + noTargetNs + } + set ::WS::Client::utilsOptionsList { UseNS parseInAttr genOutAttr valueAttrCompatiblityMode @@ -137,15 +158,24 @@ # #>>BEGIN PUBLIC<< # # Procedure Name : ::WS::Client::SetOption # -# Description : Set or get an option +# Description : Set or get file global or default option. +# Global option control the service creation process. +# Default options are takren as defaults to new created services. # # Arguments : +# -globalonly +# - Return list of global options/values +# -defaultonly +# - Return list of default options/values +# -- # option - Option to be set/retrieved +# Return all option/values if omitted # args - Value to set the option to +# Return the value if not given # # Returns : The value of the option # # Side-Effects : None # @@ -162,28 +192,81 @@ # adding a complete entry at the bottom of the list. # # Version Date Programmer Comments / Changes / Reasons # ------- ---------- ---------- ------------------------------------------- # 1 04/272009 G.Lester Initial version +# 2.4.5 2017-12-04 H.Oehlmann Return all current options if no argument +# given. Options -globalonly or -defaultonly +# limit this to options which are (not) +# copied to the service. +# ########################################################################### -proc ::WS::Client::SetOption {option args} { +proc ::WS::Client::SetOption {args} { variable options - - if {[info exists options($option)]} { - if {[llength $args] == 0} { - return $options($option) - } elseif {[llength $args] == 1} { - set options($option) [lindex $args 0] - } else { - return -code error \ - -errorcode [list WS CLIENT INVALDCNT $args] \ - "Invalid number of values: '$args'" - } - } else { + variable serviceLocalOptionsList + if {0 == [llength $args]} { + return [array get options] + } + set args [lassign $args option] + + switch -exact -- $option { + -globalonly { + ## + ## Return list of global options + ## + set res {} + foreach option [array names options] { + if {$option ni $serviceLocalOptionsList} { + lappend res $option $options($option) + } + } + return $res + } + -defaultonly { + ## + ## Return list of default options + ## + set res {} + foreach option [array names options] { + if {$option in $serviceLocalOptionsList} { + lappend res $option $options($option) + } + } + return $res + } + -- { + ## + ## End of options + ## + set args [lassign $args option] + } + } + ## + ## Check if given option exists + ## + if {![info exists options($option)]} { return -code error \ -errorcode [list WS CLIENT UNKOPT $option] \ - "Uknown option: '$option'" + "Unknown option: '$option'" + } + ## + ## Check if value is given + ## + switch -exact -- [llength $args] { + 0 { + return $options($option) + } + 1 { + set value [lindex $args 0] + set options($option) $value + return $value + } + default { + return -code error \ + -errorcode [list WS CLIENT INVALDCNT $args] \ + "To many parameters: '$args'" + } } } ########################################################################### # @@ -220,16 +303,19 @@ # adding a complete entry at the bottom of the list. # # Version Date Programmer Comments / Changes / Reasons # ------- ---------- ---------- ------------------------------------------- # 1 04/14/2009 G.Lester Initial version -# +# 2.4.5 2017-12-04 H.Oehlmann Use distinct list of option items, which are +# copied to the service array. Not all options +# are used in the service array. # ########################################################################### proc ::WS::Client::CreateService {serviceName type url target args} { variable serviceArr variable options + variable serviceLocalOptionsList if {$options(errorOnRedefine) && [info exists serviceArr($serviceName)]} { return -code error "Service '$serviceName' already exists" } elseif {[info exists serviceArr($serviceName)]} { unset serviceArr($serviceName) @@ -244,11 +330,11 @@ dict set serviceArr($serviceName) location $url dict set serviceArr($serviceName) style $type dict set serviceArr($serviceName) imports {} dict set serviceArr($serviceName) inTransform {} dict set serviceArr($serviceName) outTransform {} - foreach item [array names options] { + foreach item $serviceLocalOptionsList { dict set serviceArr($serviceName) $item $options($item) } foreach {name value} $args { set name [string trimleft $name {-}] dict set serviceArr($serviceName) $name $value @@ -274,15 +360,18 @@ # Procedure Name : ::WS::Client::Config # # Description : Configure a service information # # Arguments : -# serviceName - Service name to add namespace to -# item - The item to configure -# value - Optional, the new value +# serviceName - Service name to add namespace to. +# Return a list of items/values of default options if not +# given. +# item - The item to configure. Return a list of all items/values +# if not given. +# value - Optional, the new value. Return the value, if not given. # -# Returns : The value of the option +# Returns : The value of the option or a list of item/value pairs. # # Side-Effects : None # # Exception Conditions : None # @@ -297,31 +386,67 @@ # adding a complete entry at the bottom of the list. # # Version Date Programmer Comments / Changes / Reasons # ------- ---------- ---------- ------------------------------------------- # 1 04/14/2009 G.Lester Initial version -# +# 2.4.5 2017-12-04 H.Oehlmann Allow to set an option to the empty string. +# Return all option/values, if called without +# item. Return default items/values if no +# service given. # ########################################################################### -proc ::WS::Client::Config {serviceName item {value {}}} { +proc ::WS::Client::Config {args} { variable serviceArr variable options + variable serviceLocalOptionsList - set serviceInfo $serviceArr($serviceName) - set validOptionList [array names options] + set validOptionList $serviceLocalOptionsList lappend validOptionList location targetNamespace - if {[lsearch -exact $validOptionList $item] == -1} { + + if {0 == [llength $args]} { + set res {} + foreach item $validOptionList { + lappend res $item + if {[info exists options($item)]} { + lappend res $options($item) + } else { + lappend res {} + } + } + return $res + } + set args [lassign $args serviceName] + if {0 == [llength $args]} { + set res {} + foreach item $validOptionList { + lappend res $item [dict get $serviceArr($serviceName) $item] + } + return $res + } + + set args [lassign $args item] + if { $item ni $validOptionList } { return -code error "Uknown option '$item' -- must be one of: [join $validOptionList {, }]" } - if {$value ne {}} { - dict set serviceInfo $item $value - set serviceArr($serviceName) $serviceInfo + switch -exact -- [llength $args] { + 0 { + return [dict get $serviceArr($serviceName) $item] + } + 1 { + set value [lindex $args 0] + dict set serviceArr($serviceName) $item $value + return $value + } + default { + ::log::log debug "To many arguments arguments {$args}" + return \ + -code error \ + -errorcode [list WS CLIENT INVARGCNT $args] \ + "To many arguments '$args'" + } } - - return [dict get $serviceInfo $item] - } ########################################################################### # # Public Procedure Header - as this procedure is modified, please be sure @@ -995,16 +1120,18 @@ # nodes and not only in definition node # of wsdl file. # 2.4.4 2017-11-06 H.Oehlmann Added check (for nested namespace prefix # case), that a namespace prefix is not # reused for another URI. -# +# 2.4.5 2017-11-24 H.Oehlmann Added option "inlineElementNS" to activate +# namespace definition search in element nodes # ########################################################################### proc ::WS::Client::ParseWsdl {wsdlXML args} { variable currentBaseUrl variable serviceArr + variable options array set defaults { -createStubs 0 -headers {} -serviceAlias {} @@ -1058,16 +1185,30 @@ d http://schemas.xmlsoap.org/wsdl/soap/ xs http://www.w3.org/2001/XMLSchema } ## - ## loop over the top definitions node and all elements nodes + ## build list of namespace definition nodes + ## + ## the top node is always used + set NSDefinitionNodeList [list $wsdlNode] + + ## + ## get namespace definitions in element nodes ## - # Element nodes may declare namespaces inline like: - # - # ticket [dcce437d7a] - foreach elemNode [linsert [$wsdlDoc selectNodes {//xs:element}] 0 $wsdlNode] { + ## Element nodes may declare namespaces inline like: + ## + ## ticket [dcce437d7a] + + # This is only done, if option inlineElementNS is set in the default + # options. Service dependent options may not be used at this stage, + # as serviceArr is not created jet (Client::Config will fail) and the + # service name is not known jet. + if {$options(inlineElementNS)} { + lappend NSDefinitionNodeList {*}[$wsdlDoc selectNodes {//xs:element}] + } + foreach elemNode $NSDefinitionNodeList { # Get list of xmlns attributes # This list looks for the example like: {{q1 q1 {}} ... } set xmlnsAttributes [$elemNode attributes xmlns:*] # Loop over found namespaces foreach itemList $xmlnsAttributes { Index: docs/Calling_a_Web_Service.html ================================================================== --- docs/Calling_a_Web_Service.html +++ docs/Calling_a_Web_Service.html @@ -298,11 +298,11 @@

Returns : A string describing the created procedures.

Side-Effects : Existing namespace is deleted.

Exception Conditions : None

Pre-requisite Conditions : Service must have been defined.

-
+

Synchronous Call returning the raw XML

Procedure Name : ::WS::Client::DoRawCall

Description : Call an operation of a web service

@@ -323,10 +323,11 @@

Side-Effects : None

Exception Conditions :

     WSCLIENT HTTPERROR      - if an HTTP error occured
 

Pre-requisite Conditions : Service must have been defined.

+

Generating a Template Dictionary

Procedure Name : ::WS::Utils::GenerateTemplateDict

Description : Generate a template dictionary object for a given type.

@@ -341,35 +342,103 @@

Returns :

A dictionary object for a given type.  If any circular references exist, they will have the value of <** Circular Reference **>
 

Side-Effects : None

Exception Conditions  : None

Pre-requisite Conditions : Service must have been defined.

+

Configuring a Service

+ +There are two procedures to configure a service: + + +

The first procedure contains the default options of the package. +The default options are used on service creation and are then copied to the service.

+ +

The second procedure contains the options of each service. +They are copied on service creation from the default options.

+ +

Most option items may be accessed by both functions. +Some options are only used on service creation phase, which do not exist as service option. +Other options do not exist as default option, as they are initialized from the WSDL file.

+ +

In the following, first the two access routines are described. +Then, a list of options for both functions are given, with remarks, if they are only valid for one of the two procedures.

+ +

Procedure Name : ::WS::Client::SetOption

+

Description : Get or set the default options of the package

+

Arguments :

+
+     -globalonly   - Return a list of global-only options and their values.
+                     Global-only options are not copied to the service.
+     -defaultonly  - Return a list of default-only options and their values.
+                     default-only options are copied to the service.
+     --            - End of options
+     item          - The option item to get or configure.
+                     Return a list of all item/value pairs if ommitted. 
+     value         - The value to set the option item to.
+                     Return current value if omitted.
+
+

Procedure Name : ::WS::Client::Config

-

Description : Configure a service's information

+

Description : Get or set the options local to a service definition

Arguments :

-     serviceName     - The name of the Webservice
-     item   - The item to configure.  Must be one of
+     serviceName - The name of the Webservice.
+                   Return a list of default items/values paires if not given.
+     item        - The option item to get or configure.
+                   Return a list of all item/value pairs, if not given. 
+     value       - The value to set the option item to.
+                   Return current value if omitted.
 
+ +

Option List:

+