aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Harsanyi2012-04-25 12:28:29 +0200
committerMichael Albinus2012-04-25 12:28:29 +0200
commitdb9b177bcc4aabebebf604de7a0efc5b32981c5b (patch)
treedb389c859ea4965a2d36215dbe24671f52c1098c
parent1fc6097bfa931cf17f8a5b76ec8442e22d33c724 (diff)
downloademacs-db9b177bcc4aabebebf604de7a0efc5b32981c5b.tar.gz
emacs-db9b177bcc4aabebebf604de7a0efc5b32981c5b.zip
Sync with soap-client repository. Support SOAP simpleType. (Bug#10331)
* soap-client.el (soap-resolve-references-for-sequence-type) (soap-resolve-references-for-array-type): hack to prevent self references, see Bug#9. (soap-parse-envelope): report the contents of the 'detail' node when receiving a fault reply. (soap-parse-envelope): report the contents of the entire 'detail' node. * soap-inspect.el (soap-sample-value-for-simple-type) (soap-inspect-simple-type): new function * soap-client.el (soap-simple-type): new struct (soap-default-xsd-types, soap-default-soapenc-types) (soap-decode-basic-type, soap-encode-basic-type): support unsignedInt and double basic types (soap-resolve-references-for-simple-type) (soap-parse-simple-type, soap-encode-simple-type): new function (soap-parse-schema): parse xsd:simpleType declarations * soap-client.el (soap-default-xsd-types) (soap-default-soapenc-types): add integer, byte and anyURI types (soap-parse-complex-type-complex-content): use `soap-wk2l' to find the local name of "soapenc:Array" (soap-decode-basic-type, soap-encode-basic-type): support encoding decoding integer, byte and anyURI xsd types.
-rw-r--r--lisp/ChangeLog30
-rw-r--r--lisp/net/soap-client.el110
-rw-r--r--lisp/net/soap-inspect.el25
3 files changed, 149 insertions, 16 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 76b855e6bc9..533c1775ea9 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,33 @@
12012-04-25 Alex Harsanyi <AlexHarsanyi@gmail.com>
2
3 Sync with soap-client repository. Support SOAP simpleType. (Bug#10331)
4
5 * soap-client.el (soap-resolve-references-for-sequence-type)
6 (soap-resolve-references-for-array-type): hack to prevent self
7 references, see Bug#9.
8 (soap-parse-envelope): report the contents of the 'detail' node
9 when receiving a fault reply.
10 (soap-parse-envelope): report the contents of the entire 'detail'
11 node.
12
13 * soap-inspect.el (soap-sample-value-for-simple-type)
14 (soap-inspect-simple-type): new function
15
16 * soap-client.el (soap-simple-type): new struct
17 (soap-default-xsd-types, soap-default-soapenc-types)
18 (soap-decode-basic-type, soap-encode-basic-type): support
19 unsignedInt and double basic types
20 (soap-resolve-references-for-simple-type)
21 (soap-parse-simple-type, soap-encode-simple-type): new function
22 (soap-parse-schema): parse xsd:simpleType declarations
23
24 * soap-client.el (soap-default-xsd-types)
25 (soap-default-soapenc-types): add integer, byte and anyURI types
26 (soap-parse-complex-type-complex-content): use `soap-wk2l' to find
27 the local name of "soapenc:Array"
28 (soap-decode-basic-type, soap-encode-basic-type): support encoding
29 decoding integer, byte and anyURI xsd types.
30
12012-04-25 Chong Yidong <cyd@gnu.org> 312012-04-25 Chong Yidong <cyd@gnu.org>
2 32
3 * cus-edit.el (custom-buffer-create-internal): Update header text. 33 * cus-edit.el (custom-buffer-create-internal): Update header text.
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index e17b283c55f..39369111935 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -369,6 +369,9 @@ binding) but the same name."
369 kind ; a symbol of: string, dateTime, long, int 369 kind ; a symbol of: string, dateTime, long, int
370 ) 370 )
371 371
372(defstruct (soap-simple-type (:include soap-basic-type))
373 enumeration)
374
372(defstruct soap-sequence-element 375(defstruct soap-sequence-element
373 name type nillable? multiple?) 376 name type nillable? multiple?)
374 377
@@ -415,8 +418,9 @@ binding) but the same name."
415(defun soap-default-xsd-types () 418(defun soap-default-xsd-types ()
416 "Return a namespace containing some of the XMLSchema types." 419 "Return a namespace containing some of the XMLSchema types."
417 (let ((ns (make-soap-namespace :name "http://www.w3.org/2001/XMLSchema"))) 420 (let ((ns (make-soap-namespace :name "http://www.w3.org/2001/XMLSchema")))
418 (dolist (type '("string" "dateTime" "boolean" "long" "int" "float" 421 (dolist (type '("string" "dateTime" "boolean"
419 "base64Binary" "anyType" "Array" "byte[]")) 422 "long" "int" "integer" "unsignedInt" "byte" "float" "double"
423 "base64Binary" "anyType" "anyURI" "Array" "byte[]"))
420 (soap-namespace-put 424 (soap-namespace-put
421 (make-soap-basic-type :name type :kind (intern type)) 425 (make-soap-basic-type :name type :kind (intern type))
422 ns)) 426 ns))
@@ -425,9 +429,10 @@ binding) but the same name."
425(defun soap-default-soapenc-types () 429(defun soap-default-soapenc-types ()
426 "Return a namespace containing some of the SOAPEnc types." 430 "Return a namespace containing some of the SOAPEnc types."
427 (let ((ns (make-soap-namespace 431 (let ((ns (make-soap-namespace
428 :name "http://schemas.xmlsoap.org/soap/encoding/"))) 432 :name "http://schemas.xmlsoap.org/soap/encoding/")))
429 (dolist (type '("string" "dateTime" "boolean" "long" "int" "float" 433 (dolist (type '("string" "dateTime" "boolean"
430 "base64Binary" "anyType" "Array" "byte[]")) 434 "long" "int" "integer" "unsignedInt" "byte" "float" "double"
435 "base64Binary" "anyType" "anyURI" "Array" "byte[]"))
431 (soap-namespace-put 436 (soap-namespace-put
432 (make-soap-basic-type :name type :kind (intern type)) 437 (make-soap-basic-type :name type :kind (intern type))
433 ns)) 438 ns))
@@ -555,6 +560,15 @@ updated."
555 (when resolver 560 (when resolver
556 (funcall resolver element wsdl)))) 561 (funcall resolver element wsdl))))
557 562
563(defun soap-resolve-references-for-simple-type (type wsdl)
564 "Resolve the base type for the simple TYPE using the WSDL
565 document."
566 (let ((kind (soap-basic-type-kind type)))
567 (unless (symbolp kind)
568 (let ((basic-type (soap-wsdl-get kind wsdl 'soap-basic-type-p)))
569 (setf (soap-basic-type-kind type)
570 (soap-basic-type-kind basic-type))))))
571
558(defun soap-resolve-references-for-sequence-type (type wsdl) 572(defun soap-resolve-references-for-sequence-type (type wsdl)
559 "Resolve references for a sequence TYPE using WSDL document. 573 "Resolve references for a sequence TYPE using WSDL document.
560See also `soap-resolve-references-for-element' and 574See also `soap-resolve-references-for-element' and
@@ -562,12 +576,18 @@ See also `soap-resolve-references-for-element' and
562 (let ((parent (soap-sequence-type-parent type))) 576 (let ((parent (soap-sequence-type-parent type)))
563 (when (or (consp parent) (stringp parent)) 577 (when (or (consp parent) (stringp parent))
564 (setf (soap-sequence-type-parent type) 578 (setf (soap-sequence-type-parent type)
565 (soap-wsdl-get parent wsdl 'soap-type-p)))) 579 (soap-wsdl-get
580 parent wsdl
581 ;; Prevent self references, see Bug#9
582 (lambda (e) (and (not (eq e type)) (soap-type-p e)))))))
566 (dolist (element (soap-sequence-type-elements type)) 583 (dolist (element (soap-sequence-type-elements type))
567 (let ((element-type (soap-sequence-element-type element))) 584 (let ((element-type (soap-sequence-element-type element)))
568 (cond ((or (consp element-type) (stringp element-type)) 585 (cond ((or (consp element-type) (stringp element-type))
569 (setf (soap-sequence-element-type element) 586 (setf (soap-sequence-element-type element)
570 (soap-wsdl-get element-type wsdl 'soap-type-p))) 587 (soap-wsdl-get
588 element-type wsdl
589 ;; Prevent self references, see Bug#9
590 (lambda (e) (and (not (eq e type)) (soap-type-p e))))))
571 ((soap-element-p element-type) 591 ((soap-element-p element-type)
572 ;; since the element already has a child element, it 592 ;; since the element already has a child element, it
573 ;; could be an inline structure. we must resolve 593 ;; could be an inline structure. we must resolve
@@ -582,7 +602,10 @@ See also `soap-resolve-references-for-element' and
582 (let ((element-type (soap-array-type-element-type type))) 602 (let ((element-type (soap-array-type-element-type type)))
583 (when (or (consp element-type) (stringp element-type)) 603 (when (or (consp element-type) (stringp element-type))
584 (setf (soap-array-type-element-type type) 604 (setf (soap-array-type-element-type type)
585 (soap-wsdl-get element-type wsdl 'soap-type-p))))) 605 (soap-wsdl-get
606 element-type wsdl
607 ;; Prevent self references, see Bug#9
608 (lambda (e) (and (not (eq e type)) (soap-type-p e))))))))
586 609
587(defun soap-resolve-references-for-message (message wsdl) 610(defun soap-resolve-references-for-message (message wsdl)
588 "Resolve references for a MESSAGE type using the WSDL document. 611 "Resolve references for a MESSAGE type using the WSDL document.
@@ -679,6 +702,8 @@ See also `soap-resolve-references-for-element' and
679 702
680;; Install resolvers for our types 703;; Install resolvers for our types
681(progn 704(progn
705 (put (aref (make-soap-simple-type) 0) 'soap-resolve-references
706 'soap-resolve-references-for-simple-type)
682 (put (aref (make-soap-sequence-type) 0) 'soap-resolve-references 707 (put (aref (make-soap-sequence-type) 0) 'soap-resolve-references
683 'soap-resolve-references-for-sequence-type) 708 'soap-resolve-references-for-sequence-type)
684 (put (aref (make-soap-array-type) 0) 'soap-resolve-references 709 (put (aref (make-soap-array-type) 0) 'soap-resolve-references
@@ -854,6 +879,9 @@ Return a SOAP-NAMESPACE containing the elements."
854 (let ((ns (make-soap-namespace :name (soap-get-target-namespace node)))) 879 (let ((ns (make-soap-namespace :name (soap-get-target-namespace node))))
855 ;; NOTE: we only extract the complexTypes from the schema, we wouldn't 880 ;; NOTE: we only extract the complexTypes from the schema, we wouldn't
856 ;; know how to handle basic types beyond the built in ones anyway. 881 ;; know how to handle basic types beyond the built in ones anyway.
882 (dolist (node (soap-xml-get-children1 node 'xsd:simpleType))
883 (soap-namespace-put (soap-parse-simple-type node) ns))
884
857 (dolist (node (soap-xml-get-children1 node 'xsd:complexType)) 885 (dolist (node (soap-xml-get-children1 node 'xsd:complexType))
858 (soap-namespace-put (soap-parse-complex-type node) ns)) 886 (soap-namespace-put (soap-parse-complex-type node) ns))
859 887
@@ -862,6 +890,26 @@ Return a SOAP-NAMESPACE containing the elements."
862 890
863 ns))) 891 ns)))
864 892
893(defun soap-parse-simple-type (node)
894 "Parse NODE and construct a simple type from it."
895 (assert (eq (soap-l2wk (xml-node-name node)) 'xsd:simpleType)
896 nil
897 "soap-parse-complex-type: expecting xsd:simpleType node, got %s"
898 (soap-l2wk (xml-node-name node)))
899 (let ((name (xml-get-attribute-or-nil node 'name))
900 type
901 enumeration
902 (restriction (car-safe
903 (soap-xml-get-children1 node 'xsd:restriction))))
904 (unless restriction
905 (error "simpleType %s has no base type" name))
906
907 (setq type (xml-get-attribute-or-nil restriction 'base))
908 (dolist (e (soap-xml-get-children1 restriction 'xsd:enumeration))
909 (push (xml-get-attribute e 'value) enumeration))
910
911 (make-soap-simple-type :name name :kind type :enumeration enumeration)))
912
865(defun soap-parse-schema-element (node) 913(defun soap-parse-schema-element (node)
866 "Parse NODE and construct a schema element from it." 914 "Parse NODE and construct a schema element from it."
867 (assert (eq (soap-l2wk (xml-node-name node)) 'xsd:element) 915 (assert (eq (soap-l2wk (xml-node-name node)) 'xsd:element)
@@ -975,7 +1023,7 @@ contents."
975 extension 'xsd:sequence))))) 1023 extension 'xsd:sequence)))))
976 (restriction 1024 (restriction
977 (let ((base (xml-get-attribute-or-nil restriction 'base))) 1025 (let ((base (xml-get-attribute-or-nil restriction 'base)))
978 (assert (equal base "soapenc:Array") 1026 (assert (equal base (soap-wk2l "soapenc:Array"))
979 nil 1027 nil
980 "restrictions supported only for soapenc:Array types, this is a %s" 1028 "restrictions supported only for soapenc:Array types, this is a %s"
981 base)) 1029 base))
@@ -1245,9 +1293,9 @@ type-info stored in TYPE."
1245 (if (null contents) 1293 (if (null contents)
1246 nil 1294 nil
1247 (ecase type-kind 1295 (ecase type-kind
1248 (string (car contents)) 1296 ((string anyURI) (car contents))
1249 (dateTime (car contents)) ; TODO: convert to a date time 1297 (dateTime (car contents)) ; TODO: convert to a date time
1250 ((long int float) (string-to-number (car contents))) 1298 ((long int integer unsignedInt byte float double) (string-to-number (car contents)))
1251 (boolean (string= (downcase (car contents)) "true")) 1299 (boolean (string= (downcase (car contents)) "true"))
1252 (base64Binary (base64-decode-string (car contents))) 1300 (base64Binary (base64-decode-string (car contents)))
1253 (anyType (soap-decode-any-type node)) 1301 (anyType (soap-decode-any-type node))
@@ -1293,6 +1341,10 @@ This is because it is easier to work with list results in LISP."
1293(progn 1341(progn
1294 (put (aref (make-soap-basic-type) 0) 1342 (put (aref (make-soap-basic-type) 0)
1295 'soap-decoder 'soap-decode-basic-type) 1343 'soap-decoder 'soap-decode-basic-type)
1344 ;; just use the basic type decoder for the simple type -- we accept any
1345 ;; value and don't do any validation on it.
1346 (put (aref (make-soap-simple-type) 0)
1347 'soap-decoder 'soap-decode-basic-type)
1296 (put (aref (make-soap-sequence-type) 0) 1348 (put (aref (make-soap-sequence-type) 0)
1297 'soap-decoder 'soap-decode-sequence-type) 1349 'soap-decoder 'soap-decode-sequence-type)
1298 (put (aref (make-soap-array-type) 0) 1350 (put (aref (make-soap-array-type) 0)
@@ -1322,10 +1374,11 @@ WSDL is used to decode the NODE"
1322 fault 'faultcode)))) 1374 fault 'faultcode))))
1323 (car-safe (xml-node-children n)))) 1375 (car-safe (xml-node-children n))))
1324 (fault-string (let ((n (car (xml-get-children 1376 (fault-string (let ((n (car (xml-get-children
1325 fault 'faultstring)))) 1377 fault 'faultstring))))
1326 (car-safe (xml-node-children n))))) 1378 (car-safe (xml-node-children n))))
1379 (detail (xml-get-children fault 'detail)))
1327 (while t 1380 (while t
1328 (signal 'soap-error (list fault-code fault-string)))))) 1381 (signal 'soap-error (list fault-code fault-string detail))))))
1329 1382
1330 ;; First (non string) element of the body is the root node of he 1383 ;; First (non string) element of the body is the root node of he
1331 ;; response 1384 ;; response
@@ -1457,7 +1510,7 @@ instead."
1457 (progn 1510 (progn
1458 (insert ">") 1511 (insert ">")
1459 (case basic-type 1512 (case basic-type
1460 (string 1513 ((string anyURI)
1461 (unless (stringp value) 1514 (unless (stringp value)
1462 (error "Soap-encode-basic-type(%s, %s, %s): not a string value" 1515 (error "Soap-encode-basic-type(%s, %s, %s): not a string value"
1463 xml-tag value xsi-type)) 1516 xml-tag value xsi-type))
@@ -1484,10 +1537,19 @@ instead."
1484 xml-tag value xsi-type)) 1537 xml-tag value xsi-type))
1485 (insert (if value "true" "false"))) 1538 (insert (if value "true" "false")))
1486 1539
1487 ((long int) 1540 ((long int integer byte unsignedInt)
1488 (unless (integerp value) 1541 (unless (integerp value)
1489 (error "Soap-encode-basic-type(%s, %s, %s): not an integer value" 1542 (error "Soap-encode-basic-type(%s, %s, %s): not an integer value"
1490 xml-tag value xsi-type)) 1543 xml-tag value xsi-type))
1544 (when (and (eq basic-type 'unsignedInt) (< value 0))
1545 (error "Soap-encode-basic-type(%s, %s, %s): not a positive integer"
1546 xml-tag value xsi-type))
1547 (insert (number-to-string value)))
1548
1549 ((float double)
1550 (unless (numberp value)
1551 (error "Soap-encode-basic-type(%s, %s, %s): not a number"
1552 xml-tag value xsi-type))
1491 (insert (number-to-string value))) 1553 (insert (number-to-string value)))
1492 1554
1493 (base64Binary 1555 (base64Binary
@@ -1504,6 +1566,20 @@ instead."
1504 (insert " xsi:nil=\"true\">")) 1566 (insert " xsi:nil=\"true\">"))
1505 (insert "</" xml-tag ">\n"))) 1567 (insert "</" xml-tag ">\n")))
1506 1568
1569(defun soap-encode-simple-type (xml-tag value type)
1570 "Encode inside XML-TAG the LISP VALUE according to TYPE."
1571
1572 ;; Validate VALUE agains the simple type's enumeration, than just encode it
1573 ;; using `soap-encode-basic-type'
1574
1575 (let ((enumeration (soap-simple-type-enumeration type)))
1576 (unless (and (> (length enumeration) 1)
1577 (member value enumeration))
1578 (error "soap-encode-simple-type(%s, %s, %s): bad value, should be one of %s"
1579 xml-tag value (soap-element-fq-name type) enumeration)))
1580
1581 (soap-encode-basic-type xml-tag value type))
1582
1507(defun soap-encode-sequence-type (xml-tag value type) 1583(defun soap-encode-sequence-type (xml-tag value type)
1508 "Encode inside XML-TAG the LISP VALUE according to TYPE. 1584 "Encode inside XML-TAG the LISP VALUE according to TYPE.
1509Do not call this function directly, use `soap-encode-value' 1585Do not call this function directly, use `soap-encode-value'
@@ -1564,6 +1640,8 @@ instead."
1564(progn 1640(progn
1565 (put (aref (make-soap-basic-type) 0) 1641 (put (aref (make-soap-basic-type) 0)
1566 'soap-encoder 'soap-encode-basic-type) 1642 'soap-encoder 'soap-encode-basic-type)
1643 (put (aref (make-soap-simple-type) 0)
1644 'soap-encoder 'soap-encode-simple-type)
1567 (put (aref (make-soap-sequence-type) 0) 1645 (put (aref (make-soap-sequence-type) 0)
1568 'soap-encoder 'soap-encode-sequence-type) 1646 'soap-encoder 'soap-encode-sequence-type)
1569 (put (aref (make-soap-array-type) 0) 1647 (put (aref (make-soap-array-type) 0)
diff --git a/lisp/net/soap-inspect.el b/lisp/net/soap-inspect.el
index 823f815d58f..23937e21770 100644
--- a/lisp/net/soap-inspect.el
+++ b/lisp/net/soap-inspect.el
@@ -66,6 +66,15 @@ use `soap-sample-value' instead."
66 ;; TODO: we need better sample values for more types. 66 ;; TODO: we need better sample values for more types.
67 (t (format "%s" (soap-basic-type-kind type))))) 67 (t (format "%s" (soap-basic-type-kind type)))))
68 68
69(defun soap-sample-value-for-simple-type (type)
70 "Provive a sample value for TYPE which is a simple type.
71This is a specific function which should not be called directly,
72use `soap-sample-value' instead."
73 (let ((enumeration (soap-simple-type-enumeration type)))
74 (if (> (length enumeration) 1)
75 (elt enumeration (random (length enumeration)))
76 (soap-sample-value-for-basic-type type))))
77
69(defun soap-sample-value-for-seqence-type (type) 78(defun soap-sample-value-for-seqence-type (type)
70 "Provide a sample value for TYPE which is a sequence type. 79 "Provide a sample value for TYPE which is a sequence type.
71Values for sequence types are ALISTS of (slot-name . VALUE) for 80Values for sequence types are ALISTS of (slot-name . VALUE) for
@@ -115,6 +124,9 @@ use `soap-sample-value' instead."
115 (put (aref (make-soap-basic-type) 0) 'soap-sample-value 124 (put (aref (make-soap-basic-type) 0) 'soap-sample-value
116 'soap-sample-value-for-basic-type) 125 'soap-sample-value-for-basic-type)
117 126
127 (put (aref (make-soap-simple-type) 0) 'soap-sample-value
128 'soap-sample-value-for-simple-type)
129
118 (put (aref (make-soap-sequence-type) 0) 'soap-sample-value 130 (put (aref (make-soap-sequence-type) 0) 'soap-sample-value
119 'soap-sample-value-for-seqence-type) 131 'soap-sample-value-for-seqence-type)
120 132
@@ -204,6 +216,16 @@ entire WSDL can be inspected."
204 (insert "\nSample value\n") 216 (insert "\nSample value\n")
205 (pp (soap-sample-value basic-type) (current-buffer))) 217 (pp (soap-sample-value basic-type) (current-buffer)))
206 218
219(defun soap-inspect-simple-type (simple-type)
220 "Insert information about SIMPLE-TYPE into the current buffer"
221 (insert "Simple type: " (soap-element-fq-name simple-type) "\n")
222 (insert "Base: " (symbol-name (soap-basic-type-kind simple-type)) "\n")
223 (let ((enumeration (soap-simple-type-enumeration simple-type)))
224 (when (> (length enumeration) 1)
225 (insert "Valid values: ")
226 (dolist (e enumeration)
227 (insert "\"" e "\" ")))))
228
207(defun soap-inspect-sequence-type (sequence) 229(defun soap-inspect-sequence-type (sequence)
208 "Insert information about SEQUENCE into the current buffer." 230 "Insert information about SEQUENCE into the current buffer."
209 (insert "Sequence type: " (soap-element-fq-name sequence) "\n") 231 (insert "Sequence type: " (soap-element-fq-name sequence) "\n")
@@ -331,6 +353,9 @@ entire WSDL can be inspected."
331 (put (aref (make-soap-basic-type) 0) 'soap-inspect 353 (put (aref (make-soap-basic-type) 0) 'soap-inspect
332 'soap-inspect-basic-type) 354 'soap-inspect-basic-type)
333 355
356 (put (aref (make-soap-simple-type) 0) 'soap-inspect
357 'soap-inspect-simple-type)
358
334 (put (aref (make-soap-sequence-type) 0) 'soap-inspect 359 (put (aref (make-soap-sequence-type) 0) 'soap-inspect
335 'soap-inspect-sequence-type) 360 'soap-inspect-sequence-type)
336 361