riddl 0.99.105
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/COPYING +165 -0
- data/INSTALL +24 -0
- data/README.rdoc +2 -0
- data/Rakefile +17 -0
- data/TODO +17 -0
- data/contrib/riddl.jpg +0 -0
- data/contrib/riddl.png +0 -0
- data/contrib/riddl.svg +138 -0
- data/lib/riddl/client.rb +423 -0
- data/lib/riddl/commonlogger.rb +16 -0
- data/lib/riddl/constants.rb +5 -0
- data/lib/riddl/error.rb +8 -0
- data/lib/riddl/handlers.rb +14 -0
- data/lib/riddl/handlers/oauth.rb +19 -0
- data/lib/riddl/handlers/plain-type.rb +21 -0
- data/lib/riddl/handlers/relaxng.rb +16 -0
- data/lib/riddl/handlers/xmlschema.rb +16 -0
- data/lib/riddl/header.rb +9 -0
- data/lib/riddl/implementation.rb +57 -0
- data/lib/riddl/ns/common-patterns/addon-security/request.xml +25 -0
- data/lib/riddl/ns/common-patterns/addon-security/response.xml +25 -0
- data/lib/riddl/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
- data/lib/riddl/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
- data/lib/riddl/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.xml +150 -0
- data/lib/riddl/ns/common/datatypes-1_0.rng +79 -0
- data/lib/riddl/ns/common/relaxng-modular.rng +330 -0
- data/lib/riddl/ns/common/relaxng.rng +10 -0
- data/lib/riddl/ns/declaration/1.0/declaration.rng +114 -0
- data/lib/riddl/ns/description/1.0/description.rng +302 -0
- data/lib/riddl/option.rb +9 -0
- data/lib/riddl/parameter.rb +54 -0
- data/lib/riddl/protocols/http/generator.rb +121 -0
- data/lib/riddl/protocols/http/parser.rb +199 -0
- data/lib/riddl/protocols/websocket.rb +103 -0
- data/lib/riddl/protocols/xmpp/generator.rb +176 -0
- data/lib/riddl/protocols/xmpp/parser.rb +118 -0
- data/lib/riddl/roles.rb +15 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Faccess_token.rb +30 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Fon_behalf.rb +22 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Frequest_token.rb +30 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0/base.rb +67 -0
- data/lib/riddl/server.rb +519 -0
- data/lib/riddl/utils/description.rb +29 -0
- data/lib/riddl/utils/downloadify.rb +14 -0
- data/lib/riddl/utils/erbserve.rb +23 -0
- data/lib/riddl/utils/fileserve.rb +31 -0
- data/lib/riddl/utils/notifications_producer.rb +310 -0
- data/lib/riddl/utils/properties.rb +474 -0
- data/lib/riddl/utils/xsloverlay.rb +21 -0
- data/lib/riddl/wrapper.rb +280 -0
- data/lib/riddl/wrapper/declaration.rb +103 -0
- data/lib/riddl/wrapper/declaration/facade.rb +94 -0
- data/lib/riddl/wrapper/declaration/interface.rb +34 -0
- data/lib/riddl/wrapper/declaration/tile.rb +107 -0
- data/lib/riddl/wrapper/description.rb +69 -0
- data/lib/riddl/wrapper/description/access.rb +108 -0
- data/lib/riddl/wrapper/description/message_and_transformation.rb +131 -0
- data/lib/riddl/wrapper/description/resource.rb +271 -0
- data/lib/riddl/wrapper/layerchecker.rb +33 -0
- data/lib/riddl/wrapper/messageparser.rb +221 -0
- data/lib/riddl/wrapper/resourcechecker.rb +98 -0
- data/ns/common-patterns/addon-security/request.xml +25 -0
- data/ns/common-patterns/addon-security/response.xml +25 -0
- data/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
- data/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
- data/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
- data/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
- data/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
- data/ns/common-patterns/properties/1.0/properties.xml +150 -0
- data/ns/common/datatypes-1_0.rng +79 -0
- data/ns/common/relaxng-modular.rng +330 -0
- data/ns/common/relaxng.rng +10 -0
- data/ns/declaration/1.0/declaration.rng +114 -0
- data/ns/description/1.0/description.rng +302 -0
- data/riddl.gemspec +33 -0
- data/test/smartrunner.rb +48 -0
- data/test/tc_declaration-distributed.rb +79 -0
- data/test/tc_declaration-hybrid.rb +71 -0
- data/test/tc_declaration-local.rb +47 -0
- data/test/tc_helloworld.rb +17 -0
- data/test/tc_producer.rb +54 -0
- data/test/tc_properties.rb +72 -0
- data/tools/flash-policy-server.rb +12 -0
- data/tools/riddlcheck +36 -0
- data/tools/riddlcheck-1_0 +36 -0
- data/tools/riddlprocess +51 -0
- data/tools/riddlprocess-1_0 +51 -0
- metadata +291 -0
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Jürgen Mangler <juergen.mangler@gmail.com>
|
data/COPYING
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/INSTALL
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
== Ubuntu & Debian
|
2
|
+
|
3
|
+
sudo apt-get install libxml2-dev libxslt1-dev zlib1g-dev ruby-dev build-essential ruby ruby
|
4
|
+
sudo gem install pkg/riddl.gem
|
5
|
+
|
6
|
+
If "pkg/riddl.gem" not exists, then create it with "rake gem".
|
7
|
+
|
8
|
+
== Others
|
9
|
+
|
10
|
+
find out yourself
|
11
|
+
|
12
|
+
== Gem Dependencies
|
13
|
+
|
14
|
+
You don't need to care about them, as they will be automatically installed
|
15
|
+
during the installation of the riddl.gem. Here is a list of them just in case
|
16
|
+
you are interessted:
|
17
|
+
|
18
|
+
* ruby-xml-smart (>= 0.2.1.1 needed)
|
19
|
+
* rack
|
20
|
+
* thin
|
21
|
+
* mime-types
|
22
|
+
* eventmachine (>= 1.0.0.beta.4')
|
23
|
+
* em-websocket
|
24
|
+
* em-websocket-client
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems/package_task'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList['./test/tc_*.rb']
|
8
|
+
t.verbose = false
|
9
|
+
end
|
10
|
+
|
11
|
+
spec = eval(File.read('riddl.gemspec'))
|
12
|
+
Gem::PackageTask.new(spec) do |pkg|
|
13
|
+
pkg.need_zip = true
|
14
|
+
pkg.need_tar = true
|
15
|
+
`rm pkg/* -rf`
|
16
|
+
`ln -sf #{pkg.name}.gem pkg/riddl.gem`
|
17
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Fixing:
|
2
|
+
fix examples/declaration-test
|
3
|
+
fix examples/description-test
|
4
|
+
fix examples/flickr/Exif/exif.ru
|
5
|
+
fix examples/flickr/client.rb ???
|
6
|
+
fix examples/library
|
7
|
+
fix examples/websocket
|
8
|
+
|
9
|
+
Tests:
|
10
|
+
examples/downloadify
|
11
|
+
examples/oauth
|
12
|
+
|
13
|
+
Features:
|
14
|
+
examples/xmpp
|
15
|
+
|
16
|
+
|
17
|
+
@Florian: Try out flickr, zotero && twitter examples and write doku
|
data/contrib/riddl.jpg
ADDED
Binary file
|
data/contrib/riddl.png
ADDED
Binary file
|
data/contrib/riddl.svg
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
<svg
|
4
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
5
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
6
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
7
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
9
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
10
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
11
|
+
width="150.49515"
|
12
|
+
height="150.48607"
|
13
|
+
id="svg2"
|
14
|
+
sodipodi:version="0.32"
|
15
|
+
inkscape:version="0.46"
|
16
|
+
version="1.0"
|
17
|
+
sodipodi:docname="riddl.svg"
|
18
|
+
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
19
|
+
<defs
|
20
|
+
id="defs4">
|
21
|
+
<inkscape:perspective
|
22
|
+
sodipodi:type="inkscape:persp3d"
|
23
|
+
inkscape:vp_x="0 : 526.18109 : 1"
|
24
|
+
inkscape:vp_y="0 : 1000 : 0"
|
25
|
+
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
26
|
+
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
27
|
+
id="perspective10" />
|
28
|
+
</defs>
|
29
|
+
<sodipodi:namedview
|
30
|
+
id="base"
|
31
|
+
pagecolor="#ffffff"
|
32
|
+
bordercolor="#666666"
|
33
|
+
borderopacity="1.0"
|
34
|
+
gridtolerance="10000"
|
35
|
+
guidetolerance="10"
|
36
|
+
objecttolerance="10"
|
37
|
+
inkscape:pageopacity="0.0"
|
38
|
+
inkscape:pageshadow="2"
|
39
|
+
inkscape:zoom="5.6568543"
|
40
|
+
inkscape:cx="119.22439"
|
41
|
+
inkscape:cy="73.453113"
|
42
|
+
inkscape:document-units="px"
|
43
|
+
inkscape:current-layer="layer1"
|
44
|
+
showgrid="false"
|
45
|
+
showguides="true"
|
46
|
+
inkscape:guide-bbox="true"
|
47
|
+
inkscape:window-width="1466"
|
48
|
+
inkscape:window-height="1095"
|
49
|
+
inkscape:window-x="227"
|
50
|
+
inkscape:window-y="5">
|
51
|
+
<inkscape:grid
|
52
|
+
type="xygrid"
|
53
|
+
id="grid2383"
|
54
|
+
visible="true"
|
55
|
+
enabled="true" />
|
56
|
+
</sodipodi:namedview>
|
57
|
+
<metadata
|
58
|
+
id="metadata7">
|
59
|
+
<rdf:RDF>
|
60
|
+
<cc:Work
|
61
|
+
rdf:about="">
|
62
|
+
<dc:format>image/svg+xml</dc:format>
|
63
|
+
<dc:type
|
64
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
65
|
+
</cc:Work>
|
66
|
+
</rdf:RDF>
|
67
|
+
</metadata>
|
68
|
+
<g
|
69
|
+
inkscape:label="Layer 1"
|
70
|
+
inkscape:groupmode="layer"
|
71
|
+
id="layer1"
|
72
|
+
transform="translate(-84.552784,-165.73163)">
|
73
|
+
<g
|
74
|
+
id="g2511"
|
75
|
+
transform="matrix(0.7071068,0.7071067,-0.7071067,0.7071068,212.06882,-50.278325)">
|
76
|
+
<path
|
77
|
+
id="rect2385"
|
78
|
+
d="M 108.99079,227.89353 L 108.98179,257.89354 L 108.97282,287.89355 L 198.78532,287.92041 L 198.79429,257.92041 L 138.98181,257.90252 L 138.99079,227.90252 L 108.99079,227.89353 z"
|
79
|
+
style="opacity:1;fill:#a40000;fill-opacity:0.96078431;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
80
|
+
<path
|
81
|
+
id="rect2390"
|
82
|
+
d="M 138.98181,257.88969 L 168.9818,257.89868 L 168.99079,227.8987 L 198.99079,227.90766 L 198.99977,197.90765 L 168.99976,197.89867 L 169.00875,167.89869 L 139.00874,167.8897 L 138.98181,257.88969 z"
|
83
|
+
style="opacity:1;fill:#4e9a06;fill-opacity:0.96078431;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
84
|
+
<path
|
85
|
+
id="path2395"
|
86
|
+
d="M 228.99976,197.91664 L 198.99977,197.90765 L 198.99079,227.90766 L 168.99079,227.8987 L 168.9818,257.89868 L 198.98182,257.90766 L 198.97283,287.90766 L 228.97282,287.91663 L 228.99976,197.91664 z"
|
87
|
+
style="opacity:1;fill:#204a87;fill-opacity:0.96078431;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
88
|
+
<text
|
89
|
+
transform="matrix(0.9999845,-5.5671781e-3,5.5671781e-3,0.9999845,0,0)"
|
90
|
+
sodipodi:linespacing="100%"
|
91
|
+
id="text3231"
|
92
|
+
y="262.52325"
|
93
|
+
x="108.71021"
|
94
|
+
style="font-size:43.54337311px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Narrow;-inkscape-font-specification:Arial Narrow Bold Condensed"
|
95
|
+
xml:space="preserve"><tspan
|
96
|
+
y="262.52325"
|
97
|
+
x="108.71021"
|
98
|
+
id="tspan3233"
|
99
|
+
sodipodi:role="line">R</tspan></text>
|
100
|
+
<text
|
101
|
+
transform="matrix(0.9999845,-5.5671781e-3,5.5671781e-3,0.9999845,0,0)"
|
102
|
+
sodipodi:linespacing="100%"
|
103
|
+
id="text3235"
|
104
|
+
y="255.87482"
|
105
|
+
x="168.65849"
|
106
|
+
style="font-size:33.26409912px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Narrow;-inkscape-font-specification:Arial Narrow Bold Condensed"
|
107
|
+
xml:space="preserve"><tspan
|
108
|
+
y="255.87482"
|
109
|
+
x="168.65849"
|
110
|
+
id="tspan3239"
|
111
|
+
sodipodi:role="line">DDL</tspan></text>
|
112
|
+
<text
|
113
|
+
transform="matrix(-4.6457888e-3,-1.1983093,0.8344832,-6.6713043e-3,0,0)"
|
114
|
+
sodipodi:linespacing="100%"
|
115
|
+
id="text3245"
|
116
|
+
y="233.83086"
|
117
|
+
x="-183.64711"
|
118
|
+
style="font-size:40.01108551px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Narrow;-inkscape-font-specification:Arial Narrow Bold Condensed"
|
119
|
+
xml:space="preserve"><tspan
|
120
|
+
y="233.83086"
|
121
|
+
x="-183.64711"
|
122
|
+
id="tspan3247"
|
123
|
+
sodipodi:role="line">I</tspan></text>
|
124
|
+
<path
|
125
|
+
sodipodi:end="5.2460972"
|
126
|
+
sodipodi:start="0"
|
127
|
+
transform="matrix(-5.5671778e-3,-0.9999845,0.9999845,-5.5671778e-3,-49.705462,375.31674)"
|
128
|
+
d="M 169.28572,213.79076 A 7.8571429,7.8571429 0 1 1 165.42573,207.02633 L 161.42857,213.79076 z"
|
129
|
+
sodipodi:ry="7.8571429"
|
130
|
+
sodipodi:rx="7.8571429"
|
131
|
+
sodipodi:cy="213.79076"
|
132
|
+
sodipodi:cx="161.42857"
|
133
|
+
id="path3251"
|
134
|
+
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
135
|
+
sodipodi:type="arc" />
|
136
|
+
</g>
|
137
|
+
</g>
|
138
|
+
</svg>
|
data/lib/riddl/client.rb
ADDED
@@ -0,0 +1,423 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/https'
|
3
|
+
require 'socket'
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'em-websocket-client'
|
6
|
+
require 'blather/client/client'
|
7
|
+
require 'uri'
|
8
|
+
require 'openssl'
|
9
|
+
require 'digest/md5'
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/wrapper')
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + '/error')
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + '/protocols/http/generator')
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + '/protocols/http/parser')
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/generator')
|
15
|
+
require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/parser')
|
16
|
+
require File.expand_path(File.dirname(__FILE__) + '/header')
|
17
|
+
require File.expand_path(File.dirname(__FILE__) + '/option')
|
18
|
+
|
19
|
+
class StringIO #{{{
|
20
|
+
def continue_timeout; nil; end
|
21
|
+
end #}}}
|
22
|
+
|
23
|
+
class SignalWait #{{{
|
24
|
+
def initialize
|
25
|
+
@q = Queue.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def wait
|
29
|
+
@q.deq
|
30
|
+
end
|
31
|
+
|
32
|
+
def continue
|
33
|
+
@q.push nil
|
34
|
+
end
|
35
|
+
end #}}}
|
36
|
+
|
37
|
+
unless Module.constants.include?('CLIENT_INCLUDED')
|
38
|
+
CLIENT_INCLUDED = true
|
39
|
+
|
40
|
+
module Riddl
|
41
|
+
|
42
|
+
class Client
|
43
|
+
#{{{
|
44
|
+
def initialize(base, riddl=nil, options={})
|
45
|
+
@base = base.nil? ? '' : base.gsub(/\/+$/,'')
|
46
|
+
@options = options
|
47
|
+
@wrapper = nil
|
48
|
+
@thread = nil
|
49
|
+
sig = SignalWait.new
|
50
|
+
if URI.parse(@base).scheme == 'xmpp' && @options[:jid] && @options[:pass]
|
51
|
+
@thread = Thread.new do
|
52
|
+
EM.run do
|
53
|
+
client = Blather::Client.setup @options[:jid], @options[:pass]
|
54
|
+
client.register_handler(:ready) { sig.continue; }
|
55
|
+
client.connect
|
56
|
+
@options[:xmpp] = client
|
57
|
+
sig.continue
|
58
|
+
end
|
59
|
+
end
|
60
|
+
sig.wait
|
61
|
+
sig.wait
|
62
|
+
end
|
63
|
+
unless riddl.nil?
|
64
|
+
@wrapper = (riddl.class == Riddl::Wrapper ? riddl : Riddl::Wrapper::new(riddl))
|
65
|
+
if @wrapper.declaration? && !base.nil?
|
66
|
+
@wrapper = @wrapper.declaration.description
|
67
|
+
end
|
68
|
+
raise SpecificationError, 'No RIDDL description or declaration found.' if !@wrapper.description? && !@wrapper.declaration?
|
69
|
+
raise SpecificationError, 'RIDDL does not conform to specification' unless @wrapper.validate!
|
70
|
+
@wrapper.load_necessary_handlers!
|
71
|
+
@wrapper.load_necessary_roles!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
attr_reader :base
|
75
|
+
|
76
|
+
def self::location(base,options={})
|
77
|
+
new(base,nil,options)
|
78
|
+
end
|
79
|
+
def self::interface(base,riddl,options={})
|
80
|
+
new(base,riddl,options)
|
81
|
+
end
|
82
|
+
def self::facade(riddl,options={})
|
83
|
+
new(nil,riddl,options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def resource(path="")
|
87
|
+
Resource.new(@base,@wrapper,path,@options)
|
88
|
+
end
|
89
|
+
def get(parameters = []); resource('/').get(parameters); end
|
90
|
+
def simulate_get(parameters = []); resource('/').simulate_get(parameters); end
|
91
|
+
def post(parameters = []); resource('/').post(parameters); end
|
92
|
+
def simulate_post(parameters = []); resource('/').simulate_post(parameters); end
|
93
|
+
def put(parameters = []); resource('/').put(parameters); end
|
94
|
+
def simulate_put(parameters = []); resource('/').simulate_put(parameters); end
|
95
|
+
def delete(parameters = []); resource('/').delete(parameters); end
|
96
|
+
def simulate_delete(parameters = []); resource('/').simulate_delete(parameters); end
|
97
|
+
def request(what) resource('/').request(what); end
|
98
|
+
def simulate_request(what) resource('/').simulate_request(what); end
|
99
|
+
def ws(blk) resource('/').ws(blk); end
|
100
|
+
#}}}
|
101
|
+
|
102
|
+
class Resource
|
103
|
+
def initialize(base,wrapper,path,options) #{{{
|
104
|
+
@base = base
|
105
|
+
@wrapper = wrapper
|
106
|
+
@rpath = "/#{path}".gsub(/\/+/,'/')
|
107
|
+
@options = options
|
108
|
+
@path = if @wrapper.nil?
|
109
|
+
@rpath
|
110
|
+
else
|
111
|
+
@path = @wrapper.paths.find{ |e| e[1] =~ @rpath }
|
112
|
+
raise PathError, 'Path not found.' if @path.nil?
|
113
|
+
@path[0]
|
114
|
+
end
|
115
|
+
@rpath = @rpath == '/' ? '' : @rpath
|
116
|
+
end #}}}
|
117
|
+
attr_reader :rpath
|
118
|
+
|
119
|
+
def ws(&blk) #{{{
|
120
|
+
EM.run do
|
121
|
+
conn = EventMachine::WebSocketClient.connect((@base + @rpath).sub(/^http/,'ws'))
|
122
|
+
|
123
|
+
conn.disconnect do
|
124
|
+
EM::stop_event_loop
|
125
|
+
end
|
126
|
+
|
127
|
+
if @options[:debug]
|
128
|
+
conn.errback do |e|
|
129
|
+
@options[:debug].puts "WS ERROR: #{e}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
blk.call(conn)
|
134
|
+
end
|
135
|
+
end #}}}
|
136
|
+
|
137
|
+
def get(parameters = []) #{{{
|
138
|
+
exec_request('GET',parameters,false)
|
139
|
+
end #}}}
|
140
|
+
def simulate_get(parameters = []) #{{{
|
141
|
+
exec_request('GET',parameters,true)
|
142
|
+
end #}}}
|
143
|
+
|
144
|
+
def post(parameters = []) #{{{
|
145
|
+
exec_request('POST',parameters,false)
|
146
|
+
end #}}}
|
147
|
+
def simulate_post(parameters = []) #{{{
|
148
|
+
exec_request('POST',parameters,true)
|
149
|
+
end #}}}
|
150
|
+
|
151
|
+
def put(parameters = []) #{{{
|
152
|
+
exec_request('PUT',parameters,false)
|
153
|
+
end #}}}
|
154
|
+
def simulate_put(parameters = []) #{{{
|
155
|
+
exec_request('PUT',parameters,true)
|
156
|
+
end #}}}
|
157
|
+
|
158
|
+
def delete(parameters = []) #{{{
|
159
|
+
exec_request('DELETE',parameters,false)
|
160
|
+
end #}}}
|
161
|
+
def simulate_delete(parameters = []) #{{{
|
162
|
+
exec_request('DELETE',parameters,true)
|
163
|
+
end #}}}
|
164
|
+
|
165
|
+
def request(what) #{{{
|
166
|
+
priv_request(what,false)
|
167
|
+
end #}}}
|
168
|
+
def simulate_request(what) #{{{
|
169
|
+
priv_request(what,true)
|
170
|
+
end #}}}
|
171
|
+
def priv_request(what,simulate) #{{{
|
172
|
+
if what.class == Hash && what.length == 1
|
173
|
+
what.each do |method,parameters|
|
174
|
+
return exec_request(method.to_s.upcase,parameters,simulate)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
raise ArgumentError, "Hash with ONE method => parameters pair required"
|
178
|
+
end #}}}
|
179
|
+
private :priv_request
|
180
|
+
|
181
|
+
def extract_options(parameters) #{{{
|
182
|
+
options = {}
|
183
|
+
parameters.delete_if do |p|
|
184
|
+
if p.class == Riddl::Option
|
185
|
+
options[p.name] = "#{p.value}"
|
186
|
+
true
|
187
|
+
else
|
188
|
+
false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
options
|
192
|
+
end #}}}
|
193
|
+
private :extract_options
|
194
|
+
def extract_headers(parameters) #{{{
|
195
|
+
headers = {}
|
196
|
+
parameters.delete_if do |p|
|
197
|
+
if p.class == Riddl::Header
|
198
|
+
headers[p.name.upcase] = "#{p.value}"
|
199
|
+
true
|
200
|
+
else
|
201
|
+
false
|
202
|
+
end
|
203
|
+
end
|
204
|
+
headers
|
205
|
+
end #}}}
|
206
|
+
private :extract_headers
|
207
|
+
|
208
|
+
def extract_qparams(parameters,method) #{{{
|
209
|
+
qparams = []
|
210
|
+
starting = true
|
211
|
+
parameters.delete_if do |p|
|
212
|
+
if starting && p.class == Riddl::Parameter::Simple && method == 'get'
|
213
|
+
p.type = :query
|
214
|
+
end
|
215
|
+
if p.class == Riddl::Parameter::Simple && p.type == :query
|
216
|
+
qparams << Protocols::HTTP::Generator::escape(p.name) + (p.value.nil? ? '' : '=' + Protocols::HTTP::Generator::escape(p.value))
|
217
|
+
true
|
218
|
+
else
|
219
|
+
starting = false
|
220
|
+
false
|
221
|
+
end
|
222
|
+
end
|
223
|
+
qparams
|
224
|
+
end #}}}
|
225
|
+
private :extract_qparams
|
226
|
+
|
227
|
+
def exec_request(riddl_method,parameters,simulate) #{{{
|
228
|
+
parameters = parameters.dup
|
229
|
+
headers = extract_headers(parameters)
|
230
|
+
options = extract_options(parameters)
|
231
|
+
role = nil
|
232
|
+
|
233
|
+
unless @wrapper.nil?
|
234
|
+
role = @wrapper.role(@path)
|
235
|
+
if Riddl::Roles::roles[role]
|
236
|
+
Riddl::Roles::roles[role]::before(@base + @rpath,riddl_method.downcase,parameters,headers,options) if Riddl::Roles::roles[role].respond_to?(:before)
|
237
|
+
end
|
238
|
+
riddl_message = @wrapper.io_messages(@path,riddl_method.downcase,parameters,headers)
|
239
|
+
if riddl_message.nil?
|
240
|
+
raise InputError, "Not a valid input to service."
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
qparams = extract_qparams(parameters,riddl_method.downcase)
|
245
|
+
|
246
|
+
res = response = nil
|
247
|
+
if @wrapper.nil? || @wrapper.description? || (@wrapper.declaration? && !@base.nil?)
|
248
|
+
status, response, response_headers = make_request(@base + @rpath,riddl_method,parameters,headers,qparams,simulate)
|
249
|
+
return response if simulate
|
250
|
+
if !@wrapper.nil? && status == 200
|
251
|
+
unless @wrapper.check_message(response,response_headers,riddl_message.out)
|
252
|
+
raise OutputError, "Not a valid output from service."
|
253
|
+
end
|
254
|
+
end
|
255
|
+
elsif !@wrapper.nil? && @base.nil? && @wrapper.declaration?
|
256
|
+
headers['RIDDL-DECLARATION-PATH'] = @rpath
|
257
|
+
if !riddl_message.route?
|
258
|
+
status, response, response_headers = make_request(riddl_message.interface.real_url(@rpath,@base),riddl_method,parameters,headers,qparams,simulate)
|
259
|
+
return response if simulate
|
260
|
+
if status == 200
|
261
|
+
unless @wrapper.check_message(response,response_headers,riddl_message.out)
|
262
|
+
raise OutputError, "Not a valid output from service."
|
263
|
+
end
|
264
|
+
end
|
265
|
+
else
|
266
|
+
tp = parameters
|
267
|
+
th = headers
|
268
|
+
tq = qparams
|
269
|
+
riddl_message.route.each do |m|
|
270
|
+
status, response, response_headers = make_request(m.interface.real_url(@rpath,@base),riddl_method,tp,th,tq,simulate)
|
271
|
+
return response if simulate
|
272
|
+
if status != 200 || !@wrapper.check_message(response,response_headers,m.out)
|
273
|
+
raise OutputError, "Not a valid output from service."
|
274
|
+
end
|
275
|
+
unless m == riddl_message.route.last
|
276
|
+
tp = response
|
277
|
+
th = extract_headers(response) # TODO extract relvant headers from res (get from m.out)
|
278
|
+
tq = extract_qparams(response,riddl_method.downcase)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
else
|
283
|
+
raise OutputError, "Impossible Error :-)"
|
284
|
+
end
|
285
|
+
unless role.nil?
|
286
|
+
if Riddl::Roles::roles[role]
|
287
|
+
response = Riddl::Roles::roles[role]::after(@base + @rpath,riddl_method.downcase,status,response,response_headers,options) if Riddl::Roles::roles[role].respond_to?(:after)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
return status, response, response_headers
|
291
|
+
end #}}}
|
292
|
+
private :exec_request
|
293
|
+
|
294
|
+
def make_request(url,riddl_method,parameters,headers,qparams,simulate) #{{{
|
295
|
+
url = URI.parse(url)
|
296
|
+
qs = qparams.join('&')
|
297
|
+
if url.class == URI::HTTP || url.class == URI::HTTPS
|
298
|
+
#{{{
|
299
|
+
req = Riddl::Client::HTTPRequest.new(riddl_method,url.path,parameters,headers,qs)
|
300
|
+
return req.simulate if simulate
|
301
|
+
|
302
|
+
res = response = nil
|
303
|
+
|
304
|
+
http = Net::HTTP.new(url.host, url.port)
|
305
|
+
if url.class == URI::HTTPS
|
306
|
+
http.use_ssl = true
|
307
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
308
|
+
end
|
309
|
+
deb = nil
|
310
|
+
if @options[:debug]
|
311
|
+
http.set_debug_output @options[:debug]
|
312
|
+
end
|
313
|
+
http.start do
|
314
|
+
http.request(req) do |resp|
|
315
|
+
res = resp
|
316
|
+
bs = Parameter::Tempfile.new("RiddlBody")
|
317
|
+
res.read_body(bs)
|
318
|
+
bs.rewind
|
319
|
+
response = Riddl::Protocols::HTTP::Parser.new(
|
320
|
+
"",
|
321
|
+
bs,
|
322
|
+
res['CONTENT-TYPE'],
|
323
|
+
res['CONTENT-LENGTH'],
|
324
|
+
res['CONTENT-DISPOSITION'],
|
325
|
+
res['CONTENT-ID'],
|
326
|
+
res['RIDDL-TYPE']
|
327
|
+
).params
|
328
|
+
end
|
329
|
+
end
|
330
|
+
response_headers = {}
|
331
|
+
res.each do |k,v|
|
332
|
+
if v.nil?
|
333
|
+
response_headers[k.name.upcase.gsub(/\-/,'_')] = v
|
334
|
+
else
|
335
|
+
response_headers[k.upcase.gsub(/\-/,'_')] = v
|
336
|
+
end
|
337
|
+
end
|
338
|
+
return res.code.to_i, response, response_headers
|
339
|
+
#}}}
|
340
|
+
elsif url.class == URI::Generic && url.scheme.downcase == 'xmpp'
|
341
|
+
req = Riddl::Client::XMPPRequest.new(riddl_method,url.user + "@" + url.host,url.path,parameters,headers,qs)
|
342
|
+
return req.simulate if simulate
|
343
|
+
|
344
|
+
sig = SignalWait.new
|
345
|
+
stanza = req.stanza
|
346
|
+
|
347
|
+
@options[:debug].puts(stanza) if @options[:debug]
|
348
|
+
|
349
|
+
status = 404
|
350
|
+
response = []
|
351
|
+
response_headers = {}
|
352
|
+
@options[:xmpp].write_with_handler(stanza) do |raw|
|
353
|
+
res = XML::Smart::Dom::Element.new(raw).parent
|
354
|
+
@options[:debug].puts(res.to_s) if @options[:debug]
|
355
|
+
res.register_namespace 'xr', Riddl::Protocols::XMPP::XR_NS
|
356
|
+
if res.find('/message/error').empty?
|
357
|
+
status = 200
|
358
|
+
response_headers = {}
|
359
|
+
res.find('/message/xr:header').each do |e|
|
360
|
+
response_headers[e.attributes['name']] = e.text
|
361
|
+
end
|
362
|
+
response = Protocols::XMPP::Parser.new('', res).params
|
363
|
+
else
|
364
|
+
res.register_namespace 'se', Blather::StanzaError::STANZA_ERR_NS
|
365
|
+
err = res.find('string(/message/error/se:text)')
|
366
|
+
status = (err.match(/\d+/)[0] || 209).to_i
|
367
|
+
end
|
368
|
+
sig.continue
|
369
|
+
end
|
370
|
+
sig.wait
|
371
|
+
return status, response, response_headers
|
372
|
+
end
|
373
|
+
raise URIError, "not a valid URI (http, https, xmpp are accepted)"
|
374
|
+
end #}}}
|
375
|
+
private :make_request
|
376
|
+
|
377
|
+
end #}}}
|
378
|
+
|
379
|
+
class HTTPRequest < Net::HTTPGenericRequest #{{{
|
380
|
+
def initialize(method, path, parameters, headers, qs)
|
381
|
+
path = (path.strip == '' ? '/' : path)
|
382
|
+
path += "?#{qs}" unless qs == ''
|
383
|
+
super method, true, true, path, headers
|
384
|
+
tmp = Protocols::HTTP::Generator.new(parameters,self).generate(:input)
|
385
|
+
self.content_length = tmp.size
|
386
|
+
self.body_stream = tmp
|
387
|
+
end
|
388
|
+
|
389
|
+
def supply_default_content_type
|
390
|
+
### none, Protocols::HTTP::Generator handles this
|
391
|
+
end
|
392
|
+
|
393
|
+
def simulate
|
394
|
+
sock = StringIO.new('')
|
395
|
+
self.exec(sock,"1.1",self.path)
|
396
|
+
sock.rewind
|
397
|
+
[nil, sock, []]
|
398
|
+
end
|
399
|
+
end # }}}
|
400
|
+
|
401
|
+
class XMPPRequest #{{{
|
402
|
+
attr_reader :stanza
|
403
|
+
|
404
|
+
def initialize(method, to, path, parameters, headers, qs)
|
405
|
+
path = (path.strip == '' ? '/' : path)
|
406
|
+
path += "?#{qs}" unless qs == ''
|
407
|
+
@stanza = Protocols::XMPP::Generator.new(method,parameters,headers).generate
|
408
|
+
@stanza.to = to + path
|
409
|
+
end
|
410
|
+
|
411
|
+
def simulate
|
412
|
+
sock = StringIO.new('')
|
413
|
+
sock.write @stanza.to_s
|
414
|
+
sock.rewind
|
415
|
+
[nil, sock, []]
|
416
|
+
end
|
417
|
+
end #}}}
|
418
|
+
|
419
|
+
end
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
end
|