Module: Occi::Parser::Text

Defined in:
lib/occi/parser/text.rb

Constant Summary collapse

REGEXP =
Regexp
REGEXP_QUOTED_STRING =

Regular expressions

/([^"\\]|\\.)*/
REGEXP_LOALPHA =
/[a-z]/
REGEXP_DIGIT =
/[0-9]/
REGEXP_INT =
/#{REGEXP_DIGIT}*/
REGEXP_FLOAT =
/#{REGEXP_DIGIT}*\.#{REGEXP_DIGIT}*/
REGEXP_NUMBER =
/#{REGEXP_INT}|#{REGEXP_FLOAT}/
REGEXP_BOOL =
/true|false/
REGEXP_TERM =

Regular expressions for OCCI

/#{REGEXP_LOALPHA}(#{REGEXP_LOALPHA}|#{REGEXP_DIGIT}|-|_)*/
REGEXP_SCHEME =
/#{URI::ABS_URI_REF}#/
REGEXP_TYPE_IDENTIFIER =
/#{REGEXP_SCHEME}#{REGEXP_TERM}/
REGEXP_CLASS =
/action|mixin|kind/
REGEXP_ATTR_COMPONENT =
/#{REGEXP_LOALPHA}(#{REGEXP_LOALPHA}|#{REGEXP_DIGIT}|-|_)*/
REGEXP_ATTRIBUTE_NAME =
/#{REGEXP_ATTR_COMPONENT}(\.#{REGEXP_ATTR_COMPONENT})*/
REGEXP_ATTRIBUTE_PROPERTY =
/immutable|required/
REGEXP_ATTRIBUTE_DEF =
/(#{REGEXP_ATTRIBUTE_NAME})(\{#{REGEXP_ATTRIBUTE_PROPERTY}(\s+#{REGEXP_ATTRIBUTE_PROPERTY})*\})?/
REGEXP_ATTRIBUTE_LIST =
/#{REGEXP_ATTRIBUTE_DEF}(\s+#{REGEXP_ATTRIBUTE_DEF})*/
REGEXP_ATTRIBUTE_REPR =
/#{REGEXP_ATTRIBUTE_NAME}=("#{REGEXP_QUOTED_STRING}"|#{REGEXP_NUMBER}|#{REGEXP_BOOL})/
REGEXP_ACTION =
/#{REGEXP_TYPE_IDENTIFIER}/
REGEXP_ACTION_LIST =
/#{REGEXP_ACTION}(\s+#{REGEXP_ACTION})*/
REGEXP_RESOURCE_TYPE =
/#{REGEXP_TYPE_IDENTIFIER}(\s+#{REGEXP_TYPE_IDENTIFIER})*/
/#{URI::URI_REF}/
/#{REGEXP_TYPE_IDENTIFIER}(\s+#{REGEXP_TYPE_IDENTIFIER})*/
REGEXP_CATEGORY =

Regular expression for OCCI Categories

"Category:\\s*(?<term>#{REGEXP_TERM})" << # term (mandatory)
";\\s*scheme=\"(?<scheme>#{REGEXP_SCHEME})\"" << # scheme (mandatory)
";\\s*class=\"(?<class>#{REGEXP_CLASS})\"" << # class (mandatory)
"(;\\s*title=\"(?<title>#{REGEXP_QUOTED_STRING})\")?" << # title (optional)
"(;\\s*rel=\"(?<rel>#{REGEXP_TYPE_IDENTIFIER})\")?"<< # rel (optional)
"(;\\s*location=\"(?<location>#{URI::URI_REF})\")?" << # location (optional)
"(;\\s*attributes=\"(?<attributes>#{REGEXP_ATTRIBUTE_LIST})\")?" << # attributes (optional)
"(;\\s*actions=\"(?<actions>#{REGEXP_ACTION_LIST})\")?" << # actions (optional)
';?'
"Link:\\s*\\<(?<uri>#{URI::URI_REF})\\>" << # uri (mandatory)
";\\s*rel=\"(?<rel>#{REGEXP_RESOURCE_TYPE})\"" << # rel (mandatory)
"(;\\s*self=\"(?<self>#{REGEXP_LINK_INSTANCE})\")?" << # self (optional)
"(;\\s*category=\"(?<category>#{REGEXP_LINK_TYPE})\")?" << # category (optional)
"(?<attributes>(;\\s*(#{REGEXP_ATTRIBUTE_REPR}))*)" << # attributes (optional)
';?'
REGEXP_ATTRIBUTE =

Regular expression for OCCI Entity Attributes

"X-OCCI-Attribute:\\s*(?<name>#{REGEXP_ATTRIBUTE_NAME})=(\"(?<string>#{REGEXP_QUOTED_STRING})\"|(?<number>#{REGEXP_NUMBER})|(?<bool>#{REGEXP_BOOL}))" <<
';?'
REGEXP_LOCATION =

Regular expression for OCCI Location

"X-OCCI-Location:\\s*(?<location>#{URI::URI_REF})" <<
';?'

Class Method Summary collapse

Class Method Details

.attribute(string) ⇒ Object (private)


167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/occi/parser/text.rb', line 167

def self.attribute(string)
  # create regular expression from regexp string
  regexp = REGEXP.new(REGEXP_ATTRIBUTE)
  # match string to regular expression
  match = regexp.match string

  raise "could not match #{string}" unless match

  value = match[:string] if match[:string]
  value = match[:number].to_i if match[:number]
  value = match[:bool] == "true" if match[:bool]
  Occi::Core::Attributes.split match[:name] => value
end

.categories(lines) ⇒ Object


69
70
71
72
73
74
75
76
77
# File 'lib/occi/parser/text.rb', line 69

def self.categories(lines)
  collection = Occi::Collection.new
  lines.each do |line|
    line.strip!
    category = self.category(line) if line.start_with? 'Category:'
    collection << category if category.kind_of? Occi::Core::Category
  end
  collection
end

.category(string) ⇒ Object (private)


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/occi/parser/text.rb', line 128

def self.category(string)
  # create regular expression from regexp string
  regexp = REGEXP.new(REGEXP_CATEGORY)
  # match string to regular expression
  match = regexp.match string

  raise "could not match #{string}" unless match

  term = match[:term]
  scheme = match[:scheme]
  title = match[:title]
  related = match[:rel].to_s.split
  if match[:attributes]
    attributes = Hashie::Mash.new
    match[:attributes].split.each do |attribute|
      property_string = attribute[/#{REGEXP_ATTRIBUTE_DEF}/, -2]
      properties = Occi::Core::AttributeProperties.new
      if property_string
        properties.required = true if property_string.include? 'required'
        properties.mutable = false if property_string.include? 'immutable'
      end
      name = attribute[/#{REGEXP_ATTRIBUTE_DEF}/, 1]
      attributes.merge! name.split('.').reverse.inject(properties) { |a, n| {n => a} }
    end
  end
  actions = match[:actions].to_s.split
  location = match[:location]
  case match[:class]
    when 'kind'
      Occi::Core::Kind.new scheme, term, title, attributes, related, actions, location
    when 'mixin'
      Occi::Core::Mixin.new scheme, term, title, attributes, related, actions, location
    when 'action'
      Occi::Core::Action.new scheme, term, title, attributes
    else
      raise "Category with class #{match[:class]} not recognized in string: #{string}"
  end
end

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/occi/parser/text.rb', line 99

def self.link(lines)
  collection = Occi::Collection.new
  link = Occi::Core::Link.new
  lines.each do |line|
    line.strip!
    case line
      when /^Category:/
        category = self.category(line)
        link.kind = category if category.kind_of? Occi::Core::Kind
        link.mixins << category if category.kind_of? Occi::Core::Mixin
      when /^X-OCCI-Attribute:/
        link.attributes.merge! self.attribute(line)
    end
  end
  collection << link if link.kind_of? Occi::Core::Link
  collection
end

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/occi/parser/text.rb', line 181

def self.link_string(string, source)
  # create regular expression from regexp string
  regexp = REGEXP.new(REGEXP_LINK)
  # match string to regular expression
  match = regexp.match string

  raise "could not match #{string}" unless match

  categories = match[:category].split
  kind = categories.shift
  mixins = categories
  actions = nil
  rel = match[:rel]
  target = match[:uri]
  location = match[:self]

  # create an array of the list of attributes
  attributes = match[:attributes].sub(/^\s*;\s*/, '').split ';'
  # parse each attribute and create an OCCI Attribute object from it
  attributes = attributes.inject(Occi::Core::Attributes.new) { |hsh, attribute| hsh.merge!(Occi::Parser::Text.attribute('X-OCCI-Attribute: ' + attribute)) }
  Occi::Core::Link.new kind, mixins, attributes, actions, rel, target, source, location
end

.location(string) ⇒ Object (private)


204
205
206
207
208
209
210
211
212
213
# File 'lib/occi/parser/text.rb', line 204

def self.location(string)
  # create regular expression from regexp string
  regexp = REGEXP.new(REGEXP_LOCATION)
  # match string to regular expression
  match = regexp.match string

  raise "could not match #{string}" unless match

  match[:location]
end

.locations(lines) ⇒ Object


117
118
119
120
121
122
123
124
# File 'lib/occi/parser/text.rb', line 117

def self.locations(lines)
  locations = []
  lines.each do |line|
    line.strip!
    locations << self.location(line) if line.start_with? 'X-OCCI-Location:'
  end
  locations
end

.resource(lines) ⇒ Object


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/occi/parser/text.rb', line 79

def self.resource(lines)
  collection = Occi::Collection.new
  resource = Occi::Core::Resource.new
  lines.each do |line|
    line.strip!
    case line
      when /^Category:/
        category = self.category(line)
        resource.kind = category if category.kind_of? Occi::Core::Kind
        resource.mixins << category if category.kind_of? Occi::Core::Mixin
      when /^X-OCCI-Attribute:/
        resource.attributes.merge! self.attribute(line)
      when /^Link:/
        resource.links << self.link_string(line, resource)
    end
  end
  collection << resource if resource.kind_of? Occi::Core::Resource
  collection
end