source: josm/trunk/src/org/openstreetmap/josm/data/osm/NoteData.java@ 8115

Last change on this file since 8115 was 7937, checked in by bastiK, 10 years ago

add subversion property svn:eol=native

  • Property svn:eol-style set to native
File size: 10.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.Date;
8import java.util.List;
9import java.util.Map;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.data.coor.LatLon;
13import org.openstreetmap.josm.data.notes.Note;
14import org.openstreetmap.josm.data.notes.Note.State;
15import org.openstreetmap.josm.data.notes.NoteComment;
16import org.openstreetmap.josm.gui.JosmUserIdentityManager;
17
18/**
19 * Class to hold and perform operations on a set of notes
20 */
21public class NoteData {
22
23 private long newNoteId = -1;
24
25 private final List<Note> noteList;
26 private Note selectedNote = null;
27 private Comparator<Note> comparator = DEFAULT_COMPARATOR;
28
29 /**
30 * Sorts notes in the following order:
31 * 1) Open notes
32 * 2) Closed notes
33 * 3) New notes
34 * Within each subgroup it sorts by ID
35 */
36 public static final Comparator<Note> DEFAULT_COMPARATOR = new Comparator<Note>() {
37 @Override
38 public int compare(Note n1, Note n2) {
39 if (n1.getId() < 0 && n2.getId() > 0) {
40 return 1;
41 }
42 if (n1.getId() > 0 && n2.getId() < 0) {
43 return -1;
44 }
45 if (n1.getState() == State.closed && n2.getState() == State.open) {
46 return 1;
47 }
48 if (n1.getState() == State.open && n2.getState() == State.closed) {
49 return -1;
50 }
51 return Long.valueOf(Math.abs(n1.getId())).compareTo(Long.valueOf(Math.abs(n2.getId())));
52 }
53 };
54
55 /** Sorts notes strictly by creation date */
56 public static final Comparator<Note> DATE_COMPARATOR = new Comparator<Note>() {
57 @Override
58 public int compare(Note n1, Note n2) {
59 return n1.getCreatedAt().compareTo(n2.getCreatedAt());
60 }
61 };
62
63 /** Sorts notes by user, then creation date */
64 public static final Comparator<Note> USER_COMPARATOR = new Comparator<Note>() {
65 @Override
66 public int compare(Note n1, Note n2) {
67 String n1User = n1.getFirstComment().getUser().getName();
68 String n2User = n2.getFirstComment().getUser().getName();
69 if (n1User.equals(n2User)) {
70 return n1.getCreatedAt().compareTo(n2.getCreatedAt());
71 }
72 return n1.getFirstComment().getUser().getName().compareTo(n2.getFirstComment().getUser().getName());
73 }
74 };
75
76 /** Sorts notes by the last modified date */
77 public static final Comparator<Note> LAST_ACTION_COMPARATOR = new Comparator<Note>() {
78 @Override
79 public int compare(Note n1, Note n2) {
80 Date n1Date = n1.getComments().get(n1.getComments().size()-1).getCommentTimestamp();
81 Date n2Date = n2.getComments().get(n2.getComments().size()-1).getCommentTimestamp();
82 return n1Date.compareTo(n2Date);
83 }
84 };
85
86 /**
87 * Construct a new note container with an empty note list
88 */
89 public NoteData() {
90 noteList = new ArrayList<>();
91 }
92
93 /**
94 * Construct a new note container with a given list of notes
95 * @param notes The list of notes to populate the container with
96 */
97 public NoteData(List<Note> notes) {
98 noteList = notes;
99 Collections.sort(notes, comparator);
100 for (Note note : notes) {
101 if (note.getId() <= newNoteId) {
102 newNoteId = note.getId() - 1;
103 }
104 }
105 }
106
107 /**
108 * Returns the notes stored in this layer
109 * @return List of Note objects
110 */
111 public List<Note> getNotes() {
112 return noteList;
113 }
114
115 /** Returns the currently selected note
116 * @return currently selected note
117 */
118 public Note getSelectedNote() {
119 return selectedNote;
120 }
121
122 /** Set a selected note. Causes the dialog to select the note and
123 * the note layer to draw the selected note's comments.
124 * @param note Selected note. Null indicates no selection
125 */
126 public void setSelectedNote(Note note) {
127 selectedNote = note;
128 if (Main.map != null) {
129 Main.map.noteDialog.selectionChanged();
130 Main.map.mapView.repaint();
131 }
132 }
133
134 /**
135 * Return whether or not there are any changes in the note data set.
136 * These changes may need to be either uploaded or saved.
137 * @return true if local modifications have been made to the note data set. False otherwise.
138 */
139 public synchronized boolean isModified() {
140 for (Note note : noteList) {
141 if (note.getId() < 0) { //notes with negative IDs are new
142 return true;
143 }
144 for (NoteComment comment : note.getComments()) {
145 if (comment.getIsNew()) {
146 return true;
147 }
148 }
149 }
150 return false;
151 }
152
153 /**
154 * Add notes to the data set. It only adds a note if the ID is not already present
155 * @param newNotes A list of notes to add
156 */
157 public synchronized void addNotes(List<Note> newNotes) {
158 for (Note newNote : newNotes) {
159 if (!noteList.contains(newNote)) {
160 noteList.add(newNote);
161 }
162 if (newNote.getId() <= newNoteId) {
163 newNoteId = newNote.getId() - 1;
164 }
165 }
166 dataUpdated();
167 if (Main.isDebugEnabled()) {
168 Main.debug("notes in current set: " + noteList.size());
169 }
170 }
171
172 /**
173 * Create a new note
174 * @param location Location of note
175 * @param text Required comment with which to open the note
176 */
177 public synchronized void createNote(LatLon location, String text) {
178 if(text == null || text.isEmpty()) {
179 throw new IllegalArgumentException("Comment can not be blank when creating a note");
180 }
181 Note note = new Note(location);
182 note.setCreatedAt(new Date());
183 note.setState(State.open);
184 note.setId(newNoteId--);
185 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.opened, true);
186 note.addComment(comment);
187 if (Main.isDebugEnabled()) {
188 Main.debug("Created note {0} with comment: {1}", note.getId(), text);
189 }
190 noteList.add(note);
191 dataUpdated();
192 }
193
194 /**
195 * Add a new comment to an existing note
196 * @param note Note to add comment to. Must already exist in the layer
197 * @param text Comment to add
198 */
199 public synchronized void addCommentToNote(Note note, String text) {
200 if (!noteList.contains(note)) {
201 throw new IllegalArgumentException("Note to modify must be in layer");
202 }
203 if (note.getState() == State.closed) {
204 throw new IllegalStateException("Cannot add a comment to a closed note");
205 }
206 if (Main.isDebugEnabled()) {
207 Main.debug("Adding comment to note {0}: {1}", note.getId(), text);
208 }
209 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.commented, true);
210 note.addComment(comment);
211 dataUpdated();
212 }
213
214 /**
215 * Close note with comment
216 * @param note Note to close. Must already exist in the layer
217 * @param text Comment to attach to close action, if desired
218 */
219 public synchronized void closeNote(Note note, String text) {
220 if (!noteList.contains(note)) {
221 throw new IllegalArgumentException("Note to close must be in layer");
222 }
223 if (note.getState() != State.open) {
224 throw new IllegalStateException("Cannot close a note that isn't open");
225 }
226 if (Main.isDebugEnabled()) {
227 Main.debug("closing note {0} with comment: {1}", note.getId(), text);
228 }
229 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.closed, true);
230 note.addComment(comment);
231 note.setState(State.closed);
232 note.setClosedAt(new Date());
233 dataUpdated();
234 }
235
236 /**
237 * Reopen a closed note.
238 * @param note Note to reopen. Must already exist in the layer
239 * @param text Comment to attach to the reopen action, if desired
240 */
241 public synchronized void reOpenNote(Note note, String text) {
242 if (!noteList.contains(note)) {
243 throw new IllegalArgumentException("Note to reopen must be in layer");
244 }
245 if (note.getState() != State.closed) {
246 throw new IllegalStateException("Cannot reopen a note that isn't closed");
247 }
248 if (Main.isDebugEnabled()) {
249 Main.debug("reopening note {0} with comment: {1}", note.getId(), text);
250 }
251 NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.reopened, true);
252 note.addComment(comment);
253 note.setState(State.open);
254 dataUpdated();
255 }
256
257 private void dataUpdated() {
258 Collections.sort(noteList, comparator);
259 Main.map.noteDialog.setNoteList(noteList);
260 Main.map.mapView.repaint();
261 }
262
263 private User getCurrentUser() {
264 JosmUserIdentityManager userMgr = JosmUserIdentityManager.getInstance();
265 return User.createOsmUser(userMgr.getUserId(), userMgr.getUserName());
266 }
267
268 /**
269 * Updates notes with new state. Primarily to be used when updating the
270 * note layer after uploading note changes to the server.
271 * @param updatedNotes Map containing the original note as the key and the updated note as the value
272 */
273 public synchronized void updateNotes(Map<Note, Note> updatedNotes) {
274 for (Map.Entry<Note, Note> entry : updatedNotes.entrySet()) {
275 Note oldNote = entry.getKey();
276 Note newNote = entry.getValue();
277 oldNote.updateWith(newNote);
278 }
279 dataUpdated();
280 }
281
282 /** @return The current comparator being used to sort the note list */
283 public Comparator<Note> getCurrentSortMethod() {
284 return comparator;
285 }
286
287 /** Set the comparator to be used to sort the note list. Several are available
288 * as public static members of this class.
289 * @param comparator - The Note comparator to sort by
290 */
291 public void setSortMethod(Comparator<Note> comparator) {
292 this.comparator = comparator;
293 dataUpdated();
294 }
295}
Note: See TracBrowser for help on using the repository browser.