ImpsChatSessionManager.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:9k
源码类别:
android开发
开发平台:
C/C++
- /*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.android.im.imps;
- import java.util.ArrayList;
- import java.util.Date;
- import android.pim.Time;
- import android.util.TimeFormatException;
- import com.android.im.engine.Address;
- import com.android.im.engine.ChatSession;
- import com.android.im.engine.ChatSessionManager;
- import com.android.im.engine.ImEntity;
- import com.android.im.engine.ImErrorInfo;
- import com.android.im.engine.Message;
- /**
- * The implementation of ChatSessionManager with Wireless Village IMPS protocol.
- */
- public class ImpsChatSessionManager extends ChatSessionManager
- implements ServerTransactionListener {
- private ImpsConnection mConnection;
- private ImpsTransactionManager mTransactionManager;
- private ArrayList<Message> mMessageQueue;
- private boolean mStartNotifying;
- ImpsChatSessionManager(ImpsConnection connection) {
- mConnection = connection;
- mMessageQueue = new ArrayList<Message>();
- mTransactionManager = connection.getTransactionManager();
- mTransactionManager.setTransactionListener(ImpsTags.NewMessage, this);
- mTransactionManager.setTransactionListener(ImpsTags.DeliveryReport_Request, this);
- }
- @Override
- protected void sendMessageAsync(final ChatSession ses, final Message message) {
- // force to send from the currently logged user.
- message.setFrom(mConnection.getSession().getLoginUserAddress());
- if(message.getDateTime() == null) {
- message.setDateTime(new Date());
- }
- Primitive primitive = createSendMessagePrimitive(message);
- AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
- @Override
- public void onResponseOk(Primitive response) { }
- @Override
- public void onResponseError(ImpsErrorInfo error) {
- ses.onSendMessageError(message, error);
- }
- };
- tx.sendRequest(primitive);
- }
- public void notifyServerTransaction(ServerTransaction tx) {
- Primitive primitive = tx.getRequest();
- if (ImpsTags.NewMessage.equals(primitive.getType())) {
- Message msg = extractMessage(primitive);
- // send response to the server.
- Primitive response = new Primitive(ImpsTags.MessageDelivered);
- response.addElement(ImpsTags.MessageID, msg.getID());
- tx.sendResponse(response);
- synchronized(mMessageQueue) {
- if(mStartNotifying){
- processMessage(msg);
- } else {
- mMessageQueue.add(msg);
- }
- }
- } else if(ImpsTags.DeliveryReport_Request.equals(primitive.getType())) {
- tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);
- // We only notify the user when an error occurs.
- ImErrorInfo error = ImpsUtils.checkResultError(primitive);
- if(error != null) {
- PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);
- String msgId = msgInfo.getChildContents(ImpsTags.MessageID);
- PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
- ImpsAddress recipentAddress = ImpsAddress.fromPrimitiveElement(
- recipent.getFirstChild());
- ChatSession session = findSession(recipentAddress);
- if(session != null) {
- session.onSendMessageError(msgId, error);
- } else {
- ImpsLog.log("Session has closed when received delivery error: "
- + error);
- }
- }
- }
- }
- public void start() {
- synchronized (mMessageQueue) {
- mStartNotifying = true;
- for (Message message : mMessageQueue) {
- processMessage(message);
- }
- mMessageQueue.clear();
- }
- }
- /**
- * Extracts a message from a NewMessage primitive.
- *
- * @param primitive
- * the NewMessage primitive.
- * @return an instance of message.
- */
- private Message extractMessage(Primitive primitive) {
- String msgBody = primitive.getElementContents(ImpsTags.ContentData);
- if (msgBody == null) {
- msgBody = "";
- }
- Message msg = new Message(msgBody);
- PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);
- String id = msgInfo.getChildContents(ImpsTags.MessageID);
- msg.setID(id);
- PrimitiveElement sender = msgInfo.getChild(ImpsTags.Sender);
- msg.setFrom(ImpsAddress.fromPrimitiveElement(sender.getFirstChild()));
- PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
- if (recipent != null && recipent.getFirstChild() != null) {
- msg.setTo(ImpsAddress.fromPrimitiveElement(recipent.getFirstChild()));
- } else {
- msg.setTo(mConnection.getLoginUser().getAddress());
- }
- String dateTime = msgInfo.getChildContents(ImpsTags.DateTime);
- if (dateTime != null) {
- try {
- Time t = new Time();
- t.parse2445(dateTime);
- msg.setDateTime(new Date(t.toMillis(false /* use isDst */)));
- } catch (TimeFormatException e) {
- msg.setDateTime(new Date());
- }
- } else {
- msg.setDateTime(new Date());
- }
- return msg;
- }
- /**
- * Creates a SendMessage-Request primitive to send message.
- *
- * @param message the message to send.
- * @return the SendMessage-Request primitive.
- */
- private Primitive createSendMessagePrimitive(Message message) {
- Primitive primitive = new Primitive(ImpsTags.SendMessage_Request);
- primitive.addElement(ImpsTags.DeliveryReport,
- mConnection.getConfig().needDeliveryReport());
- PrimitiveElement msgInfo = primitive.addElement(ImpsTags.MessageInfo);
- PrimitiveElement recipient = msgInfo.addChild(ImpsTags.Recipient);
- recipient.addChild(((ImpsAddress)message.getTo()).toPrimitiveElement());
- PrimitiveElement sender = msgInfo.addChild(ImpsTags.Sender);
- sender.addChild(((ImpsAddress)message.getFrom()).toPrimitiveElement());
- // XXX: ContentType is optional and by default is "text/plain".
- // However without this the OZ IMPS server wouldn't reply to our
- // SendMessage requests and just let the HTTP connection times out.
- msgInfo.addChild(ImpsTags.ContentType, "text/plain");
- // optional
- // Calendar calendar = Calendar.getInstance();
- // calendar.setTime(message.getDateTime());
- // msgInfo.addChild(ImpsTags.DateTime, DateUtils.writeDateTime(calendar));
- String msgBody = message.getBody();
- msgInfo.addChild(ImpsTags.ContentSize, Integer.toString(msgBody.length()));
- primitive.addElement(ImpsTags.ContentData, msgBody);
- return primitive;
- }
- /**
- * Processes an incoming message. Called by the sub protocol implementation
- * when an incoming message arrived.
- *
- * @param msg the incoming message.
- */
- void processMessage(Message msg) {
- ImpsAddress selfAddress = mConnection.getSession().getLoginUserAddress();
- // If the message is not sent to the currently logged user, it must be
- // sent to a group.
- ImpsAddress address = (msg.getTo().equals(selfAddress) ?
- (ImpsAddress)msg.getFrom() : (ImpsAddress)msg.getTo());
- synchronized (this) {
- ChatSession ses = findSession(address);
- if (ses == null) {
- ImEntity participant = address.getEntity(mConnection);
- if (participant != null) {
- ses = createChatSession(address.getEntity(mConnection));
- } else {
- ImpsLog.log("Message from unknown sender");
- return;
- }
- }
- ses.onReceiveMessage(msg);
- }
- }
- /**
- * Finds the ChatSession which the message belongs to.
- *
- * @param msg the message.
- * @return the ChatSession or <code>null</code> if the session not exists.
- */
- private ChatSession findSession(Address address) {
- for(ChatSession session : mSessions) {
- ImEntity participant = session.getParticipant();
- if(participant.getAddress().equals(address)) {
- return session;
- }
- }
- return null;
- }
- }