Problem when moving an entry to another group

I am having a problem when moving an entry from one group to another group. I implemented the move feature like this:

rosterGroupNew.addEntry(entry);

rosterGroupOld.removeEntry(entry);

The roster is updated but the subscription of that entry is “none” instead of the original status.

Is it the expected behavior? Does that mean when an entry is moved from one group to another we will need to send a subscribe event again? Is there a way to subscibe an entry without explictly sending an presence packet?

Also, is there a way to add an entry to the “unfiled” category?

Thanks in advance Smack API is great!

Peter,

I am having a problem when moving an entry from one group to another group. I implemented the move feature like this:

rosterGroupNew.addEntry(entry);

rosterGroupOld.removeEntry(entry);

The roster is updated but the subscription of that entry is “none” instead of the original status.

I tried your code in a test case and couldn’'t reproduce the problem.

// Add a new roster entry
    conn1.getRoster().createEntry("gato11@" + conn1.getHost(), "gato11", new String[] {"Friends", "Family"});
    conn1.getRoster().createEntry("gato12@" + conn1.getHost(), "gato12", new String[] {"Family"});     Thread.sleep(200);     RosterGroup friendsGroup = conn1.getRoster().getGroup("Friends");
    RosterGroup familyGroup = conn1.getRoster().getGroup("Family");
        RosterEntry entryToMove = familyGroup.getEntry("gato12@" + conn1.getHost());
        String subscriptionType = entryToMove.getType().toString();
        friendsGroup.addEntry(entryToMove);
    familyGroup.removeEntry(entryToMove);     assertEquals("Subscription Type of the moved entry is wrong", subscriptionType, entryToMove.getType().toString());

In my test case the moved entry maintains its subscription status. Where are you checking for the subscription status? Are you doing the same check that the test case does?. It would be great if you can give me a test case so I can reproduce your case.

Also, is there a way to add an entry to the “unfiled” category

To add a new entry that won’'t belong to a group just send #createEntry to Roster and pass null to the last parameter that is the list of groups for the new entry.

Regards,

– Gato

Gato,

To add a new entry that won’'t belong to a group just

send #createEntry to Roster and pass null to the last

parameter that is the list of groups for the new

entry.

One alternative to this is that we could make it so that if an entry belongs to one group and you remove it from that group, it’‘s now an unfiled entry. In other words, you’'d always have to use Roster.removeEntry to truly get rid of an entry. What do you think?

-Matt

Matt,

If I’'m not wrong this is the actual behavior with the last changes that we made into 1.2.1.

Regards,

– Gato

Sorry my order was reversed

I actually called

rosterGroupOld.removeEntry(entry);

rosterGroupNew.addEntry(entry);

Does that make any difference? I know I shouldn’'t

do this because if the connection is interrupted

between the calls than the entry might be loss forever,

but I couldn’'t find a way to move a contact from the

unfiled catregory to a new group. Here is why:

I couldn’'t do the move like this, since there is

no group for the unfiled contacts:

rosterGroupNew.addEntry(entry);

rosterGroupOld.removeEntry(entry);

I have to call them like this:

rosterGroupNew.addEntry(entry);

roster.removeEnrty(entry);

But I am afraid that roster.removeEntry will remove

the entry I just added, so I reversed the

order to be:

roster.removeEnrty(entry);

rosterGroupNew.addEntry(entry);

So does roster.removeEntry() remove the entry or just

remove the entry from “unfiled”? The javadocs didn’'t specified the behavior so I thought I should play it

safe. I will try to reverse the order tonight and test it

again.

To add a new entry that won’'t belong to a group just

send #createEntry to Roster and pass null to the last

parameter that is the list of groups for the new

entry.

I didn’‘t do that because I don’'t want to ask for

subscription from the other user again. Perhaps another

subscription won’'t matter since the entry was already

subscripted? I don’'t want the server to send another

subscription event to the contact.

Where are you checking for the

subscription status?

I checked the status from the roster packet from the server.

All the entries I moved doesn’'t get a presence from the server anymore, so I checked the roster packet and found out that their subscription status are changed to “none”, while

the unmoved contacts have “both”.

Peter,

Sorry my order was reversed

I actually called

rosterGroupOld.removeEntry(entry);

rosterGroupNew.addEntry(entry);

Does that make any difference? I know I shouldn’'t

do this because if the connection is interrupted

between the calls than the entry might be loss forever,

When you send #removeEntry to a RosterGroup the effect that you get is that the entry is removed from the group. If the entry does not belong to any other group then it will be considered as unfiled.

The inverse thing happens when you send #addEntry to a RosterGroup. If the entry was unfiled then it will be removed from the unfiled list and will be added to the group.

This means that you can never loose the entries while moving them between groups even if the connection gets lost in the middle of the operation. That entry will always be part of your roster. The only way to remove an entry from the roster (and from any group) is by sending #removeEntry to the Roster (we need to make it clearer in the javadoc) :). This also means that the add and remove order doesn’'t really matter.

but I couldn’'t find a way to move a contact from the

unfiled category to a new group

To move a contact from the unfiled category all you have to do is add it to a group. Smack will automatically remove the entry from the unfiled list.

To add a new entry that won’'t belong to a group just

send #createEntry to Roster and pass null to the last

parameter that is the list of groups for the new

entry.

I didn’‘t do that because I don’'t want to ask for

subscription from the other user again. Perhaps another

subscription won’'t matter since the entry was already

subscripted? I don’'t want the server to send another

subscription event to the contact.

If you already have an entry in your roster and you want to move it to the unfiled category all you have to do is remove the entry from all the groups where it belongs. Smack will detect that the entry does no longer belong to any group and will add it to the unfiled category.

Adding o removing an entry from a group does not send any subscription to the contact. The only message that will Smack send is to the server in order to update your roster configuration.

Where are you checking for the

subscription status?

I checked the status from the roster packet from the >server.

All the entries I moved doesn’'t get a presence from the >server anymore

That´s ok. Since you didn’'t modify your subscription. You have just modified your roster configuration.

so I checked the roster packet and found out that their subscription status are changed to “none”, while the unmoved contacts have “both”.

How are you getting the RosterEntries that you inspect? If I inspect the connection → roster → entries and I go over each RosterEntry I see that all the RosterEntries maintain their types (RosterPacket$ItemType).

Could you put a breakpoint in RosterEntry>>updateState and detect who is changing the type to none?

Regards,

– Gato

Thanks for the clarifying the use of removeEntry and addEntry. I was using them incorrectly, and after I fixed my code the problem seems be solved.

I believe the use of roster.removeEntry() is the cause of the subscription problem. Previously when I tried to move a contact from unfiled to a group, I called roster.removeEntry(entry) and then rosterGroup.addEntry(entry). I am guessing that the first call remove the entry from the list (from the server as well), and then the 2nd call add the entry back (which create a new entry with no subscription) but no subscription packet is sent afterward (which make sense since subscription status shouldn’'t be changed).

Now I never call roster.removeEntry unless I want to remove a contact for the roster, and everything seems to work fine.

Once again thanks for the quick reply and support.