riddl 0.99.105

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +165 -0
  3. data/INSTALL +24 -0
  4. data/README.rdoc +2 -0
  5. data/Rakefile +17 -0
  6. data/TODO +17 -0
  7. data/contrib/riddl.jpg +0 -0
  8. data/contrib/riddl.png +0 -0
  9. data/contrib/riddl.svg +138 -0
  10. data/lib/riddl/client.rb +423 -0
  11. data/lib/riddl/commonlogger.rb +16 -0
  12. data/lib/riddl/constants.rb +5 -0
  13. data/lib/riddl/error.rb +8 -0
  14. data/lib/riddl/handlers.rb +14 -0
  15. data/lib/riddl/handlers/oauth.rb +19 -0
  16. data/lib/riddl/handlers/plain-type.rb +21 -0
  17. data/lib/riddl/handlers/relaxng.rb +16 -0
  18. data/lib/riddl/handlers/xmlschema.rb +16 -0
  19. data/lib/riddl/header.rb +9 -0
  20. data/lib/riddl/implementation.rb +57 -0
  21. data/lib/riddl/ns/common-patterns/addon-security/request.xml +25 -0
  22. data/lib/riddl/ns/common-patterns/addon-security/response.xml +25 -0
  23. data/lib/riddl/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
  24. data/lib/riddl/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
  25. data/lib/riddl/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
  26. data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
  27. data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
  28. data/lib/riddl/ns/common-patterns/properties/1.0/properties.xml +150 -0
  29. data/lib/riddl/ns/common/datatypes-1_0.rng +79 -0
  30. data/lib/riddl/ns/common/relaxng-modular.rng +330 -0
  31. data/lib/riddl/ns/common/relaxng.rng +10 -0
  32. data/lib/riddl/ns/declaration/1.0/declaration.rng +114 -0
  33. data/lib/riddl/ns/description/1.0/description.rng +302 -0
  34. data/lib/riddl/option.rb +9 -0
  35. data/lib/riddl/parameter.rb +54 -0
  36. data/lib/riddl/protocols/http/generator.rb +121 -0
  37. data/lib/riddl/protocols/http/parser.rb +199 -0
  38. data/lib/riddl/protocols/websocket.rb +103 -0
  39. data/lib/riddl/protocols/xmpp/generator.rb +176 -0
  40. data/lib/riddl/protocols/xmpp/parser.rb +118 -0
  41. data/lib/riddl/roles.rb +15 -0
  42. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Faccess_token.rb +30 -0
  43. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Fon_behalf.rb +22 -0
  44. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Frequest_token.rb +30 -0
  45. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0/base.rb +67 -0
  46. data/lib/riddl/server.rb +519 -0
  47. data/lib/riddl/utils/description.rb +29 -0
  48. data/lib/riddl/utils/downloadify.rb +14 -0
  49. data/lib/riddl/utils/erbserve.rb +23 -0
  50. data/lib/riddl/utils/fileserve.rb +31 -0
  51. data/lib/riddl/utils/notifications_producer.rb +310 -0
  52. data/lib/riddl/utils/properties.rb +474 -0
  53. data/lib/riddl/utils/xsloverlay.rb +21 -0
  54. data/lib/riddl/wrapper.rb +280 -0
  55. data/lib/riddl/wrapper/declaration.rb +103 -0
  56. data/lib/riddl/wrapper/declaration/facade.rb +94 -0
  57. data/lib/riddl/wrapper/declaration/interface.rb +34 -0
  58. data/lib/riddl/wrapper/declaration/tile.rb +107 -0
  59. data/lib/riddl/wrapper/description.rb +69 -0
  60. data/lib/riddl/wrapper/description/access.rb +108 -0
  61. data/lib/riddl/wrapper/description/message_and_transformation.rb +131 -0
  62. data/lib/riddl/wrapper/description/resource.rb +271 -0
  63. data/lib/riddl/wrapper/layerchecker.rb +33 -0
  64. data/lib/riddl/wrapper/messageparser.rb +221 -0
  65. data/lib/riddl/wrapper/resourcechecker.rb +98 -0
  66. data/ns/common-patterns/addon-security/request.xml +25 -0
  67. data/ns/common-patterns/addon-security/response.xml +25 -0
  68. data/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
  69. data/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
  70. data/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
  71. data/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
  72. data/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
  73. data/ns/common-patterns/properties/1.0/properties.xml +150 -0
  74. data/ns/common/datatypes-1_0.rng +79 -0
  75. data/ns/common/relaxng-modular.rng +330 -0
  76. data/ns/common/relaxng.rng +10 -0
  77. data/ns/declaration/1.0/declaration.rng +114 -0
  78. data/ns/description/1.0/description.rng +302 -0
  79. data/riddl.gemspec +33 -0
  80. data/test/smartrunner.rb +48 -0
  81. data/test/tc_declaration-distributed.rb +79 -0
  82. data/test/tc_declaration-hybrid.rb +71 -0
  83. data/test/tc_declaration-local.rb +47 -0
  84. data/test/tc_helloworld.rb +17 -0
  85. data/test/tc_producer.rb +54 -0
  86. data/test/tc_properties.rb +72 -0
  87. data/tools/flash-policy-server.rb +12 -0
  88. data/tools/riddlcheck +36 -0
  89. data/tools/riddlcheck-1_0 +36 -0
  90. data/tools/riddlprocess +51 -0
  91. data/tools/riddlprocess-1_0 +51 -0
  92. 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
@@ -0,0 +1,2 @@
1
+ All code in this package is provided under the LGPL license.
2
+ Please read the file COPYING.
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>
@@ -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