ImpsChatGroupManager.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:17k
源码类别:

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007 Esmertec AG.
  3.  * Copyright (C) 2007 The Android Open Source Project
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package com.android.im.imps;
  18. import java.util.ArrayList;
  19. import com.android.im.engine.Address;
  20. import com.android.im.engine.ChatGroup;
  21. import com.android.im.engine.ChatGroupManager;
  22. import com.android.im.engine.Contact;
  23. import com.android.im.engine.GroupListener;
  24. import com.android.im.engine.GroupMemberListener;
  25. import com.android.im.engine.Invitation;
  26. /**
  27.  * The implementation of ChatGroupManager with IMPS protocol.
  28.  */
  29. public class ImpsChatGroupManager extends ChatGroupManager implements
  30.         ServerTransactionListener {
  31.     private ImpsConnection mConnection;
  32.     private ImpsTransactionManager mTransactionManager;
  33.     ImpsChatGroupManager(ImpsConnection connection) {
  34.         mConnection = connection;
  35.         mTransactionManager = connection.getTransactionManager();
  36.         mTransactionManager.setTransactionListener(ImpsTags.GroupChangeNotice, this);
  37.         mTransactionManager.setTransactionListener(ImpsTags.LeaveGroup_Response, this);
  38.         mTransactionManager.setTransactionListener(ImpsTags.InviteUser_Request, this);
  39.         mTransactionManager.setTransactionListener(ImpsTags.Invite_Response, this);
  40.     }
  41.     @Override
  42.     protected void addGroupMemberAsync(final ChatGroup group, final Contact contact){
  43.         Primitive request = buildAddGroupMemberRequest(group, contact);
  44.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  45.             @Override
  46.             public void onResponseError(ImpsErrorInfo error) {
  47.                 notifyGroupMemberError(group, error);
  48.             }
  49.             @Override
  50.             public void onResponseOk(Primitive response) {
  51.                 notifyMemberJoined(group, contact);
  52.             }
  53.         };
  54.         tx.sendRequest(request);
  55.     }
  56.     @Override
  57.     public void createChatGroupAsync(final String name) {
  58.         final ImpsAddress loginUserAddress = mConnection.getSession()
  59.                 .getLoginUserAddress();
  60.         final ImpsAddress groupAddress = new ImpsGroupAddress(loginUserAddress, name);
  61.         Primitive primitive = buildCreateGroupRequest(name, groupAddress);
  62.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  63.             @Override
  64.             public void onResponseError(ImpsErrorInfo error) {
  65.                 notifyGroupError(GroupListener.ERROR_CREATING_GROUP, name, error);
  66.             }
  67.             @Override
  68.             public void onResponseOk(Primitive response) {
  69.                 // The current user is joined into the group automatically.
  70.                 ArrayList<Contact> members = new ArrayList<Contact>();
  71.                 members.add(new Contact(loginUserAddress, loginUserAddress
  72.                         .getUser()));
  73.                 ChatGroup group = new ChatGroup(groupAddress, name, members,
  74.                         ImpsChatGroupManager.this);
  75.                 notifyGroupCreated(group);
  76.             }
  77.         };
  78.         tx.sendRequest(primitive);
  79.     }
  80.     @Override
  81.     public void deleteChatGroupAsync(final ChatGroup group) {
  82.         Primitive request = new Primitive(ImpsTags.DeleteGroup_Request);
  83.         request.addElement(ImpsTags.GroupID, group.getAddress().getFullName());
  84.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  85.             @Override
  86.             public void onResponseError(ImpsErrorInfo error) {
  87.                 notifyGroupError(GroupListener.ERROR_DELETING_GROUP,
  88.                     group.getName(), error);
  89.             }
  90.             @Override
  91.             public void onResponseOk(Primitive response) {
  92.                 notifyGroupDeleted(group);
  93.             }
  94.         };
  95.         tx.sendRequest(request);
  96.     }
  97.     @Override
  98.     public void inviteUserAsync(final ChatGroup group, Contact contact) {
  99.         Primitive request = buildInviteUserRequest(group, contact);
  100.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager){
  101.             @Override
  102.             public void onResponseError(ImpsErrorInfo error) {
  103.                 notifyGroupMemberError(group, error);
  104.             }
  105.             @Override
  106.             public void onResponseOk(Primitive response) {
  107.                 //Do nothing
  108.             }
  109.         };
  110.         tx.sendRequest(request);
  111.     }
  112.     @Override
  113.     public void acceptInvitationAsync(Invitation invitation){
  114.         joinChatGroupAsync(invitation.getGroupAddress());
  115.         sendInvitationResposne(invitation, true);
  116.     }
  117.     @Override
  118.     public void rejectInvitationAsync(Invitation invitation) {
  119.         sendInvitationResposne(invitation, false);
  120.     }
  121.     private void sendInvitationResposne(Invitation invitation, boolean accept) {
  122.         Primitive response = new Primitive(ImpsTags.InviteUser_Response);
  123.         response.addElement(ImpsTags.InviteID, invitation.getInviteID());
  124.         response.addElement(ImpsTags.Acceptance, ImpsUtils.toImpsBool(accept));
  125.         ImpsAddress sender = (ImpsAddress) invitation.getSender();
  126.         response.addElement(sender.toPrimitiveElement());
  127.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager){
  128.             @Override
  129.             public void onResponseError(ImpsErrorInfo error) {
  130.                 // Ignore
  131.             }
  132.             @Override
  133.             public void onResponseOk(Primitive res) {
  134.                 // Ignore
  135.             }
  136.         };
  137.         tx.sendRequest(response);
  138.     }
  139.     @Override
  140.     public void joinChatGroupAsync(final Address address) {
  141.         Primitive request = buildJoinGroupRequest(address);
  142.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  143.             @Override
  144.             public void onResponseError(ImpsErrorInfo error) {
  145.                 notifyGroupError(GroupListener.ERROR_JOINING_IN_GROUP,
  146.                     address.getScreenName(), error);
  147.             }
  148.             @Override
  149.             public void onResponseOk(Primitive response) {
  150.                 ArrayList<Contact> members = new ArrayList<Contact>();
  151.                 // FIXME: UserMapList is a child of Joined in version 1.3
  152.                 PrimitiveElement userMapping = response
  153.                         .getElement(ImpsTags.UserMapList);
  154.                 extractUserMapList(userMapping, members);
  155.                 ChatGroup group = new ChatGroup(address, address
  156.                         .getScreenName(), members, ImpsChatGroupManager.this);
  157.                 notifyJoinedGroup(group);
  158.             }
  159.         };
  160.         tx.sendRequest(request);
  161.     }
  162.     @Override
  163.     public void leaveChatGroupAsync(final ChatGroup group) {
  164.         Primitive leaveRequest = buildLeaveGroupRequest(group);
  165.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  166.             @Override
  167.             public void onResponseError(ImpsErrorInfo error) {
  168.                 notifyGroupError(GroupListener.ERROR_LEAVING_GROUP,
  169.                     group.getName(), error);
  170.             }
  171.             @Override
  172.             public void onResponseOk(Primitive response) {
  173.                 notifyLeftGroup(group);
  174.             }
  175.         };
  176.         tx.sendRequest(leaveRequest);
  177.     }
  178.     @Override
  179.     protected void removeGroupMemberAsync(final ChatGroup group, final Contact contact) {
  180.         Primitive request = buildRemoveGroupMemberRequest(group, contact);
  181.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  182.             @Override
  183.             public void onResponseError(ImpsErrorInfo error) {
  184.                 notifyGroupMemberError(group, error);
  185.             }
  186.             @Override
  187.             public void onResponseOk(Primitive response) {
  188.                 notifyMemberLeft(group, contact);
  189.             }
  190.         };
  191.         tx.sendRequest(request);
  192.     }
  193.     /**
  194.      * Loads the members of a ChatGroup asynchronously. This method will create
  195.      * a ChatGroup and return immediately. After the members are fetched from
  196.      * the server,
  197.      * {@link GroupMemberListener#onMemberJoined(ChatGroup, Contact)}} will be
  198.      * called.
  199.      *
  200.      * @param address
  201.      */
  202.     ChatGroup loadGroupMembersAsync(ImpsGroupAddress address) {
  203.         //FIXME: NowIMP Server doesn't support this primitive.
  204. //        Primitive request = new Primitive(ImpsTags.GetJoinedUsers_Request);
  205. //        request.addElement(ImpsTags.GroupID, address.getFullName());
  206. //        Primitive response = mConnection.sendRequest(request);
  207. //        ImpsUtils.checkResult(response);
  208. //
  209. //        ChatGroup group = new ChatGroup(address, address.getScreenName(), this);
  210.         throw new RuntimeException("Not implemented yet");
  211.     }
  212.     public void notifyServerTransaction(ServerTransaction tx) {
  213.         final Primitive primitive = tx.getRequest();
  214.         String type = primitive.getType();
  215.         if (ImpsTags.GroupChangeNotice.equals(type)) {
  216.             tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
  217.             handleGroupChange(primitive);
  218.         } else if (ImpsTags.InviteUser_Request.equals(type)) {
  219.             tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
  220.             String inviteType = primitive.getElementContents(ImpsTags.InviteType);
  221.             // We only handle Group invitation right now.
  222.             if (ImpsConstants.GROUP_INVITATION.equals(inviteType)) {
  223.                 handleInvitation(primitive);
  224.             }
  225.         } else if (ImpsTags.LeaveGroup_Response.equals(type)) {
  226.             tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
  227.             String groupId = primitive.getElementContents(ImpsTags.GroupID);
  228.             ChatGroup group = mGroups.get(new ImpsGroupAddress(groupId));
  229.             if(group != null) {
  230.                 notifyLeftGroup(group);
  231.             } else {
  232.                 ImpsLog.log("Leave unknown group:" + groupId);
  233.             }
  234.         } else if (ImpsTags.Invite_Response.equals(type)) {
  235.             tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
  236.             //TODO: notify the user?
  237.         }
  238.     }
  239.     void handleGroupChange(final Primitive primitive) {
  240.         String groupId = primitive.getElementContents(ImpsTags.GroupID);
  241.         ImpsGroupAddress address = new ImpsGroupAddress(groupId);
  242.         ArrayList<Contact> joined = new ArrayList<Contact>();
  243.         PrimitiveElement joinedElem = primitive.getElement(ImpsTags.Joined);
  244.         if (joinedElem != null) {
  245.             extractUserMapList(joinedElem.getFirstChild(), joined);
  246.         }
  247.         ArrayList<Contact> left = new ArrayList<Contact>();
  248.         PrimitiveElement leftElem = primitive.getElement(ImpsTags.Left);
  249.         if (leftElem != null) {
  250.             extractUserMapList(leftElem.getFirstChild(), left);
  251.         }
  252.         notifyGroupChanged(address, joined, left);
  253.     }
  254.     void handleInvitation(final Primitive primitive) {
  255.         String inviteId = primitive.getElementContents(ImpsTags.InviteID);
  256.         PrimitiveElement sender = primitive.getElement(ImpsTags.Sender);
  257.         ImpsAddress senderAddress = ImpsAddress.fromPrimitiveElement(sender
  258.                 .getFirstChild());
  259.         String groupId = primitive.getElementContents(ImpsTags.GroupID);
  260.         Address groupAddress = new ImpsGroupAddress(groupId);
  261.         String inviteNote = primitive.getElementContents(ImpsTags.InviteNote);
  262.         Invitation invitation = new Invitation(inviteId, groupAddress,
  263.                 senderAddress, inviteNote);
  264.         notifyGroupInvitation(invitation);
  265.     }
  266.     private Primitive buildAddGroupMemberRequest(final ChatGroup group, final Contact contact) {
  267.         Primitive request = new Primitive(ImpsTags.AddGroupMembers_Request);
  268.         request.addElement(ImpsTags.GroupID, group.getAddress().getFullName());
  269.         // FIXME: It's UserIDList in 1.3
  270.         PrimitiveElement userList = request.addElement(ImpsTags.UserList);
  271.         PrimitiveElement user = userList.addChild(ImpsTags.User);
  272.         user.addChild(ImpsTags.UserID, contact.getAddress().getFullName());
  273.         return request;
  274.     }
  275.     private Primitive buildCreateGroupRequest(String name, ImpsAddress groupAddress) {
  276.         Primitive primitive = new Primitive(ImpsTags.CreateGroup_Request);
  277.         primitive.addElement(ImpsTags.GroupID, groupAddress.getFullName());
  278.         PrimitiveElement propertiesElem = primitive.addElement(ImpsTags.GroupProperties);
  279.         propertiesElem.addPropertyChild(ImpsTags.Name, name);
  280.         propertiesElem.addPropertyChild(ImpsTags.Accesstype, ImpsConstants.Open);
  281.         propertiesElem.addPropertyChild(ImpsTags.PrivateMessaging, false);
  282.         propertiesElem.addPropertyChild(ImpsTags.Searchable, false);
  283.         propertiesElem.addPropertyChild(ImpsTags.AutoDelete, true);
  284.         // TODO: welcome note?
  285.         primitive.addElement(ImpsTags.JoinGroup, true);
  286.         PrimitiveElement screenName = primitive.addElement(ImpsTags.ScreenName);
  287.         screenName.addChild(ImpsTags.SName, mConnection.getLoginUserName());
  288.         screenName.addChild(ImpsTags.GroupID, groupAddress.getFullName());
  289.         primitive.addElement(ImpsTags.SubscribeNotification, true);
  290.         return primitive;
  291.     }
  292.     private Primitive buildInviteUserRequest(ChatGroup group, Contact contact) {
  293.         String inviteId = nextInviteID();
  294.         Primitive request = new Primitive(ImpsTags.Invite_Request);
  295.         request.addElement(ImpsTags.InviteID, inviteId);
  296.         request.addElement(ImpsTags.InviteType, ImpsConstants.GROUP_INVITATION);
  297.         // FIXME: <Sender> is only required in IMPS1.3
  298.         // ImpsGroupAddress groupAddress = (ImpsGroupAddress)group.getAddress();
  299.         // groupAddress.setScreenName(mConnection.getLoginUser());
  300.         // request.addElement(ImpsTags.Sender).addChild(groupAddress.toPrimitiveElement());
  301.         request.addElement(ImpsTags.Recipient).addChild(
  302.                 ((ImpsAddress)contact.getAddress()).toPrimitiveElement());
  303.         request.addElement(ImpsTags.GroupID, group.getAddress().getFullName());
  304.         // FIXME: <ScreenName> is only needed in IMPS1.2
  305.         PrimitiveElement screenName = request.addElement(ImpsTags.ScreenName);
  306.         screenName.addChild(ImpsTags.SName, mConnection.getLoginUserName());
  307.         screenName.addChild(ImpsTags.GroupID, group.getAddress().getFullName());
  308.         return request;
  309.     }
  310.     private Primitive buildJoinGroupRequest(Address address) {
  311.         Primitive request = new Primitive(ImpsTags.JoinGroup_Request);
  312.         request.addElement(ImpsTags.GroupID, address.getFullName());
  313.         PrimitiveElement screenName = request.addElement(ImpsTags.ScreenName);
  314.         screenName.addChild(ImpsTags.SName, mConnection.getLoginUserName());
  315.         screenName.addChild(ImpsTags.GroupID, address.getFullName());
  316.         request.addElement(ImpsTags.JoinedRequest, true);
  317.         request.addElement(ImpsTags.SubscribeNotification, true);
  318.         return request;
  319.     }
  320.     private Primitive buildLeaveGroupRequest(ChatGroup group) {
  321.         Primitive leaveRequest = new Primitive(ImpsTags.LeaveGroup_Request);
  322.         leaveRequest.addElement(ImpsTags.GroupID, group.getAddress().getFullName());
  323.         return leaveRequest;
  324.     }
  325.     private Primitive buildRemoveGroupMemberRequest(ChatGroup group, Contact contact) {
  326.         Primitive request = new Primitive(ImpsTags.RemoveGroupMembers_Request);
  327.         request.addElement(ImpsTags.GroupID, group.getAddress().getFullName());
  328.         // FIXME: It's UserIDList in 1.3
  329.         PrimitiveElement userList = request.addElement(ImpsTags.UserList);
  330.         PrimitiveElement user = userList.addChild(ImpsTags.User);
  331.         user.addChild(ImpsTags.UserID, contact.getAddress().getFullName());
  332.         return request;
  333.     }
  334.     private void extractUserMapList(PrimitiveElement userMapList,
  335.             ArrayList<Contact> list) {
  336.         // FIXME: UserMapping is the child of UserMapList in version 1.3
  337.         PrimitiveElement userMapping = userMapList;
  338.         if (userMapping != null) {
  339.             for (PrimitiveElement mapping : userMapping.getChildren()) {
  340.                 String name = mapping.getChildContents(ImpsTags.SName);
  341.                 String id = mapping.getChildContents(ImpsTags.UserID);
  342.                 if (id == null) {
  343.                     id = name;
  344.                 }
  345.                 list.add((Contact)(new ImpsUserAddress(id)).getEntity(mConnection));
  346.             }
  347.         }
  348.     }
  349.     private static int sInviteID = 0;
  350.     private synchronized String nextInviteID() {
  351.         return "invite" + System.currentTimeMillis() + (sInviteID++);
  352.     }
  353. }