def write
@@logger.debug("stub: write called")
validate
entry = []
@@logger.debug("#write: dup'ing @ldap_data")
ldap_data = @ldap_data.dup
@@logger.debug("#write: dup finished @ldap_data")
@@logger.debug("#write: expanding subtypes in @ldap_data")
ldap_data.keys.each do |key|
ldap_data[key].each do |value|
if value.class == Hash
suffix, real_value = extract_subtypes(value)
if ldap_data.has_key? key + suffix
ldap_data[key + suffix].push(real_value)
else
ldap_data[key + suffix] = real_value
end
ldap_data[key].delete(value)
end
end
end
@@logger.debug("#write: subtypes expanded for @ldap_data")
@@logger.debug("#write: dup'ing @data")
data = @data.dup
@@logger.debug("#write: finished dup'ing @data")
@@logger.debug("#write: expanding subtypes for @data")
data.keys.each do |key|
data[key].each do |value|
if value.class == Hash
suffix, real_value = extract_subtypes(value)
if data.has_key? key + suffix
data[key + suffix].push(real_value)
else
data[key + suffix] = real_value
end
data[key].delete(value)
end
end
end
@@logger.debug("#write: subtypes expanded for @data")
if @exists
action = {}
replaceable = []
@@logger.debug("#write: traversing ldap_data determining replaces and deletes")
ldap_data.each do |pair|
suffix = ''
binary = 0
name, *suffix_a = pair[0].split(/;/)
suffix = ';'+ suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil?
value = data[name+suffix]
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
replaceable.push(name+suffix)
if pair[1] != value
if not value.empty?
@@logger.debug("updating attribute of existing entry: #{name+suffix}: #{value.inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, value))
else
@@logger.debug("removing attribute from existing entry: #{name+suffix}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, []))
end
end
end
@@logger.debug("#write: finished traversing ldap_data")
@@logger.debug("#write: traversing data determining adds")
data.each do |pair|
suffix = ''
binary = 0
name, *suffix_a = pair[0].split(/;/)
suffix = ';' + suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil?
value = pair[1]
if not replaceable.member? name+suffix
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
@@logger.debug("adding attribute to existing entry: #{name+suffix}: #{value.inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, value)) unless value.empty?
end
end
@@logger.debug("#write: traversing data complete")
begin
@@logger.debug("#write: modifying #{@dn}")
@@conn.modify(@dn, entry)
@@logger.debug("#write: modify successful")
rescue => detail
raise WriteError, "Could not update LDAP entry: #{detail}"
end
else
@@logger.debug("#write: adding all attribute value pairs")
@@logger.debug("#write: adding #{@attr_methods[dnattr()].inspect} = #{data[@attr_methods[dnattr()]].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD, @attr_methods[dnattr()],
data[@attr_methods[dnattr()]]))
@@logger.debug("#write: adding objectClass = #{data[@attr_methods['objectClass']].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD, 'objectClass',
data[@attr_methods['objectClass']]))
data.each do |pair|
if pair[1].size > 0 and pair[0] != 'objectClass' and pair[0] != @attr_methods[dnattr()]
if Base.schema.binary? pair[0].split(/;/)[0]
binary = LDAP::LDAP_MOD_BVALUES
else
binary = 0
end
@@logger.debug("adding attribute to new entry: #{pair[0].inspect}: #{pair[1].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD|binary, pair[0], pair[1]))
end
end
begin
@@logger.debug("#write: adding #{@dn}")
@@conn.add(@dn, entry)
@@logger.debug("#write: add successful")
@exists = true
rescue LDAP::ResultError => detail
raise WriteError, "Could not add LDAP entry[#{Base.connection.err2string(Base.connection.err)}]: #{detail}"
end
end
@@logger.debug("#write: resetting @ldap_data to a dup of @data")
@ldap_data = @data.dup
@@logger.debug("#write: @ldap_data reset complete")
@@logger.debug("stub: write exitted")
end