001package com.pusher.client.channel;
002
003import com.google.gson.Gson;
004
005/**
006 * Represents a user that is subscribed to a
007 * {@link com.pusher.client.channel.PresenceChannel PresenceChannel}.
008 */
009public class User {
010
011    private static final Gson GSON = new Gson();
012    private final String id;
013    private final String jsonData;
014
015    /**
016     * Create a new user. Users should not be created within an application.
017     * Users are created within the library and represent subscriptions to
018     * presence channels.
019     *
020     * @param id       The user id
021     * @param jsonData The user JSON data
022     */
023    public User(final String id, final String jsonData) {
024        this.id = id;
025        this.jsonData = jsonData;
026    }
027
028    /**
029     * A unique identifier for the user within a Pusher application.
030     *
031     * @return The unique id.
032     */
033    public String getId() {
034        return id;
035    }
036
037    /**
038     * Custom additional information about a user as a String encoding a JSON
039     * hash
040     *
041     * @return The user info as a JSON string
042     */
043    public String getInfo() {
044        return jsonData;
045    }
046
047    /**
048     * <p>
049     * Custom additional information about a user decoded as a new instance of
050     * the provided POJO bean type
051     * </p>
052     *
053     * <p>
054     * e.g. if {@link #getInfo()} returns
055     * <code>{"name":"Mr User","number":9}</code> then you might implement as
056     * follows:
057     * </p>
058     *
059     * <pre>
060     * public class UserInfo {
061     *     private String name;
062     *     private Integer number;
063     *
064     *     public String getName() { return name; }
065     *     public void setName(String name) { this.name = name; }
066     *
067     *     public Integer getNumber() { return number; }
068     *     public void setNumber(Integer number) { this.number = number; }
069     * }
070     *
071     * UserInfo info = user.getInfo(UserInfo.class);
072     *
073     * info.getName() // returns "Mr User"
074     * info.getNumber() // returns 9
075     * </pre>
076     *
077     * @param <V>   The class of the info
078     * @param clazz the class into which the user info JSON representation should
079     *              be parsed.
080     * @return V An instance of clazz, populated with the user info
081     */
082    public <V> V getInfo(final Class<V> clazz) {
083        return GSON.fromJson(jsonData, clazz);
084    }
085
086    @Override
087    public String toString() {
088        return String.format("[User id=%s, data=%s]", id, jsonData);
089    }
090
091    @Override
092    public int hashCode() {
093        return id.hashCode() + (jsonData != null ? jsonData.hashCode() : 0);
094    }
095
096    @Override
097    public boolean equals(final Object other) {
098        if (other instanceof User) {
099            final User otherUser = (User) other;
100            return (getId().equals(otherUser.getId()) && this.getInfo().equals(otherUser.getInfo()));
101        }
102
103        return false;
104    }
105}