Permalink
Browse files

refactoring of the code base. Improved rendering. Overall usage of ru…

…by and sinatra best practises. Code cleanup. Dummy backend now persistent. Improved rSpec scenarios.
  • Loading branch information...
1 parent fcf81ba commit c979a76789830869ddca9b06e2f14cffa041b6b5 Florian Feldhaus committed May 19, 2012
Showing with 3,830 additions and 5,188 deletions.
  1. +8 −0 AUTHORS
  2. +3 −1 Gemfile
  3. +3 −0 Gemfile.lock
  4. +13 −0 LICENSE
  5. +2 −2 config.ru
  6. +13 −0 etc/model/extensions/console_link.json
  7. +115 −0 etc/model/infrastructure/compute.json
  8. +52 −0 etc/model/infrastructure/ipnetwork.json
  9. +43 −0 etc/model/infrastructure/ipnetworkinterface.json
  10. +56 −0 etc/model/infrastructure/network.json
  11. +40 −0 etc/model/infrastructure/networkinterface.json
  12. +9 −0 etc/model/infrastructure/os_template.json
  13. +9 −0 etc/model/infrastructure/resource_template.json
  14. +75 −0 etc/model/infrastructure/storage.json
  15. +38 −0 etc/model/infrastructure/storagelink.json
  16. +2 −0 etc/occi-server.conf
  17. +0 −70 lib/occi/CategoryRegistry.rb
  18. +32 −18 lib/occi/Exceptions.rb
  19. +88 −0 lib/occi/Registry.rb
  20. +204 −0 lib/occi/Request.rb
  21. +34 −35 lib/occi/antlr/OCCI.g
  22. +506 −534 lib/occi/antlr/OCCILexer.rb
  23. +1,014 −910 lib/occi/antlr/OCCIParser.rb
  24. +77 −47 lib/occi/backend/Dummy.rb
  25. +24 −24 lib/occi/backend/Manager.rb
  26. +50 −46 lib/occi/backend/ec2/Compute.rb
  27. +82 −82 lib/occi/backend/ec2/EC2.rb
  28. +147 −143 lib/occi/backend/opennebula/Compute.rb
  29. +27 −27 lib/occi/backend/opennebula/Network.rb
  30. +78 −79 lib/occi/backend/opennebula/OpenNebula.rb
  31. +48 −46 lib/occi/backend/opennebula/Storage.rb
  32. +2 −10 lib/occi/core/Action.rb
  33. +0 −48 lib/occi/core/Attribute.rb
  34. +22 −34 lib/occi/core/Category.rb
  35. +90 −127 lib/occi/core/Entity.rb
  36. +18 −24 lib/occi/core/Kind.rb
  37. +45 −24 lib/occi/core/Link.rb
  38. +6 −13 lib/occi/core/Mixin.rb
  39. +24 −20 lib/occi/core/Resource.rb
  40. +0 −56 lib/occi/extensions/ConsoleLink.rb
  41. +0 −98 lib/occi/extensions/NFSStorage.rb
  42. +0 −58 lib/occi/extensions/Reservation.rb
  43. +8 −8 lib/occi/extensions/one/{VirtualMachine.rb → virtual_machine.rb}
  44. +0 −32 lib/occi/helpers/OCCIRequestHelper.rb
  45. +0 −115 lib/occi/infrastructure/Compute.rb
  46. +0 −52 lib/occi/infrastructure/IPNetworkInterface.rb
  47. +0 −52 lib/occi/infrastructure/Ipnetworking.rb
  48. +0 −82 lib/occi/infrastructure/Network.rb
  49. +0 −72 lib/occi/infrastructure/Networkinterface.rb
  50. +0 −47 lib/occi/infrastructure/OSTemplate.rb
  51. +0 −46 lib/occi/infrastructure/ResourceTemplate.rb
  52. +0 −103 lib/occi/infrastructure/Storage.rb
  53. +0 −71 lib/occi/infrastructure/StorageLink.rb
  54. +0 −688 lib/occi/occi-server.rb
  55. +0 −78 lib/occi/rendering/AbstractRenderer.rb
  56. +0 −81 lib/occi/rendering/Renderer.rb
  57. +0 −214 lib/occi/rendering/http/JSONRenderer.rb
  58. +0 −135 lib/occi/rendering/http/LocationRegistry.rb
  59. +0 −220 lib/occi/rendering/http/Request.rb
  60. +0 −99 lib/occi/rendering/http/Response.rb
  61. +0 −299 lib/occi/rendering/http/TextRenderer.rb
  62. +571 −0 lib/occi/server.rb
  63. +17 −17 lib/occi/{StateMachine.rb → state_machine.rb}
  64. +4 −3 spec/occi/antlr/parser_spec.rb
  65. +0 −31 spec/occi/occi_server_spec.rb
  66. +0 −27 spec/occi/rendering/http/location_registry_spec.rb
  67. +0 −40 spec/occi/rendering/http/request_spec.rb
  68. +101 −0 spec/occi/server_spec.rb
  69. +30 −0 views/text.erb
