Class: Confetti::Config

Inherits:
Object
  • Object
show all
Extended by:
TemplateHelper
Includes:
Helpers, PhoneGap
Defined in:
lib/confetti/config.rb,
lib/confetti/config/image.rb,
lib/confetti/config/classes.rb,
lib/confetti/config/feature.rb,
lib/confetti/config/url_scheme.rb

Defined Under Namespace

Classes: Access, Author, Content, EncodingError, Feature, FileError, FiletypeError, Image, License, Name, Param, Platform, Preference, UrlScheme, XMLError

Constant Summary

Constants included from PhoneGap

PhoneGap::PHONEGAP_APIS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from TemplateHelper

generate_and_write

Methods included from PhoneGap

#add_stock_phonegap_apis, #legacy_plugins, #phonegap_version, #phonegap_version=

Methods included from Helpers

#is_file?

Constructor Details

#initialize(*args) ⇒ Config

Returns a new instance of Config.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/confetti/config.rb', line 31

def initialize( *args )
  @author           = Author.new
  @name             = Name.new
  @license          = License.new
  @content          = Content.new
  @icon_set         = TypedSet.new Image
  @plist_icon_set   = [] 
  @feature_set      = TypedSet.new Feature
  @platform_set     = TypedSet.new Platform
  @splash_set       = TypedSet.new Image
  @preference_set   = TypedSet.new Preference
  @access_set       = TypedSet.new Access
  @url_scheme_set   = TypedSet.new UrlScheme

  # defined in PhoneGap module
  @plugin_set       = TypedSet.new Plugin
  @viewmodes        = []

  return if args.empty?

  input = args.first

  if is_file?( input ) || File.extname( input ) == ".xml"
    populate_from_xml input
  elsif input.kind_of?( String )
    populate_from_string input
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object

handle bad generate/write calls



20
21
22
23
24
25
26
27
28
29
# File 'lib/confetti/config.rb', line 20

def method_missing(method_name, *args)
  bad_call = /^(generate)|(write)_(.*)$/
  matches = method_name.to_s.match(bad_call)

  if matches
    raise FiletypeError, "#{ matches[3] } not supported"
  else
    super method_name, *args
  end
end

Instance Attribute Details

#access_setObject (readonly)

Returns the value of attribute access_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def access_set
  @access_set
end

#authorObject (readonly)

Returns the value of attribute author.



9
10
11
# File 'lib/confetti/config.rb', line 9

def author
  @author
end

#contentObject (readonly)

Returns the value of attribute content.



9
10
11
# File 'lib/confetti/config.rb', line 9

def content
  @content
end

#descriptionObject

Returns the value of attribute description.



7
8
9
# File 'lib/confetti/config.rb', line 7

def description
  @description
end

#feature_setObject (readonly)

Returns the value of attribute feature_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def feature_set
  @feature_set
end

#heightObject

Returns the value of attribute height.



7
8
9
# File 'lib/confetti/config.rb', line 7

def height
  @height
end

#icon_setObject (readonly)

Returns the value of attribute icon_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def icon_set
  @icon_set
end

#licenseObject (readonly)

Returns the value of attribute license.



9
10
11
# File 'lib/confetti/config.rb', line 9

def license
  @license
end

#nameObject (readonly)

Returns the value of attribute name.



9
10
11
# File 'lib/confetti/config.rb', line 9

def name
  @name
end

#packageObject

Returns the value of attribute package.



7
8
9
# File 'lib/confetti/config.rb', line 7

def package
  @package
end

#platform_setObject (readonly)

Returns the value of attribute platform_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def platform_set
  @platform_set
end

#plist_icon_setObject

Returns the value of attribute plist_icon_set.



7
8
9
# File 'lib/confetti/config.rb', line 7

def plist_icon_set
  @plist_icon_set
end

#plugin_setObject (readonly)

Returns the value of attribute plugin_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def plugin_set
  @plugin_set
end

#preference_setObject (readonly)

Returns the value of attribute preference_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def preference_set
  @preference_set
end

#splash_setObject (readonly)

