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

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 java.util.HashMap;
  20. import java.util.List;
  21. import com.android.im.engine.Contact;
  22. import com.android.im.engine.ImErrorInfo;
  23. import com.android.im.engine.ImException;
  24. import com.android.im.engine.LoginInfo;
  25. import com.android.im.imps.ImpsConnectionConfig.CirMethod;
  26. import com.android.im.imps.ImpsConnectionConfig.TransportType;
  27. /**
  28.  * Represents the context of an IMPS session. The IMPS session is a framework in
  29.  * which the IMPS services are provided to the IMPS client. It's established
  30.  * when the client logs in and terminated when either the client logs out or the
  31.  * SAP decides to disconnect the session.
  32.  */
  33. public class ImpsSession {
  34.     private static final String KEY_CIR_HTTP_ADDRESS = "cirHttpAddress";
  35.     private static final String KEY_CIR_TCP_PORT = "cirTcpPort";
  36.     private static final String KEY_CIR_TCP_ADDRESS = "cirTcpAddress";
  37.     private static final String KEY_CIR_METHOD = "CirMethod";
  38.     private static final String KEY_SERVER_POLL_MIN = "serverPollMin";
  39.     private static final String KEY_PASSWORD = "password";
  40.     private static final String KEY_USERNAME = "username";
  41.     private static final String KEY_KEEP_ALIVE_TIME = "keepAliveTime";
  42.     private static final String KEY_SESSION_COOKIE = "sessionCookie";
  43.     private static final String KEY_SESSION_ID = "sessionId";
  44.     private static final int DEFAULT_TCP_PORT = 3171;
  45.     private ImpsConnection mConnection;
  46.     private String mId;
  47.     private String mCookie;
  48.     private long mKeepAliveTime;
  49.     private CirMethod mCurrentCirMethod;
  50.     private String mCirTcpAddress;
  51.     private int mCirTcpPort = DEFAULT_TCP_PORT;
  52.     private long mServerPollMin;
  53.     private String mCirHttpAddress;
  54.     private LoginInfo mLoginInfo;
  55.     private boolean mCapablityRequest;
  56.     private List<CirMethod> mSupportedCirMethod;
  57.     private Contact mLoginUser;
  58.     PrimitiveElement mServiceTree;
  59.     /**
  60.      * Flag that indicates this is a new created session or not.
  61.      */
  62.     private boolean mNew;
  63.     ImpsSession(ImpsConnection connection, LoginInfo info) throws ImException{
  64.         mConnection = connection;
  65.         setLoginInfo(info);
  66.         mNew = true;
  67.         mCookie = ImpsUtils.genSessionCookie();
  68.         mCirTcpPort = DEFAULT_TCP_PORT;
  69.         mServerPollMin = connection.getConfig().getDefaultServerPollMin();
  70.     }
  71.     ImpsSession(ImpsConnection connection, HashMap<String, String> values)
  72.             throws ImException {
  73.         mConnection = connection;
  74.         mNew = false;
  75.         mId = values.get(KEY_SESSION_ID);
  76.         if (mId == null || mId.length() == 0) {
  77.             throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  78.                 "Missing session id");
  79.         }
  80.         mCookie = values.get(KEY_SESSION_COOKIE);
  81.         if (mCookie == null || mCookie.length() == 0) {
  82.             throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  83.                 "Missing session cookie");
  84.         }
  85.         try {
  86.             mKeepAliveTime = Long.parseLong(values.get(KEY_KEEP_ALIVE_TIME));
  87.         } catch (NumberFormatException e) {
  88.             throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  89.                 "Invalid keepAliveTime");
  90.         }
  91.         try {
  92.             mServerPollMin = Long.parseLong(values.get(KEY_SERVER_POLL_MIN));
  93.         } catch (NumberFormatException e) {
  94.             throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  95.                 "Invalid serverPollMin");
  96.         }
  97.         String username = values.get(KEY_USERNAME);
  98.         String password = values.get(KEY_PASSWORD);
  99.         // Empty password might be valid
  100.         if (username == null || username.length() == 0 || password == null) {
  101.             throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  102.                 "Invalid username or password");
  103.         }
  104.         setLoginInfo(new LoginInfo(username, password));
  105.         mCurrentCirMethod = CirMethod.valueOf(values.get(KEY_CIR_METHOD));
  106.         if (mCurrentCirMethod == CirMethod.STCP) {
  107.             mCirTcpAddress = values.get(KEY_CIR_TCP_ADDRESS);
  108.             if (mCirTcpAddress == null || mCirTcpAddress.length() == 0) {
  109.                 throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  110.                     "Missing CirTcpAddress");
  111.             }
  112.             try {
  113.                 mCirTcpPort = Integer.parseInt(values.get(KEY_CIR_TCP_PORT));
  114.             } catch (NumberFormatException e) {
  115.                 throw new ImException(ImErrorInfo.INVALID_SESSION_CONTEXT,
  116.                     "Invalid CirTcpPort");
  117.             }
  118.         } else if (mCurrentCirMethod == CirMethod.SHTTP) {
  119.             mCirHttpAddress = values.get(KEY_CIR_HTTP_ADDRESS);
  120.         }
  121.     }
  122.     public HashMap<String, String> getContext() {
  123.         HashMap<String, String> values = new HashMap<String, String>();
  124.         values.put(KEY_SESSION_ID, mId);
  125.         values.put(KEY_SESSION_COOKIE, mCookie);
  126.         values.put(KEY_KEEP_ALIVE_TIME, Long.toString(mKeepAliveTime));
  127.         values.put(KEY_USERNAME, mLoginInfo.getUserName());
  128.         values.put(KEY_PASSWORD, mLoginInfo.getPassword());
  129.         values.put(KEY_SERVER_POLL_MIN, Long.toString(mServerPollMin));
  130.         values.put(KEY_CIR_METHOD, mCurrentCirMethod.name());
  131.         if(mCurrentCirMethod == CirMethod.STCP) {
  132.             values.put(KEY_CIR_TCP_ADDRESS, mCirTcpAddress);
  133.             values.put(KEY_CIR_TCP_PORT, Integer.toString(mCirTcpPort));
  134.         } else if (mCurrentCirMethod == CirMethod.SHTTP) {
  135.             values.put(KEY_CIR_HTTP_ADDRESS, mCirHttpAddress);
  136.         }
  137.         return values;
  138.     }
  139.     /**
  140.      * Gets the unique id of the session.
  141.      *
  142.      * @return the unique id of the session.
  143.      */
  144.     public String getID() {
  145.         return mId;
  146.     }
  147.     public void setId(String id) {
  148.         mId = id;
  149.     }
  150.     public String getCookie() {
  151.         return mCookie;
  152.     }
  153.     public String getUserName() {
  154.         return mLoginInfo.getUserName();
  155.     }
  156.     public String getPassword() {
  157.         return mLoginInfo.getPassword();
  158.     }
  159.     public LoginInfo getLoginInfo() {
  160.         return mLoginInfo;
  161.     }
  162.     /**
  163.      * Gets the auto logout timer value.
  164.      *
  165.      * @return the auto logout timer value.
  166.      */
  167.     public long getKeepAliveTime() {
  168.         return mKeepAliveTime;
  169.     }
  170.     public void setKeepAliveTime(long keepAliveTime) {
  171.         mKeepAliveTime = keepAliveTime;
  172.     }
  173.     /**
  174.      * Gets if further capability request is required in the session.
  175.      *
  176.      * @return <code>true</code> if further capability request is required.
  177.      */
  178.     public boolean isCapablityRequestRequired() {
  179.         return mCapablityRequest || mNew;
  180.     }
  181.     public void setCapablityRequestRequired(boolean required) {
  182.         mCapablityRequest = required;
  183.     }
  184.     public ImpsUserAddress getLoginUserAddress() {
  185.         return (ImpsUserAddress) mLoginUser.getAddress();
  186.     }
  187.     public Contact getLoginUser() {
  188.         return mLoginUser;
  189.     }
  190.     /**
  191.      * Sets the Login information. After login successfully, the login
  192.      * information should be saved in the session context so that we can auto
  193.      * login when reconnect to the server.
  194.      *
  195.      * @param loginInfo the login information.
  196.      * @throws ImException
  197.      */
  198.     private void setLoginInfo(LoginInfo loginInfo) throws ImException {
  199.         try {
  200.             ImpsAddress address = new ImpsUserAddress(loginInfo.getUserName());
  201.             mLoginUser = new Contact(address, address.getScreenName());
  202.             mLoginInfo = loginInfo;
  203.         } catch (IllegalArgumentException e) {
  204.             throw new ImException(ImErrorInfo.INVALID_USERNAME,
  205.                     "Invalid username");
  206.         }
  207.     }
  208.     /**
  209.      * Gets a collection of CIR methods that are supported by both the client
  210.      * and the server.
  211.      *
  212.      * @return a collection of supported CIR methods
  213.      */
  214.     public List<CirMethod> getSupportedCirMethods() {
  215.         return mSupportedCirMethod;
  216.     }
  217.     public CirMethod getCurrentCirMethod() {
  218.         return mCurrentCirMethod;
  219.     }
  220.     public void setCurrentCirMethod(CirMethod cirMethod) {
  221.         mCurrentCirMethod = cirMethod;
  222.     }
  223.     /**
  224.      * Gets the IP address for standalone TCP/IP CIR method.
  225.      *
  226.      * @return the IP address for standalone TCP/IP CIR method
  227.      */
  228.     public String getCirTcpAddress() {
  229.         return mCirTcpAddress;
  230.     }
  231.     /**
  232.      * Gets the port number for the standalone TCP/IP CIR method.
  233.      *
  234.      * @return the port number for the standalone TCP/IP CIR method.
  235.      */
  236.     public int getCirTcpPort() {
  237.         return mCirTcpPort;
  238.     }
  239.     /**
  240.      * Gets the minimum time interval (in seconds) that MUST pass before two
  241.      * subsequent PollingRequest transactions.
  242.      *
  243.      * @return the minimum time interval in seconds.
  244.      */
  245.     public long getServerPollMin() {
  246.         return mServerPollMin;
  247.     }
  248.     /**
  249.      * Gets the URL used for standalone HTTP binding of CIR channel.
  250.      *
  251.      * @return the URL.
  252.      */
  253.     public String getCirHttpAddress() {
  254.         return mCirHttpAddress;
  255.     }
  256.     /**
  257.      * Gets the service tree of the features and functions that the server
  258.      * supports.
  259.      *
  260.      * @return the service tree.
  261.      */
  262.     public PrimitiveElement getServiceTree() {
  263.         return mServiceTree;
  264.     }
  265.     /**
  266.      * Perform client capability negotiation with the server asynchronously.
  267.      *
  268.      * @param completion Async completion object.
  269.      */
  270.     public void negotiateCapabilityAsync(AsyncCompletion completion) {
  271.         Primitive capabilityRequest = buildCapabilityRequest();
  272.         AsyncTransaction tx = new AsyncTransaction(
  273.                 mConnection.getTransactionManager(), completion) {
  274.             @Override
  275.             public void onResponseOk(Primitive response) {
  276.                 extractCapability(response);
  277.             }
  278.             @Override
  279.             public void onResponseError(ImpsErrorInfo error) { }
  280.         };
  281.         tx.sendRequest(capabilityRequest);
  282.     }
  283.     /**
  284.      * Perform service negotiation with the server asynchronously.
  285.      *
  286.      * @param completion Async completion object.
  287.      */
  288.     public void negotiateServiceAsync(AsyncCompletion completion) {
  289.         Primitive serviceRequest = buildServiceRequest();
  290.         AsyncTransaction tx = new AsyncTransaction(
  291.                 mConnection.getTransactionManager(), completion) {
  292.             @Override
  293.             public void onResponseOk(Primitive response) {
  294.                 mServiceTree = response.getElement(ImpsTags.AllFunctions).getFirstChild();
  295.             }
  296.             @Override
  297.             public void onResponseError(ImpsErrorInfo error) { }
  298.         };
  299.         tx.sendRequest(serviceRequest);
  300.     }
  301.     private Primitive buildCapabilityRequest() {
  302.         Primitive capabilityRequest = new Primitive(ImpsTags.ClientCapability_Request);
  303.         PrimitiveElement list = capabilityRequest.addElement(ImpsTags.CapabilityList);
  304.         list.addChild(ImpsTags.ClientType, ImpsClientCapability.getClientType());
  305.         list.addChild(ImpsTags.AcceptedContentLength, Integer
  306.                 .toString(ImpsClientCapability.getAcceptedContentLength()));
  307.         list.addChild(ImpsTags.ParserSize,
  308.                 Integer.toString(ImpsClientCapability.getParserSize()));
  309.         list.addChild(ImpsTags.MultiTrans,
  310.                 Integer.toString(ImpsClientCapability.getMultiTrans()));
  311.         // TODO: MultiTransPerMessage is IMPS 1.3
  312.         //list.addChild(ImpsTags.MultiTransPerMessage,
  313.         //        Integer.toString(ImpsClientCapability.getMultiTransPerMessage()));
  314.         list.addChild(ImpsTags.InitialDeliveryMethod,
  315.                 ImpsClientCapability.getInitialDeliveryMethod());
  316.         list.addChild(ImpsTags.ServerPollMin, Long.toString(mServerPollMin));
  317.         for(TransportType supportedBear : ImpsClientCapability.getSupportedBearers()) {
  318.             list.addChild(ImpsTags.SupportedBearer, supportedBear.toString());
  319.         }
  320.         for(CirMethod supportedCirMethod : ImpsClientCapability.getSupportedCirMethods()) {
  321.             list.addChild(ImpsTags.SupportedCIRMethod, supportedCirMethod.toString());
  322.             if (CirMethod.SUDP.equals(supportedCirMethod)) {
  323.                 list.addChild(ImpsTags.UDPPort,
  324.                         Integer.toString(mConnection.getConfig().getUdpPort()));
  325.             }
  326.         }
  327.         return capabilityRequest;
  328.     }
  329.     /* keep this method package private instead of private to avoid the
  330.      * overhead of calling from a inner class.
  331.      */
  332.     void extractCapability(Primitive capabilityResponse) {
  333.         mSupportedCirMethod = new ArrayList<CirMethod>();
  334.         PrimitiveElement agreedList = capabilityResponse.getContentElement()
  335.                 .getFirstChild();
  336.         for (PrimitiveElement element : agreedList.getChildren()) {
  337.             String tag = element.getTagName();
  338.             if (tag.equals(ImpsTags.SupportedCIRMethod)) {
  339.                 try {
  340.                     mSupportedCirMethod.add(CirMethod.valueOf(element.getContents()));
  341.                 } catch (IllegalArgumentException e) {
  342.                     ImpsLog.log("Unrecognized CIR method " + element.getContents());
  343.                 }
  344.             } else if (tag.equals(ImpsTags.TCPAddress)) {
  345.                 mCirTcpAddress = element.getContents();
  346.             } else if (tag.equals(ImpsTags.TCPPort)) {
  347.                 mCirTcpPort = (int)ImpsUtils.parseLong(element.getContents(),
  348.                         DEFAULT_TCP_PORT);
  349.             } else if (tag.equals(ImpsTags.ServerPollMin)) {
  350.                 long defaultPollMin = mConnection.getConfig().getDefaultServerPollMin();
  351.                 mServerPollMin = ImpsUtils.parseLong(element.getContents(),
  352.                         defaultPollMin);
  353.                 if (mServerPollMin <= 0) {
  354.                     mServerPollMin = defaultPollMin;
  355.                 }
  356.             } else if (tag.equals(ImpsTags.CIRHTTPAddress)
  357.                     || tag.equals(ImpsTags.CIRURL)) {
  358.                 // This tag is CIRHTTPAddress in 1.3 and CIRURL in 1.2
  359.                 mCirHttpAddress = element.getChildContents(ImpsTags.URL);
  360.             }
  361.         }
  362.     }
  363.     private Primitive buildServiceRequest() {
  364.         Primitive serviceRequest = new Primitive(ImpsTags.Service_Request);
  365.         PrimitiveElement functions = serviceRequest.addElement(ImpsTags.Functions);
  366.         PrimitiveElement features = functions.addChild(ImpsTags.WVCSPFeat);
  367.         features.addChild(ImpsTags.FundamentalFeat);
  368.         features.addChild(ImpsTags.PresenceFeat);
  369.         features.addChild(ImpsTags.IMFeat);
  370.         features.addChild(ImpsTags.GroupFeat);
  371.         serviceRequest.addElement(ImpsTags.AllFunctionsRequest, true);
  372.         return serviceRequest;
  373.     }
  374. }