Class: UCB::LDAP::Org
Overview
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:
-
all_nodes()
-
flattened_tree()
-
root_node()
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().
Constant Summary
Constants inherited from Entry
Class Method Summary collapse
-
.add_to_flattened_tree(node) ⇒ Object
Adds a node and its children to @flattened_tree.
-
.all_nodes ⇒ Object
Returns a
Hash
of all org nodes whose keys are deptids and whose values are corresponding Org instances. -
.all_nodes_i ⇒ Object
Direct access to instance variables for unit testing.
-
.build_flattened_tree ⇒ Object
Builds flattened tree.
-
.build_test_node_cache ⇒ Object
Build cache of all nodes.
-
.calculate_all_child_nodes ⇒ Object
Will calculate child_nodes for every node.
- .clear_all_nodes ⇒ Object
-
.find_by_ou(ou) ⇒ Object
(also: org_by_ou)
Returns an instance of Org for the matching ou.
-
.find_by_ou_from_cache(ou) ⇒ Object
Returns an instance of Org from the local if cache exists, else
nil
. -
.flattened_tree(options = {}) ⇒ Object
Returns an
Array
of all nodes in hierarchy order. -
.load_all_nodes ⇒ Object
Loads all org nodes and stores them in Hash returned by all_nodes().
-
.nodes_from_test_cache ⇒ Object
Returns cached nodes if we are testing and have already fetched all the nodes.
-
.rebuild_node_cache ⇒ Object
Rebuild the org tree using fresh data from ldap.
-
.root_node ⇒ Object
Returns the root node in the Org Tree.
Instance Method Summary collapse
-
#child_nodes ⇒ Object
Returns
Array
of child nodes, each an instance of Org, sorted by department id. -
#child_nodes_i ⇒ Object
Access to instance variables for testing.
-
#code_or_name_at_level(level, code_or_name) ⇒ Object
Return the level “n” code or name.
-
#deptid ⇒ Object
(also: #code)
Returns the department id.
-
#init_child_nodes ⇒ Object
— Must be public for load_all_nodes().
-
#level ⇒ Object
Returns the entry’s level in the Org Tree.
-
#load_child_nodes ⇒ Object
Loads child nodes for individual node.
-
#method_missing(method, *args) ⇒ Object
Support for method names like level_2_code, level_2_name.
-
#name ⇒ Object
Returns the department name.
-
#parent_deptid ⇒ Object
Returns parent node’s deptid.
-
#parent_deptids ⇒ Object
Returns Array of parent deptids.
-
#parent_node ⇒ Object
Return parent node which is an instance of Org.
-
#parent_nodes ⇒ Object
Returns
Array
of parent nodes which are instances of Org. -
#persons ⇒ Object
(also: #people)
Returns
Array
of UCB::LDAP::Person instances for each person in the org node. -
#processing_unit? ⇒ Boolean
Returns
true
if org is a processing unit. -
#push_child_node(child_node) ⇒ Object
— Add node to child node array.
Methods inherited from Entry
#assigned_attributes, #attributes, canonical, #canonical, combine_filters, create, create!, #dn, entity_name, filter_in, find_by_dn, #initialize, make_search_filter, net_ldap, #net_ldap, object_classes, required_attributes, required_schema_attributes, schema_attribute, schema_attributes_array, schema_attributes_hash, search, set_schema_attributes, tree_base, tree_base=, unique_object_class
Constructor Details
This class inherits a constructor from UCB::LDAP::Entry
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Support for method names like level_2_code, level_2_name
216 217 218 219 |
# File 'lib/ucb_ldap/org.rb', line 216 def method_missing(method, *args) #:nodoc: return code_or_name_at_level($1, $2) if method.to_s =~ /^level_([1-6])_(code|name)$/ super end |
Class Method Details
.add_to_flattened_tree(node) ⇒ Object
Adds a node and its children to @flattened_tree.
404 405 406 407 |
# 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 ⇒ Object
Returns a Hash
of all org nodes whose keys are deptids and whose values are corresponding Org instances.
291 292 293 |
# File 'lib/ucb_ldap/org.rb', line 291 def all_nodes @all_nodes ||= load_all_nodes end |
.all_nodes_i ⇒ Object
Direct access to instance variables for unit testing
411 412 413 |
# File 'lib/ucb_ldap/org.rb', line 411 def all_nodes_i @all_nodes end |
.build_flattened_tree ⇒ Object
Builds flattened tree. See RDoc for flattened_tree() for details.
394 395 396 397 398 399 |
# 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 ⇒ Object
Build cache of all nodes. Only used during testing.
374 375 376 377 |
# 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 ⇒ Object
Will calculate child_nodes for every node.
382 383 384 385 386 387 388 389 |
# 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.downcase == "org units" parent_node = find_by_ou_from_cache(node.parent_deptids.last) parent_node.push_child_node(node) end end |
.clear_all_nodes ⇒ Object
415 416 417 |
# File 'lib/ucb_ldap/org.rb', line 415 def clear_all_nodes @all_nodes = nil end |
.find_by_ou(ou) ⇒ Object Also known as: org_by_ou
Returns an instance of Org for the matching ou.
298 299 300 |
# 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 |
.find_by_ou_from_cache(ou) ⇒ Object
Returns an instance of Org from the local if cache exists, else nil
.
354 355 356 357 358 |
# File 'lib/ucb_ldap/org.rb', line 354 def find_by_ou_from_cache(ou) #:nodoc: return nil if ou.nil? return nil unless @all_nodes @all_nodes[ou.upcase] end |
.flattened_tree(options = {}) ⇒ Object
315 316 317 318 319 |
# File 'lib/ucb_ldap/org.rb', line 315 def flattened_tree(={}) @flattened_tree ||= build_flattened_tree return @flattened_tree unless [:level] @flattened_tree.reject { |o| o.level > [:level] } end |
.load_all_nodes ⇒ Object
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.
326 327 328 329 330 331 332 333 334 335 336 337 338 |
# 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 ⇒ Object
Returns cached nodes if we are testing and have already fetched all the nodes.
364 365 366 367 368 369 |
# 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 |
.rebuild_node_cache ⇒ Object
Rebuild the org tree using fresh data from ldap
282 283 284 285 |
# File 'lib/ucb_ldap/org.rb', line 282 def rebuild_node_cache clear_all_nodes load_all_nodes end |
.root_node ⇒ Object
Returns the root node in the Org Tree.
343 344 345 346 |
# File 'lib/ucb_ldap/org.rb', line 343 def root_node load_all_nodes find_by_ou('UCBKL') end |
Instance Method Details
#child_nodes ⇒ Object
Returns Array
of child nodes, each an instance of Org, sorted by department id.
145 146 147 |
# 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 ⇒ Object
Access to instance variables for testing
271 272 273 |
# File 'lib/ucb_ldap/org.rb', line 271 def child_nodes_i @child_nodes end |
#code_or_name_at_level(level, code_or_name) ⇒ Object
Return the level “n” code or name. Returns nil if level > self.level. Called from method_messing().
225 226 227 228 229 230 |
# File 'lib/ucb_ldap/org.rb', line 225 def code_or_name_at_level(level, code_or_name) #:nodoc: return (code_or_name == 'code' ? code : name) if level.to_i == self.level element = level.to_i - 1 return parent_deptids[element] if code_or_name == 'code' parent_nodes[element] && parent_nodes[element].name end |
#deptid ⇒ Object Also known as: code
Returns the department id.
152 153 154 |
# File 'lib/ucb_ldap/org.rb', line 152 def deptid ou.first end |
#init_child_nodes ⇒ Object
Must be public for load_all_nodes()
244 245 246 |
# File 'lib/ucb_ldap/org.rb', line 244 def init_child_nodes #:nodoc: @child_nodes = [] end |
#level ⇒ Object
Returns the entry’s level in the Org Tree.
161 162 163 |
# File 'lib/ucb_ldap/org.rb', line 161 def level @level ||= parent_deptids.size + 1 end |
#load_child_nodes ⇒ Object
Loads child nodes for individual node. If all_nodes_nodes() has been called, child nodes are all loaded/calculated.
264 265 266 |
# 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 ⇒ Object
Returns the department name.
168 169 170 |
# File 'lib/ucb_ldap/org.rb', line 168 def name description.first end |
#parent_deptid ⇒ Object
Returns parent node’s deptid
175 176 177 |
# File 'lib/ucb_ldap/org.rb', line 175 def parent_deptid @parent_deptid ||= parent_deptids.last end |
#parent_deptids ⇒ Object
Returns Array of parent deptids.
Highest level is first element; immediate parent is last element.
184 185 186 187 188 189 |
# 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 ⇒ Object
Return parent node which is an instance of Org.
201 202 203 204 |
# 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 ⇒ Object
Returns Array
of parent nodes which are instances of Org.
209 210 211 |
# 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 |
#persons ⇒ Object Also known as: people
Returns Array
of UCB::LDAP::Person instances for each person in the org node.
236 237 238 |
# File 'lib/ucb_ldap/org.rb', line 236 def persons @persons ||= UCB::LDAP::Person.search(:filter => { :departmentnumber => ou.first.to_s }) end |
#processing_unit? ⇒ Boolean
Returns true
if org is a processing unit.
194 195 196 |
# File 'lib/ucb_ldap/org.rb', line 194 def processing_unit? berkeleyEduOrgUnitProcessUnitFlag end |
#push_child_node(child_node) ⇒ Object
Add node to child node array.
250 251 252 253 254 255 |
# File 'lib/ucb_ldap/org.rb', line 250 def push_child_node(child_node) #:nodoc: @child_nodes ||= [] unless @child_nodes.find { |n| n.ou == child_node.ou } @child_nodes.push(child_node) end end |