class UCB::LDAP::Org

UCB::LDAP::Org

Class for accessing the Org Unit tree of the UCB LDAP directory.

You can search by specifying your own filter:

e = Org.search(:filter => 'ou=jkasd')

But most of the time you'll use the find_by_ou() method:

e = Org.find_by_ou('jkasd')

Get attribute values as if the attribute names were instance methods. Values returned reflect the cardinality and type as specified in the LDAP schema.

e = Org.find_by_ou('jkasd')

e.ou                                 #=> ['JKASD']
e.description                        #=> ['Application Services']
e.berkeleyEduOrgUnitProcessUnitFlag  #=> true

Convenience methods are provided that have friendlier names and return scalars for attributes the schema says are mulit-valued, but in practice are single-valued:

e = Org.find_by_ou('jkasd')

e.deptid                      #=> 'JKASD'
e.name                        #=> 'Application Services'
e.processing_unit?            #=> true

Other methods encapsulate common processing:

e.level                       #=> 4
e.parent_node                 #=> #<UCB::LDAP::Org: ...>
e.parent_node.deptid          #=> 'VRIST'
e.child_nodes                 #=> [#<UCB::LDAP::Org: ..>, ...]

You can retrieve people in a department. This will be an Array of UCB::LDAP::Person.

asd = Org.find_by_ou('jkasd')

asd_staff = asd.persons       #=> [#<UCB::LDAP::Person: ...>, ...]

Getting a Node's Level “n” Code or Name

There are methods that will return the org code and org name at a particular level. They are implemented by method_missing and so are not documented in the instance method section.

o = Org.find_by_ou('jkasd')

o.code          #=> 'JKASD'
o.level         #=> 4
o.level_4_code  #=> 'JKASD'
o.level_3_name  #=> 'Info Services & Technology'
o.level_2_code  #=> 'AVCIS'
o.level_5_code  #=> nil

Dealing With the Entire Org Tree

There are several class methods that simplify most operations involving the entire org tree.

Org.all_nodes()

Returns a Hash of all org nodes whose keys are deptids and whose values are corresponding Org instances.

# List all nodes alphabetically by department name

nodes_by_name = Org.all_nodes.values.sort_by{|n| n.name.upcase}
nodes_by_name.each do |n|
  puts "#{n.deptid} - #{n.name}"
end

Org.flattened_tree()

Returns an Array of all nodes in hierarchy order.

UCB::LDAP::Org.flattened_tree.each do |node|
  puts "#{node.level} #{node.deptid} - #{node.name}"
end

Produces:

1 UCBKL - UC Berkeley Campus
2 AVCIS - Information Sys & Technology
3 VRIST - Info Systems & Technology
4 JFAVC - Office of the CIO
5 JFADM - Assoc VC Off General Ops
4 JGMIP - Museum Informatics Project
4 JHSSC - Social Sci Computing Lab
etc.

Org.root_node()

Returns the root node in the Org Tree.

By recursing down child_nodes you can access the entire org tree:

# display deptid, name and children recursively
def display_node(node)
  indent = "  " * (node.level - 1)
  puts "#{indent} #{node.deptid} - #{node.name}"
  node.child_nodes.each{|child| display_node(child)}
end

# start at root node
display_node(Org.root_node)

Caching of Search Results

Calls to any of the following class methods automatically cache the entire Org tree:

Subsequent calls to any of these methods return the results from cache and don't require another LDAP query.

Subsequent calls to find_by_ou() are done against the local cache. Searches done via the search() method do not use the local cache.

Force loading of the cache by calling load_all_nodes().

Public Class Methods

add_to_flattened_tree(node) click to toggle source

Adds a node and its children to @flattened_tree.

# File lib/ucb_ldap/org.rb, line 404
def add_to_flattened_tree(node)
  @flattened_tree.push(node)
  node.child_nodes.each { |child| add_to_flattened_tree(child) }
end
all_nodes() click to toggle source

Returns a Hash of all org nodes whose keys are deptids and whose values are corresponding Org instances.

# File lib/ucb_ldap/org.rb, line 291
def all_nodes
  @all_nodes ||= load_all_nodes
end
all_nodes_i() click to toggle source

Direct access to instance variables for unit testing

# File lib/ucb_ldap/org.rb, line 411
def all_nodes_i
  @all_nodes
end
build_flattened_tree() click to toggle source

Builds flattened tree. See RDoc for flattened_tree() for details.

# File lib/ucb_ldap/org.rb, line 394
def build_flattened_tree
  load_all_nodes
  @flattened_tree = []
  add_to_flattened_tree(UCB::LDAP::Org.root_node)
  @flattened_tree
end
build_test_node_cache() click to toggle source

Build cache of all nodes. Only used during testing.

# File lib/ucb_ldap/org.rb, line 374
def build_test_node_cache
  @test_node_cache = {}
  @all_nodes.each { |k, v| @test_node_cache[k] = v.clone }
end
calculate_all_child_nodes() click to toggle source

Will calculate child_nodes for every node.

# File lib/ucb_ldap/org.rb, line 382
def calculate_all_child_nodes
  @all_nodes.values.each { |node| node.init_child_nodes }
  @all_nodes.values.each do |node|
    next if node.deptid == 'UCBKL' || node.deptid == "Org Units"
    parent_node = find_by_ou_from_cache(node.parent_deptids.last)
    parent_node.push_child_node(node)
  end
