1 /* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 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 18 package com.android.im.imps; 19 20 import com.android.im.engine.Presence; 21 import com.android.im.plugin.PresenceMapping; 22 23 import org.apache.commons.codec.binary.Base64; 24 25 import android.os.Base64Utils; 26 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.HashMap; 30 import java.util.Map; 31 32 /** 33 * A helper class used to extract presence values from the primitive received 34 * from the server and create the primitive for updating the presence. 35 */ 36 public class ImpsPresenceUtils { 37 ImpsPresenceUtils()38 private ImpsPresenceUtils() { 39 } 40 41 /** 42 * Extract the <code>Presence</code> from the <code>PrimitiveElement</code> 43 * which contains the <code>PresenceSubList</code>. 44 * 45 * @param presenceListElem the <code>PrimitiveElement</code> 46 * @return A new <code>Presence</code> containing the info extracted from the 47 * <code>PrimitiveElement</code> 48 */ extractPresence(PrimitiveElement presenceListElem, PresenceMapping mapping)49 public static Presence extractPresence(PrimitiveElement presenceListElem, 50 PresenceMapping mapping){ 51 int status = extractPresenceStatus(presenceListElem, mapping); 52 String statusText = extractStatusText(presenceListElem); 53 byte[] avatarData = extractAvatarBytes(presenceListElem); 54 String avatarType = extractAvatarType(presenceListElem); 55 56 int clientType = Presence.CLIENT_TYPE_DEFAULT; 57 HashMap<String, String> clientInfo = extractClientInfo(presenceListElem); 58 if (ImpsConstants.PRESENCE_MOBILE_PHONE.equals(clientInfo.get(ImpsTags.ClientType))) { 59 clientType = Presence.CLIENT_TYPE_MOBILE; 60 } 61 return new Presence(status, statusText, avatarData, avatarType, clientType); 62 } 63 64 /** 65 * Builds a list of PrimitiveElement need be sent to the server to update 66 * the user's presence. 67 * 68 * @param oldPresence 69 * @param newPresence 70 * @return 71 */ buildUpdatePresenceElems( Presence oldPresence, Presence newPresence, PresenceMapping mapping)72 public static ArrayList<PrimitiveElement> buildUpdatePresenceElems( 73 Presence oldPresence, Presence newPresence, PresenceMapping mapping) { 74 int status = newPresence.getStatus(); 75 ArrayList<PrimitiveElement> elems = new ArrayList<PrimitiveElement>(); 76 77 boolean newOnlineStatus = mapping.getOnlineStatus(status); 78 PrimitiveElement onlineElem = new PrimitiveElement(ImpsTags.OnlineStatus); 79 onlineElem.addChild(ImpsTags.Qualifier, true); 80 onlineElem.addChild(ImpsTags.PresenceValue, newOnlineStatus); 81 elems.add(onlineElem); 82 83 String newUserAvailablity = mapping.getUserAvaibility(status); 84 PrimitiveElement availElem = new PrimitiveElement(ImpsTags.UserAvailability); 85 availElem.addChild(ImpsTags.Qualifier, true); 86 availElem.addChild(ImpsTags.PresenceValue, newUserAvailablity); 87 elems.add(availElem); 88 Map<String, Object> extra = mapping.getExtra(status); 89 if (extra != null) { 90 mapToPrimitives(extra, elems); 91 } 92 String statusText = newPresence.getStatusText(); 93 if (statusText == null) { 94 statusText = ""; 95 } 96 if (!statusText.equals(oldPresence.getStatusText())) { 97 PrimitiveElement statusElem = new PrimitiveElement(ImpsTags.StatusText); 98 statusElem.addChild(ImpsTags.Qualifier, true); 99 statusElem.addChild(ImpsTags.PresenceValue, statusText); 100 elems.add(statusElem); 101 } 102 103 byte[] avatar = newPresence.getAvatarData(); 104 if (avatar != null && !Arrays.equals(avatar, oldPresence.getAvatarData())) { 105 String base64Avatar = new String(Base64.encodeBase64(avatar)); 106 PrimitiveElement statusContent = new PrimitiveElement(ImpsTags.StatusContent); 107 statusContent.addChild(ImpsTags.Qualifier, true); 108 statusContent.addChild(ImpsTags.DirectContent, base64Avatar); 109 statusContent.addChild(ImpsTags.ContentType, newPresence.getAvatarType()); 110 elems.add(statusContent); 111 } 112 113 return elems; 114 } 115 extractPresenceStatus(PrimitiveElement presenceListElem, PresenceMapping mapping)116 private static int extractPresenceStatus(PrimitiveElement presenceListElem, 117 PresenceMapping mapping) { 118 PrimitiveElement onlineStatusElem = presenceListElem.getChild(ImpsTags.OnlineStatus); 119 boolean onlineStatus = ImpsUtils.isQualifiedPresence(onlineStatusElem) 120 && ImpsUtils.isTrue(onlineStatusElem.getChildContents(ImpsTags.PresenceValue)); 121 122 PrimitiveElement availabilityElem = presenceListElem.getChild(ImpsTags.UserAvailability); 123 String userAvailability = ImpsUtils.isQualifiedPresence(availabilityElem) ? 124 availabilityElem.getChildContents(ImpsTags.PresenceValue) : null; 125 126 HashMap<String, Object> all = null; 127 if (mapping.requireAllPresenceValues()) { 128 all = new HashMap<String, Object>(); 129 primitivetoMap(presenceListElem, all); 130 } 131 return mapping.getPresenceStatus(onlineStatus, userAvailability, all); 132 } 133 primitivetoMap(PrimitiveElement elem, HashMap<String, Object> map)134 private static void primitivetoMap(PrimitiveElement elem, HashMap<String, Object> map) { 135 String key = elem.getTagName(); 136 int childrenCount = elem.getChildCount(); 137 if (childrenCount > 0) { 138 HashMap<String, Object> childrenMap = new HashMap<String, Object>(); 139 for (PrimitiveElement child : elem.getChildren()) { 140 primitivetoMap(child, childrenMap); 141 } 142 map.put(key, childrenMap); 143 } else { 144 map.put(key, elem.getContents()); 145 } 146 } 147 mapToPrimitives(Map<String, Object> map, ArrayList<PrimitiveElement> elems)148 private static void mapToPrimitives(Map<String, Object> map, ArrayList<PrimitiveElement> elems) { 149 for (Map.Entry<String, Object> entry : map.entrySet()) { 150 String tag = entry.getKey(); 151 Object value = entry.getValue(); 152 PrimitiveElement elem = new PrimitiveElement(tag); 153 if (value instanceof String) { 154 elem.setContents((String)value); 155 } else if (value instanceof Map) { 156 mapToPrimitives((Map<String, Object>)value, elem.getChildren()); 157 } 158 elems.add(elem); 159 } 160 } 161 extractClientInfo(PrimitiveElement presenceListElem)162 private static HashMap<String, String> extractClientInfo(PrimitiveElement presenceListElem) { 163 HashMap<String, String> clientInfo = new HashMap<String, String>(); 164 PrimitiveElement clientInfoElem = presenceListElem.getChild(ImpsTags.ClientInfo); 165 if (ImpsUtils.isQualifiedPresence(clientInfoElem)) { 166 String clientType = clientInfoElem.getChildContents(ImpsTags.ClientType); 167 if (clientType != null) { 168 clientInfo.put(ImpsTags.ClientType, clientType); 169 } 170 171 String clientProducer = clientInfoElem.getChildContents(ImpsTags.ClientProducer); 172 if (clientProducer != null) { 173 clientInfo.put(ImpsTags.ClientProducer, clientProducer); 174 } 175 176 String clientVersion = clientInfoElem.getChildContents(ImpsTags.ClientVersion); 177 if (clientVersion != null) { 178 clientInfo.put(ImpsTags.ClientVersion, clientVersion); 179 } 180 } 181 return clientInfo; 182 } 183 extractStatusText(PrimitiveElement presenceListElem)184 private static String extractStatusText(PrimitiveElement presenceListElem) { 185 String statusText = null; 186 PrimitiveElement statusTextElem = presenceListElem.getChild(ImpsTags.StatusText); 187 if (ImpsUtils.isQualifiedPresence(statusTextElem)) { 188 statusText = statusTextElem.getChildContents(ImpsTags.PresenceValue); 189 } 190 return statusText; 191 } 192 extractAvatarBytes(PrimitiveElement presenceListElem)193 private static byte[] extractAvatarBytes(PrimitiveElement presenceListElem) { 194 PrimitiveElement statusContentElem = presenceListElem.getChild(ImpsTags.StatusContent); 195 if(ImpsUtils.isQualifiedPresence(statusContentElem)) { 196 String avatarStr = statusContentElem.getChildContents(ImpsTags.DirectContent); 197 if(avatarStr != null){ 198 return Base64Utils.decodeBase64(avatarStr); 199 } 200 } 201 return null; 202 } 203 extractAvatarType(PrimitiveElement presenceListElem)204 private static String extractAvatarType(PrimitiveElement presenceListElem) { 205 PrimitiveElement statusContentElem = presenceListElem.getChild(ImpsTags.StatusContent); 206 if(ImpsUtils.isQualifiedPresence(statusContentElem)) { 207 return statusContentElem.getChildContents(ImpsTags.ContentType); 208 } 209 return null; 210 } 211 } 212