Returns the value of attribute splash_set.



9
10
11
# File 'lib/confetti/config.rb', line 9

def splash_set
  @splash_set
end

#url_scheme_setObject

Returns the value of attribute url_scheme_set.



7
8
9
# File 'lib/confetti/config.rb', line 7

def url_scheme_set
  @url_scheme_set
end

#version_codeObject

Returns the value of attribute version_code.



7
8
9
# File 'lib/confetti/config.rb', line 7

def version_code
  @version_code
end

#version_stringObject

Returns the value of attribute version_string.



7
8
9
# File 'lib/confetti/config.rb', line 7

def version_string
  @version_string
end

#viewmodesObject (readonly)

Returns the value of attribute viewmodes.



9
10
11
# File 'lib/confetti/config.rb', line 9

def viewmodes
  @viewmodes
end

#widthObject

Returns the value of attribute width.



7
8
9
# File 'lib/confetti/config.rb', line 7

def width
  @width
end

#xml_docObject (readonly)

Returns the value of attribute xml_doc.



9
10
11
# File 'lib/confetti/config.rb', line 9

def xml_doc
  @xml_doc
end

Instance Method Details

#biggest_iconObject



178
179
180
# File 'lib/confetti/config.rb', line 178

def biggest_icon
  @icon_set.max { |a,b| a.width.to_i <=> b.width.to_i }
end

#boolean_value(value, default = false) ⇒ Object

convert string (attribute) to boolean



282
283
284
285
286
287
288
# File 'lib/confetti/config.rb', line 282

def boolean_value value, default=false
  if default
    value != "false"
  else
    value == "true"
  end
end

#default_iconObject



254
255
256
257
258
259
# File 'lib/confetti/config.rb', line 254

def default_icon
  @icon_set.each do |icon|
    return icon if icon.src.match /^icon(\.[a-zA-Z0-9]+)+$/i
  end
  nil
end

#default_splashObject



261
262
263
264
265
266
# File 'lib/confetti/config.rb', line 261

def default_splash
  @splash_set.each do |splash|
    return splash if splash.src.match /^splash(\.[a-zA-Z0-9]+)$/i
  end
  nil
end

#feature(name) ⇒ Object



216
217
218
# File 'lib/confetti/config.rb', line 216

def feature name
  @feature_set.detect { |feature| feature.name == name }
end

#filter_images(images, filter) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/confetti/config.rb', line 268

def filter_images images, filter
  imgs = images.clone

  # filter can have multiple criteria
  filter.each_pair do |name, value|
    imgs = imgs.reject do |img|
      !img.respond_to?(name) || img.send(name) != value
    end
  end

  imgs
end

#filtered_to_s(xpaths = []) ⇒ Object



290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/confetti/config.rb', line 290

def filtered_to_s( xpaths = [] )
  xpaths = [ xpaths ] unless xpaths.kind_of?(Array)

  xml = @xml_doc.dup unless @xml_doc.nil?
  xml ||= to_xml

  xpaths.each do |path|
    xml.root.elements.delete_all path
  end

  xml.root.to_s
end

#find_best_fit_img(images, opts = {}) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/confetti/config.rb', line 224

def find_best_fit_img images, opts = {}
  opts['width']     ||= nil
  opts['height']    ||= nil
  opts['role']      ||= nil
  opts['density']   ||= nil
  opts['state']     ||= nil
  opts['platform']  ||= nil

  # filters to look through sets for
  filters = [
    {'height' => opts['height'], 'width' => opts['width']},
    {'platform' => opts['platform'], 'density' => opts['density']},
    {'platform' => opts['platform'], 'state' => opts['state']},
    {'platform' => opts['platform'], 'role' => opts['role']},
    {'platform' => opts['platform']}
  ]

  matches = nil

  filters.each do |filter|
    matches = filter_images(images, filter)

    if matches.length == 1
      break
    end
  end

  matches.first unless matches.empty?
end

#full_access?Boolean

Returns:

  • (Boolean)


220
221
222
# File 'lib/confetti/config.rb', line 220