View
8 AUTHORS
@@ -0,0 +1,8 @@
+rOCCI was designed and is mainly developed by Florian Feldhaus (GWDG) and Piotr Kasprzak (GWDG) in Germany.
+
+Special thanks to the following extraordinary individuals, who-out which rOCCI would not be possible:
+
+* Hayati Bice - who wrote the initial version of an OCCI server rOCCI is based on
+* Max Günther - who wrote the EC2 backend
+* Andre Thevapalan - for his input regarding the JSON rendering
+* the OCCI Working Group - for developing OCCI
View
4 Gemfile
@@ -4,8 +4,9 @@ source :rubygems
gem "uuidtools"
gem "json"
gem "antlr3"
+#gem "hashie", :git => 'git://github.com/ffeldhaus/hashie.git', :branch => "hash_deep_merge_with_array_concatenation"
gem "hashie"
-gem "nokogiri", "<=1.5.0"
+gem "nokogiri", "<=1.5.0"
# sinatra and related
gem "sinatra"
@@ -28,4 +29,5 @@ group :development do
gem "simplecov"
gem "yard"
gem "yard-sinatra"
+ gem "rspec-http"
end
View
3 Gemfile.lock
@@ -42,6 +42,8 @@ GEM
rspec-core (2.9.0)
rspec-expectations (2.9.0)
diff-lcs (~> 1.1.3)
+ rspec-http (0.10.0)
+ rspec (~> 2.0)
rspec-mocks (2.9.0)
simplecov (0.6.1)
multi_json (~> 1.0)
@@ -78,6 +80,7 @@ DEPENDENCIES
nokogiri (<= 1.5.0)
passenger
rspec
+ rspec-http
simplecov
sinatra
sinatra-contrib
View
13 LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012 GWDG
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
View
4 config.ru
@@ -2,8 +2,8 @@ $: << 'lib'
require 'rubygems'
require 'sinatra'
-require 'occi/occi-server.rb'
+require 'occi/server'
VERSION_NUMBER=0.5
-run OCCIServer.new
+run OCCI::Server.new
View
13 etc/model/extensions/console_link.json
@@ -0,0 +1,13 @@
+{
+ "kinds":[
+ {
+ "term":"console",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/compute#",
+ "title":"Link to the VM's console",
+ "related":[
+ "http://schemas.ogf.org/occi/core#link"
+ ],
+ "location":"/consolelink/"
+ }
+ ]
+}
View
115 etc/model/infrastructure/compute.json
@@ -0,0 +1,115 @@
+{
+ "kinds":[
+ {
+ "term":"compute",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Compute Resource",
+ "related":[
+ "http://schemas.ogf.org/occi/core#resource"
+ ],
+ "attributes":{
+ "occi":{
+ "compute":{
+ "architecture":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"x86|x64",
+ "default":"x86"
+ },
+ "cores":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "minimum":1,
+ "maximum":32767
+ },
+ "hostname":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*"
+ },
+ "speed":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "minimum":0,
+ "maximum":32767
+ },
+ "memory":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "minimum":0,
+ "maximum":32767
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"inactive|active|suspended|failed",
+ "default":"inactive"
+ }
+ }
+ }
+ },
+ "actions":[
+ "http://schemas.ogf.org/occi/infrastructure/compute/action#start",
+ "http://schemas.ogf.org/occi/infrastructure/compute/action#stop",
+ "http://schemas.ogf.org/occi/infrastructure/compute/action#restart",
+ "http://schemas.ogf.org/occi/infrastructure/compute/action#suspend"
+ ],
+ "location":"/compute/"
+ }
+ ],
+ "actions":[
+ {
+ "term":"start",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#",
+ "title":"Start Compute instance"
+ },
+ {
+ "term":"stop",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#",
+ "title":"Stop Compute instance",
+ "attributes":{
+ "method":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"graceful|acpioff|poweroff",
+ "default":"poweroff"
+ }
+ }
+ },
+ {
+ "term":"restart",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#",
+ "title":"Restart Compute instance",
+ "attributes":{
+ "method":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"graceful|warm|cold",
+ "default":"cold"
+ }
+ }
+ },
+ {
+ "term":"suspend",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#",
+ "title":"Suspend Compute instance",
+ "attributes":{
+ "method":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"hibernate|suspend",
+ "default":"suspend"
+ }
+ }
+ }
+ ]
+}
View
52 etc/model/infrastructure/ipnetwork.json
@@ -0,0 +1,52 @@
+{
+ "mixins":[
+ {
+ "term":"ipnetwork",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/network#",
+ "title":"IP Network Mixin",
+ "attributes":{
+ "occi":{
+ "network":{
+ "address":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*(\\/(\\d|\\d\\d|1[0-1]\\d|12[0-8]))$)|(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(\\d|[1-2]\\d|3[0-2]))$)",
+ "default":"10.0.0.0/8"
+ },
+ "gateway":{
+ "mutable":true,
+ "required":false,
+ "type":{
+ "string":{
+ "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)"
+ }
+ },
+ "default":"10.0.0.1"
+ },
+ "allocation":{
+ "mutable":true,
+ "required":false,
+ "type":{
+ "string":{
+ "pattern":"dynamic|static"
+ }
+ },
+ "default":"dynamic"
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":{
+ "string":{
+ "pattern":"active|inactive"
+ }
+ },
+ "default":"inactive"
+ }
+ }
+ }
+ }
+ }
+ ]
+}
View
43 etc/model/infrastructure/ipnetworkinterface.json
@@ -0,0 +1,43 @@
+{
+ "mixins":[
+ {
+ "term":"ipnetworkinterface",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/networkinterface#",
+ "title":"IP Networkinterface Mixin",
+ "attributes":{
+ "occi":{
+ "networkinterface":{
+ "address":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)",
+ "default":"10.0.0.0/8"
+ },
+ "gateway":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)",
+ "default":"10.0.0.1"
+ },
+ "allocation":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"dynamic|static",
+ "default":"dynamic"
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"active|inactive",
+ "default":"inactive"
+ }
+ }
+ }
+ }
+ }
+ ]
+}
View
56 etc/model/infrastructure/network.json
@@ -0,0 +1,56 @@
+{
+ "kinds":[
+ {
+ "term":"network",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Network Resource",
+ "related":[
+ "http://schemas.ogf.org/occi/core#resource"
+ ],
+ "attributes":{
+ "occi":{
+ "storage":{
+ "vlan":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "minimum":0,
+ "maximum":4095,
+ "default":0
+ },
+ "label":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":".*"
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"active|inactive",
+ "default":"inactive"
+ }
+ }
+ }
+ },
+ "actions":[
+ "http://schemas.ogf.org/occi/infrastructure/network/action#up" ,
+ "http://schemas.ogf.org/occi/infrastructure/network/action#down"
+ ],
+ "location":"/network/"
+ }
+ ],
+ "actions":[
+ {
+ "term":"up",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/network/action#",
+ "title":"Activate network"
+ },
+ {
+ "term":"down",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/network/action#up",
+ "title":"Activate network"
+ }
+ ]
+}
View
40 etc/model/infrastructure/networkinterface.json
@@ -0,0 +1,40 @@
+{
+ "kinds":[
+ {
+ "term":"networkinterface",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Networkinterface",
+ "related":[
+ "http://schemas.ogf.org/occi/core#link"
+ ],
+ "attributes":{
+ "occi":{
+ "networkinterface":{
+ "interface":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":".*",
+ "default":"eth0"
+ },
+ "mac":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":"^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$",
+ "default":"00:16:3e:00:00:00"
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"active|inactive",
+ "default":"inactive"
+ }
+ }
+ }
+ },
+ "location":"/networkinterface/"
+ }
+ ]
+}
View
9 etc/model/infrastructure/os_template.json
@@ -0,0 +1,9 @@
+{
+ "mixins":[
+ {
+ "term":"os_tpl",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Operating System Template"
+ }
+ ]
+}
View
9 etc/model/infrastructure/resource_template.json
@@ -0,0 +1,9 @@
+{
+ "mixins":[
+ {
+ "term":"resource_tpl",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Resource Template"
+ }
+ ]
+}
View
75 etc/model/infrastructure/storage.json
@@ -0,0 +1,75 @@
+{
+ "kinds":[
+ {
+ "term":"storage",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Storage Resource",
+ "related":[
+ "http://schemas.ogf.org/occi/core#resource"
+ ],
+ "attributes":{
+ "occi":{
+ "storage":{
+ "size":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "minimum":0,
+ "maximum":32767
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"online|offline|backup|snapshot|resize|degraded",
+ "default":"offline"
+ }
+ }
+ }
+ },
+ "actions":[
+ "http://schemas.ogf.org/occi/infrastructure/storage/action#online",
+ "http://schemas.ogf.org/occi/infrastructure/storage/action#offline",
+ "http://schemas.ogf.org/occi/infrastructure/storage/action#backup",
+ "http://schemas.ogf.org/occi/infrastructure/storage/action#snapshot",
+ "http://schemas.ogf.org/occi/infrastructure/storage/action#resize"
+ ],
+ "location":"/storage/"
+ }
+ ],
+ "actions":[
+ {
+ "term":"online",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#",
+ "title":"Activate Storage"
+ },
+ {
+ "term":"offline",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#",
+ "title":"Deactivate Storage"
+ },
+ {
+ "term":"backup",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#",
+ "title":"Backup Storage"
+ },
+ {
+ "term":"snapshot",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#",
+ "title":"Snapshot Storage"
+ },
+ {
+ "term":"resize",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#",
+ "title":"Resize Storage",
+ "attributes":{
+ "size":{
+ "mutable":true,
+ "required":false,
+ "type":"number",
+ "default":"suspend"
+ }
+ }
+ }
+ ]
+}
View
38 etc/model/infrastructure/storagelink.json
@@ -0,0 +1,38 @@
+{
+ "kinds":[
+ {
+ "term":"storagelink",
+ "scheme":"http://schemas.ogf.org/occi/infrastructure#",
+ "title":"Storage Link",
+ "related":[
+ "http://schemas.ogf.org/occi/core#link"
+ ],
+ "attributes":{
+ "occi":{
+ "storagelink":{
+ "deviceid":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":".*"
+ },
+ "mountpoint":{
+ "mutable":true,
+ "required":false,
+ "type":"string",
+ "pattern":".*"
+ },
+ "state":{
+ "mutable":false,
+ "required":false,
+ "type":"string",
+ "pattern":"active|inactive",
+ "default":"inactive"
+ }
+ }
+ }
+ },
+ "location":"/storagelink/"
+ }
+ ]
+}
View
2 etc/occi-server.conf
@@ -11,6 +11,8 @@ ONE_XMLRPC=http://134.76.9.66:2633/RPC2
TEMPLATE_LOCATION=etc/one_templates/
+OCCI_MODEL_PATH=etc/model/
+
ONE_USER=oneadmin
ONE_PASSWORD=oneadmin
View
70 lib/occi/CategoryRegistry.rb
@@ -1,70 +0,0 @@
-##############################################################################
-# Copyright 2011 Service Computing group, TU Dortmund
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##############################################################################
-
-##############################################################################
-# Description: registry for all Category/Kind/Mixin instances currently
-# known to the OCCI server
-# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak
-##############################################################################
-
-require 'occi/Log'
-
-module OCCI
- # ---------------------------------------------------------------------------------------------------------------------
- module CategoryRegistry
-
- @@categories_by_id = {}
- @@categories_by_location = {}
-
- # ---------------------------------------------------------------------------------------------------------------------
- def self.register(category)
- @@categories_by_id[category.type_identifier] = category
- @@categories_by_location[category.location] = category if category.respond_to?('location')
- end
-
- # ---------------------------------------------------------------------------------------------------------------------
- def self.unregister(category)
- @@categories_by_id.delete(category.type_identifier)
- @@categories_by_location.delete(category.location)
- end
-
- # ---------------------------------------------------------------------------------------------------------------------
- def self.get_by_id(id)
- @@categories_by_id.fetch(id) { raise OCCI::CategoryNotFoundException, "Category with key " + id + " not found" }
- end
-
- def self.get_by_location(location)
- @@categories_by_location.fetch(location) { raise "Category with location " + location + " not found" }
- end
-
- # Return all categories from category registry. If filter is present, return only the categories specified by filter
- #
- # @param [Hashie:Mash] filter
- # @return [Array] categories
- def self.get(filter)
- categories = Array.new
- filter.values.flatten(1).each do |category|
- begin
- occi_categories << self.get_by_id(category.type_identifier)
- rescue OCCI::CategoryNotFoundException => e
- OCCI::Log.warn(e.message)
- end
- end
- return categories unless categories.empty?
- return @@categories_by_id.values
- end
- end
-end
View
50 lib/occi/Exceptions.rb
@@ -21,25 +21,39 @@
##############################################################################
module OCCI
-
+
# Tried to create an already existing mixin
- class MixinAlreadyExistsError < RuntimeError; end
-
- class CategoryNotFoundException < RuntimeError; end
-
- class CategoryMissingException < RuntimeError; end
-
- class MixinNotFoundException < RuntimeError; end
-
- class MixinCreationException < RuntimeError; end
-
- class LocationAlreadyRegisteredException < RuntimeError; end
-
- class LocationNotRegisteredException < RuntimeError; end
-
+ class MixinAlreadyExistsError < RuntimeError;
+ end
+
+ class CategoryNotFoundException < RuntimeError;
+ end
+
+ class CategoryMissingException < RuntimeError;
+ end
+
+ class MixinNotFoundException < RuntimeError;
+ end
+
+ class MixinCreationException < RuntimeError;
+ end
+
+ class LocationAlreadyRegisteredException < RuntimeError;
+ end
+
+ class LocationNotRegisteredException < RuntimeError;
+ end
+
# Tried to create an already existing mixin
- class BackendError < RuntimeError; end
+ class BackendError < RuntimeError;
+ end
+
+ class ParserException < RuntimeError;
+ end
+
+ class ContentTypeNotSupported < RuntimeError;
+ end
- class ParserException < RuntimeError; end
-
+ class CategoryNotFound < RuntimeError;
+ end
end
View
88 lib/occi/Registry.rb
@@ -0,0 +1,88 @@
+##############################################################################
+# Copyright 2011 Service Computing group, TU Dortmund
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+
+##############################################################################
+# Description: registry for all Category/Kind/Mixin instances currently
+# known to the OCCI server
+# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak
+##############################################################################
+
+require 'occi/log'
+
+module OCCI
+ # ---------------------------------------------------------------------------------------------------------------------
+ module Registry
+
+ @@categories = {}
+ @@categories_initial = {}
+ @@locations = {}
+
+ def self.reset()
+ @@categories = @@categories_initial
+ end
+
+ # ---------------------------------------------------------------------------------------------------------------------
+ def self.register(category)
+ @@categories[category.type_identifier] = category
+ @@categories_initial[category.type_identifier] = category
+ @@locations[category.term] = category.type_identifier unless category.kind_of?(OCCI::Core::Action)
+ end
+
+ # ---------------------------------------------------------------------------------------------------------------------
+ def self.unregister(category)
+ @@categories.delete(category.type_identifier)
+ @@categories_initial.delete(category.type_identifier)
+ @@locations.delete(category.term) unless category.kind_of?(OCCI :Core::Action)
+ end
+
+ # Returns the category corresponding to a given type identifier
+ #
+ # @param [URI] type identifier of a category
+ def self.get_by_id(id)
+ @@categories.fetch(id) { OCCI::Log.debug("Category with id #{id} not found"); nil }
+ end
+
+ # Returns the category corresponding to a given location
+ #
+ # @param [URI] Location of a category
+ def self.get_by_location(location)
+ id = @@locations.fetch(location.delete('/')) { OCCI::Log.debug("Category with location #{location} not found"); nil }
+ self.get_by_id(id)
+ end
+
+ # Return all categories from category registry. If filter is present, return only the categories specified by filter
+ #
+ # @param [Hashie:Hash] filter
+ # @return [Hashie::Mash] collection
+ def self.get(filter = [])
+ collection = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []})
+ filter.each do |cat|
+ category = get_by_id(cat.type_identifier)
+ collection.kinds << category if category.kind_of?(OCCI::Core::Kind)
+ collection.mixins << category if category.kind_of?(OCCI::Core::Mixin)
+ collection.actions << category if category.kind_of?(OCCI::Core::Action)
+ end
+ if filter.empty?
+ @@categories.each_value do |category|
+ collection.kinds << category if category.kind_of? OCCI::Core::Kind
+ collection.mixins << category if category.kind_of? OCCI::Core::Mixin
+ collection.actions << category if category.kind_of? OCCI::Core::Action
+ end
+ end
+ return collection
+ end
+ end
+end
View
204 lib/occi/Request.rb
@@ -0,0 +1,204 @@
+##############################################################################
+# Copyright 2011 Service Computing group, TU Dortmund
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+
+##############################################################################
+# @note OCCI RESTful Web Service
+# @author Florian Feldhaus, Piotr Kasprzak
+##############################################################################
+
+require 'json'
+require 'occi/Log'
+require 'occi/antlr/OCCIParser'
+
+module OCCI
+ class Request
+
+ attr_reader :kinds
+ attr_reader :mixins
+ attr_reader :actions
+ attr_reader :resources
+ attr_reader :links
+ attr_reader :locations
+
+ # Parses a Rack/Sinatra Request and extract OCCI relevant information
+ #
+ # @param [Rack::Request] request from Sinatra/Rack
+ def initialize(request)
+ @kinds = []
+ @mixins = []
+ @actions = []
+ @resources = []
+ @links = []
+ @locations = []
+
+=begin
+ if content_type.includes?('multipart')
+ # TODO: implement multipart handling
+ # handle file upload
+ if params['file'] != nil
+ OCCI::Log.debug("Location of Image #{params['file'][:tempfile].path}")
+ $image_path = $config[:one_image_tmp_dir] + '/' + params['file'][:filename]
+ FileUtils.cp(params['file'][:tempfile].path, $image_path)
+ end
+
+ # handle file upload in multipart requests
+ request.POST.values.each do |body|
+ if body.kind_of?(String)
+ parse_text(body)
+ elsif body.kind_of?(Hash)
+ if body['type'].include?('application/json')
+ # try to parse body as JSON object
+ parse_json(body.read)
+ elsif body['type'].include?('text/plain') # text/plain
+ parse_text(body.read)
+ end unless body['type'].nil?
+ end
+ end
+ end
+=end
+
+ body = request.body.read.to_s
+
+ # always check headers
+ parse_header_locations(request.env)
+ if @locations.empty?
+ if request.path_info.include?('/-/')
+ parse_header_categories(request.env)
+ else
+ parse_header_entity(request.env)
+ end
+ end
+
+ case request.media_type
+ when 'text/uri-list'
+ body.each_line do |line|
+ @locations << URI.parse(line)
+ end
+ when 'text/plain', nil
+ parse_text_locations(body)
+ if @locations.empty?
+ if request.path_info.include?('/-/')
+ parse_text_categories(body)
+ else
+ parse_text_entity(body)
+ end
+ end
+ when 'application/occi+json' || 'application/json'
+ parse_json(body)
+ else
+ raise OCCI::ContentTypeNotSupported
+ end
+
+ end
+
+ def categories
+ @kinds + @mixins + @actions
+ end
+
+ # ---------------------------------------------------------------------------------------------------------------------
+ private
+ # ---------------------------------------------------------------------------------------------------------------------
+
+ def parse_header_locations(header)
+ x_occi_location_strings = header['HTTP_X_OCCI_LOCATION'].to_s.split(',')
+ x_occi_location_strings.each { |loc| @locations << OCCI::Parser.new('X-OCCI-Location: ' + loc).x_occi_location }
+ end
+
+ def parse_header_categories(header)
+ category_strings = header['HTTP_CATEGORY'].to_s.split(',')
+ category_strings.each do |cat|
+ category = OCCI::Parser.new('Category: ' + cat).category
+ @kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
+ @mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
+ @actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
+ end
+ end
+
+ def parse_header_entity(header)
+ entity = Hashie::Mash.new
+ category_strings = header['HTTP_CATEGORY'].to_s.split(',')
+ return if category_strings.empty?
+ attribute_strings = header['HTTP_X_OCCI_ATTRIBUTE'].to_s.split(',')
+ categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []})
+ category_strings.each { |cat| categories.merge!(OCCI::Parser.new('Category: ' + cat).category) }
+ return if categories.kinds.empty?
+ entity.kind = categories.kinds.first.scheme + categories.kinds.first.term
+ entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins.any?
+ attribute_strings.each { |attr| entity.attributes!.merge!(OCCI::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) }
+ kind = OCCI::Registry.get_by_id(entity.kind)
+ # TODO: error handling
+ return if kind.nil?
+ if kind.entity_type == OCCI::Core::Link.name
+ entity.target = link.attributes.occi!.core!.target
+ entity.source = link.attributes.occi!.core!.source
+ @links << OCCI::Core::Link.new(entity)
+ elsif kind.entity_type == OCCI::Core::Resource.name
+ link_strings = header['HTTP_LINK'].to_s.split(',')
+ link_strings.each { |link| entity.links << OCCI::Parser.new('Link: ' + link).link }
+ @resources << OCCI::Core::Resource.new(entity)
+ end
+ end
+
+ def parse_text_locations(body)
+ body.each_line do |line|
+ @locations << OCCI::Parser.new(line).x_occi_location if line.include? 'X-OCCI-Location'
+ end
+ end
+
+ def parse_text_categories(body)
+ body.each_line do |line|
+ category = OCCI::Parser.new(line).category
+ @kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
+ @mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
+ @actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
+ end
+ end
+
+ def parse_text_entity(body)
+ entity = Hashie::Mash.new
+ links = []
+ categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []})
+ body.each_line do |line|
+ categories.merge!(OCCI::Parser.new(line).category) if line.include? 'Category'
+ entity.attributes!.merge!(OCCI::Parser.new(line).x_occi_attribute) if line.include? 'X-OCCI-Attribute'
+ links << OCCI::Parser.new(line).link if line.include? 'Link'
+ end
+ entity.kind = categories.kinds.first.scheme + categories.kinds.first.term if categories.kinds.first
+ entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if entity.mixins
+ kind = OCCI::Registry.get_by_id(entity.kind)
+ # TODO: error handling
+ return if kind.nil?
+ if OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Link.name
+ entity.target = links.first.attributes.occi!.core!.target
+ entity.source = links.first.attributes.occi!.core!.source
+ @links << OCCI::Core::Link.new(entity)
+ elsif OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Resource.name
+ entity.links = links
+ @resources << OCCI::Core::Resource.new(entity)
+ end unless entity.kind.nil?
+ end
+
+ def parse_json(body)
+ collection = Hashie::Mash.new(JSON.parse(body))
+ @kinds.concat collection.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if collection.kinds
+ @mixins.concat collection.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if collection.mixins
+ @resources.concat collection.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if collection.resources
+ @links.concat collection.links.collect { |link| OCCI::Core::Link.new(link) } if collection.links
+ @locations.concat collection.locations.collect { |location| URI.parse(location) } if collection.locations
+ end
+
+ end
+end
View
69 lib/occi/antlr/OCCI.g
@@ -49,22 +49,21 @@ Category: storage;
actions="http://schemas.ogf.org/occi/infrastructure/storage/action#resize http://schemas.ogf.org/occi/infrastructure/storage/action#online"
*/
-category returns [mash]
- : 'Category' ':' category_value { mash = $category_value.mash };
- category_value returns [mash]
- @init{ mash = Hashie::Mash.new( {:kinds=>[],:mixins=>[],:actions=>[] } ) }
+category returns [hash]
+ : 'Category' ':' category_value { hash = $category_value.hash };
+ category_value returns [hash]
+ @init{ hash = Hashie::Mash.new( {:kinds=>[],:mixins=>[],:actions=>[] } ) }
: category_term category_scheme category_class category_title? category_rel? category_location? category_attributes? category_actions? ';'?
{ type = $category_class.value
cat = Hashie::Mash.new
cat.term = $category_term.value
cat.scheme = $category_scheme.value
- cat.type_identifier = cat.scheme + cat.term
cat.title = $category_title.value
cat.related = $category_rel.value
cat.location = $category_location.value
- cat.attributes = $category_attributes.mash
+ cat.attributes = $category_attributes.hash
cat.actions = $category_actions.array
- mash[(type+'s').to_sym] << cat
+ hash[(type+'s').to_sym] << cat
};
category_term returns [value] : WS? term
{ value = $term.text };
@@ -78,9 +77,9 @@ category returns [mash]
{ value = $rel.text };
category_location returns [value] : ';' WS? 'location' '=' '"' location '"'
{ value = $location.text };
- category_attributes returns [mash] @init{mash = Hashie::Mash.new}
- : ';' WS? 'attributes' '=' '"' attr=attribute_name { mash.merge!($attr.mash) }
- ( WS? next_attr=attribute_name { mash.merge!($next_attr.mash) } )* '"';
+ category_attributes returns [hash] @init{hash = Hashie::Mash.new}
+ : ';' WS? 'attributes' '=' '"' attr=attribute_name { hash.merge!($attr.hash) }
+ ( WS? next_attr=attribute_name { hash.merge!($next_attr.hash) } )* '"';
category_actions returns [array] @init{array = Array.new}
: ';' WS? 'actions' '=' '"' act=action_location { array << $act.text }
( WS? next_act=action_location { array << $next_act.text } )* '"';
@@ -94,24 +93,23 @@ category="http://example.com/occi/link#disk_drive";
com.example.drive0.interface="ide0"; com.example.drive1.interface="ide1"
*/
-link returns [mash]
- @init{mash = Hashie::Mash.new}
- : 'Link' ':' link_value { mash = $link_value.mash };
- link_value returns [mash]
- @init{ mash = Hashie::Mash.new }
- : link_target { mash[:target] = $link_target.value }
- link_rel { mash[:rel] = $link_rel.value }
- link_self? { mash[:self] = $link_self.value }
- link_category? { mash[:category] = $link_category.value }
- link_attributes { mash[:attributes] = $link_attributes.mash }
+link returns [hash]
+ : 'Link' ':' link_value { hash = $link_value.hash };
+ link_value returns [hash]
+ @init{ hash = Hashie::Mash.new }
+ : link_target { hash[:target] = $link_target.value }
+ link_rel { hash[:rel] = $link_rel.value }
+ link_self? { hash[:self] = $link_self.value }
+ link_category? { hash[:category] = $link_category.value }
+ link_attributes { hash[:attributes] = $link_attributes.hash }
';'?
;
link_target returns [value] : WS? '<' target '>' { value = $target.text };
link_rel returns [value] : ';' WS? 'rel' '=' '"' rel '"' { value = $rel.text };
link_self returns [value] : ';' WS? 'self' '=' '"' self_location '"' { value = $self_location.text };
link_category returns [value] : ';' WS? 'category' '=' '"' category_name '"' { value = $category_name.text };
- link_attributes returns [mash] @init { mash = Hashie::Mash.new }
- : (';' WS? attribute { mash.merge!($attribute.mash) } )*;
+ link_attributes returns [hash] @init { hash = Hashie::Mash.new }
+ : (';' WS? attribute { hash.merge!($attribute.hash) } )*;
/*
e.g.
@@ -123,9 +121,8 @@ X-OCCI-Attribute: occi.compute.memory=3.0
X-OCCI-Attribute: occi.compute.state="active"
*/
-x_occi_attribute returns [mash]
- @init { mash = Hashie::Mash.new }
- : 'X-OCCI-Attribute' ':' WS? attribute ';'? { mash = $attribute.mash } ;
+x_occi_attribute returns [hash]
+ : 'X-OCCI-Attribute' ':' WS? attribute ';'? { hash = $attribute.hash } ;
/*
e.g.
@@ -143,23 +140,25 @@ class_type : ( 'kind' | 'mixin' | 'action' );
title : ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )*;
rel : uri;
location : uri;
-attribute returns [mash] @init { mash = Hashie::Mash.new }
- : comp_first=attribute_component { cur_mash = mash; comp = $comp_first.text }
- ( '.' comp_next=attribute_component { cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = $comp_next.text })*
- '=' attribute_value { cur_mash[comp.to_sym] = $attribute_value.text };
-attribute_name returns [mash] @init { mash = Hashie::Mash.new }
- : comp_first=attribute_component { cur_mash = mash; comp = $comp_first.text }
- ( '.' comp_next=attribute_component { cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = $comp_next.text })*
- { cur_mash[comp.to_sym] = ATTRIBUTE };
+attribute returns [hash] @init { hash = Hashie::Mash.new }
+ : comp_first=attribute_component { cur_hash = hash; comp = $comp_first.text }
+ ( '.' comp_next=attribute_component { cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = $comp_next.text })*
+ '=' attribute_value { cur_hash[comp.to_sym] = $attribute_value.value };
+attribute_name returns [hash] @init { hash = Hashie::Mash.new }
+ : comp_first=attribute_component { cur_hash = hash; comp = $comp_first.text }
+ ( '.' comp_next=attribute_component { cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = $comp_next.text })*
+ { cur_hash[comp.to_sym] = ATTRIBUTE };
attribute_component : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )*;
-attribute_value : ( ( '"' ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )* '"') | ( DIGIT ( '.' DIGIT )* ) );
+attribute_value returns [value] : ( string { value = $string.text } | number { value = $number.text.to_i } );
+string : ( '"' ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )* '"');
+number : ( DIGIT* ( '.' DIGIT+ )? );
action_location : uri;
target : uri;
self_location : uri;
category_name : uri;
LOALPHA : ('a'..'z')+;
UPALPHA : ('A'..'Z')+;
-DIGIT : ('0'..'9')+;
+DIGIT : ('0'..'9');
WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+;
ESC : '\\' ( '"' | '\'' );
View
1,040 lib/occi/antlr/OCCILexer.rb
@@ -5,15 +5,15 @@
# Generated using ANTLR version: 3.2.1-SNAPSHOT Jul 31, 2010 19:34:52
# Ruby runtime library version: 1.8.11
# Input grammar file: OCCI.g
-# Generated at: 2012-03-28 22:43:36
+# Generated at: 2012-05-18 21:42:45
#
# ~~~> start load path setup
-this_directory = File.expand_path( File.dirname( __FILE__ ) )
-$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory )
+this_directory = File.expand_path(File.dirname(__FILE__))
+$LOAD_PATH.unshift(this_directory) unless $LOAD_PATH.include?(this_directory)
antlr_load_failed = proc do
- load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join( $/ )
+ load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join($/)
raise LoadError, <<-END.strip!
Failed to load the ANTLR3 runtime library (version 1.8.11):
@@ -30,29 +30,29 @@
END
end
-defined?( ANTLR3 ) or begin
-
- # 1: try to load the ruby antlr3 runtime library from the system path
+defined?(ANTLR3) or begin
+
+ # 1: try to load the ruby antlr3 runtime library from the system path
require 'antlr3'
-
+
rescue LoadError
-
+
# 2: try to load rubygems if it isn't already loaded
- defined?( Gem ) or begin
+ defined?(Gem) or begin
require 'rubygems'
rescue LoadError
antlr_load_failed.call
end
-
+
# 3: try to activate the antlr3 gem
begin
- Gem.activate( 'antlr3', '~> 1.8.11' )
+ Gem.activate('antlr3', '~> 1.8.11')
rescue Gem::LoadError
antlr_load_failed.call
end
-
+
require 'antlr3'
-
+
end
# <~~~ end load path setup
@@ -61,58 +61,58 @@ module OCCI
# TokenData defines all of the token type integer values
# as constants, which will be included in all
# ANTLR-generated recognizers.
- const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new
+ const_defined?(:TokenData) or TokenData = ANTLR3::TokenScheme.new
module TokenData
# define the token constants
- define_tokens( :T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26,
- :T__25 => 25, :T__24 => 24, :T__23 => 23, :ESC => 8,
- :T__22 => 22, :T__21 => 21, :T__20 => 20, :EOF => -1,
- :T__9 => 9, :T__19 => 19, :T__16 => 16, :T__15 => 15,
- :T__18 => 18, :T__17 => 17, :T__12 => 12, :T__11 => 11,
- :T__14 => 14, :T__13 => 13, :T__10 => 10, :DIGIT => 7,
- :LOALPHA => 5, :T__42 => 42, :T__43 => 43, :T__40 => 40,
- :T__41 => 41, :T__30 => 30, :T__31 => 31, :T__32 => 32,
- :T__33 => 33, :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36,
- :T__37 => 37, :UPALPHA => 6, :T__38 => 38, :T__39 => 39 )
-
+ define_tokens(:T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26,
+ :T__25 => 25, :T__24 => 24, :T__23 => 23, :ESC => 8,
+ :T__22 => 22, :T__21 => 21, :T__20 => 20, :EOF => -1,
+ :T__9 => 9, :T__19 => 19, :T__16 => 16, :T__15 => 15,
+ :T__18 => 18, :T__17 => 17, :T__12 => 12, :T__11 => 11,
+ :T__14 => 14, :T__13 => 13, :T__10 => 10, :DIGIT => 7,
+ :LOALPHA => 5, :T__42 => 42, :T__43 => 43, :T__40 => 40,
+ :T__41 => 41, :T__30 => 30, :T__31 => 31, :T__32 => 32,
+ :T__33 => 33, :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36,
+ :T__37 => 37, :UPALPHA => 6, :T__38 => 38, :T__39 => 39)
+
end
class Lexer < ANTLR3::Lexer
@grammar_home = OCCI
include TokenData
-
+
begin
- generated_using( "OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11" )
+ generated_using("OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11")
rescue NoMethodError => error
# ignore
end
-
- RULE_NAMES = [ "T__9", "T__10", "T__11", "T__12", "T__13", "T__14",
- "T__15", "T__16", "T__17", "T__18", "T__19", "T__20",
- "T__21", "T__22", "T__23", "T__24", "T__25", "T__26",
- "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
- "T__33", "T__34", "T__35", "T__36", "T__37", "T__38",
- "T__39", "T__40", "T__41", "T__42", "T__43", "LOALPHA",
- "UPALPHA", "DIGIT", "WS", "ESC" ].freeze
- RULE_METHODS = [ :t__9!, :t__10!, :t__11!, :t__12!, :t__13!, :t__14!,
- :t__15!, :t__16!, :t__17!, :t__18!, :t__19!, :t__20!,
- :t__21!, :t__22!, :t__23!, :t__24!, :t__25!, :t__26!,
- :t__27!, :t__28!, :t__29!, :t__30!, :t__31!, :t__32!,
- :t__33!, :t__34!, :t__35!, :t__36!, :t__37!, :t__38!,
- :t__39!, :t__40!, :t__41!, :t__42!, :t__43!, :loalpha!,
- :upalpha!, :digit!, :ws!, :esc! ].freeze
-
-
- def initialize( input=nil, options = {} )
- super( input, options )
+
+ RULE_NAMES = ["T__9", "T__10", "T__11", "T__12", "T__13", "T__14",
+ "T__15", "T__16", "T__17", "T__18", "T__19", "T__20",
+ "T__21", "T__22", "T__23", "T__24", "T__25", "T__26",
+ "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
+ "T__33", "T__34", "T__35", "T__36", "T__37", "T__38",
+ "T__39", "T__40", "T__41", "T__42", "T__43", "LOALPHA",
+ "UPALPHA", "DIGIT", "WS", "ESC"].freeze
+ RULE_METHODS = [:t__9!, :t__10!, :t__11!, :t__12!, :t__13!, :t__14!,
+ :t__15!, :t__16!, :t__17!, :t__18!, :t__19!, :t__20!,
+ :t__21!, :t__22!, :t__23!, :t__24!, :t__25!, :t__26!,
+ :t__27!, :t__28!, :t__29!, :t__30!, :t__31!, :t__32!,
+ :t__33!, :t__34!, :t__35!, :t__36!, :t__37!, :t__38!,
+ :t__39!, :t__40!, :t__41!, :t__42!, :t__43!, :loalpha!,
+ :upalpha!, :digit!, :ws!, :esc!].freeze
+
+
+ def initialize(input=nil, options = {})
+ super(input, options)
end
-
-
+
+
# - - - - - - - - - - - lexer rules - - - - - - - - - - - -
# lexer rule t__9! (T__9)
# (in OCCI.g)
@@ -123,12 +123,12 @@ def t__9!
type = T__9
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 7:8: 'Category'
- match( "Category" )
+ match("Category")
+
-
@state.type = type
@state.channel = channel
@@ -147,12 +147,12 @@ def t__10!
type = T__10
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 8:9: ':'
- match( 0x3a )
+ match(0x3a)
+
-
@state.type = type
@state.channel = channel
@@ -171,12 +171,12 @@ def t__11!
type = T__11
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 9:9: ';'
- match( 0x3b )
+ match(0x3b)
+
-
@state.type = type
@state.channel = channel
@@ -195,12 +195,12 @@ def t__12!
type = T__12
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 10:9: 'scheme'
- match( "scheme" )
+ match("scheme")
+
-
@state.type = type
@state.channel = channel
@@ -219,12 +219,12 @@ def t__13!
type = T__13
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 11:9: '='
- match( 0x3d )
+ match(0x3d)
+
-
@state.type = type
@state.channel = channel
@@ -243,12 +243,12 @@ def t__14!
type = T__14
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 12:9: '\"'
- match( 0x22 )
+ match(0x22)
+
-
@state.type = type
@state.channel = channel
@@ -267,12 +267,12 @@ def t__15!
type = T__15
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 13:9: 'class'
- match( "class" )
+ match("class")
+
-
@state.type = type
@state.channel = channel
@@ -291,12 +291,12 @@ def t__16!
type = T__16
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 14:9: 'title'
- match( "title" )
+ match("title")
+
-
@state.type = type
@state.channel = channel
@@ -315,12 +315,12 @@ def t__17!
type = T__17
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 15:9: 'rel'
- match( "rel" )
+ match("rel")
+
-
@state.type = type
@state.channel = channel
@@ -339,12 +339,12 @@ def t__18!
type = T__18
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 16:9: 'location'
- match( "location" )
+ match("location")
+
-
@state.type = type
@state.channel = channel
@@ -363,12 +363,12 @@ def t__19!
type = T__19
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 17:9: 'attributes'
- match( "attributes" )
+ match("attributes")
+
-
@state.type = type
@state.channel = channel
@@ -387,12 +387,12 @@ def t__20!
type = T__20
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 18:9: 'actions'
- match( "actions" )
+ match("actions")
+
-
@state.type = type
@state.channel = channel
@@ -411,12 +411,12 @@ def t__21!
type = T__21
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 19:9: 'Link'
- match( "Link" )
+ match("Link")
+
-
@state.type = type
@state.channel = channel
@@ -435,12 +435,12 @@ def t__22!
type = T__22
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 20:9: '<'
- match( 0x3c )
+ match(0x3c)
+
-
@state.type = type
@state.channel = channel
@@ -459,12 +459,12 @@ def t__23!
type = T__23
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 21:9: '>'
- match( 0x3e )
+ match(0x3e)
+
-
@state.type = type
@state.channel = channel
@@ -483,12 +483,12 @@ def t__24!
type = T__24
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 22:9: 'self'
- match( "self" )
+ match("self")
+
-
@state.type = type
@state.channel = channel
@@ -507,12 +507,12 @@ def t__25!
type = T__25
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 23:9: 'category'
- match( "category" )
+ match("category")
+
-
@state.type = type
@state.channel = channel
@@ -531,12 +531,12 @@ def t__26!
type = T__26
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 24:9: 'X-OCCI-Attribute'
- match( "X-OCCI-Attribute" )
+ match("X-OCCI-Attribute")
+
-
@state.type = type
@state.channel = channel
@@ -555,12 +555,12 @@ def t__27!
type = T__27
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 25:9: 'X-OCCI-Location'
- match( "X-OCCI-Location" )
+ match("X-OCCI-Location")
+
-
@state.type = type
@state.channel = channel
@@ -579,12 +579,12 @@ def t__28!
type = T__28
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 26:9: '@'
- match( 0x40 )
+ match(0x40)
+
-
@state.type = type
@state.channel = channel
@@ -603,12 +603,12 @@ def t__29!
type = T__29
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 27:9: '%'
- match( 0x25 )
+ match(0x25)
+
-
@state.type = type
@state.channel = channel
@@ -627,12 +627,12 @@ def t__30!
type = T__30
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 28:9: '_'
- match( 0x5f )
+ match(0x5f)
+
-
@state.type = type
@state.channel = channel
@@ -651,12 +651,12 @@ def t__31!
type = T__31
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 29:9: '\\\\'
- match( 0x5c )
+ match(0x5c)
+
-
@state.type = type
@state.channel = channel
@@ -675,12 +675,12 @@ def t__32!
type = T__32
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 30:9: '+'
- match( 0x2b )
+ match(0x2b)
+
-
@state.type = type
@state.channel = channel
@@ -699,12 +699,12 @@ def t__33!
type = T__33
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 31:9: '.'
- match( 0x2e )
+ match(0x2e)
+
-
@state.type = type
@state.channel = channel
@@ -723,12 +723,12 @@ def t__34!
type = T__34
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 32:9: '~'
- match( 0x7e )
+ match(0x7e)
+
-
@state.type = type
@state.channel = channel
@@ -747,12 +747,12 @@ def t__35!
type = T__35
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 33:9: '#'
- match( 0x23 )
+ match(0x23)
+
-
@state.type = type
@state.channel = channel
@@ -771,12 +771,12 @@ def t__36!
type = T__36
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 34:9: '?'
- match( 0x3f )
+ match(0x3f)
+
-
@state.type = type
@state.channel = channel
@@ -795,12 +795,12 @@ def t__37!
type = T__37
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 35:9: '&'
- match( 0x26 )
+ match(0x26)
+
-
@state.type = type
@state.channel = channel
@@ -819,12 +819,12 @@ def t__38!
type = T__38
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 36:9: '/'
- match( 0x2f )
+ match(0x2f)
+
-
@state.type = type
@state.channel = channel
@@ -843,12 +843,12 @@ def t__39!
type = T__39
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 37:9: '-'
- match( 0x2d )
+ match(0x2d)
+
-
@state.type = type
@state.channel = channel
@@ -867,12 +867,12 @@ def t__40!
type = T__40
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 38:9: 'action'
- match( "action" )
+ match("action")
+
-
@state.type = type
@state.channel = channel
@@ -891,12 +891,12 @@ def t__41!
type = T__41
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 39:9: 'kind'
- match( "kind" )
+ match("kind")
+
-
@state.type = type
@state.channel = channel
@@ -915,12 +915,12 @@ def t__42!
type = T__42
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 40:9: 'mixin'
- match( "mixin" )
+ match("mixin")
+
-
@state.type = type
@state.channel = channel
@@ -939,12 +939,12 @@ def t__43!
type = T__43
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
# at line 41:9: '\\''
- match( 0x27 )
+ match(0x27)
+
-
@state.type = type
@state.channel = channel
@@ -963,36 +963,35 @@ def loalpha!
type = LOALPHA
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
- # at line 161:11: ( 'a' .. 'z' )+
- # at file 161:11: ( 'a' .. 'z' )+
+ # at line 160:11: ( 'a' .. 'z' )+
+ # at file 160:11: ( 'a' .. 'z' )+
match_count_1 = 0
while true
alt_1 = 2
- look_1_0 = @input.peek( 1 )
+ look_1_0 = @input.peek(1)
- if ( look_1_0.between?( 0x61, 0x7a ) )
+ if (look_1_0.between?(0x61, 0x7a))
alt_1 = 1
end
case alt_1
- when 1
- # at line 161:12: 'a' .. 'z'
- match_range( 0x61, 0x7a )
+ when 1
+ # at line 160:12: 'a' .. 'z'
+ match_range(0x61, 0x7a)
- else
- match_count_1 > 0 and break
- eee = EarlyExit(1)
+ else
+ match_count_1 > 0 and break
+ eee = EarlyExit(1)
- raise eee
+ raise eee
end
match_count_1 += 1
end
-
@state.type = type
@state.channel = channel
@@ -1011,36 +1010,35 @@ def upalpha!
type = UPALPHA
channel = ANTLR3::DEFAULT_CHANNEL
-
+
# - - - - main rule block - - - -
- # at line 162:11: ( 'A' .. 'Z' )+
- # at file 162:11: ( 'A' .. 'Z' )+
+ # at line 161:11: ( 'A' .. 'Z' )+
+ # at file 161:11: ( 'A' .. 'Z' )+
match_count_2 = 0
while true
alt_2 = 2
- look_2_0 = @input.peek( 1 )
+ look_2_0 = @input.peek(1)
- if ( look_2_0.between?( 0x41, 0x5a ) )
+ if (look_2_0.between?(0x41, 0x5a))
alt_2 = 1
end
case alt_2
- when 1
- # at line 162:12: 'A' .. 'Z'
- match_range( 0x41, 0x5a )
+ when 1
+ # at line 161:12: 'A' .. 'Z'
+ match_range(0x41, 0x5a)
- else
- match_count_2 > 0 and break
- eee = EarlyExit(2)
+ else
+ match_count_2 > 0 and break
+ eee = EarlyExit(2)
- raise eee
+ raise eee
end
match_count_2 += 1
end
-
@state.type = type
@state.channel = channel
@@ -1059,36 +1057,14 @@ def digit!
type = DIGIT
channel = ANTLR3::DEFAULT_CHANNEL
-
- # - - - - main rule block - - - -
- # at line 163:11: ( '0' .. '9' )+
- # at file 163:11: ( '0' .. '9' )+
- match_count_3 = 0
- while true
- alt_3 = 2
- look_3_0 = @input.peek( 1 )
-
- if ( look_3_0.between?( 0x30, 0x39 ) )
- alt_3 = 1
-
- end
- case alt_3
- when 1
- # at line 163:12: '0' .. '9'
- match_range( 0x30, 0x39 )
-
- else
- match_count_3 > 0 and break
- eee = EarlyExit(3)
-
- raise eee
- end
- match_count_3 += 1
- end
+ # - - - - main rule block - - - -
+ # at line 162:11: ( '0' .. '9' )
+ # at line 162:11: ( '0' .. '9' )
+ # at line 162:12: '0' .. '9'