/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * 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 net.java.sip.communicator.service.protocol.jabberconstants; import java.io.*; import java.net.*; import java.util.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import org.jitsi.service.resources.*; /** * The <tt>JabberStatusEnum</tt> gives access to presence states for the Sip * protocol. All status icons corresponding to presence states are located with * the help of the <tt>imagePath</tt> parameter * * @author Emil Ivov * @author Yana Stamcheva * @author Lubomir Marinov */ public class JabberStatusEnum { /** * The <tt>Logger</tt> used by the <tt>JabberStatusEnum</tt> class and its * instances for logging output. */ private static final Logger logger = Logger.getLogger(JabberStatusEnum.class); /** * The Online status. Indicate that the user is able and willing to * communicate. */ public static final String AVAILABLE = "Available"; /** * The Away status. Indicates that the user has connectivity but might not * be able to immediately act upon initiation of communication. */ public static final String AWAY = "Away"; /** * The DND status. Indicates that the user has connectivity but prefers not * to be contacted. */ public static final String DO_NOT_DISTURB = "Do Not Disturb"; /** * The Free For Chat status. Indicates that the user is eager to * communicate. */ public static final String FREE_FOR_CHAT = "Free For Chat"; /** * On The Phone Chat status. * Indicates that the user is talking to the phone. */ public static final String ON_THE_PHONE = "On the phone"; /** * In meeting Chat status. * Indicates that the user is in meeting. */ public static final String IN_A_MEETING = "In a meeting"; /** * The Free For Chat status. Indicates that the user is eager to * communicate. */ public static final String EXTENDED_AWAY = "Extended Away"; /** * Indicates an Offline status or status with 0 connectivity. */ public static final String OFFLINE = "Offline"; /** * The Unknown status. Indicate that we don't know if the user is present or * not. */ public static final String UNKNOWN = "Unknown"; /** * The Online status. Indicate that the user is able and willing to * communicate. */ private final JabberPresenceStatus availableStatus; /** * The Away status. Indicates that the user has connectivity but might not * be able to immediately act upon initiation of communication. */ private final JabberPresenceStatus awayStatus; /** * The DND status. Indicates that the user has connectivity but prefers not * to be contacted. */ private final JabberPresenceStatus doNotDisturbStatus; /** * The Free For Chat status. Indicates that the user is eager to * communicate. */ private final JabberPresenceStatus freeForChatStatus; /** * Indicates an Offline status or status with 0 connectivity. */ private final JabberPresenceStatus offlineStatus; /** * Indicates an On The Phone status. */ private final JabberPresenceStatus onThePhoneStatus; /** * Indicates an On The Phone status. */ private final JabberPresenceStatus inMeetingStatus; /** * Indicates an Extended Away status or status. */ private final JabberPresenceStatus extendedAwayStatus; /** * The supported status set stores all statuses supported by this protocol * implementation. */ public final List<PresenceStatus> supportedStatusSet = new LinkedList<PresenceStatus>(); /** * The Unknown status. Indicate that we don't know if the user is present or * not. */ private final JabberPresenceStatus unknownStatus; private static final Map<String, JabberStatusEnum> existingEnums = new Hashtable<String, JabberStatusEnum>(); /** * Returns an instance of JabberStatusEnum for the specified * <tt>iconPath</tt> or creates a new one if it doesn't already exist. * * @param iconPath the location containing the status icons that should * be used by this enumeration. * * @return the newly created JabberStatusEnum instance. */ public static JabberStatusEnum getJabberStatusEnum(String iconPath) { JabberStatusEnum statusEnum = existingEnums.get(iconPath); if(statusEnum != null) return statusEnum; statusEnum = new JabberStatusEnum(iconPath); existingEnums.put(iconPath, statusEnum); return statusEnum; } /** * Creates a new instance of JabberStatusEnum using <tt>iconPath</tt> as the * root path where it should be reading status icons from. * * @param iconPath the location containing the status icons that should * be used by this enumeration. */ private JabberStatusEnum(String iconPath) { this.offlineStatus = new JabberPresenceStatus(0, OFFLINE, loadIcon(iconPath + "/status16x16-offline.png")); this.doNotDisturbStatus = new JabberPresenceStatus(30, DO_NOT_DISTURB, loadIcon(iconPath + "/status16x16-dnd.png")); this.onThePhoneStatus = new JabberPresenceStatus(31, ON_THE_PHONE, loadIcon(iconPath + "/status16x16-phone.png")); this.inMeetingStatus = new JabberPresenceStatus(32, IN_A_MEETING, loadIcon(iconPath + "/status16x16-meeting.png")); this.extendedAwayStatus = new JabberPresenceStatus(35, EXTENDED_AWAY, loadIcon(iconPath + "/status16x16-xa.png")); this.awayStatus = new JabberPresenceStatus(40, AWAY, loadIcon(iconPath + "/status16x16-away.png")); this.availableStatus = new JabberPresenceStatus(65, AVAILABLE, loadIcon(iconPath + "/status16x16-online.png")); this.freeForChatStatus = new JabberPresenceStatus(85, FREE_FOR_CHAT, loadIcon(iconPath + "/status16x16-ffc.png")); this.unknownStatus = new JabberPresenceStatus(1, UNKNOWN, loadIcon(iconPath + "/status16x16-offline.png")); // Initialize the list of supported status states. supportedStatusSet.add(freeForChatStatus); supportedStatusSet.add(availableStatus); supportedStatusSet.add(awayStatus); supportedStatusSet.add(onThePhoneStatus); supportedStatusSet.add(inMeetingStatus); supportedStatusSet.add(extendedAwayStatus); supportedStatusSet.add(doNotDisturbStatus); supportedStatusSet.add(offlineStatus); } /** * Returns the offline Jabber status. * * @param statusName the name of the status. * @return the offline Jabber status. */ public JabberPresenceStatus getStatus(String statusName) { if (statusName.equals(AVAILABLE)) return availableStatus; else if (statusName.equals(OFFLINE)) return offlineStatus; else if (statusName.equals(FREE_FOR_CHAT)) return freeForChatStatus; else if (statusName.equals(DO_NOT_DISTURB)) return doNotDisturbStatus; else if (statusName.equals(AWAY)) return awayStatus; else if (statusName.equals(ON_THE_PHONE)) return onThePhoneStatus; else if(statusName.equals(IN_A_MEETING)) return inMeetingStatus; else if (statusName.equals(EXTENDED_AWAY)) return extendedAwayStatus; else return unknownStatus; } /** * Returns an iterator over all status instances supported by the sip * provider. * * @return an <tt>Iterator</tt> over all status instances supported by the * sip provider. */ public Iterator<PresenceStatus> getSupportedStatusSet() { return supportedStatusSet.iterator(); } /** * Get all status name as array. * * @return array of <tt>String</tt> representing the different status name */ public static String[] getStatusNames() { return new String[] { OFFLINE, DO_NOT_DISTURB, AWAY, AVAILABLE, FREE_FOR_CHAT }; } /** * Loads an image from a given image path. * * @param imagePath The path to the image resource. * @return The image extracted from the resource at the specified path. */ public static byte[] loadIcon(String imagePath) { return loadIcon(imagePath, JabberStatusEnum.class); } /** * Loads the icon. * * @param imagePath path of the image * @param clazz class name * @return the image bytes */ public static byte[] loadIcon(String imagePath, Class<?> clazz) { InputStream is = getResourceAsStream(imagePath, clazz); if(is == null) return null; byte[] icon = null; try { icon = new byte[is.available()]; is.read(icon); } catch (IOException exc) { logger.error("Failed to load icon: " + imagePath, exc); } finally { try { if(is != null) is.close(); } catch (IOException ex) { /* * We're closing an InputStream so there shouldn't be data loss * because of it (in contrast to an OutputStream) and a warning * in the log should be enough. */ logger.warn("Failed to close the InputStream of icon: " + imagePath, ex); } } return icon; } private static InputStream getResourceAsStream(String name, Class<?> clazz) { if (name.indexOf("://") != -1) { try { return new URL(name).openStream(); } catch (IOException ex) { /* * Well, we didn't really know whether the specified name * represented an URL so we just tried. We'll resort to * Class#getResourceAsStream then. */ } } ResourceManagementService resourcesService = ProtocolProviderActivator.getResourceService(); return resourcesService.getImageInputStreamForPath(name); } /** * An implementation of <tt>PresenceStatus</tt> that enumerates all states * that a Jabber contact can currently have. */ private static class JabberPresenceStatus extends PresenceStatus { /** * Creates an instance of <tt>JabberPresenceStatus</tt> with the * specified parameters. * * @param status the connectivity level of the new presence status * instance * @param statusName the name of the presence status. * @param statusIcon the icon associated with this status */ private JabberPresenceStatus(int status, String statusName, byte[] statusIcon) { super(status, statusName, statusIcon); } } }