Class: Virginity::BaseField

Inherits:
ContentLine show all
Includes:
FieldCleaning, Vcard21::Writer
Defined in:
lib/virginity/vcard/base_field.rb,
lib/virginity/api_extensions.rb,
lib/virginity/api_extensions/fields_to_xml.rb,
lib/virginity/api_extensions/fields_to_xml.rb

Overview

As a Vcard is a special type of DirectoryInformation, so is the Field a special type of ContentLine. A Field in Virginity is more content aware than a ContentLine. It knows what sort of content to expect for BDAY or ADR (respectively date or text, and a structured text value) and it provides the according methods that handle the differences in encoding.

Constant Summary collapse

TYPE =

is this field a preferred field?

"TYPE"
PREF =
/^pref$/i
BEGIN_REGEX =
/^BEGIN$/i
END_REGEX =
/^END$/i
@@field_register =

a Hash to containing name => class

Hash.new(self)

Constants included from FieldCleaning

FieldCleaning::BOM_BINARY, FieldCleaning::BOM_UTF8, FieldCleaning::CASE_SENSITIVE_TYPES, FieldCleaning::CHARSET, FieldCleaning::ENCODING, FieldCleaning::LIST_NAMES, FieldCleaning::QUOTED_PRINTABLE, FieldCleaning::X_SYNTHESIS_REF

Constants inherited from ContentLine

ContentLine::COLON_CHAR, ContentLine::GROUP, ContentLine::GROUP_DELIMITER, ContentLine::NAME

Instance Attribute Summary

Attributes inherited from ContentLine

#group, #name, #params

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FieldCleaning

#clean!, #clean_base64!, #clean_binary_data!, #clean_charsets!, #clean_quoted_printable_encoding!, #clean_types!, #guess_latin!, #remove_bom!, #remove_encoding_8bit!, #remove_x_synthesis_ref_params!, #uniq_params!

Methods included from Vcard21::Writer

#encode21, #vcard21line

Methods inherited from ContentLine

#api_id, #encode, #eql?, #has_name?, #hash, #initialize, line_parts, #merge_with!, #param_values, #params_to_s, #pretty_print, #to_field

Methods included from Encodings

#binary?, #to_ascii, #to_binary, #to_default, #to_default!, #verify_utf8ness

Constructor Details

This class inherits a constructor from Virginity::ContentLine

Class Method Details

.[](name) ⇒ Object

TODO: figure out if we really need upcase here



115
116
117
# File 'lib/virginity/vcard/base_field.rb', line 115

def self.[](name)
  @@field_register[name.to_s.upcase]
end

.field_registerObject



68
69
70
# File 'lib/virginity/vcard/base_field.rb', line 68

def self.field_register
  @@field_register
end

.merger(left, right) ⇒ Object



14
15
16
17
# File 'lib/virginity/vcard/base_field.rb', line 14

def self.merger(left, right)
  # ContentLine.merger returns a ContentLine, let's convert it to a field again.
  Field.parse(super)
end

.named(name) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/virginity/vcard/base_field.rb', line 72

def self.named(name)
  if registered? name
    self[name].new(name)
  else
    new(name)
  end
end

.parse(line) ⇒ Object Also known as: from_line

redefine ContentLine#parse to gain a few nanoseconds and initialize the correct Field using the register



81
82
83
84
85
86
87
88
# File 'lib/virginity/vcard/base_field.rb', line 81

def self.parse(line)
  if line.is_a? ContentLine
    self[line.name].new(line.name, line.raw_value, line.params, line.group)
  else
    group, name, params, value = line_parts(line.to_s)
    self[name].new(name, value, params, group, :no_deep_copy => true)
  end
end

.register_field(name, field_class) ⇒ Object

register a new field name with the class that should be used to represent it



95
96
97
98
# File 'lib/virginity/vcard/base_field.rb', line 95

def self.register_field(name, field_class)
  raise "#{name} is already registered" if registered?(name)
  @@field_register[name.to_s.upcase] = field_class
end

.register_for(*names) ⇒ Object

when called from a Field-descendant, this method registers that class as the one handling fields with a name in names



101
102
103
# File 'lib/virginity/vcard/base_field.rb', line 101

def self.register_for(*names)
  names.each { |name| register_field(name, self) }
end

.registered?(name) ⇒ Boolean

is name registered?

Returns:

  • (Boolean)


106
107
108
# File 'lib/virginity/vcard/base_field.rb', line 106

