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, 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
# 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
  @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

#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



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

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



279
280
281
282
283
284
285
# File 'lib/confetti/config.rb', line 279

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

#default_iconObject



251
252
253
254
255
256
# File 'lib/confetti/config.rb', line 251

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



258
259
260
261
262
263
# File 'lib/confetti/config.rb', line 258

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



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

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

#filter_images(images, filter) ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/confetti/config.rb', line 265

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



287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/confetti/config.rb', line 287

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



221
222
223
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
# File 'lib/confetti/config.rb', line 221

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)


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

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

#iconObject



171
172
173
# File 'lib/confetti/config.rb', line 171

def icon
  @icon_set.first
end

#orientationObject

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



185
186
187
188
189
190
191
192
193
194
# File 'lib/confetti/config.rb', line 185

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

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

#populate(config_doc) ⇒ Object



73
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
# File 'lib/confetti/config.rb', line 73

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 "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



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

def populate_from_string( xml_str )
  populate xml_str 
end

#populate_from_xml(xml_file) ⇒ Object



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

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



198
199
200
201
202
203
204
# File 'lib/confetti/config.rb', line 198

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



208
209
210
211
# File 'lib/confetti/config.rb', line 208

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

#splashObject



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

def splash
  @splash_set.first
end

#to_sObject



300
301
302
# File 'lib/confetti/config.rb', line 300

def to_s
  @xml_doc.root.to_s
end

#to_xmlObject



304
305
306
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
# File 'lib/confetti/config.rb', line 304

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

  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 }
  url_schemes.each { | schm | widget.elements.add schm }

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