def full_access?
  @access_set.detect { |a| a.origin == '*' }
end

#iconObject



174
175
176
# File 'lib/confetti/config.rb', line 174

def icon
  @icon_set.first
end

#orientationObject

simple helper for grabbing chosen orientation, or the default returns one of :portrait, :landscape, or :default



188
189
190
191
192
193
194
195
196
197
# File 'lib/confetti/config.rb', line 188

def orientation
  values = [:portrait, :landscape, :default]
  choice = preference :orientation

  unless choice and values.include?(choice)
    :default
  else
    choice
  end
end

#populate(config_doc) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
166
167
168
169
170
171
172
# File 'lib/confetti/config.rb', line 74

def populate( config_doc )
  begin
    config_doc = REXML::Document.new( config_doc ).root
  rescue REXML::ParseException
    raise XMLError, "malformed config.xml"
  rescue Iconv::InvalidCharacter
    raise EncodingError, "unable to read config.xml"
  end

  if config_doc.nil?
    raise XMLError, "no doc parsed"
  end

  @xml_doc = config_doc # save reference to doc

  @package = config_doc.attributes["id"]
  @version_string = config_doc.attributes["version"]
  @version_code = config_doc.attributes["versionCode"]

  config_doc.elements.each do |ele|
    attr = ele.attributes

    case ele.namespace

    # W3C widget elements
    when "http://www.w3.org/ns/widgets"
      case ele.name
      when "name"
        @name = Name.new(ele.text.nil? ? "" : ele.text.strip,
                          attr["shortname"])

      when "author"
        @author = Author.new(ele.text.nil? ? "" : ele.text.strip,
                              attr["href"], attr["email"])

      when "description"
        @description = ele.text.nil? ? "" : ele.text.strip

      when "icon"
        @icon_set << Image.new(attr["src"], attr["height"], attr["width"],
                                attr)
        # used for the info.plist file
        @plist_icon_set << attr["src"]

      when "feature"
        feature = Feature.new(attr["name"], attr["required"])

        ele.each_element( 'param' ) do |param|
          p_attr = param.attributes
          feature.param_set << Param.new(p_attr["name"], p_attr["value"])
        end

        @feature_set  << feature

      when "preference"
        @preference_set << Preference.new(attr["name"], attr["value"],
                                          attr["readonly"])

      when "license"
        @license = License.new(ele.text.nil? ? "" : ele.text.strip,
                               attr["href"])

      when "access"
        sub = boolean_value(attr["subdomains"], true)
        browserOnly = boolean_value(attr["browserOnly"])
        @access_set << Access.new(attr["origin"], sub, browserOnly)

      when "content"
        @content = Content.new(attr["src"], attr["type"], attr["encoding"])

      end

    # PhoneGap extensions (gap:)
    when "http://phonegap.com/ns/1.0"
      case ele.name
      when "platform"
        @platform_set << Platform.new(attr["name"])
      when "splash"
        next if attr["src"].nil? or attr["src"].empty?
        @splash_set << Image.new(attr["src"], attr["height"], attr["width"],
                                  attr)
      when "url-scheme"
        schms = ele.elements.to_a('scheme').map { |a| a.text }
        schms.reject! { |a| a.nil? || a.empty? }
        next if schms.empty?
        @url_scheme_set << UrlScheme.new(schms, attr["name"], attr["role"])
        
      when "plugin"
        next if attr["name"].nil? or attr["name"].empty?
        plugin = Plugin.new(attr["name"], attr["version"])
        ele.each_element('param') do |param|
          p_attr = param.attributes
          plugin.param_set << Param.new(p_attr["name"], p_attr["value"])
        end
        @plugin_set << plugin
      end
    end
  end
end

#populate_from_string(xml_str) ⇒ Object



70
71
72
# File 'lib/confetti/config.rb', line 70

def populate_from_string( xml_str )
  populate xml_str 
end

#populate_from_xml(xml_file) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/confetti/config.rb', line 60

def populate_from_xml(xml_file)
  begin
    file = File.read(xml_file)
  rescue Errno::ENOENT
    raise FileError, "file #{ xml_file } doesn't exist"
  end
  
  populate file 
