treequel 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +163 -76
- data/History.rdoc +11 -0
- data/README.rdoc +14 -16
- data/Rakefile +6 -1
- data/bin/treequel +4 -10
- data/bin/treewhat +2 -4
- data/lib/treequel/branch.rb +49 -163
- data/lib/treequel/branchcollection.rb +11 -16
- data/lib/treequel/branchset.rb +24 -17
- data/lib/treequel/control.rb +8 -6
- data/lib/treequel/controls/contentsync.rb +2 -2
- data/lib/treequel/controls/pagedresults.rb +1 -10
- data/lib/treequel/directory.rb +36 -78
- data/lib/treequel/exceptions.rb +1 -2
- data/lib/treequel/filter.rb +3 -8
- data/lib/treequel/mixins.rb +2 -7
- data/lib/treequel/model/errors.rb +1 -4
- data/lib/treequel/model/objectclass.rb +14 -26
- data/lib/treequel/model.rb +18 -64
- data/lib/treequel/monkeypatches.rb +2 -3
- data/lib/treequel/schema/attributetype.rb +0 -5
- data/lib/treequel/schema/objectclass.rb +9 -27
- data/lib/treequel/schema.rb +1 -18
- data/lib/treequel/utils.rb +0 -3
- data/lib/treequel.rb +48 -75
- data/spec/treequel/branchset_spec.rb +24 -0
- data/spec/treequel/monkeypatches_spec.rb +9 -9
- data.tar.gz.sig +0 -0
- metadata +27 -27
- metadata.gz.sig +1 -3
data/lib/treequel/branch.rb
CHANGED
@@ -53,11 +53,6 @@ class Treequel::Branch
|
|
53
53
|
|
54
54
|
|
55
55
|
### Create a new Treequel::Branch from the given +entry+ hash from the specified +directory+.
|
56
|
-
###
|
57
|
-
### @param [LDAP::Entry] entry The raw entry object the Branch is wrapping.
|
58
|
-
### @param [Treequel::Directory] directory The directory object the Branch is from.
|
59
|
-
###
|
60
|
-
### @return [Treequel::Branch] The new branch object.
|
61
56
|
def self::new_from_entry( entry, directory )
|
62
57
|
entry = Treequel::HashUtilities.stringify_keys( entry )
|
63
58
|
dnvals = entry.delete( 'dn' ) or
|
@@ -77,10 +72,6 @@ class Treequel::Branch
|
|
77
72
|
### If the optional +entry+ object is given, it will be used to fetch values from the
|
78
73
|
### directory; if it isn't provided, it will be fetched from the +directory+ the first
|
79
74
|
### time it is needed.
|
80
|
-
###
|
81
|
-
### @param [Treequel::Directory] directory The directory the Branch belongs to.
|
82
|
-
### @param [String] dn The DN of the entry the Branch is wrapping.
|
83
|
-
### @param [LDAP::Entry, Hash] entry The entry object if it's already been fetched.
|
84
75
|
def initialize( directory, dn, entry=nil )
|
85
76
|
raise ArgumentError, "nil DN" unless dn
|
86
77
|
raise ArgumentError, "invalid DN" unless
|
@@ -111,11 +102,9 @@ class Treequel::Branch
|
|
111
102
|
|
112
103
|
|
113
104
|
# The directory the branch's entry lives in
|
114
|
-
# @return [Treequel::Directory]
|
115
105
|
attr_reader :directory
|
116
106
|
|
117
107
|
# The DN of the branch.
|
118
|
-
# @return [String]
|
119
108
|
attr_reader :dn
|
120
109
|
alias_method :to_s, :dn
|
121
110
|
|
@@ -124,20 +113,15 @@ class Treequel::Branch
|
|
124
113
|
alias_method :include_operational_attributes?, :include_operational_attrs?
|
125
114
|
|
126
115
|
|
127
|
-
### Change the DN the Branch uses to look up its entry
|
128
|
-
###
|
129
|
-
### @param [String] newdn The new DN.
|
130
|
-
### @return [void]
|
116
|
+
### Change the DN the Branch uses to look up its entry to +newdn+.
|
131
117
|
def dn=( newdn )
|
132
118
|
self.clear_caches
|
133
119
|
@dn = newdn
|
134
120
|
end
|
135
121
|
|
136
122
|
|
137
|
-
### Enable or disable fetching of operational attributes (RC4512,
|
138
|
-
###
|
139
|
-
### @param [Boolean] new_setting
|
140
|
-
### @return [void]
|
123
|
+
### Enable (if +new_setting+ is true) or disable fetching of operational attributes (RC4512,
|
124
|
+
### section 3.4).
|
141
125
|
def include_operational_attrs=( new_setting )
|
142
126
|
self.clear_caches
|
143
127
|
@include_operational_attrs = new_setting ? true : false
|
@@ -145,8 +129,7 @@ class Treequel::Branch
|
|
145
129
|
alias_method :include_operational_attributes=, :include_operational_attrs=
|
146
130
|
|
147
131
|
|
148
|
-
### Return the attribute/s which make up this Branch's RDN.
|
149
|
-
### @return [Hash<Symbol => String>] The Branch's RDN attributes as a Hash.
|
132
|
+
### Return the attribute/s which make up this Branch's RDN as a Hash.
|
150
133
|
def rdn_attributes
|
151
134
|
return make_rdn_hash( self.rdn )
|
152
135
|
end
|
@@ -155,8 +138,6 @@ class Treequel::Branch
|
|
155
138
|
### Return the LDAP::Entry associated with the receiver, fetching it from the
|
156
139
|
### directory if necessary. Returns +nil+ if the entry doesn't exist in the
|
157
140
|
### directory.
|
158
|
-
###
|
159
|
-
### @return [LDAP::Entry] The entry wrapped by the Branch.
|
160
141
|
def entry
|
161
142
|
@entry ||= self.lookup_entry
|
162
143
|
end
|
@@ -164,38 +145,32 @@ class Treequel::Branch
|
|
164
145
|
|
165
146
|
### Returns <tt>true</tt> if there is an entry currently in the directory with the
|
166
147
|
### branch's DN.
|
167
|
-
### @return [Boolean]
|
168
148
|
def exists?
|
169
149
|
return self.entry ? true : false
|
170
150
|
end
|
171
151
|
|
172
152
|
|
173
153
|
### Returns +true+ if the Branch's entry has been fetched from the directory.
|
174
|
-
### @return [Boolean]
|
175
154
|
def loaded?
|
176
155
|
return @entry ? true : false
|
177
156
|
end
|
178
157
|
|
179
158
|
|
180
159
|
### Return the RDN of the branch.
|
181
|
-
### @return [String]
|
182
160
|
def rdn
|
183
161
|
return self.split_dn( 2 ).first
|
184
162
|
end
|
185
163
|
|
186
164
|
|
187
|
-
### Return the receiver's DN as an Array of attribute=value pairs.
|
188
|
-
###
|
189
|
-
###
|
190
|
-
### are split from the DN, and the remainder will be returned as the last
|
191
|
-
### element.
|
165
|
+
### Return the receiver's DN as an Array of attribute=value pairs. If the optional +limit+ is
|
166
|
+
### non-zero, only the <code>limit-1</code> first pairs are split from the DN, and the
|
167
|
+
### remainder will be returned as the last element.
|
192
168
|
def split_dn( limit=0 )
|
193
169
|
return self.dn.split( /\s*,\s*/, limit )
|
194
170
|
end
|
195
171
|
|
196
172
|
|
197
173
|
### Return the LDAP URI for this branch
|
198
|
-
### @return [URI]
|
199
174
|
def uri
|
200
175
|
uri = self.directory.uri
|
201
176
|
uri.dn = self.dn
|
@@ -204,7 +179,6 @@ class Treequel::Branch
|
|
204
179
|
|
205
180
|
|
206
181
|
### Return the DN of this entry's parent, or nil if it doesn't have one.
|
207
|
-
### @return [String]
|
208
182
|
def parent_dn
|
209
183
|
return nil if self.dn == self.directory.base_dn
|
210
184
|
return '' if self.dn.index( ',' ).nil?
|
@@ -213,36 +187,27 @@ class Treequel::Branch
|
|
213
187
|
|
214
188
|
|
215
189
|
### Return the Branch's immediate parent node.
|
216
|
-
### @return [Treequel::Branch]
|
217
190
|
def parent
|
218
191
|
pardn = self.parent_dn or return nil
|
219
192
|
return self.class.new( self.directory, pardn )
|
220
193
|
end
|
221
194
|
|
222
195
|
|
223
|
-
### Perform a search with the specified +scope+, +filter+, and +parameters+
|
224
|
-
###
|
225
|
-
###
|
226
|
-
### @param scope (see Trequel::Directory#search)
|
227
|
-
### @param filter (see Trequel::Directory#search)
|
228
|
-
### @param parameters (see Trequel::Directory#search)
|
229
|
-
### @param block (see Trequel::Directory#search)
|
230
|
-
###
|
231
|
-
### @return [Array<Treequel::Branch>] the search results
|
196
|
+
### Perform a search with the specified +scope+, +filter+, and +parameters+ using the
|
197
|
+
### receiver as the base. See Trequel::Directory#search for details. Returns an Array of
|
198
|
+
### Treequel::Branch objects.
|
232
199
|
def search( scope=:subtree, filter='(objectClass=*)', parameters={}, &block )
|
233
200
|
return self.directory.search( self, scope, filter, parameters, &block )
|
234
201
|
end
|
235
202
|
|
236
203
|
|
237
204
|
### Return the Branch's immediate children as Treeque::Branch objects.
|
238
|
-
### @return [Array<Treequel::Branch>]
|
239
205
|
def children
|
240
206
|
return self.search( :one, '(objectClass=*)' )
|
241
207
|
end
|
242
208
|
|
243
209
|
|
244
210
|
### Return a Treequel::Branchset that will use the receiver as its base.
|
245
|
-
### @return [Treequel::Branchset]
|
246
211
|
def branchset
|
247
212
|
return Treequel::Branchset.new( self )
|
248
213
|
end
|
@@ -250,8 +215,6 @@ class Treequel::Branch
|
|
250
215
|
|
251
216
|
### Returns a human-readable representation of the object suitable for
|
252
217
|
### debugging.
|
253
|
-
###
|
254
|
-
### @return [String]
|
255
218
|
def inspect
|
256
219
|
return "#<%s:0x%0x %s @ %s entry=%p>" % [
|
257
220
|
self.class.name,
|
@@ -264,7 +227,6 @@ class Treequel::Branch
|
|
264
227
|
|
265
228
|
|
266
229
|
### Return the entry's DN as an RFC1781-style UFN (User-Friendly Name).
|
267
|
-
### @return [String]
|
268
230
|
def to_ufn
|
269
231
|
if LDAP.respond_to?( :dn2ufn )
|
270
232
|
return LDAP.dn2ufn( self.dn )
|
@@ -298,7 +260,6 @@ class Treequel::Branch
|
|
298
260
|
|
299
261
|
|
300
262
|
### Return the Branch as an LDAP::LDIF::Entry.
|
301
|
-
### @return [String]
|
302
263
|
def to_ldif( width=DEFAULT_LDIF_WIDTH )
|
303
264
|
ldif = "dn: %s\n" % [ self.dn ]
|
304
265
|
|
@@ -316,8 +277,6 @@ class Treequel::Branch
|
|
316
277
|
|
317
278
|
|
318
279
|
### Return the Branch as a Hash.
|
319
|
-
### @see Treequel::Branch#[]
|
320
|
-
### @return [Hash] the entry as a Hash with converted values
|
321
280
|
def to_hash
|
322
281
|
entry = self.entry || self.valid_attributes_hash
|
323
282
|
self.log.debug " making a Hash from an entry: %p" % [ entry ]
|
@@ -334,12 +293,11 @@ class Treequel::Branch
|
|
334
293
|
|
335
294
|
|
336
295
|
### Fetch the value/s associated with the given +attrname+ from the underlying entry.
|
337
|
-
### @return [Array, String]
|
338
296
|
def []( attrname )
|
339
297
|
attrsym = attrname.to_sym
|
340
298
|
|
341
299
|
if @values.key?( attrsym )
|
342
|
-
self.log.debug " value for %p is cached (%p)." % [ attrname, @values[attrsym] ]
|
300
|
+
# self.log.debug " value for %p is cached (%p)." % [ attrname, @values[attrsym] ]
|
343
301
|
else
|
344
302
|
self.log.debug " value for %p is NOT cached." % [ attrsym ]
|
345
303
|
value = self.get_converted_object( attrsym )
|
@@ -354,10 +312,10 @@ class Treequel::Branch
|
|
354
312
|
end
|
355
313
|
|
356
314
|
|
357
|
-
### Fetch one or more values from the entry.
|
358
|
-
###
|
359
|
-
###
|
360
|
-
###
|
315
|
+
### Fetch one or more values for the specified +attributes+ from the entry.
|
316
|
+
###
|
317
|
+
### branch.values_at( :cn, :objectClass )
|
318
|
+
### => [["sysadmin"], ["top", "posixGroup", "apple-group"]]
|
361
319
|
def values_at( *attributes )
|
362
320
|
return attributes.collect do |attribute|
|
363
321
|
self[ attribute ]
|
@@ -366,9 +324,6 @@ class Treequel::Branch
|
|
366
324
|
|
367
325
|
|
368
326
|
### Set attribute +attrname+ to a new +value+.
|
369
|
-
###
|
370
|
-
### @param [Symbol, String] attrname attribute name
|
371
|
-
### @param [Object] value the attribute value
|
372
327
|
def []=( attrname, value )
|
373
328
|
value = [ value ] unless value.is_a?( Array )
|
374
329
|
value.collect! {|val| self.get_converted_attribute(attrname, val) }
|
@@ -380,9 +335,8 @@ class Treequel::Branch
|
|
380
335
|
|
381
336
|
|
382
337
|
### Make the changes to the entry specified by the given +attributes+.
|
383
|
-
###
|
384
|
-
###
|
385
|
-
### @return [TrueClass] if the merge succeeded
|
338
|
+
###
|
339
|
+
### branch.merge( :description => ['The syadmin group'], :cn => ['sysadmin'] )
|
386
340
|
def merge( attributes )
|
387
341
|
self.directory.modify( self, attributes )
|
388
342
|
self.clear_caches
|
@@ -392,20 +346,19 @@ class Treequel::Branch
|
|
392
346
|
alias_method :modify, :merge
|
393
347
|
|
394
348
|
|
395
|
-
### Delete the specified attributes
|
396
|
-
###
|
397
|
-
###
|
398
|
-
### attribute names (in which case all values of the attribute are deleted) or
|
399
|
-
### Hashes of attributes and the Array of value/s which should be deleted.
|
349
|
+
### Delete the specified +attributes+, which are the attributes to delete either as
|
350
|
+
### attribute names (in which case all values of the attribute are deleted), or
|
351
|
+
### Hashes of attributes and the Array of value/s which should be deleted.
|
400
352
|
###
|
401
|
-
###
|
353
|
+
### # Delete all 'description' attributes
|
402
354
|
### branch.delete( :description )
|
403
|
-
###
|
355
|
+
###
|
356
|
+
### # Delete the 'inetOrgPerson' and 'posixAccount' objectClasses from the entry
|
404
357
|
### branch.delete( :objectClass => [:inetOrgPerson, :posixAccount] )
|
405
|
-
###
|
358
|
+
###
|
359
|
+
### # Delete any blank 'description' or 'cn' attributes:
|
406
360
|
### branch.delete( :description => '', :cn => '' )
|
407
361
|
###
|
408
|
-
### @return [TrueClass] if the delete succeeded
|
409
362
|
def delete( *attributes )
|
410
363
|
|
411
364
|
# If no attributes are given, delete the whole entry
|
@@ -443,9 +396,12 @@ class Treequel::Branch
|
|
443
396
|
|
444
397
|
|
445
398
|
### Create the entry for this Branch with the specified +attributes+. The +attributes+ should,
|
446
|
-
### at a minimum, contain the pair `:objectClass => :someStructuralObjectClass`.
|
447
|
-
###
|
448
|
-
###
|
399
|
+
### at a minimum, contain the pair `:objectClass => [:someStructuralObjectClass]`.
|
400
|
+
###
|
401
|
+
### groups = dir.ou( :groups )
|
402
|
+
### newgroup = groups.cn( :staff )
|
403
|
+
### newgroup.create( :objectClass => ['posixGroup'], :gidNumber => 2100 )
|
404
|
+
### # => #<Treequel::Branch:0x1086a0ac8 cn=staff,ou=groups,dc=example,dc=com>
|
449
405
|
def create( attributes={} )
|
450
406
|
self.directory.create( self, attributes )
|
451
407
|
self.clear_caches
|
@@ -455,10 +411,6 @@ class Treequel::Branch
|
|
455
411
|
|
456
412
|
### Copy the entry for this Branch to a new entry with the given +newdn+ and merge in the
|
457
413
|
### specified +attributes+.
|
458
|
-
###
|
459
|
-
### @param [String] newdn the dn of the new entry
|
460
|
-
### @param [Hash<String, Symbol => Object>] attributes merge attributes
|
461
|
-
### @return [Treequel::Branch] a Branch for the new entry
|
462
414
|
def copy( newdn, attributes={} )
|
463
415
|
|
464
416
|
# Fully-qualify RDNs
|
@@ -479,9 +431,6 @@ class Treequel::Branch
|
|
479
431
|
### Move the entry associated with this branch to a new entry indicated by +rdn+. If
|
480
432
|
### any +attributes+ are given, also replace the corresponding attributes on the new
|
481
433
|
### entry with them.
|
482
|
-
###
|
483
|
-
### @param [String] rdn
|
484
|
-
### @param [Hash<String, Symbol => Object>] attributes
|
485
434
|
def move( rdn )
|
486
435
|
self.log.debug "Asking the directory to move me to an entry called %p" % [ rdn ]
|
487
436
|
self.directory.move( self, rdn )
|
@@ -491,11 +440,8 @@ class Treequel::Branch
|
|
491
440
|
end
|
492
441
|
|
493
442
|
|
494
|
-
### Comparable interface: Returns -1 if other_branch is less than, 0 if other_branch is
|
495
|
-
### equal to, and +1 if other_branch is greater than the receiving Branch.
|
496
|
-
###
|
497
|
-
### @param [Treequel::Branch] other_branch
|
498
|
-
### @return [Fixnum]
|
443
|
+
### Comparable interface: Returns -1 if other_branch is less than, 0 if +other_branch+ is
|
444
|
+
### equal to, and +1 if +other_branch+ is greater than the receiving Branch.
|
499
445
|
def <=>( other_branch )
|
500
446
|
# Try the easy cases first
|
501
447
|
return nil unless other_branch.respond_to?( :dn ) &&
|
@@ -517,9 +463,6 @@ class Treequel::Branch
|
|
517
463
|
|
518
464
|
### Fetch a new Treequel::Branch object for the child of the receiver with the specified
|
519
465
|
### +rdn+.
|
520
|
-
###
|
521
|
-
### @param [String] rdn The RDN of the child to fetch.
|
522
|
-
### @return [Treequel::Branch]
|
523
466
|
def get_child( rdn )
|
524
467
|
self.log.debug "Getting child %p from base = %p" % [ rdn, self.dn ]
|
525
468
|
newdn = [ rdn, self.dn ].reject {|part| part.empty? }.join( ',' )
|
@@ -529,9 +472,6 @@ class Treequel::Branch
|
|
529
472
|
|
530
473
|
### Addition operator: return a Treequel::BranchCollection that contains both the receiver
|
531
474
|
### and +other_branch+.
|
532
|
-
###
|
533
|
-
### @param [Treequel::Branch] other_branch
|
534
|
-
### @return [Treequel::BranchCollection]
|
535
475
|
def +( other_branch )
|
536
476
|
return Treequel::BranchCollection.new( self.branchset, other_branch.branchset )
|
537
477
|
end
|
@@ -540,11 +480,8 @@ class Treequel::Branch
|
|
540
480
|
### Return Treequel::Schema::ObjectClass instances for each of the receiver's
|
541
481
|
### objectClass attributes. If any +additional_classes+ are given,
|
542
482
|
### merge them with the current list of the current objectClasses for the lookup.
|
543
|
-
###
|
544
|
-
### @param [Array<String, Symbol>] additional_classes
|
545
|
-
### @return [Array<Treequel::Schema::ObjectClass>]
|
546
483
|
def object_classes( *additional_classes )
|
547
|
-
self.log.debug "Fetching object classes for %s" % [ self.dn ]
|
484
|
+
# self.log.debug "Fetching object classes for %s" % [ self.dn ]
|
548
485
|
schema = self.directory.schema
|
549
486
|
|
550
487
|
oc_oids = self[:objectClass] || []
|
@@ -558,14 +495,12 @@ class Treequel::Branch
|
|
558
495
|
oclasses << oc
|
559
496
|
end
|
560
497
|
|
561
|
-
self.log.debug " found %d objectClasses: %p" % [ oclasses.length, oclasses.map(&:name) ]
|
498
|
+
# self.log.debug " found %d objectClasses: %p" % [ oclasses.length, oclasses.map(&:name) ]
|
562
499
|
return oclasses.uniq
|
563
500
|
end
|
564
501
|
|
565
502
|
|
566
503
|
### Return the receiver's operational attributes as attributeType schema objects.
|
567
|
-
###
|
568
|
-
### @return [Array<Treequel::Schema::AttributeType>] the operational attributes
|
569
504
|
def operational_attribute_types
|
570
505
|
return self.directory.schema.operational_attribute_types
|
571
506
|
end
|
@@ -586,19 +521,9 @@ class Treequel::Branch
|
|
586
521
|
### include the MUST attributeTypes for them as well. This can be used to predict what
|
587
522
|
### attributes would need to be present for the entry to be saved if it added the
|
588
523
|
### +additional_object_classes+ to its own.
|
589
|
-
###
|
590
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
591
|
-
### @return [Array<Treequel::Schema::AttributeType>]
|
592
524
|
def must_attribute_types( *additional_object_classes )
|
593
|
-
types = []
|
594
525
|
oclasses = self.object_classes( *additional_object_classes )
|
595
|
-
|
596
|
-
[ oclasses.map(&:name) ]
|
597
|
-
|
598
|
-
oclasses.each do |oc|
|
599
|
-
self.log.debug " adding %p from %p" % [ oc.must.map(&:name), oc.name ]
|
600
|
-
types |= oc.must
|
601
|
-
end
|
526
|
+
types = oclasses.map( &:must ).flatten.uniq
|
602
527
|
|
603
528
|
return types
|
604
529
|
end
|
@@ -609,9 +534,6 @@ class Treequel::Branch
|
|
609
534
|
### include the OIDs of the MUST attributes for them as well. This can be used to predict
|
610
535
|
### what attributes would need to be present for the entry to be saved if it added the
|
611
536
|
### +additional_object_classes+ to its own.
|
612
|
-
###
|
613
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
614
|
-
### @return [Array<String, Symbol>] oid strings and symbols
|
615
537
|
def must_oids( *additional_object_classes )
|
616
538
|
return self.object_classes( *additional_object_classes ).
|
617
539
|
collect {|oc| oc.must_oids }.flatten.uniq.reject {|val| val == '' }
|
@@ -621,9 +543,6 @@ class Treequel::Branch
|
|
621
543
|
### Return a Hash of the attributes required by the Branch's objectClasses. If
|
622
544
|
### any +additional_object_classes+ are given, include the attributes that would be
|
623
545
|
### necessary for the entry to be saved with them.
|
624
|
-
###
|
625
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
626
|
-
### @return [Hash<String => String>]
|
627
546
|
def must_attributes_hash( *additional_object_classes )
|
628
547
|
attrhash = {}
|
629
548
|
|
@@ -648,9 +567,6 @@ class Treequel::Branch
|
|
648
567
|
### include the MAY attributeTypes for them as well. This can be used to predict what
|
649
568
|
### optional attributes could be added to the entry if the +additional_object_classes+
|
650
569
|
### were added to it.
|
651
|
-
###
|
652
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
653
|
-
### @return [Array<Treequel::Schema::AttributeType>]
|
654
570
|
def may_attribute_types( *additional_object_classes )
|
655
571
|
return self.object_classes( *additional_object_classes ).
|
656
572
|
collect {|oc| oc.may }.flatten.uniq
|
@@ -662,9 +578,6 @@ class Treequel::Branch
|
|
662
578
|
### include the OIDs of the MAY attributes for them as well. This can be used to predict
|
663
579
|
### what optional attributes could be added to the entry if the +additional_object_classes+
|
664
580
|
### were added to it.
|
665
|
-
###
|
666
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
667
|
-
### @return [Array<String, Symbol>] oid strings and symbols
|
668
581
|
def may_oids( *additional_object_classes )
|
669
582
|
return self.object_classes( *additional_object_classes ).
|
670
583
|
collect {|oc| oc.may_oids }.flatten.uniq
|
@@ -674,9 +587,6 @@ class Treequel::Branch
|
|
674
587
|
### Return a Hash of the optional attributes allowed by the Branch's objectClasses. If
|
675
588
|
### any +additional_object_classes+ are given, include the attributes that would be
|
676
589
|
### available for the entry if it had them.
|
677
|
-
###
|
678
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
679
|
-
### @return [Hash<String => String>]
|
680
590
|
def may_attributes_hash( *additional_object_classes )
|
681
591
|
entry = self.entry
|
682
592
|
attrhash = {}
|
@@ -702,8 +612,6 @@ class Treequel::Branch
|
|
702
612
|
|
703
613
|
### Return Treequel::Schema::AttributeType instances for the set of all of the receiver's
|
704
614
|
### MUST and MAY attributeTypes plus the operational attributes.
|
705
|
-
###
|
706
|
-
### @return [Array<Treequel::Schema::AttributeType>]
|
707
615
|
def valid_attribute_types
|
708
616
|
return self.must_attribute_types |
|
709
617
|
self.may_attribute_types |
|
@@ -714,8 +622,6 @@ class Treequel::Branch
|
|
714
622
|
### Return a uniqified Array of OIDs (numeric OIDs as Strings, named OIDs as Symbols) for
|
715
623
|
### the set of all of the receiver's MUST and MAY attributeTypes plus the operational
|
716
624
|
### attributes.
|
717
|
-
###
|
718
|
-
### @return [Array<String, Symbol>]
|
719
625
|
def valid_attribute_oids
|
720
626
|
return self.must_oids | self.may_oids
|
721
627
|
end
|
@@ -725,9 +631,6 @@ class Treequel::Branch
|
|
725
631
|
### attributeTypes for the receiver given its objectClasses, return the
|
726
632
|
### AttributeType object that corresponds with it. If it isn't valid, return nil.
|
727
633
|
### Includes operational attributes.
|
728
|
-
###
|
729
|
-
### @param [String,Symbol] attroid a numeric OID (as a String) or a named OID (as a Symbol)
|
730
|
-
### @return [Treequel::Schema::AttributeType] the validated attributeType
|
731
634
|
def valid_attribute_type( attroid )
|
732
635
|
return self.valid_attribute_types.find {|attr_type| attr_type.valid_name?(attroid) }
|
733
636
|
end
|
@@ -735,9 +638,6 @@ class Treequel::Branch
|
|
735
638
|
|
736
639
|
### Return +true+ if the specified +attrname+ is a valid attributeType given the
|
737
640
|
### receiver's current objectClasses. Does not include operational attributes.
|
738
|
-
###
|
739
|
-
### @param [String, Symbol] the OID (numeric or name) of the attribute in question
|
740
|
-
### @return [Boolean]
|
741
641
|
def valid_attribute?( attroid )
|
742
642
|
return !self.valid_attribute_type( attroid ).nil?
|
743
643
|
end
|
@@ -746,9 +646,6 @@ class Treequel::Branch
|
|
746
646
|
### Return a Hash of all the attributes allowed by the Branch's objectClasses. If
|
747
647
|
### any +additional_object_classes+ are given, include the attributes that would be
|
748
648
|
### available for the entry if it had them.
|
749
|
-
###
|
750
|
-
### @param [Array<String, Symbol>] additional_object_classes
|
751
|
-
### @return [Hash<String => String>]
|
752
649
|
def valid_attributes_hash( *additional_object_classes )
|
753
650
|
self.log.debug "Gathering a hash of all valid attributes:"
|
754
651
|
must = self.must_attributes_hash( *additional_object_classes )
|
@@ -766,7 +663,6 @@ class Treequel::Branch
|
|
766
663
|
|
767
664
|
### Proxy method: call #traverse_branch if +attribute+ is a valid attribute
|
768
665
|
### and +value+ isn't +nil+.
|
769
|
-
### @see Treequel::Branch#traverse_branch
|
770
666
|
def method_missing( attribute, value=nil, additional_attributes={} )
|
771
667
|
return super( attribute ) if value.nil?
|
772
668
|
return self.traverse_branch( attribute, value, additional_attributes )
|
@@ -774,23 +670,18 @@ class Treequel::Branch
|
|
774
670
|
|
775
671
|
|
776
672
|
### If +attribute+ matches a valid attribute type in the directory's
|
777
|
-
### schema, return a new Branch for the RDN of +attribute+ and +value
|
778
|
-
### +additional_attributes+ if it's a multi-value RDN.
|
673
|
+
### schema, return a new Branch for the RDN of +attribute+ and +value+ and
|
674
|
+
### +additional_attributes+ (if it's a multi-value RDN).
|
779
675
|
###
|
780
|
-
###
|
781
|
-
###
|
782
|
-
###
|
783
|
-
###
|
784
|
-
###
|
785
|
-
###
|
786
|
-
###
|
787
|
-
###
|
788
|
-
###
|
789
|
-
### # => 'uid=chester+employeeType=admin,ou=people,dc=acme,dc=com'
|
790
|
-
###
|
791
|
-
### @return [Treequel::Branch] the Branch for the specified child
|
792
|
-
### @raise [NoMethodError] if the +attribute+ or any +additional_attributes+ are
|
793
|
-
### not valid attributeTypes.
|
676
|
+
### # (Called via #method_missing)
|
677
|
+
### branch = Treequel::Branch.new( directory, 'ou=people,dc=acme,dc=com' )
|
678
|
+
### branch.uid( :chester ).dn
|
679
|
+
### # => 'uid=chester,ou=people,dc=acme,dc=com'
|
680
|
+
### branch.uid( :chester, :employeeType => 'admin' ).dn
|
681
|
+
### # => 'uid=chester+employeeType=admin,ou=people,dc=acme,dc=com'
|
682
|
+
###
|
683
|
+
### Raises a NoMethodError if the +attribute+ or any +additional_attributes+ are
|
684
|
+
### not valid attributeTypes.
|
794
685
|
def traverse_branch( attribute, value, additional_attributes={} )
|
795
686
|
valid_types = self.directory.schema.attribute_types
|
796
687
|
|
@@ -854,8 +745,8 @@ class Treequel::Branch
|
|
854
745
|
### and return it.
|
855
746
|
def get_converted_attribute( attrsym, object )
|
856
747
|
if attribute = self.directory.schema.attribute_types[ attrsym ]
|
857
|
-
self.log.debug "converting %p object (a %p) to a %
|
858
|
-
[ attrsym, object.class, attribute.
|
748
|
+
self.log.debug "converting %p object (a %p) to a %s attribute" %
|
749
|
+
[ attrsym, object.class, attribute.syntax.desc ]
|
859
750
|
return self.directory.convert_to_attribute( attribute.syntax_oid, object )
|
860
751
|
else
|
861
752
|
self.log.info "no attributeType for %p" % [ attrsym ]
|
@@ -865,7 +756,6 @@ class Treequel::Branch
|
|
865
756
|
|
866
757
|
|
867
758
|
### Clear any cached values when the structural state of the object changes.
|
868
|
-
### @return [void]
|
869
759
|
def clear_caches
|
870
760
|
self.log.debug "Clearing entry and values caches."
|
871
761
|
@entry = nil
|
@@ -914,10 +804,6 @@ class Treequel::Branch
|
|
914
804
|
|
915
805
|
### Make LDIF for the given +attribute+ and its +values+, wrapping at the given
|
916
806
|
### +width+.
|
917
|
-
###
|
918
|
-
### @param [String] attribute the attribute
|
919
|
-
### @param [Array<String>] values the values for the given +attribute+
|
920
|
-
### @param [Fixnum] width the maximum width of the lines to return
|
921
807
|
def ldif_for_attr( attribute, value, width )
|
922
808
|
unsplit_line = "#{attribute}:"
|
923
809
|
|
@@ -44,7 +44,6 @@ class Treequel::BranchCollection
|
|
44
44
|
### Create a delegator that will return an instance of the receiver
|
45
45
|
### created with the results of iterating over the branchsets and calling
|
46
46
|
### the delegated method.
|
47
|
-
### @param [Array<Symbol>] symbols The methods to define
|
48
47
|
def self::def_cloning_delegators( *symbols )
|
49
48
|
symbols.each do |methname|
|
50
49
|
# Create the method body
|
@@ -72,9 +71,8 @@ class Treequel::BranchCollection
|
|
72
71
|
### I N S T A N C E M E T H O D S
|
73
72
|
#################################################################
|
74
73
|
|
75
|
-
### Create a new Treequel::BranchCollection that will operate on the given +branchsets
|
76
|
-
###
|
77
|
-
### combined in the BranchCollection.
|
74
|
+
### Create a new Treequel::BranchCollection that will operate on the given +branchsets+, which
|
75
|
+
### can be either Treequel::Branchset or Treequel::Branch objects.
|
78
76
|
def initialize( *branchsets )
|
79
77
|
@branchsets = branchsets.flatten.collect do |obj|
|
80
78
|
if obj.respond_to?( :each )
|
@@ -86,12 +84,16 @@ class Treequel::BranchCollection
|
|
86
84
|
end
|
87
85
|
|
88
86
|
|
89
|
-
|
90
|
-
|
87
|
+
##
|
88
|
+
# Delegator methods that clone the receiver with the results of mapping
|
89
|
+
# the branchsets with the delegated method.
|
90
|
+
|
91
91
|
def_cloning_delegators :filter, :scope, :select, :select_all, :select_more, :timeout,
|
92
92
|
:without_timeout
|
93
93
|
|
94
|
-
|
94
|
+
##
|
95
|
+
# Delegators that some methods through the collection directly
|
96
|
+
|
95
97
|
def_method_delegators :branchsets, :include?
|
96
98
|
|
97
99
|
|
@@ -107,7 +109,6 @@ class Treequel::BranchCollection
|
|
107
109
|
|
108
110
|
|
109
111
|
### Return a human-readable string representation of the object suitable for debugging.
|
110
|
-
### @return [String]
|
111
112
|
def inspect
|
112
113
|
"#<%s:0x%0x %d branchsets: %p>" % [
|
113
114
|
self.class.name,
|
@@ -120,7 +121,6 @@ class Treequel::BranchCollection
|
|
120
121
|
|
121
122
|
### Iterate over the Treequel::Branches found by each member branchset, yielding each
|
122
123
|
### one in turn.
|
123
|
-
### @yield [Treequel::Branch]
|
124
124
|
def each( &block )
|
125
125
|
raise LocalJumpError, "no block given" unless block
|
126
126
|
self.branchsets.each do |bs|
|
@@ -130,7 +130,6 @@ class Treequel::BranchCollection
|
|
130
130
|
|
131
131
|
|
132
132
|
### Return the first Treequel::Branch that is returned from the collection's branchsets.
|
133
|
-
### @return [Treequel::Branch]
|
134
133
|
def first
|
135
134
|
branch = nil
|
136
135
|
|
@@ -143,14 +142,12 @@ class Treequel::BranchCollection
|
|
143
142
|
|
144
143
|
|
145
144
|
### Return +true+ if none of the collection's branches match any entries.
|
146
|
-
### @return [Boolean]
|
147
145
|
def empty?
|
148
146
|
return self.branchsets.all? {|bs| bs.empty? } ? true : false
|
149
147
|
end
|
150
148
|
|
151
149
|
|
152
150
|
### Overridden to support Branchset#map
|
153
|
-
### @param (see Treequel::Branchset#map)
|
154
151
|
def map( attribute=nil, &block )
|
155
152
|
if attribute
|
156
153
|
if block
|
@@ -181,7 +178,6 @@ class Treequel::BranchCollection
|
|
181
178
|
### Return either a new Treequel::BranchCollection that includes both the receiver's
|
182
179
|
### Branchsets and those in +other_object+ (if it responds_to #branchsets), or the results
|
183
180
|
### from executing the BranchCollection's search with +other_object+ appended if it doesn't.
|
184
|
-
### @param [Object] other_object
|
185
181
|
def +( other_object )
|
186
182
|
if other_object.respond_to?( :branchsets )
|
187
183
|
return self.class.new( self.branchsets + other_object.branchsets )
|
@@ -193,9 +189,8 @@ class Treequel::BranchCollection
|
|
193
189
|
end
|
194
190
|
|
195
191
|
|
196
|
-
### Return the results from each of the receiver's Branchsets without the +other_object
|
197
|
-
###
|
198
|
-
### @return [Array<Treequel::Branch>]
|
192
|
+
### Return the results from each of the receiver's Branchsets without the +other_object+,
|
193
|
+
### which must respond to #dn.
|
199
194
|
def -( other_object )
|
200
195
|
other_dn = other_object.dn
|
201
196
|
return self.reject {|branch| branch.dn == other_dn }
|