Class: NMEAPlus::MessageFactory Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/nmea_plus/message_factory.rb

Overview

This class is abstract.

MessageFactory is meant to be extended by actual implementations of message parsing classes

The base class for MessageFactory objects, which are instantiated in the Parser. MessageFactory objects create message classes with a common prefix and variable suffix. In an NMEA example, the prefix might be GP and the suffixes might be AAM or GLL (making GPAAM and GPGLL).

If you are creating more subclasses of MessageFactory, you are probably a developer adding more NMEA-style message factories to the parser, and you are working with the repo (not the gem).

Direct Known Subclasses

AISMessageFactory, NMEAMessageFactory

Class Method Summary collapse

Class Method Details

.alternate_data_type(data_type) ⇒ Array

This method is abstract.

Sometimes we want to override the data_type specified in the message (e.g. __AAM) with an alternate type (like GPAAM) or a generic type (like AAM). This is where we put that logic.



24
25
26
# File 'lib/nmea_plus/message_factory.rb', line 24

def self.alternate_data_type(data_type)
  [data_type] # in basic implementation, there is no alternative.
end

.best_match_for_data_type(data_type) ⇒ String

Try to load a class for the data_type specified in the message. If it doesn’t exist, then try an alternate. If that doesn’t work, fail.



49
50
51
52
53
54
55
56
# File 'lib/nmea_plus/message_factory.rb', line 49

def self.best_match_for_data_type(data_type)
  return data_type if self.message_class_exists?(self.message_class_name(data_type))

  self.alternate_data_type(data_type).each do |alternate_type|
    return alternate_type if self.message_class_exists?(self.message_class_name(alternate_type))
  end
  data_type
end

.create(message_prefix, fields, checksum) ⇒ NMEAPlus::Message

Choose what message class to create, and create it based on the first of the (unsplitted) fields – which is the data_type



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/nmea_plus/message_factory.rb', line 73

def self.create(message_prefix, fields, checksum)
  # get the data type and adjust it if necessary (e.g. support for NMEA standard sentences like __AAM)
  data_type = fields.split(",", 2)[0].upcase  # assumed to be 'GPGGA', etc
  interpreted_type = self.best_match_for_data_type(data_type)
  class_name = self.message_class_name(interpreted_type)

  # create message and make sure it's the right type
  message = self.dynamically_get_message_object(class_name)
  unless message.is_a? NMEAPlus::Message::Base
    raise ArgumentError, "Undefined message type #{data_type} (classname #{class_name})"
  end

  # assign its data and return it
  message.checksum = checksum
  message.payload = fields
  message.prefix = message_prefix
  message.interpreted_data_type = interpreted_type
  message
end

.dynamically_get_message_object(class_identifier) ⇒ Object

Get a message class through reflection



61
62
63
64
65
# File 'lib/nmea_plus/message_factory.rb', line 61

def self.dynamically_get_message_object(class_identifier)
  Object::const_get(class_identifier).new
rescue ::NameError => e
  raise ::NameError, "Couldn't instantiate a #{class_identifier} object: #{e}"
end

.message_class_exists?(class_identifier) ⇒ bool

Check whether a given object exists. this will work for all consts but shhhhhhhhh



31
32
33
34
35
36
# File 'lib/nmea_plus/message_factory.rb', line 31

def self.message_class_exists?(class_identifier)
  Object::const_get(class_identifier)
  true
rescue ::NameError
  false
end

.message_class_name(data_type) ⇒ String

Shortcut for the full name to a message class built from this factory.



41
42
43
# File 'lib/nmea_plus/message_factory.rb', line 41

def self.message_class_name(data_type)
  "NMEAPlus::Message::#{self.parent_module}::#{data_type}"
end

.parent_moduleString

This method is abstract.

For dynamic loading purposes. Don’t mess this up!



15
16
17
# File 'lib/nmea_plus/message_factory.rb', line 15

def self.parent_module
  "FIXME_parent_module"
end