source: josm/trunk/src/org/openstreetmap/josm/data/osm/User.java @ 5241

Revision 4602, 9.2 KB checked in by bastiK, 6 months ago (diff)

upgrade historic users to real users, so their CT status can be shown in the history panel

  • Property svn:eol-style set to native
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.BufferedReader;
7import java.io.InputStreamReader;
8import java.io.IOException;
9
10import java.util.ArrayList;
11import java.util.concurrent.atomic.AtomicLong;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.List;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.io.MirroredInputStream;
18import org.openstreetmap.josm.tools.Utils;
19
20/**
21 * A simple class to keep a list of user names.
22 *
23 * Instead of storing user names as strings with every OSM primitive, we store
24 * a reference to an user object, and make sure that for each username there
25 * is only one user object.
26 *
27 *
28 */
29public class User {
30
31    static private AtomicLong uidCounter = new AtomicLong();
32
33    /**
34     * the map of known users
35     */
36    private static HashMap<Long,User> userMap = new HashMap<Long,User>();
37    private static HashSet<Long> relicensingUsers = null;
38    private static HashSet<Long> nonRelicensingUsers = null;
39    private final static User anonymous = createLocalUser(tr("<anonymous>"));
40
41    private static long getNextLocalUid() {
42        return uidCounter.decrementAndGet();
43    }
44
45    /**
46     * Creates a local user with the given name
47     *
48     * @param name the name
49     */
50    public static User createLocalUser(String name) {
51        for(long i = -1; i >= uidCounter.get(); --i)
52        {
53          User olduser = getById(i);
54          if(olduser != null && olduser.hasName(name))
55            return olduser;
56        }
57        User user = new User(getNextLocalUid(), name);
58        userMap.put(user.getId(), user);
59        return user;
60    }
61
62    /**
63     * Creates a user known to the OSM server
64     *
65     * @param uid  the user id
66     * @param name the name
67     */
68    public static User createOsmUser(long uid, String name) {
69        User user = userMap.get(uid);
70        if (user == null) {
71            user = new User(uid, name);
72            userMap.put(user.getId(), user);
73        }
74        if (name != null) user.addName(name);
75        return user;
76    }
77
78    /**
79     * clears the static map of user ids to user objects
80     *
81     */
82    public static void clearUserMap() {
83        userMap.clear();
84    }
85
86    /**
87     * Returns the user with user id <code>uid</code> or null if this user doesn't exist
88     *
89     * @param uid the user id
90     * @return the user; null, if there is no user with  this id
91     */
92    public static User getById(long uid) {
93        return userMap.get(uid);
94    }
95
96    /**
97     * Returns the list of users with name <code>name</code> or the empty list if
98     * no such users exist
99     *
100     * @param name the user name
101     * @return the list of users with name <code>name</code> or the empty list if
102     * no such users exist
103     */
104    public static List<User> getByName(String name) {
105        if (name == null) {
106            name = "";
107        }
108        List<User> ret = new ArrayList<User>();
109        for (User user: userMap.values()) {
110            if (user.hasName(name)) {
111                ret.add(user);
112            }
113        }
114        return ret;
115    }
116
117    public static User getAnonymous() {
118        return anonymous;
119    }
120
121    public static void initRelicensingInformation() {
122        if (relicensingUsers == null) {
123            loadRelicensingInformation(false);
124        }
125    }
126
127    public static void loadRelicensingInformation(boolean clean) {
128        relicensingUsers = new HashSet<Long>();
129        nonRelicensingUsers = new HashSet<Long>();
130        try {
131            MirroredInputStream stream = new MirroredInputStream(
132                 Main.pref.get("url.licensechange",
133                    "http://planet.openstreetmap.org/users_agreed/users_agreed.txt"),
134                 clean ? 1 : 7200);
135            try {
136                InputStreamReader r;
137                r = new InputStreamReader(stream);
138                BufferedReader reader = new BufferedReader(r);
139                String line;
140                while ((line = reader.readLine()) != null) {
141                    if (line.startsWith("#")) continue;
142                    try {
143                        Long id = new Long(Long.parseLong(line.trim()));
144                        relicensingUsers.add(id);
145                    } catch (java.lang.NumberFormatException ex) {
146                    }
147                }
148            }
149            finally {
150                stream.close();
151            }
152        } catch (IOException ex) {
153        }
154
155        try {
156            MirroredInputStream stream = new MirroredInputStream(
157                Main.pref.get("url.licensechange_reject",
158                    "http://planet.openstreetmap.org/users_agreed/users_disagreed.txt"),
159                clean ? 1 : 7200);
160            try {
161                InputStreamReader r;
162                r = new InputStreamReader(stream);
163                BufferedReader reader = new BufferedReader(r);
164                String line;
165                while ((line = reader.readLine()) != null) {
166                    if (line.startsWith("#")) continue;
167                    try {
168                        Long id = new Long(Long.parseLong(line.trim()));
169                        nonRelicensingUsers.add(id);
170                    } catch (java.lang.NumberFormatException ex) {
171                    }
172                }
173            }
174            finally {
175                stream.close();
176            }
177        } catch (IOException ex) {
178        }
179    }
180
181    /** the user name */
182    private final HashSet<String> names = new HashSet<String>();
183    /** the user id */
184    private final long uid;
185    private int relicensingStatus = STATUS_UNKNOWN;
186
187    public static final int STATUS_UNKNOWN = -1;
188    public static final int STATUS_UNDECIDED = 0;
189    public static final int STATUS_AGREED = 1;
190    public static final int STATUS_NOT_AGREED = 2;
191    public static final int STATUS_AUTO_AGREED = 3;
192    public static final int STATUS_ANONYMOUS = 4;
193
194    /**
195    * Finds out this user's relicensing status and saves it for quicker
196    * access.
197    */
198    public int getRelicensingStatus() {
199        if (relicensingStatus != STATUS_UNKNOWN) return relicensingStatus;
200        if (uid >= 286582) return (relicensingStatus = STATUS_AUTO_AGREED);
201        if (relicensingUsers == null) return STATUS_UNKNOWN;
202        Long id = new Long(uid);
203        if (relicensingUsers.contains(id)) return (relicensingStatus = STATUS_AGREED);
204        if (nonRelicensingUsers == null) return STATUS_UNKNOWN;
205        if (nonRelicensingUsers.contains(id)) return (relicensingStatus = STATUS_NOT_AGREED);
206        return STATUS_UNDECIDED;
207    }
208
209    /**
210    * Sets this user's relicensing status. This can be used if relicensing
211    * information is available from another source so that directly looking
212    * at the users_agreed/users_not_agreed files it not required.
213    */
214    public void setRelicensingStatus(int status) {
215        relicensingStatus = status;
216    }
217
218    /**
219     * Replies the user name
220     *
221     * @return the user name. Never null, but may be the empty string
222     */
223    public String getName() {
224        return Utils.join("/", names);
225    }
226
227    /**
228     * Returns the list of user names
229     *
230     * @returns list of names
231     */
232    public ArrayList<String> getNames() {
233        return new ArrayList<String>(names);
234    }
235
236    /**
237     * Adds a user name to the list if it is not there, yet.
238     *
239     * @param name
240     */
241    public void addName(String name) {
242        names.add(name);
243    }
244
245    /**
246     * Returns true if the name is in the names list
247     *
248     * @param name
249     */
250    public boolean hasName(String name) {
251        return names.contains(name);
252    }
253
254    /**
255     * Replies the user id. If this user is known to the OSM server the positive user id
256     * from the server is replied. Otherwise, a negative local value is replied.
257     *
258     * A negative local is only unique during an editing session. It is lost when the
259     * application is closed and there is no guarantee that a negative local user id is
260     * always bound to a user with the same name.
261     *
262     */
263    public long getId() {
264        return uid;
265    }
266
267    /** private constructor, only called from get method. */
268    private User(long uid, String name) {
269        this.uid = uid;
270        if (name != null) {
271            addName(name);
272        }
273    }
274
275    public boolean isOsmUser() {
276        return uid > 0;
277    }
278
279    public boolean isLocalUser() {
280        return uid < 0;
281    }
282
283    @Override
284    public int hashCode() {
285        final int prime = 31;
286        int result = 1;
287        result = prime * result + getName().hashCode();
288        result = prime * result + (int) (uid ^ (uid >>> 32));
289        return result;
290    }
291
292    @Override
293    public boolean equals(Object obj) {
294        if (! (obj instanceof User))
295            return false;
296        User other = (User) obj;
297        if (uid != other.uid)
298            return false;
299        return true;
300    }
301
302    @Override
303    public String toString() {
304        StringBuffer s = new StringBuffer();
305        s.append("id:"+uid);
306        if (names.size() == 1) {
307            s.append(" name:"+getName());
308        }
309        else if (names.size() > 1) {
310            s.append(String.format(" %d names:%s", names.size(), getName()));
311        }
312        return s.toString();
313    }
314}
Note: See TracBrowser for help on using the repository browser.