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

Last change on this file since 4602 was 4602, checked in by bastiK, 12 years ago

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

  • Property svn:eol-style set to native
File size: 9.2 KB
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.