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:
- #
Returns : A string describing the created procedures.
Side-Effects : Existing namespace is deleted.
Exception Conditions : None
Pre-requisite Conditions : Service must have been defined.
-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.
+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.
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:
+allowOperOverloading
An overloaded operation is an operation with the same name but different may exist with different input parameter sets.
This option throws an error, if a WSDL is parsed with an overloaded operation.
Default: 1contentTypeThe http content type of the http request sent to call the web service.
errorOnRedefine- Throw an error, if a service is created (CreateService etc) for an already existing service.
Throw an error, if a service is created (CreateService etc) for an already existing service.
+Default value: 0
+This item may not be used with ::WS::Client::Config.
+ +genOutAttrgenerate attributes on outbound tags, see here for details
inlineElementNS+
Namespace prefixes for types may be defined within the WSDL root element.
+This item may not be used with ::WS::Client::Config.
+Activate this option, to also search namespace prefixes in the type definition. + As those are seen as global prefixes, there might be a double-used prefix which will cause a processing error, if different URI's are assigned.
+ +The error would be caused by a WSDL as follows
++ <wsdl:definitions targetNamespace="http://www.webserviceX.NET/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/ + xmlns:q1="myURI1" + ...> + ... + <xs:element xmlns:q1="myURI2" type="q1:MessageQ1"/> ++
location- The URL of the service. This is initialized on the value in the WSDL file, when the WSDL file is parsed. The value may be overwritten setting this option.
The URL of the service. This is initialized on the value in the WSDL file, when the WSDL file is parsed. The value may be overwritten setting this option.
+This item may not be used with ::WS::Client::SetOption.
+ +noTargetNsThe target namespace URI is normally included twice in the envelope of the webservice call:
<SOAP-ENV:Envelope ... @@ -425,11 +494,13 @@
This option was set to call a service published by SAP.
This option made a call to a certain MS Web Service fail with the error message: "Input parameter 'Parameter1' can not be NULL or Empty.".
Default is 0 (do not suppress).
targetNamespace (default: empty string)- the target namespace of the service, derived from the WSDL.
the target namespace of the service, derived from the WSDL.
+This item may not be used with ::WS::Client::SetOption.
+UseNS (default: empty string)See here
useTypeNS (default: empty string)use type's namespace prefix as prefix of elements