def self.registered?(name)
  @@field_register.keys.include?(name.to_s.upcase)
end

.typesObject

# a hash mapping field-names/types to Field-classes



120
121
122
# File 'lib/virginity/vcard/base_field.rb', line 120

def self.types
  @@field_register.dup
end

.unregister(name) ⇒ Object



110
111
112
# File 'lib/virginity/vcard/base_field.rb', line 110

def self.unregister(name)
  @@field_register[name.to_s.upcase] = nil
end

Instance Method Details

#<=>(other) ⇒ Object

Fields can be sorted



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/virginity/vcard/base_field.rb', line 30

def <=>(other)
  # BEGIN and END are special. and Virginity does not support nested vcards
  return -1 if name =~ BEGIN_REGEX or other.name =~ END_REGEX
  return 1 if name =~ END_REGEX or other.name =~ BEGIN_REGEX
  unless (diff = (name <=> other.name)) == 0
    diff
  else
    unless (diff = (pref? ? 0 : 1) <=> (other.pref? ? 0 : 1)) == 0
      diff
    else
      to_s <=> other.to_s
    end
  end
end

#==(other) ⇒ Object



57
58
59
60
61
62
# File 'lib/virginity/vcard/base_field.rb', line 57

def ==(other)
  group == other.group &&
    has_name?(other.name) &&
    params == other.params &&
    raw_value == other.raw_value
end

#extra_fields_to_xml(fields, builder) ⇒ Object



13
14
15
# File 'lib/virginity/api_extensions/fields_to_xml.rb', line 13

def extra_fields_to_xml(fields, builder)
  fields.each_pair { |k,v| builder.tag!(k, v) } unless fields.nil?
end

#field_as_json(hash, options = {}) ⇒ Object



56
57
58
# File 'lib/virginity/api_extensions.rb', line 56

def field_as_json(hash, options = {})
  group_and_params_as_json(options).merge(hash).delete_if { |k,v| v.nil? }
end

#group_and_params_as_json(options = {}) ⇒ Object



52
53
54
# File 'lib/virginity/api_extensions.rb', line 52

def group_and_params_as_json(options = {})
  { :group => group, :params => params }
end

#params_to_xmlObject



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/virginity/api_extensions/fields_to_xml.rb', line 20

def params_to_xml
  s = ""
  unless params.empty?
    s << "<params>"
    params.each do |p|
      s << xml_element(p.key, p.value)
    end
    s << "</params>"
  end
  s
end

#params_to_xml!(params, builder) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/virginity/api_extensions/fields_to_xml.rb', line 5

def params_to_xml!(params, builder)
  builder.params(:type => "array") do
    params.each do |p|
      builder.tag!(p.key, p.value, :type => "string")
    end
  end
end

#pref?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/virginity/vcard/base_field.rb', line 22

def pref?
  params(TYPE).any? { |p| p.value =~ PREF }
end

#raw_value=Object



51
# File 'lib/virginity/vcard/base_field.rb', line 51

alias_method :raw_value=, :value=

#to_xmlObject



41
42
43
44
45
46
47
# File 'lib/virginity/api_extensions/fields_to_xml.rb', line 41

def to_xml
  s = "<#{name.downcase}>"
  s << xml_element("group", group) unless group.nil?
  s << params_to_xml
  s << value_to_xml
  s << "</#{name.downcase}>"
end

#valueObject

fields ARE content_lines but most often one should not deal with the value. In virtually all cases value contains some encoded text that is only useful when decoded as text or a text list.



46
47
48
49
# File 'lib/virginity/vcard/base_field.rb', line 46

def value
  $stderr.puts "WARNING, you probably don't want to read value, if you do, please use #raw_value. Called from: #{caller.first}"
  raw_value
end

#value=(new_value) ⇒ Object



52
53
54
55
# File 'lib/virginity/vcard/base_field.rb', line 52

def value=(new_value)
  $stderr.puts "WARNING, you probably don't want to write value, if you do, please use #raw_value=. Called from: #{caller.first}"
  raw_value=(new_value)
end

#value_to_xmlObject

def params_to_xml

  return "" if params.empty?
  "<params>#{params.map {|p| xml_element(p.key, p.value) }.join}</params>"
end


37
38
39
# File 'lib/virginity/api_extensions/fields_to_xml.rb', line 37

def value_to_xml
  xml_element(@value, @value.strip)
end