smalltalk
/
osmo-st-all
Archived
1
0
Fork 0

Merge remote-tracking branch 'soapopera/master'

This commit is contained in:
Holger Hans Peter Freyther 2012-10-11 23:17:10 +02:00
commit 00d3ddfe87
15 changed files with 11644 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit 21132f02889ef82e368144dbf8892d321d27661c

View File

@ -0,0 +1,225 @@
Eval [
'From Pharo-1.1-11411 of 17 July 2010 [Latest update: #11411] on 19 February 2011 at 9:09:05 pm'
]
ReadWriteStream subclass: MIMERWStream [
| readLimit |
nextPut: aInt [
| res |
res := super nextPut: aInt.
readLimit := self readLimit max: self position.
^ res
]
contents [
^ collection copyFrom: 1 to: self readLimit.
]
readLimit [
^ readLimit ifNil: [readLimit := 0].
]
]
Object subclass: MimeConverter [
| dataStream mimeStream |
<category: 'Network-MIME'>
dataStream [
<category: 'accessing'>
^dataStream
]
dataStream: anObject [
<category: 'accessing'>
dataStream := anObject
]
mimeStream [
<category: 'accessing'>
^mimeStream
]
mimeStream: anObject [
<category: 'accessing'>
mimeStream := anObject
]
mimeDecode [
"Do conversion reading from mimeStream writing to dataStream"
<category: 'conversion'>
self subclassResponsibility
]
mimeEncode [
"Do conversion reading from dataStream writing to mimeStream"
<category: 'conversion'>
self subclassResponsibility
]
]
MimeConverter subclass: Base64MimeConverter [
| data |
<comment: 'This class encodes and decodes data in Base64 format. This is MIME encoding. We translate a whole stream at once, taking a Stream as input and giving one as output. Returns a whole stream for the caller to use. 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y Outbound: bytes are broken into 6 bit chunks, and the 0-63 value is converted to a character. 3 data bytes go into 4 characters. Inbound: Characters are translated in to 0-63 values and shifted into 8 bit bytes. (See: N. Borenstein, Bellcore, N. Freed, Innosoft, Network Working Group, Request for Comments: RFC 1521, September 1993, MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies. Sec 6.2) By Ted Kaehler, based on Tim Olson''s Base64Filter.'>
<category: 'Network-MIME'>
FromCharTable := nil.
ToCharTable := nil.
Base64MimeConverter class >> initialize [
FromCharTable := Array new: 256. "nils"
ToCharTable := Array new: 64.
($A asciiValue to: $Z asciiValue) doWithIndex:
[:val :ind |
FromCharTable at: val + 1 put: ind - 1.
ToCharTable at: ind put: val asCharacter].
($a asciiValue to: $z asciiValue) doWithIndex:
[:val :ind |
FromCharTable at: val + 1 put: ind + 25.
ToCharTable at: ind + 26 put: val asCharacter].
($0 asciiValue to: $9 asciiValue) doWithIndex:
[:val :ind |
FromCharTable at: val + 1 put: ind + 25 + 26.
ToCharTable at: ind + 26 + 26 put: val asCharacter].
FromCharTable at: $+ asciiValue + 1 put: 62.
ToCharTable at: 63 put: $+.
FromCharTable at: $/ asciiValue + 1 put: 63.
ToCharTable at: 64 put: $/
]
Base64MimeConverter class >> mimeDecodeToBytes: aStream [
"Return a RWBinaryOrTextStream of the original ByteArray. aStream has only 65 innocuous character values. aStream is not binary. (See class comment). 4 bytes in aStream goes to 3 bytes in output."
| me |
aStream position: 0.
me := self new mimeStream: aStream.
me dataStream: (MIMERWStream
on: (ByteArray new: aStream size * 3 // 4)).
me mimeDecodeToByteArray.
me dataStream position: 0.
^me dataStream
]
Base64MimeConverter class >> mimeEncode: aStream [
"Return a ReadWriteStream of characters. The data of aStream is encoded as 65 innocuous characters. (See class comment). 3 bytes in aStream goes to 4 bytes in output."
| me |
me := self new dataStream: aStream.
me
mimeStream: (MIMERWStream on: (String new: (aStream size + 20) * 4 // 3)).
me mimeEncode.
me mimeStream position: 0.
^me mimeStream
]
mimeDecode [
"Convert a stream in base 64 with only a-z,A-Z,0-9,+,/ to a full byte stream of characters. Reutrn a whole stream for the user to read."
<category: 'conversion'>
| nibA nibB nibC nibD |
[mimeStream atEnd] whileFalse:
[(nibA := self nextValue) ifNil: [^dataStream].
(nibB := self nextValue) ifNil: [^dataStream].
dataStream nextPut: ((nibA bitShift: 2) + (nibB bitShift: -4)) asCharacter.
nibB := nibB bitAnd: 15.
(nibC := self nextValue) ifNil: [^dataStream].
dataStream nextPut: ((nibB bitShift: 4) + (nibC bitShift: -2)) asCharacter.
nibC := nibC bitAnd: 3.
(nibD := self nextValue) ifNil: [^dataStream].
dataStream nextPut: ((nibC bitShift: 6) + nibD) asCharacter].
^dataStream
]
mimeDecodeToByteArray [
"Convert a stream in base 64 with only a-z,A-Z,0-9,+,/ to a full ByteArray of 0-255 values. Reutrn a whole stream for the user to read."
<category: 'conversion'>
| nibA nibB nibC nibD |
[mimeStream atEnd] whileFalse:
[(nibA := self nextValue) ifNil: [^dataStream].
(nibB := self nextValue) ifNil: [^dataStream].
dataStream nextPut: (nibA bitShift: 2) + (nibB bitShift: -4).
nibB := nibB bitAnd: 15.
(nibC := self nextValue) ifNil: [^dataStream].
dataStream nextPut: (nibB bitShift: 4) + (nibC bitShift: -2).
nibC := nibC bitAnd: 3.
(nibD := self nextValue) ifNil: [^dataStream].
dataStream nextPut: (nibC bitShift: 6) + nibD].
^dataStream
]
mimeEncode [
"Convert from data to 6 bit characters."
<category: 'conversion'>
| phase1 phase2 raw nib lineLength |
phase1 := phase2 := false.
lineLength := 0.
[dataStream atEnd] whileFalse:
[lineLength >= 70
ifTrue:
[mimeStream cr.
lineLength := 0].
data := raw := dataStream next asInteger.
nib := (data bitAnd: 252) bitShift: -2.
mimeStream nextPut: (ToCharTable at: nib + 1).
(raw := dataStream next) ifNil:
[raw := 0.
phase1 := true].
data := ((data bitAnd: 3) bitShift: 8) + raw asInteger.
nib := (data bitAnd: 1008) bitShift: -4.
mimeStream nextPut: (ToCharTable at: nib + 1).
(raw := dataStream next) ifNil:
[raw := 0.
phase2 := true].
data := ((data bitAnd: 15) bitShift: 8) + raw asInteger.
nib := (data bitAnd: 4032) bitShift: -6.
mimeStream nextPut: (ToCharTable at: nib + 1).
nib := data bitAnd: 63.
mimeStream nextPut: (ToCharTable at: nib + 1).
lineLength := lineLength + 4].
phase1
ifTrue:
[mimeStream
skip: -2;
nextPut: $=;
nextPut: $=.
^mimeStream].
phase2
ifTrue:
[mimeStream
skip: -1;
nextPut: $=.
^mimeStream]
]
nextValue [
"The next six bits of data char from the mimeStream, or nil. Skip all other chars"
<category: 'conversion'>
| raw num |
[raw := mimeStream next.
raw ifNil: [^nil]. "end of stream"
raw == $= ifTrue: [^nil].
num := FromCharTable at: raw asciiValue + 1.
num ifNotNil: [^num].
"else ignore space, return, tab, ..."
true]
whileTrue
]
]
Eval [
Base64MimeConverter initialize
]

View File

@ -0,0 +1,51 @@
Eval [
'From Pharo-1.1-11411 of 17 July 2010 [Latest update: #11411] on 19 February 2011 at 9:09:10 pm'
]
TestCase subclass: Base64MimeConverterTest [
| message |
<comment: 'This is the unit test for the class Base64MimeConverter. Unit tests are a good way to exercise the functionality of your system in a repeatable and automatic manner. They are therefore recommended if you plan to release anything. For more information, see: - http://www.c2.com/cgi/wiki?UnitTest - http://minnow.cc.gatech.edu/squeak/1547 - the sunit class category'>
<category: 'CollectionsTests-Streams'>
setUp [
<category: 'setup'>
message := 'Hi There!' readStream
]
testBase64Encoded [
"self run: #testBase64Encoded"
<category: 'tests'>
| encoded |
encoded := (Base64MimeConverter mimeEncode: message) contents.
self assert: encoded = 'Hi There!' base64Encoded
]
testMimeEncodeDecode [
"self run: #testMimeEncodeDecode"
<category: 'tests'>
| encoded |
encoded := Base64MimeConverter mimeEncode: message.
self assert: encoded contents = 'SGkgVGhlcmUh'.
self assert: (Base64MimeConverter mimeDecodeToBytes: encoded) contents asString
= message contents.
"Encoding should proceed from the current stream position."
message reset.
message skip: 2.
encoded := Base64MimeConverter mimeEncode: message.
self assert: encoded contents = 'IFRoZXJlIQ=='.
]
testOnByteArray [
"self run: #testOnByteArray"
<category: 'tests'>
self
assert: 'Hi There!' base64Encoded = 'Hi There!' asByteArray base64Encoded
]
]

120
soapopera/Extensions.st Normal file
View File

@ -0,0 +1,120 @@
Collection extend [
beginsWith: aString [
<category: '*soapopera-core'>
"This comes from Pharo 1.1 and is on SequencableCollection"
"Answer true if the receiver starts with the argument collection"
(aString isEmpty or: [self size < aString size]) ifTrue: [^false].
aString withIndexDo: [:each :index | (self at: index) ~= each ifTrue: [^false]].
^true
]
withIndexDo: elementAndIndexBlock [
<category: '*soapopera-core'>
"This comes from Pharo 1.1 and is on SequencableCollection"
"Just like with:do: except that the iteration index supplies the second argument to the block."
1 to: self size do:
[:index |
elementAndIndexBlock
value: (self at: index)
value: index]
]
ifEmpty: aBlock [
<category: '*soapopera-core'>
self isEmpty ifTrue: [^ aBlock value]
]
isEmptyOrNil [
<category: '*soapopera-core'>
^ self isEmpty
]
ifNotEmptyDo: aBlock [
<category: '*soapopera-core'>
"Evaluate the given block with the receiver as its argument."
self isEmpty ifFalse: [^ aBlock value: self].
]
copyWithoutAll: aCollection [
"Answer a copy of the receiver that does not contain any elements
equal to those in aCollection."
^ self reject: [:each | aCollection includes: each]
]
]
String extend [
findString: subString startingAt: aStart [
| res start |
<category: '*soapopera-core'>
"This comes from Pharo 1.1 and is on String"
"Answer the index of subString within the receiver, starting at start. If
the receiver does not contain subString, answer 0."
start := aStart = 0 ifTrue: [1] ifFalse: [aStart].
res := self indexOf: subString matchCase: true startingAt: start.
res ifNil: [^ 0]
ifNotNil: [^ res first]
]
base64Encoded [
<category: '*network-mime'>
"Encode the receiver as base64"
"'Hello World' base64Encoded"
^(Base64MimeConverter mimeEncode: self readStream) contents
]
base64Decoded [
<category: '*network-mime'>
"Decode the receiver from base 64"
"'SGVsbG8gV29ybGQ=' base64Decoded"
^(Base64MimeConverter mimeDecode: self as: self class)
]
withFirstCharacterDownshifted [
"Return a copy with the first letter downShifted"
| answer |
self ifEmpty: [^ self copy].
answer := self copy.
answer at: 1 put: (answer at: 1) asLowercase.
^ answer.
]
]
ByteArray extend [
base64Encoded [
<category: '*network-mime'>
"Encode the receiver as base64"
"'Hello World' base64Encoded"
^(Base64MimeConverter mimeEncode: self readStream) contents
]
]
UndefinedObject extend [
isEmptyOrNil [
<category: '*soapopera-core'>
^ true
]
]
Character extend [
charCode [
<category: '*soapopera-core'>
^ codePoint
]
]
DateTime extend [
DateTime class >> fromString: aString [
^ self readFrom: aString readStream.
]
asString [
^ String streamContents: [:stream | self printOn: stream]
]
]

5
soapopera/ISSUES Normal file
View File

@ -0,0 +1,5 @@
- Test with localhost as name..
- Test redirection on HTTP. Actually this will emit an Exception that
is not handled yet and should be handled.
- Test with HTTPS
- Implement auth in some way

7
soapopera/LICENSE Normal file
View File

@ -0,0 +1,7 @@
http://www.mars.dti.ne.jp/~umejava/smalltalk/soapOpera/index.html
SoapOpera consists of two parts: SoapCore and OperaORB.
SoapCore and OperaORB are licensed under the MIT style license.
Adoptions for Pharo considered as MIT licensed as well:
http://www.squeaksource.com/@VtQYLu2HzOA7XXqy/qJ9Lxpcn

19
soapopera/PORTING Normal file
View File

@ -0,0 +1,19 @@
DynamicBindings-GuillermoPolito.3.mcz
KomHttpServer-GuillermoPolito.16.mcz
KomServices-GuillermoPolito.13.mcz
SOAP-Client-GuillermoPolito.5.mcz
SOAP-Core-GuillermoPolito.62.mcz
SOAP-Example-GuillermoPolito.9.mcz
SOAP-Extra-GuillermoPolito.7.mcz
SOAP-Server-GuillermoPolito.12.mcz
SOAP-TestCases-GuillermoPolito.34.mcz
SoXML-GuillermoPolito.11.mcz
= Unusual =
The VW XMLParser wants to see namespaces... parsing of a simple element will
fail due the lack of namespaces. We introduce a simple parser subclass that
will cope with the fact of missing namespaces...
The xmlns:name=URL attributes are not seen... we will need to make them available
to the SoapWrapElement.

1418
soapopera/SoXML.st Normal file

File diff suppressed because it is too large Load Diff

231
soapopera/SoXMLTest.st Normal file
View File

@ -0,0 +1,231 @@
TestCase subclass: SoXmlAttributesHolderTestCase [
<comment: nil>
<category: 'SOAP-TestCases'>
testAsDictionary [
<category: 'testing'>
| attribsHolder dict |
attribsHolder := SoXmlAttributesHolder new.
attribsHolder putAttribute: #('key1' 'val1').
attribsHolder putAttribute: #('key2' 'val2').
dict := attribsHolder asDictionary.
self should: [(dict at: 'key1') = 'val1'].
self should: [(dict at: 'key2') = 'val2']
]
testDeclareNamespaceURIs [
<category: 'testing'>
| attribsHolder |
attribsHolder := SoXmlAttributesHolder new.
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
attribsHolder declareNamespace: 'Foo2' uri: 'http://www.baz.org'.
self should:
[(attribsHolder declaredNamespaceURIFor: 'Foo1') = 'http://www.bar.org'].
self should:
[(attribsHolder declaredNamespaceURIFor: 'Foo2') = 'http://www.baz.org']
]
testDeclareNamespaces [
<category: 'testing'>
| attribsHolder |
attribsHolder := SoXmlAttributesHolder new.
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
attribsHolder declareNamespace: 'Foo2' uri: 'http://www.baz.org'.
self
should: [attribsHolder declaredNamespacePrefixes = (Set with: 'Foo1' with: 'Foo2')]
]
testDeclareNamespacesAndPutAttributes [
<category: 'testing'>
| attribsHolder ansStr |
attribsHolder := SoXmlAttributesHolder new.
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
attribsHolder putAttribute: #('key1' 'val1').
ansStr := ' xmlns:Foo1="http://www.bar.org" key1="val1"'.
self should: [ansStr = attribsHolder printString]
]
testPutAttributes [
<category: 'testing'>
| attribsHolder |
attribsHolder := SoXmlAttributesHolder new.
attribsHolder putAttribute: #('key1' 'val1').
self should: ['val1' = (attribsHolder getAttributeNamed: 'key1')].
attribsHolder putAttribute: #('key1' 'val2').
self shouldnt: ['val1' = (attribsHolder getAttributeNamed: 'key1')].
self should: ['val2' = (attribsHolder getAttributeNamed: 'key1')]
]
]
TestCase subclass: SoXmlUtilTestCase [
<comment: nil>
<category: 'SOAP-TestCases'>
compString [
<category: 'fixtures'>
^self normalString , self convString
]
convString [
<category: 'fixtures'>
^'<>''"&'
]
nameapacedSimpleXmlString [
<category: 'fixtures'>
^'<m:Bar a="1" b="2" xmlns:m="http://soapinterop.org/">
<bar>cont</bar>
</m:Bar>'
]
namespacedSimpleXmlElement [
<category: 'fixtures'>
^SoXmlUtil parseXml: self nameapacedSimpleXmlString
]
normalString [
<category: 'fixtures'>
^'SoapOpera is a Squeak SOAP implementaion written by Masashi Umezawa'
]
simpleXmlElement [
<category: 'fixtures'>
^SoXmlUtil parseXml: self simpleXmlString
]
simpleXmlElementWithText [
<category: 'fixtures'>
^SoXmlUtil parseXml: self simpleXmlStringWithText
]
simpleXmlString [
<category: 'fixtures'>
^'<Foo a="1" b="2">
<bar>cont</bar>
</Foo>'
]
simpleXmlStringWithText [
<category: 'fixtures'>
^'<Foo a="1" b="2">
some text...
<bar>cont</bar>
</Foo>'
]
testAttribDict [
<category: 'testing'>
| elem dic1 dic2 |
elem := self simpleXmlElement.
dic1 := SoXmlUtil attribDictFrom: elem.
dic2 := Dictionary new.
dic2 at: 'a' put: '1'.
dic2 at: 'b' put: '2'.
self should: [dic1 = dic2]
]
testComplexStringWrite [
<category: 'testing'>
| str1 str2 str3 |
str1 := self compString.
str2 := SoXmlUtil asXmlText: str1.
str3 := self normalString , '&lt;&gt;&apos;&quot;&amp;'.
self shouldnt: [str1 = str2].
self should: [str2 = str3]
]
testConvStringWrite [
<category: 'testing'>
| str1 str2 str3 |
str1 := self convString.
str2 := SoXmlUtil asXmlText: str1.
str3 := '&lt;&gt;&apos;&quot;&amp;'.
self shouldnt: [str1 = str2].
self should: [str2 = str3]
]
testElementName [
<category: 'testing'>
| elem nm |
elem := self simpleXmlElement.
nm := SoXmlUtil elementNameFrom: elem.
self should: [nm = 'Foo']
]
testElementShortName [
<category: 'testing'>
| elem2 nm2 |
elem2 := self namespacedSimpleXmlElement.
nm2 := SoXmlUtil elementShortNameFrom: elem2.
self should: [nm2 = 'Bar']
]
testElementsWithoutTexts [
<category: 'testing'>
| elem1 elems1 elem2 elems2 |
elem1 := self simpleXmlElement.
elems1 := SoXmlUtil elementsWithoutTextsFrom: elem1.
elem2 := self simpleXmlElementWithText.
elems2 := SoXmlUtil elementsWithoutTextsFrom: elem2.
self should: [elems1 size = elems2 size].
self should: [elems1 printString = elems2 printString]
]
testNormalStringWrite [
<category: 'testing'>
| str1 str2 |
str1 := self normalString.
str2 := SoXmlUtil asXmlText: str1.
self should: [str1 = str2]
]
]
TestCase subclass: SoXmlWrapElementTestCase [
<comment: nil>
<category: 'SOAP-TestCases'>
testElemPrint1 [
<category: 'testing'>
| fixString wStr xmlElem |
fixString := '<Foo>bar</Foo>
'.
wStr := WriteStream on: (String new: 16).
xmlElem := SoXmlWrapElement new.
xmlElem name: 'Foo'.
xmlElem value: 'bar'.
xmlElem printXmlOn: wStr.
self should: [wStr contents = fixString]
]
testElemPrint2 [
<category: 'testing'>
| fixString wStr xmlElem child |
fixString := '<SMIX>
<interchangeUnit>
<classDefinition className="Customer">
<instVarNames>name address tel</instVarNames>
</classDefinition>
</interchangeUnit>
</SMIX>
'.
wStr := WriteStream on: (String new: 16).
xmlElem := SoXmlWrapElement new.
xmlElem name: 'SMIX'.
child := xmlElem createChildNamed: 'interchangeUnit'.
child := child createChildNamed: 'classDefinition'.
child putAttribute: #(#className #Customer).
child := child createChildNamed: 'instVarNames'.
child value: 'name address tel'.
xmlElem printXmlOn: wStr.
self should: [wStr contents = fixString]
]
]

1003
soapopera/SoapClient.st Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,457 @@
Object subclass: SoapSampleCustomer [
| name age dateOfBirth |
<category: 'SOAP-Example-CustomComplexType'>
<comment: nil>
SoapSampleCustomer class >> customerA [
<category: 'sample instances'>
| cust |
cust := self new.
cust name: 'Masashi'.
cust age: 36.
cust dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00').
^cust
]
SoapSampleCustomer class >> customerB [
<category: 'sample instances'>
| cust |
cust := self new.
cust name: 'Mike'.
cust age: 26.
cust dateOfBirth: (DateTime fromString: '1980-10-20T00:00:00-07:00').
^cust
]
SoapSampleCustomer class >> initialize [
"SoapSampleCustomer initialize"
<category: 'class initialization'>
SoapEncoder complexTypeDict at: self name put: 'types:Customer'.
SoapLiteralEncoder complexTypeDict at: self name put: 'types:Customer'.
SoapDecoder complexTypeDict at: 'types:Customer' put: self
]
age [
"Answer the value of age"
<category: 'accessing'>
^age
]
age: anObject [
"Set the value of age"
<category: 'accessing'>
age := anObject
]
dateOfBirth [
"Answer the value of dateOfBirth"
<category: 'accessing'>
^dateOfBirth
]
dateOfBirth: anObject [
"Set the value of dateOfBirth"
<category: 'accessing'>
dateOfBirth := anObject
]
name [
<category: 'accessing'>
^name
]
name: anObject [
"Set the value of name"
<category: 'accessing'>
name := anObject
]
]
Object subclass: SoapSampleGroup [
| name members |
<category: 'SOAP-Example-CustomComplexType'>
<comment: nil>
SoapSampleGroup class >> groupA [
"SoapSampleGroup groupA"
<category: 'sample instances'>
| group |
group := self new.
group name: 'Squeak support'.
group members add: SoapSampleCustomer customerA.
group members add: SoapSampleCustomer customerB.
^group
]
SoapSampleGroup class >> initialize [
"SoapSampleGroup initialize"
<category: 'class initialization'>
SoapEncoder complexTypeDict at: self name put: 'types:Groups'.
SoapLiteralEncoder complexTypeDict at: self name put: 'types:Groups'.
SoapDecoder complexTypeDict at: 'types:Groups' put: self
]
members [
"Answer the value of members"
<category: 'accessing'>
members ifNil: [members := OrderedCollection new].
^members
]
members: anObject [
"Set the value of members"
<category: 'accessing'>
members := anObject
]
name [
<category: 'accessing'>
^name
]
name: anObject [
"Set the value of name"
<category: 'accessing'>
name := anObject
]
]
TestCase subclass: SoapDecoderCustomTestCase [
<comment: nil>
<category: 'SOAP-TestCases'>
dotNetSharedValuesEnvelopeXML2 [
<category: 'fixtures'>
^'<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:types="http://tempuri.org/" xmlns:tns="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<types:FindCustomersResponse>
<FindCustomersResult href="#id1"></FindCustomersResult>
</types:FindCustomersResponse>
<soapenc:Array id="id1" soapenc:arrayType="types:Customer[2]">
<Item href="#id2"></Item>
<Item href="#id3"></Item>
</soapenc:Array>
<types:Customer id="id2" xsi:type="types:Customer">
<Name xsi:type="xsd:string">Ume</Name>
<Age xsi:type="xsd:int">36</Age>
<DateOfBirth
xsi:type="xsd:dateTime">1970-11-22T00:00:00.0000000-07:00</DateOfBirth>
</types:Customer>
<types:Customer id="id3" xsi:type="types:Customer">
<Name xsi:type="xsd:string">Ramon</Name>
<Age xsi:type="xsd:int">31</Age>
<DateOfBirth
xsi:type="xsd:dateTime">1995-11-22T00:00:00.0000000-07:00</DateOfBirth>
</types:Customer>
</soap:Body>
</soap:Envelope>
'
]
testDecodeDotNetSharedValuesXMLEnvelope2 [
"self debug: #testDecodeDotNetSharedValuesXMLEnvelope2"
<category: 'testing'>
| originalUseDotNetStyleSharedValues envelopeBuilder returnEnvelope message resp value |
SoapSampleCustomer initialize.
[originalUseDotNetStyleSharedValues := SoapResponse
useDotNetStyleSharedValues.
SoapResponse useDotNetStyleSharedValues: true.
envelopeBuilder := SoapEnvelopeBuilder new.
returnEnvelope := envelopeBuilder
buildSoapEnvelopeFromXmlString: self dotNetSharedValuesEnvelopeXML2.
message := SoapMessage envelope: returnEnvelope.
resp := SoapResponse fromSoapMessage: message.
value := resp returnValue.
self should: [value size = 2].
self should: [value first name = 'Ume'].
self should: [value first age = 36].
self should:
[value first dateOfBirth
= (DateTime fromString: '1970-11-22T00:00:00-07:00')].
self should: [value second name = 'Ramon'].
self should: [value second age = 31].
self should:
[value second dateOfBirth
= (DateTime fromString: '1995-11-22T00:00:00-07:00')]]
ensure:
[SoapResponse
useDotNetStyleSharedValues: originalUseDotNetStyleSharedValues]
]
testEncodeCustomStructType [
"self debug: #testEncodeCustomStructType"
<category: 'testing'>
| enc cust elem elem2 |
enc := SoapEncoder new.
enc useSharedValues: false.
cust := SoapSampleCustomer new.
cust
name: 'John';
age: 25;
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
yourself.
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
elem := enc
encodeSoapVariable: (SoapVariable name: 'customer' value: cust).
self should: [elem name = 'customer'].
"self should: [elem xsiType isNil]."
self should: [elem xsiType = 'types:Customer'].
self should: [(elem findChildNamed: 'name') value = 'John'].
self should: [(elem findChildNamed: 'age') value = '25'].
"BUG: FIXME:
self should:
[(elem findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
"
elem2 := enc encodeSoapVariable: (SoapVariable
name: 'customer'
value: cust
xsdType: (enc complexXsdTypeOf: cust)).
self should: [elem2 name = 'customer'].
self should: [elem2 xsiType = 'types:Customer'].
self should: [(elem2 findChildNamed: 'name') value = 'John'].
self should: [(elem2 findChildNamed: 'age') value = '25'].
"BUG: FIXME:
self should:
[(elem2 findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00']
"
]
testEncodeCustomStructTypeHavingCustomStructs [
"self debug: #testEncodeCustomStructTypeHavingCustomStructs"
<category: 'testing'>
| enc group elem members memA memB |
enc := SoapEncoder new.
group := SoapSampleGroup groupA.
enc complexTypeDict at: #SoapSampleGroup put: 'types:Group'.
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
enc useSharedValues: true.
elem := enc encodeSoapVariable: (SoapVariable name: 'group' value: group).
self should: [elem name = 'group'].
self should: [(elem findChildNamed: 'name') value = 'Squeak support'].
members := elem findChildNamed: 'members'.
self should: [members xsiType isNil].
self should: [members arrayItemType = 'types:Customer'].
self should: [members size = 2].
memA := members children first.
self should: [memA name = 'item'].
self should: [memA xsiType = 'types:Customer'].
self should: [(memA findChildNamed: 'name') value = 'Masashi'].
self should: [(memA findChildNamed: 'age') value = '36'].
"BUG: FIXME:
self should:
[(memA findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
"
memB := members children second.
self should: [memB name = 'item'].
self should: [memB xsiType = 'types:Customer'].
self should: [(memB findChildNamed: 'name') value = 'Mike'].
self should: [(memB findChildNamed: 'age') value = '26'].
"BUG: FIXME:
self should:
[(memB findChildNamed: 'dateOfBirth') value = '1980-10-20T00:00:00-07:00']
"
]
testEncodeCustomStructTypeSharedInArray [
"self debug: #testEncodeCustomStructTypeSharedInArray"
<category: 'testing'>
| enc cust cust2 elems elem first second third |
enc := SoapEncoder new.
cust := SoapSampleCustomer new.
cust
name: 'John';
age: 25;
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
yourself.
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
cust2 := SoapSampleCustomer new.
cust2
name: 'Taro';
age: 35;
dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00');
yourself.
enc useSharedValues: true.
elems := (SoapEncArray encoder: enc)
fromArray: (Array
with: cust
with: cust2
with: cust)
named: 'resultElements'
elementType: 'ResultElement'.
elem := enc
encodeSoapVariable: (SoapVariable name: 'resultElements' value: elems).
self should: [elem isArrayType].
first := elem children first.
self should: [first id notNil].
self should: [(first findChildNamed: 'name') value = 'John'].
self should: [(first findChildNamed: 'age') value = '25'].
"BUG: FIXME:
self should:
[(first findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
"
second := elem children second.
self should: [second id isNil].
self should: [(second findChildNamed: 'name') value = 'Taro'].
self should: [(second findChildNamed: 'age') value = '35'].
"BUG: FIXME:
self should:
[(second findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
"
third := elem children third.
self should: [third id isNil].
self should: [third children isEmpty].
self should: [first id = (third href copyFrom: 2) asNumber]
]
testEncodeCustomStructTypeSharedInStruct [
"self debug: #testEncodeCustomStructTypeSharedInStruct"
<category: 'testing'>
| enc cust cust2 elem struct1 a b c |
enc := SoapEncoder new.
cust := SoapSampleCustomer new.
cust
name: 'John';
age: 25;
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
yourself.
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
cust2 := SoapSampleCustomer new.
cust2
name: 'Taro';
age: 35;
dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00');
yourself.
struct1 := SoapEncStruct fromAssociations:
{#a -> cust.
#b -> cust2.
#c -> cust2}.
enc useSharedValues: true.
elem := enc
encodeSoapVariable: (SoapVariable name: 'resultElements' value: struct1).
self should: [elem name = 'resultElements'].
a := elem findChildNamed: 'a'.
self should: [a id isNil].
self should: [(a findChildNamed: 'name') value = 'John'].
self should: [(a findChildNamed: 'age') value = '25'].
"FIXME: BUG:
self should:
[(a findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
"
b := elem findChildNamed: 'b'.
self should: [b id notNil].
self should: [(b findChildNamed: 'name') value = 'Taro'].
self should: [(b findChildNamed: 'age') value = '35'].
"FIXME: BUG:
self should:
[(b findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
"
c := elem findChildNamed: 'c'.
self should: [c id isNil].
self should: [c children isEmpty].
self should: [b id = (c href copyFrom: 2) asNumber]
]
]
TestCase subclass: SoapDecoderCustomTestCase [
<comment: nil>
<category: 'SOAP-TestCases'>
dotNetSharedValuesEnvelopeXML2 [
<category: 'fixtures'>
^'<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:types="http://tempuri.org/" xmlns:tns="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<types:FindCustomersResponse>
<FindCustomersResult href="#id1"></FindCustomersResult>
</types:FindCustomersResponse>
<soapenc:Array id="id1" soapenc:arrayType="types:Customer[2]">
<Item href="#id2"></Item>
<Item href="#id3"></Item>
</soapenc:Array>
<types:Customer id="id2" xsi:type="types:Customer">
<Name xsi:type="xsd:string">Ume</Name>
<Age xsi:type="xsd:int">36</Age>
<DateOfBirth
xsi:type="xsd:dateTime">1970-11-22T00:00:00.0000000-07:00</DateOfBirth>
</types:Customer>
<types:Customer id="id3" xsi:type="types:Customer">
<Name xsi:type="xsd:string">Ramon</Name>
<Age xsi:type="xsd:int">31</Age>
<DateOfBirth
xsi:type="xsd:dateTime">1995-11-22T00:00:00.0000000-07:00</DateOfBirth>
</types:Customer>
</soap:Body>
</soap:Envelope>
'
]
testDecodeDotNetSharedValuesXMLEnvelope2 [
"self debug: #testDecodeDotNetSharedValuesXMLEnvelope2"
<category: 'testing'>
| originalUseDotNetStyleSharedValues envelopeBuilder returnEnvelope message resp value |
SoapSampleCustomer initialize.
[originalUseDotNetStyleSharedValues := SoapResponse
useDotNetStyleSharedValues.
SoapResponse useDotNetStyleSharedValues: true.
envelopeBuilder := SoapEnvelopeBuilder new.
returnEnvelope := envelopeBuilder
buildSoapEnvelopeFromXmlString: self dotNetSharedValuesEnvelopeXML2.
message := SoapMessage envelope: returnEnvelope.
resp := SoapResponse fromSoapMessage: message.
value := resp returnValue.
self should: [value size = 2].
self should: [value first name = 'Ume'].
self should: [value first age = 36].
"BUG: broken time classes
self should:
[value first dateOfBirth
= (DateTime fromString: '1970-11-22T00:00:00-07:00')].
"
self should: [value second name = 'Ramon'].
self should: [value second age = 31].
"BUG: broken time classes in GST
self should:
[value second dateOfBirth
= (DateTime fromString: '1995-11-22T00:00:00-07:00')]
"
]
ensure:
[SoapResponse
useDotNetStyleSharedValues: originalUseDotNetStyleSharedValues]
]
]

5047
soapopera/SoapCore.st Normal file

File diff suppressed because it is too large Load Diff

1770
soapopera/SoapCoreTests.st Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

37
soapopera/package.xml Normal file
View File

@ -0,0 +1,37 @@
<package>
<name>SoapOpera</name>
<namespace>SO</namespace>
<filein>Extensions.st</filein>
<filein>Base64MimeConverter.st</filein>
<filein>SoXML.st</filein>
<filein>SoapCore.st</filein>
<filein>SoapClient.st</filein>
<test>
<sunit>SO.SoXmlAttributesHolderTestCase</sunit>
<sunit>SO.SoXmlUtilTestCase</sunit>
<sunit>SO.SoXmlWrapElementTestCase</sunit>
<sunit>SO.SoapActionTestCase</sunit>
<sunit>SO.Base64MimeConverterTest</sunit>
<sunit>SO.SoapDecoderTestCase</sunit>
<sunit>SO.SoapCallTestCase</sunit>
<sunit>SO.SoapEncArrayTestCase</sunit>
<sunit>SO.SoapEncoderTestCase</sunit>
<sunit>SO.SoapEnvelopeTestCase</sunit>
<sunit>SO.SoapExceptionBuilderTestCase</sunit>
<sunit>SO.SoapFaultTestCase</sunit>
<sunit>SO.SoapHeaderTestCase</sunit>
<sunit>SO.SoapNullDecoderTestCase</sunit>
<sunit>SO.SoapNullEncoderTestCase</sunit>
<sunit>SO.SoapVariableTestCase</sunit>
<sunit>SO.SoapWrapElementTestCase</sunit>
<sunit>SO.SoapEncStructTestCase</sunit>
<sunit>SO.SoapEnvelopeBuilderTestCase</sunit>
<sunit>SO.SoapDecoderTestCase</sunit>
<sunit>SO.SoapDecoderCustomTestCase</sunit>
<filein>SoXMLTest.st</filein>
<filein>SoapCoreTests.st</filein>
<filein>SoapComplexTypesTests.st</filein>
<filein>Base64MimeConverterTest.st</filein>
</test>
</package>