Class: GoogleApps::Atom::Document

Inherits:
Object
  • Object
show all
Includes:
Node
Defined in:
lib/google_apps/atom/document.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Node

#add_attributes, #add_namespaces, #add_prop_node, #check_value, #create_node, #get_content, #get_values, #node_match?

Constructor Details

#initialize(doc, map = {}) ⇒ Object

Parameters:

  • doc (String)
  • map (Hash) (defaults to: {})


14
15
16
17
# File 'lib/google_apps/atom/document.rb', line 14

def initialize(doc, map = {})
  @doc = doc.nil? ? new_empty_doc : parse(doc)
  @map = map
end

Class Method Details

.add_type(type) ⇒ Object

Adds a subclass to the @types array.

Parameters:

  • type (Constant)

Returns:



65
66
67
68
# File 'lib/google_apps/atom/document.rb', line 65

def self.add_type(type)
  # TODO:  Need to convert from const to symbol before adding
  @types << type
end

.inherited(subclass) ⇒ Object

Document keeps track of all it’s subclasses. This makes it easy to look up the document types supported by the library.

Parameters:

  • subclass (Constant)

Returns:



29
30
31
32
# File 'lib/google_apps/atom/document.rb', line 29

def self.inherited(subclass)
  self.add_type subclass
  Atom.add_doc_dispatcher self.sub_to_meth(subclass)
end

.sub_to_meth(subclass) ⇒ Object

Change subclass constant into a valid method name.

Parameters:

  • subclass (Constant)

    should be a class name

Returns:



42
43
44
# File 'lib/google_apps/atom/document.rb', line 42

def self.sub_to_meth(subclass)
  subclass.to_s.split('::').last.scan(/[A-Z][a-z0-9]+/).map(&:downcase).join('_')
end

.typesObject

Accessor for the Document types array. This array is a list of all subclasses of GoogleApps::Atom::Document

Returns:



53
54
55
# File 'lib/google_apps/atom/document.rb', line 53

def self.types
  @types
end

Instance Method Details

#attrs_from_propsObject

Sets instance variables for property list type documents.

Returns:



166
167
168
169
170
171
172
173
# File 'lib/google_apps/atom/document.rb', line 166

def attrs_from_props
  @doc.find('//apps:property').each do |entry|
    prop_name = entry.attributes['name'].to_sym
    if @map.keys.include?(prop_name)
      instance_variable_set "@#{@map[prop_name]}", check_value(entry.attributes['value'])
    end
  end
end

#build_root(type) ⇒ Object

build_root creates the shared root structure for the document.

build_root

build_root returns an atom:entry node with an apps:category element appropriate for the document type.



184
185
186
187
188
189
190
191
# File 'lib/google_apps/atom/document.rb', line 184

def build_root(type)
  root = create_node(type: 'atom:entry')

  add_namespaces root, determine_namespaces(type)
  root << create_node(type: 'apps:category', attrs: Atom::CATEGORY[type.to_sym]) if Atom::CATEGORY[type.to_sym]

  root
end

#delete_node(xpath, attrs) ⇒ Object

Delete a node from the document

Parameters:

  • xpath (String)

    is a node identifier in Xpath format

  • attrs (Array)

    is an array of attr, value pairs

Returns:



242
243
244
245
246
# File 'lib/google_apps/atom/document.rb', line 242

def delete_node(xpath, attrs)
  @doc.find(xpath).each do |node|
    node.remove! if node_match?(node, attrs)
  end
end

#determine_namespaces(type) ⇒ Object

determine_namespaces builds a hash of namespace key/value pairs.

determine_namespaces

determine_namespaces returns a hash



222
223
224
225
226
227
228
229
230
231
# File 'lib/google_apps/atom/document.rb', line 222

def determine_namespaces(type)
  ns = { atom: Atom::NAMESPACES[:atom], apps: Atom::NAMESPACES[:apps] }

  case type.to_s
    when 'group', 'groupmember'
      ns[:gd] = Atom::NAMESPACES[:gd]
  end

  ns
end

#find_and_update(xpath, attributes) ⇒ Object

find_and_update updates the values for the specified attributes on the node specified by the given xpath value. It is ill behaved and will change any matching attributes in any node returned using the given xpath.

find_and_update takes an xpath value and a hash of attribute names with current and new value pairs.

find_and_update ‘/apps:nickname’, name: [‘Bob’, ‘Tom’]



132
133
134
135
136
137
138
139
140
# File 'lib/google_apps/atom/document.rb', line 132

def find_and_update(xpath, attributes)
  @doc.find(xpath).each do |node|
    if node_match?(node, attributes)
      attributes.each_key do |attrib|
        node.attributes[attrib.to_s] = attributes[attrib][1]
      end
    end
  end
end

#find_valuesObject

find_values searches @doc and assigns any values to their corresponding instance variables. This is useful when we’ve been given a string of XML and need internal consistency in the object.

find_values



114
115
116
117
118
119
# File 'lib/google_apps/atom/document.rb', line 114

def find_values
  @doc.root.each do |entry|
    intersect = @map.keys & entry.attributes.to_h.keys.map(&:to_sym)
    set_instances(intersect, entry) unless intersect.empty?
  end
end

#make_document(xml) ⇒ Object

make_document takes either an xml document or a string and generates an xml document.

make_document xml

make_document returns an xml document.



92
93
94
# File 'lib/google_apps/atom/document.rb', line 92

def make_document(xml)
  xml.is_a?(Atom::XML::Document) ? xml : Atom::XML::Document.string(xml)
end

#new_empty_docObject

new_empty_doc creates an empty LibXML::XML::Document

new_empty_doc

new_empty_doc returns a LibXML::XML::Document without any nodes.



103
104
105
# File 'lib/google_apps/atom/document.rb', line 103

def new_empty_doc
  Atom::XML::Document.new
end

#parse(xml) ⇒ Object

parse takes xml, either a document or a string and returns a parsed document. Since libxml-ruby doesn’t build a parse tree dynamically this is needed more than you would think.

parse xml

parse returns a parsed xml document



79
80
81
82
83
# File 'lib/google_apps/atom/document.rb', line 79

def parse(xml)
  document = make_document(xml)

  Atom::XML::Parser.document(document).parse
end

#set_instances(intersect, node) ⇒ Object

Parameters:

  • intersect (Array)
  • node (LibXML::XML::Node)
  • map (Hash)

Returns:



154
155
156
157
158
# File 'lib/google_apps/atom/document.rb', line 154

def set_instances(intersect, node)
  intersect.each do |attribute|
    instance_variable_set "@#{@map[attribute]}", check_value(node.attributes[attribute])
  end
end

#to_sObject

Prints the contents of @doc

Returns:



253
254
255
# File 'lib/google_apps/atom/document.rb', line 253

def to_s
  @doc.to_s
end

#type_to_sObject

type_to_s returns the current document’s type as a string.

type_to_s

type_to_s returns a string



200
201
202
# File 'lib/google_apps/atom/document.rb', line 200

def type_to_s
  self.class.to_s.split(':').last.downcase
end

#type_to_symObject

type_to_sym returns the current document’s type as a symbol.

type_to_sym

type_to_sym returns a symbol



211
212
213
# File 'lib/google_apps/atom/document.rb', line 211

def type_to_sym
  type_to_s.to_sym
end