end
clear_all_nodes() click to toggle source
# File lib/ucb_ldap/org.rb, line 415
def clear_all_nodes
  @all_nodes = nil
end
find_by_ou(ou) click to toggle source

Returns an instance of Org for the matching ou.

# File lib/ucb_ldap/org.rb, line 298
def find_by_ou(ou)
  find_by_ou_from_cache(ou) || search(:filter => { :ou => ou }).first
end
Also aliased as: org_by_ou
flattened_tree(options={}) click to toggle source

Returns an Array of all nodes in hierarchy order. If you call with :level option, only nodes down to that level are returned.

Org.flattened_tree               # returns all nodes
Org.flattened_tree(:level => 3)  # returns down to level 3
# File lib/ucb_ldap/org.rb, line 315
def flattened_tree(options={})
  @flattened_tree ||= build_flattened_tree
  return @flattened_tree unless options[:level]
  @flattened_tree.reject { |o| o.level > options[:level] }
end
load_all_nodes() click to toggle source

Loads all org nodes and stores them in Hash returned by all_nodes(). Subsequent calls to find_by_ou() will be from cache and not require a trip to the LDAP server.

# File lib/ucb_ldap/org.rb, line 326
def load_all_nodes
  return @all_nodes if @all_nodes
  return nodes_from_test_cache if $TESTING && @test_node_cache

  @all_nodes = search.inject({}) do |accum, org|
    accum[org.deptid] = org if org.deptid != "Org Units"
    accum
  end

  build_test_node_cache if $TESTING
  calculate_all_child_nodes
  @all_nodes
end
nodes_from_test_cache() click to toggle source

Returns cached nodes if we are testing and have already fetched all the nodes.

# File lib/ucb_ldap/org.rb, line 364
def nodes_from_test_cache
  @all_nodes = {}
  @test_node_cache.each { |k, v| @all_nodes[k] = v.clone }
  calculate_all_child_nodes
  @all_nodes
end
org_by_ou(ou)

for backwards compatibility – should be deprecated

Alias for: find_by_ou
rebuild_node_cache() click to toggle source

Rebuild the org tree using fresh data from ldap

# File lib/ucb_ldap/org.rb, line 282
def rebuild_node_cache
  clear_all_nodes
  load_all_nodes
end
root_node() click to toggle source

Returns the root node in the Org Tree.

# File lib/ucb_ldap/org.rb, line 343
def root_node
  load_all_nodes
  find_by_ou('UCBKL')
end

Public Instance Methods

child_nodes() click to toggle source

Returns Array of child nodes, each an instance of Org, sorted by department id.

# File lib/ucb_ldap/org.rb, line 145
def child_nodes
  @sorted_child_nodes ||= load_child_nodes.sort_by { |node| node.deptid }
end
child_nodes_i() click to toggle source

Access to instance variables for testing

# File lib/ucb_ldap/org.rb, line 271
def child_nodes_i
  @child_nodes
end
code()
Alias for: deptid
deptid() click to toggle source

Returns the department id.

# File lib/ucb_ldap/org.rb, line 152
def deptid
  ou.first
end
Also aliased as: code
level() click to toggle source

Returns the entry's level in the Org Tree.

# File lib/ucb_ldap/org.rb, line 161
def level
  @level ||= parent_deptids.size + 1
end
load_child_nodes() click to toggle source

Loads child nodes for individual node. If all_nodes_nodes() has been called, child nodes are all loaded/calculated.

# File lib/ucb_ldap/org.rb, line 264
def load_child_nodes
  @child_nodes ||= UCB::LDAP::Org.search(:scope => 1, :base => dn, :filter => { :ou => '*' })
end
name() click to toggle source

Returns the department name.

# File lib/ucb_ldap/org.rb, line 168
def name
  description.first
end
parent_deptid() click to toggle source

Returns parent node's deptid

# File lib/ucb_ldap/org.rb, line 175
def parent_deptid
  @parent_deptid ||= parent_deptids.last
end
parent_deptids() click to toggle source

Returns Array of parent deptids.

Highest level is first element; immediate parent is last element.

# File lib/ucb_ldap/org.rb, line 184
def parent_deptids
  return @parent_deptids if @parent_deptids
  hierarchy_array = berkeleyEduOrgUnitHierarchyString.split("-")
  hierarchy_array.pop # last element is deptid ... toss it
  @parent_deptids = hierarchy_array
end
parent_node() click to toggle source

Return parent node which is an instance of Org.

# File lib/ucb_ldap/org.rb, line 201
def parent_node
  return nil if parent_deptids.size == 0
  @parent_node ||= UCB::LDAP::Org.find_by_ou(parent_deptid)
end
parent_nodes() click to toggle source

Returns Array of parent nodes which are instances of Org.

# File lib/ucb_ldap/org.rb, line 209
def parent_nodes
  @parent_nodes ||= parent_deptids.map { |deptid| UCB::LDAP::Org.find_by_ou(deptid) }
end
people()
Alias for: persons
persons() click to toggle source

Returns Array of UCB::LDAP::Person instances for each person in the org node.

# File lib/ucb_ldap/org.rb, line 236
def persons
  @persons ||= UCB::LDAP::Person.search(:filter => { :departmentnumber => ou.first.to_s })
end
Also aliased as: people
processing_unit?() click to toggle source

Returns true if org is a processing unit.

# File lib/ucb_ldap/org.rb, line 194
def processing_unit?
  berkeleyEduOrgUnitProcessUnitFlag
end