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

Last change on this file since 4066 was 4066, checked in by framm, 13 years ago

add a member variable to User class for storing relicensing status,
allowing us to explicitly set it and not rely on users_agreed.txt;
to be used when relicensing info is loaded from another source.

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