Announcement Announcement Module
Collapse
No announcement yet.
Modification of multivalue attribute Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Modification of multivalue attribute

    Hi there

    If I try to modify an entry with more than one attribute, the ModificationItem Array which I get from my DirContextAdapter has two entries.
    The first tries to add my value.
    The second tries to delete it.

    Logicaly the frist operation leads to an exception. The order of the two operations is wrong.

    I allready did a workaround, which changes the ModificationItem-Array if the frist entry is a add-operation. But anyway, it just a workaround. I wonder if I'm doing anything wrong. I have a strange feeling by modifying values which I get by Spring-Ldap and which are reused by itself agian. If I really need to change this, then I'm probably doing something wrong.

    Any tipps are appreciated

    Here is my code: (just the important stuff)

    Code:
    public class RoleDaoImpl extends BaseDaoLdap implements RoleDao {
    
        protected void mapToContext(Role role, DirContextAdapter context) {
    
            Set<String> users = role.getUsers();
            Iterator<String> it = users.iterator();
            String[] members = new String[users.size()];
    
            for (int i = 0; i < users.size(); i++) {
                members[i] = "uid=" + it.next();
            }
            context.setAttributeValues("member", members, true);
        }
    
      private void save(Role role) throws Exception {
            if (findById(role.getId()) != null) {
                // this entry allready exists. update!
                Name dn = buildDn(role.getId());
                DirContextAdapter context = lookup(dn);
                mapToContext(role, context);
                /*
                 * the modificationitem seems to be in the wrong order. it first
                 * tries to add the member attribute and delete it afterwards. check
                 * if the first item is an add, if so, regroup the array
                 */
                ModificationItem mis[] = context.getModificationItems();
    
                if (mis.length > 1) {
                    if (mis[0].getModificationOp() == DirContext.ADD_ATTRIBUTE) {
                        // reverse order
                        ModificationItem mi0 = mis[0];
                        ModificationItem mi1 = mis[1];
                        mis[0] = mi1;
                        mis[1] = mi0;
                    }
                }
    
                modifyAttributes(dn, mis);
            } else {
                // this entry seems to be inexistent create
                DirContextAdapter context = new DirContextAdapter();
                mapToContext(role, context);
                bind(buildDn(role.getId()), context);
            }
    }
    
    public abstract class BaseDaoLdap {
    
        private LdapTemplate ldapTemplate;
    
        public DirContextAdapter lookup(Name dn) {
            return (DirContextAdapter) ldapTemplate.lookup(dn);
        }
    }

  • #2
    I actually think that this is more complicated than what seems to be the case at a first glance. We've seen similar problems before and they are generally caused by problems in comparing the attribute values.

    My guess is that there is a type or format mismatch somewhere in here. Consider e.g. the following:
    The Attribute contains the values (before modification):
    "uid = some.person"
    "uid=some.other.person"

    Now, consider that you set the values to:
    "uid=some.person"
    "uid=some.other.person"

    Note that there is a difference in the format in the first Attribute value - this format difference is syntactically insignificant (as they represent DNs), but textually significant (the two strings are not equal).

    Logically, this will cause DirContextAdapter to assume that it should add the new value ("uid=some.person") and remove the old value ("uid = some.person"), which will of course fail when trying to add the first value (on some servers, not all).

    While doing the remove operation first will present a workaround it will not solve the actual problem, which is that the Attribute value really didn't change (syntactically, that is).

    We do have a Jira issue on this problem and are contemplating a generic solution to syntactically comparing Attribute values. We haven't come up with a good solution yet, but the more I think about it the more I like your workaround. It's much simpler and it will solve the problem quite nicely.

    I'll see if we might be able to at least fit this in as a quick fix into the 1.2-RC1 release which is due any week now.

    Comment


    • #3
      What if I wanted to append a value and not just replace it. I badly need to Append to it and not replace. Cant think of a way to do that !!!

      Any tips would be appreciated!!

      Thanks,
      Franklin

      Comment


      • #4
        No problem. In Spring LDAP 1.2-RC1 (final release is just days away now) there is an addAttributeValue() method in DirContextAdapter which takes care of this for you.

        Comment


        • #5
          Wow. That is good news!!! Hope I made my self clear. However this is what I was looking at.

          When I call context.getModificationItems() I get a list of Add and Remove attributes. What if I wanted to merge both of them and put this as the new value. Why isn't that possible? Or is that what will be there in the new release?


          Thanks,
          Franklin.

          Comment


          • #6
            Sorry, you lost me. getModificationItems returns all modifications done to all Attributes since the entry was read from the database.

            I understood your situation as there being a number of attribute values already (e.g. a number of members in a group), and you just want to add a new entry. That case would be coded as follows:
            Code:
              DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(entryDn);
              ctx.addAttributeValue("attributeName", newValue);
              // More modifications here if applicable
              ldapTemplate.modifyAttributes(entryDn, ctx.getModificationItems());
            If this is not what you're looking for, please clarify.

            Comment


            • #7
              getModificationItems returns all modifications done to all Attributes since the entry was read from the database. Very Clear!!!

              However when I do ldapTemplate.modifyAttributes it removes the OLD value and ADDs the new value. What I need it that it appends the NEW value to the end of the OLD value.


              An example would be, what I am facing now, in the Oracle Internet Directory, I need to modify and attribute called "uniquemember" which is an attribute of a Group. I basically keeps a list of all the users in the group. If I modify this attribute using ldapTemplate.modifyAttributes it will replace all the other entries which is not what I want. I would want it to append to the list.

              Hope this is clear enough and thank you for your support.

              Waiting for a positive response

              Thanks,
              Franklin

              Comment


              • #8
                Yes, this is exactly what addAttributeValue does. It will inspect the current attribute values and append the specified one if it not present. getModificationItems will then return an ADD item with the entry (or entries) you added. Your code will be very similar to the one in my previous post.

                Comment


                • #9
                  Thanks bro!!
                  I will have a look at it soon and as you put it out.


                  Thanks a million!!
                  Franklin.

                  Comment


                  • #10
                    The RC1 is already out there, so you can try it out right away. The 1.2 final release is still a couple of days away though.

                    Comment


                    • #11
                      Does RC1 support add??

                      Comment


                      • #12
                        Yes it does. Sorry if I was unclear in my initial post.
                        http://static.springframework.org/sp...va.lang.Object)

                        Comment

                        Working...
                        X