end

#preference(name) ⇒ Object

helper to retrieve a preference’s value returns nil if the preference doesn’t exist



201
202
203
204
205
206
207
# File 'lib/confetti/config.rb', line 201

def preference name
  pref = preference_obj(name)

  if pref && pref.value && !pref.value.empty?
    pref.value.to_sym
  end
end

#preference_obj(name) ⇒ Object

mostly an internal method to help with weird cases in particular #phonegap_version



211
212
213
214
# File 'lib/confetti/config.rb', line 211

def preference_obj name
  name = name.to_s
  @preference_set.detect { |pref| pref.name == name }
end

#splashObject



182
183
184
# File 'lib/confetti/config.rb', line 182

def splash
  @splash_set.first
end

#to_sObject



303
304
305
# File 'lib/confetti/config.rb', line 303

def to_s
  @xml_doc.root.to_s
end

#to_xmlObject



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/confetti/config.rb', line 307

def to_xml
  doc = REXML::Document.new

  widget = REXML::Element.new( "widget" )
  widget.add_attributes({
    "xmlns" => "http://www.w3.org/ns/widgets",
    "xmlns:gap" =>  "http://phonegap.com/ns/1.0",
    "id" => @package,
    "version" => @version_string
    })

  if !@version_code.nil?
    widget.add_attribute({ "versionCode" => @version_code })
  end

  name = REXML::Element.new( "name" )
  name.text = @name.name
  name.add_attribute({ "shortname" => @name.shortname })

  content = REXML::Element.new( "content" )
  content.add_attributes({
      "src" => @content.src,
      "type" => @content.type
    })

  author = REXML::Element.new( "author" )
  author.text = @author.name
  author.add_attributes({
      "href" => @author.href,
      "email" => @author.email
      })

  description = REXML::Element.new( "description" )
  description.text = @description

  license = REXML::Element.new( "license" )
  license.text = @license.text
  license.add_attribute({ "href" => @license.href })

  icons = []
  @icon_set.each do | icon |
    ico = REXML::Element.new( "icon" )
    attrs = icon.defined_attrs
    ico.add_attributes attrs
    icons << ico
  end

  splashes = []
  @splash_set.each do | splash |
    spl = REXML::Element.new( "gap:splash" )
    attrs = splash.defined_attrs
    spl.add_attributes attrs
    splashes << spl
  end
  
  url_schemes = []
  @url_scheme_set.each do | scheme |
    schm = REXML::Element.new( "gap:url-scheme" )
    schm.add_attributes({"name" => scheme.name }) unless scheme.name.nil?
    schm.add_attributes({"role" => scheme.role }) unless scheme.role.nil?
    scheme.schemes.each{|s| schm.add_element("scheme").add_text(s) }
    url_schemes << schm
  end

  preferences = []
  @preference_set.each do | preference |
    pref = REXML::Element.new( "preference" )
    pref.add_attributes({
        "name" => preference.name,
        "value" => preference.value,
        "readonly" => preference.readonly
        })
    preferences << pref
  end

  features = []
  @feature_set.each do | feature |
    feat = REXML::Element.new( "feature" )
    feat.add_attributes({
        "name" => feature.name,
        "required" => feature.required,
        })

    features << feat 
  end

  platforms = []
  @platform_set.each do | platform |
    plat = REXML::Element.new( "gap:platform" )
    plat.add_attributes({
        "name" => platform.name
        })
    platforms << plat 
  end

  widget.elements.add name 
  widget.elements.add author
  widget.elements.add description 
  widget.elements.add license 
  widget.elements.add content

  icons.each { | icon | widget.elements.add icon }
  splashes.each { | splash | widget.elements.add splash }
  preferences.each { | pref | widget.elements.add pref }
  features.each { | feat | widget.elements.add feat }
  platforms.each { | plat | widget.elements.add plat }
  url_schemes.each { | schm | widget.elements.add schm }

  doc << REXML::XMLDecl.new
  doc.elements.add widget
  doc
end