// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.notes;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.tools.date.DateUtils;
/**
* A map note. It always has at least one comment since a comment is required to create a note on osm.org.
* @since 7451
*/
public class Note {
/** Note state */
public enum State {
/** Note is open */
OPEN,
/** Note is closed */
CLOSED
}
/**
* Sorts notes in the following order:
* 1) Open notes
* 2) Closed notes
* 3) New notes
* Within each subgroup it sorts by ID
*/
public static final Comparator<Note> DEFAULT_COMPARATOR = (n1, n2) -> {
if (n1.getId() < 0 && n2.getId() > 0) {
return 1;
}
if (n1.getId() > 0 && n2.getId() < 0) {
return -1;
}
if (n1.getState() == State.CLOSED && n2.getState() == State.OPEN) {
return 1;
}
if (n1.getState() == State.OPEN && n2.getState() == State.CLOSED) {
return -1;
}
return Long.compare(Math.abs(n1.getId()), Math.abs(n2.getId()));
};
/** Sorts notes strictly by creation date */
public static final Comparator<Note> DATE_COMPARATOR = (n1, n2) -> n1.createdAt.compareTo(n2.createdAt);
/** Sorts notes by user, then creation date */
public static final Comparator<Note> USER_COMPARATOR = (n1, n2) -> {
String n1User = n1.getFirstComment().getUser().getName();
String n2User = n2.getFirstComment().getUser().getName();
return n1User.equals(n2User) ? DATE_COMPARATOR.compare(n1, n2) : n1User.compareTo(n2User);
};
/** Sorts notes by the last modified date */
public static final Comparator<Note> LAST_ACTION_COMPARATOR =
(n1, n2) -> NoteComment.DATE_COMPARATOR.compare(n1.getLastComment(), n2.getLastComment());
private long id;
private LatLon latLon;
private Date createdAt;
private Date closedAt;
private State state;
private List<NoteComment> comments = new ArrayList<>();
/**
* Create a note with a given location
* @param latLon Geographic location of this note
*/
public Note(LatLon latLon) {
this.latLon = latLon;
}
/** @return The unique OSM ID of this note */
public long getId() {
return id;
}
/**
* Sets note id.
* @param id OSM ID of this note
*/
public void setId(long id) {
this.id = id;
}
/** @return The geographic location of the note */
public LatLon getLatLon() {
return latLon;
}
/** @return Date that this note was submitted */
public Date getCreatedAt() {
return DateUtils.cloneDate(createdAt);
}
/**
* Sets date at which this note has been created.
* @param createdAt date at which this note has been created
*/
public void setCreatedAt(Date createdAt) {
this.createdAt = DateUtils.cloneDate(createdAt);
}
/** @return Date that this note was closed. Null if it is still open. */
public Date getClosedAt() {
return DateUtils.cloneDate(closedAt);
}
/**
* Sets date at which this note has been closed.
* @param closedAt date at which this note has been closed
*/
public void setClosedAt(Date closedAt) {
this.closedAt = DateUtils.cloneDate(closedAt);
}
/** @return The open or closed state of this note */
public State getState() {
return state;
}
/**
* Sets the note state.
* @param state note state (open or closed)
*/
public void setState(State state) {
this.state = state;
}
/** @return An ordered list of comments associated with this note */
public List<NoteComment> getComments() {
return comments;
}
/**
* Returns the last comment, or {@code null}.
* @return the last comment, or {@code null}
* @since 11821
*/
public NoteComment getLastComment() {
return comments.isEmpty() ? null : comments.get(comments.size()-1);
}
/**
* Adds a comment.
* @param comment note comment
*/
public void addComment(NoteComment comment) {
comments.add(comment);
}
/**
* Returns the comment that was submitted by the user when creating the note
* @return First comment object
*/
public NoteComment getFirstComment() {
return comments.isEmpty() ? null : comments.get(0);
}
/**
* Copies values from a new note into an existing one. Used after a note
* has been updated on the server and the local copy needs refreshing.
* @param note New values to copy
*/
public void updateWith(Note note) {
this.comments = note.comments;
this.createdAt = DateUtils.cloneDate(note.createdAt);
this.id = note.id;
this.state = note.state;
this.latLon = note.latLon;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Note note = (Note) obj;
return id == note.id;
}
@Override
public String toString() {
return tr("Note") + ' ' + id + ": " + getFirstComment();
}
}