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

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007-2008 Esmertec AG.
  3.  * Copyright (C) 2007-2008 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 java.util.Date;
  20. import android.pim.Time;
  21. import android.util.TimeFormatException;
  22. import com.android.im.engine.Address;
  23. import com.android.im.engine.ChatSession;
  24. import com.android.im.engine.ChatSessionManager;
  25. import com.android.im.engine.ImEntity;
  26. import com.android.im.engine.ImErrorInfo;
  27. import com.android.im.engine.Message;
  28. /**
  29.  * The implementation of ChatSessionManager with Wireless Village IMPS protocol.
  30.  */
  31. public class ImpsChatSessionManager extends ChatSessionManager
  32.             implements ServerTransactionListener {
  33.     private ImpsConnection mConnection;
  34.     private ImpsTransactionManager mTransactionManager;
  35.     private ArrayList<Message> mMessageQueue;
  36.     private boolean mStartNotifying;
  37.     ImpsChatSessionManager(ImpsConnection connection) {
  38.         mConnection = connection;
  39.         mMessageQueue = new ArrayList<Message>();
  40.         mTransactionManager = connection.getTransactionManager();
  41.         mTransactionManager.setTransactionListener(ImpsTags.NewMessage, this);
  42.         mTransactionManager.setTransactionListener(ImpsTags.DeliveryReport_Request, this);
  43.     }
  44.     @Override
  45.     protected void sendMessageAsync(final ChatSession ses, final Message message) {
  46.         // force to send from the currently logged user.
  47.         message.setFrom(mConnection.getSession().getLoginUserAddress());
  48.         if(message.getDateTime() == null) {
  49.             message.setDateTime(new Date());
  50.         }
  51.         Primitive primitive = createSendMessagePrimitive(message);
  52.         AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
  53.             @Override
  54.             public void onResponseOk(Primitive response) { }
  55.             @Override
  56.             public void onResponseError(ImpsErrorInfo error) {
  57.                 ses.onSendMessageError(message, error);
  58.             }
  59.         };
  60.         tx.sendRequest(primitive);
  61.     }
  62.     public void notifyServerTransaction(ServerTransaction tx) {
  63.         Primitive primitive = tx.getRequest();
  64.         if (ImpsTags.NewMessage.equals(primitive.getType())) {
  65.             Message msg = extractMessage(primitive);
  66.             // send response to the server.
  67.             Primitive response = new Primitive(ImpsTags.MessageDelivered);
  68.             response.addElement(ImpsTags.MessageID, msg.getID());
  69.             tx.sendResponse(response);
  70.             synchronized(mMessageQueue) {
  71.                 if(mStartNotifying){
  72.                     processMessage(msg);
  73.                 } else {
  74.                     mMessageQueue.add(msg);
  75.                 }
  76.             }
  77.         } else if(ImpsTags.DeliveryReport_Request.equals(primitive.getType())) {
  78.             tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
  79.             // We only notify the user when an error occurs.
  80.             ImErrorInfo error = ImpsUtils.checkResultError(primitive);
  81.             if(error != null) {
  82.                 PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);
  83.                 String msgId = msgInfo.getChildContents(ImpsTags.MessageID);
  84.                 PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
  85.                 ImpsAddress recipentAddress = ImpsAddress.fromPrimitiveElement(
  86.                         recipent.getFirstChild());
  87.                 ChatSession session = findSession(recipentAddress);
  88.                 if(session != null) {
  89.                     session.onSendMessageError(msgId, error);
  90.                 } else {
  91.                     ImpsLog.log("Session has closed when received delivery error: "
  92.                             + error);
  93.                 }
  94.             }
  95.         }
  96.     }
  97.     public void start() {
  98.         synchronized (mMessageQueue) {
  99.             mStartNotifying = true;
  100.             for (Message message : mMessageQueue) {
  101.                 processMessage(message);
  102.             }
  103.             mMessageQueue.clear();
  104.         }
  105.     }
  106.     /**
  107.      * Extracts a message from a NewMessage primitive.
  108.      *
  109.      * @param primitive
  110.      *            the NewMessage primitive.
  111.      * @return an instance of message.
  112.      */
  113.     private Message extractMessage(Primitive primitive) {
  114.         String msgBody = primitive.getElementContents(ImpsTags.ContentData);
  115.         if (msgBody == null) {
  116.             msgBody = "";
  117.         }
  118.         Message msg = new Message(msgBody);
  119.         PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);
  120.         String id = msgInfo.getChildContents(ImpsTags.MessageID);
  121.         msg.setID(id);
  122.         PrimitiveElement sender = msgInfo.getChild(ImpsTags.Sender);
  123.         msg.setFrom(ImpsAddress.fromPrimitiveElement(sender.getFirstChild()));
  124.         PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
  125.         if (recipent != null && recipent.getFirstChild() != null) {
  126.             msg.setTo(ImpsAddress.fromPrimitiveElement(recipent.getFirstChild()));
  127.         } else {
  128.             msg.setTo(mConnection.getLoginUser().getAddress());
  129.         }
  130.         String dateTime = msgInfo.getChildContents(ImpsTags.DateTime);
  131.         if (dateTime != null) {
  132.             try {
  133.                 Time t = new Time();
  134.                 t.parse2445(dateTime);
  135.                 msg.setDateTime(new Date(t.toMillis(false /* use isDst */)));
  136.             } catch (TimeFormatException e) {
  137.                 msg.setDateTime(new Date());
  138.             }
  139.         } else {
  140.             msg.setDateTime(new Date());
  141.         }
  142.         return msg;
  143.     }
  144.     /**
  145.      * Creates a SendMessage-Request primitive to send message.
  146.      *
  147.      * @param message the message to send.
  148.      * @return the SendMessage-Request primitive.
  149.      */
  150.     private Primitive createSendMessagePrimitive(Message message) {
  151.         Primitive primitive = new Primitive(ImpsTags.SendMessage_Request);
  152.         primitive.addElement(ImpsTags.DeliveryReport,
  153.                 mConnection.getConfig().needDeliveryReport());
  154.         PrimitiveElement msgInfo = primitive.addElement(ImpsTags.MessageInfo);
  155.         PrimitiveElement recipient = msgInfo.addChild(ImpsTags.Recipient);
  156.         recipient.addChild(((ImpsAddress)message.getTo()).toPrimitiveElement());
  157.         PrimitiveElement sender = msgInfo.addChild(ImpsTags.Sender);
  158.         sender.addChild(((ImpsAddress)message.getFrom()).toPrimitiveElement());
  159.         // XXX: ContentType is optional and by default is "text/plain".
  160.         // However without this the OZ IMPS server wouldn't reply to our
  161.         // SendMessage requests and just let the HTTP connection times out.
  162.         msgInfo.addChild(ImpsTags.ContentType, "text/plain");
  163.         // optional
  164. //        Calendar calendar = Calendar.getInstance();
  165. //        calendar.setTime(message.getDateTime());
  166. //        msgInfo.addChild(ImpsTags.DateTime, DateUtils.writeDateTime(calendar));
  167.         String msgBody = message.getBody();
  168.         msgInfo.addChild(ImpsTags.ContentSize, Integer.toString(msgBody.length()));
  169.         primitive.addElement(ImpsTags.ContentData, msgBody);
  170.         return primitive;
  171.     }
  172.     /**
  173.      * Processes an incoming message. Called by the sub protocol implementation
  174.      * when an incoming message arrived.
  175.      *
  176.      * @param msg the incoming message.
  177.      */
  178.     void processMessage(Message msg) {
  179.         ImpsAddress selfAddress = mConnection.getSession().getLoginUserAddress();
  180.         // If the message is not sent to the currently logged user, it must be
  181.         // sent to a group.
  182.         ImpsAddress address = (msg.getTo().equals(selfAddress) ?
  183.                 (ImpsAddress)msg.getFrom() : (ImpsAddress)msg.getTo());
  184.         synchronized (this) {
  185.             ChatSession ses = findSession(address);
  186.             if (ses == null) {
  187.                 ImEntity participant = address.getEntity(mConnection);
  188.                 if (participant != null) {
  189.                     ses = createChatSession(address.getEntity(mConnection));
  190.                 } else {
  191.                     ImpsLog.log("Message from unknown sender");
  192.                     return;
  193.                 }
  194.             }
  195.             ses.onReceiveMessage(msg);
  196.         }
  197.     }
  198.     /**
  199.      * Finds the ChatSession which the message belongs to.
  200.      *
  201.      * @param msg the message.
  202.      * @return the ChatSession or <code>null</code> if the session not exists.
  203.      */
  204.     private ChatSession findSession(Address address) {
  205.         for(ChatSession session : mSessions) {
  206.             ImEntity participant = session.getParticipant();
  207.             if(participant.getAddress().equals(address)) {
  208.                 return session;
  209.             }
  210.         }
  211.         return null;
  212.     }
  213. }