001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.Date;
005
006import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
007import org.openstreetmap.josm.tools.LanguageInfo;
008
009/**
010 * IPrimitive captures the common functions of {@link OsmPrimitive} and {@link PrimitiveData}.
011 * @since 4098
012 */
013public interface IPrimitive extends Tagged, PrimitiveId, Stylable, Comparable<IPrimitive> {
014
015    /**
016     * Replies <code>true</code> if the object has been modified since it was loaded from
017     * the server. In this case, on next upload, this object will be updated.
018     *
019     * Deleted objects are deleted from the server. If the objects are added (id=0),
020     * the modified is ignored and the object is added to the server.
021     *
022     * @return <code>true</code> if the object has been modified since it was loaded from
023     * the server
024     */
025    boolean isModified();
026
027    /**
028     * Marks this primitive as being modified.
029     *
030     * @param modified true, if this primitive is to be modified
031     */
032    void setModified(boolean modified);
033
034    /**
035     * Checks if object is known to the server.
036     * Replies true if this primitive is either unknown to the server (i.e. its id
037     * is 0) or it is known to the server and it hasn't be deleted on the server.
038     * Replies false, if this primitive is known on the server and has been deleted
039     * on the server.
040     *
041     * @return <code>true</code>, if the object is visible on server.
042     * @see #setVisible(boolean)
043     */
044    boolean isVisible();
045
046    /**
047     * Sets whether this primitive is visible, i.e. whether it is known on the server
048     * and not deleted on the server.
049     * @param visible {@code true} if this primitive is visible
050     *
051     * @throws IllegalStateException if visible is set to false on an primitive with id==0
052     * @see #isVisible()
053     */
054    void setVisible(boolean visible);
055
056    /**
057     * Replies <code>true</code>, if the object has been deleted.
058     *
059     * @return <code>true</code>, if the object has been deleted.
060     * @see #setDeleted(boolean)
061     */
062    boolean isDeleted();
063
064    /**
065     * Sets whether this primitive is deleted or not.
066     *
067     * Also marks this primitive as modified if deleted is true.
068     *
069     * @param deleted  true, if this primitive is deleted; false, otherwise
070     */
071    void setDeleted(boolean deleted);
072
073    /**
074     * Determines if this primitive is incomplete.
075     * @return {@code true} if this primitive is incomplete, {@code false} otherwise
076     */
077    boolean isIncomplete();
078
079    /**
080     * Replies <code>true</code> if the object has been deleted on the server and was undeleted by the user.
081     * @return <code>true</code> if the object has been undeleted
082     */
083    boolean isUndeleted();
084
085    /**
086     * Replies <code>true</code>, if the object is usable
087     * (i.e. complete and not deleted).
088     *
089     * @return <code>true</code>, if the object is usable.
090     * @see #setDeleted(boolean)
091     */
092    boolean isUsable();
093
094    /**
095     * Determines if this primitive is new or undeleted.
096     * @return True if primitive is new or undeleted
097     * @see #isNew()
098     * @see #isUndeleted()
099     */
100    boolean isNewOrUndeleted();
101
102    /**
103     * Replies true, if this primitive is disabled. (E.g. a filter applies)
104     * @return {@code true} if this object has the "disabled" flag enabled
105     * @since 13662
106     */
107    default boolean isDisabled() {
108        return false;
109    }
110
111    /**
112     * Replies true, if this primitive is disabled and marked as completely hidden on the map.
113     * @return {@code true} if this object has both the "disabled" and "hide if disabled" flags enabled
114     * @since 13662
115     */
116    default boolean isDisabledAndHidden() {
117        return false;
118    }
119
120    /**
121     * Determines if this object is selectable.
122     * <p>
123     * A primitive can be selected if all conditions are met:
124     * <ul>
125     * <li>it is drawable
126     * <li>it is not disabled (greyed out) by a filter.
127     * </ul>
128     * @return {@code true} if this object is selectable
129     * @since 13664
130     */
131    default boolean isSelectable() {
132        return true;
133    }
134
135    /**
136     * Determines if this object is drawable.
137     * <p>
138     * A primitive is complete if all conditions are met:
139     * <ul>
140     * <li>type and id is known
141     * <li>tags are known
142     * <li>it is not deleted
143     * <li>it is not hidden by a filter
144     * <li>for nodes: lat/lon are known
145     * <li>for ways: all nodes are known and complete
146     * <li>for relations: all members are known and complete
147     * </ul>
148     * @return {@code true} if this object is drawable
149     * @since 13664
150     */
151    default boolean isDrawable() {
152        return true;
153    }
154
155    /**
156     * Determines whether the primitive is selected
157     * @return whether the primitive is selected
158     * @since 13664
159     */
160    default boolean isSelected() {
161        return false;
162    }
163
164    /**
165     * Determines if this primitive is a member of a selected relation.
166     * @return {@code true} if this primitive is a member of a selected relation, {@code false} otherwise
167     * @since 13664
168     */
169    default boolean isMemberOfSelected() {
170        return false;
171    }
172
173    /**
174     * Determines if this primitive is an outer member of a selected multipolygon relation.
175     * @return {@code true} if this primitive is an outer member of a selected multipolygon relation, {@code false} otherwise
176     * @since 13664
177     */
178    default boolean isOuterMemberOfSelected() {
179        return false;
180    }
181
182    /**
183     * Replies the id of this primitive.
184     *
185     * @return the id of this primitive.
186     */
187    long getId();
188
189    /**
190     * Replies the unique primitive id for this primitive
191     *
192     * @return the unique primitive id for this primitive
193     */
194    PrimitiveId getPrimitiveId();
195
196    /**
197     * Replies the version number as returned by the API. The version is 0 if the id is 0 or
198     * if this primitive is incomplete.
199     * @return the version number as returned by the API
200     *
201     * @see PrimitiveData#setVersion(int)
202     */
203    int getVersion();
204
205    /**
206     * Sets the id and the version of this primitive if it is known to the OSM API.
207     *
208     * Since we know the id and its version it can't be incomplete anymore. incomplete
209     * is set to false.
210     *
211     * @param id the id. &gt; 0 required
212     * @param version the version &gt; 0 required
213     * @throws IllegalArgumentException if id &lt;= 0
214     * @throws IllegalArgumentException if version &lt;= 0
215     * @throws DataIntegrityProblemException if id is changed and primitive was already added to the dataset
216     */
217    void setOsmId(long id, int version);
218
219    /**
220     * Replies the user who has last touched this object. May be null.
221     *
222     * @return the user who has last touched this object. May be null.
223     */
224    User getUser();
225
226    /**
227     * Sets the user who has last touched this object.
228     *
229     * @param user the user
230     */
231    void setUser(User user);
232
233    /**
234     * Time of last modification to this object. This is not set by JOSM but
235     * read from the server and delivered back to the server unmodified. It is
236     * used to check against edit conflicts.
237     *
238     * @return date of last modification
239     * @see #setTimestamp
240     */
241    Date getTimestamp();
242
243    /**
244     * Time of last modification to this object. This is not set by JOSM but
245     * read from the server and delivered back to the server unmodified. It is
246     * used to check against edit conflicts.
247     *
248     * @return last modification as timestamp
249     * @see #setRawTimestamp
250     */
251    int getRawTimestamp();
252
253    /**
254     * Sets time of last modification to this object
255     * @param timestamp date of last modification
256     * @see #getTimestamp
257     */
258    void setTimestamp(Date timestamp);
259
260    /**
261     * Sets time of last modification to this object
262     * @param timestamp date of last modification
263     * @see #getRawTimestamp
264     */
265    void setRawTimestamp(int timestamp);
266
267    /**
268     * Determines if this primitive has no timestamp information.
269     * @return {@code true} if this primitive has no timestamp information
270     * @see #getTimestamp
271     * @see #getRawTimestamp
272     */
273    boolean isTimestampEmpty();
274
275    /**
276     * Replies the id of the changeset this primitive was last uploaded to.
277     * 0 if this primitive wasn't uploaded to a changeset yet or if the
278     * changeset isn't known.
279     *
280     * @return the id of the changeset this primitive was last uploaded to.
281     */
282    int getChangesetId();
283
284    /**
285     * Sets the changeset id of this primitive. Can't be set on a new primitive.
286     *
287     * @param changesetId the id. &gt;= 0 required.
288     * @throws IllegalStateException if this primitive is new.
289     * @throws IllegalArgumentException if id &lt; 0
290     */
291    void setChangesetId(int changesetId);
292
293    /**
294     * Makes the given visitor visit this primitive.
295     * @param visitor visitor
296     */
297    void accept(PrimitiveVisitor visitor);
298
299    /**
300     * Replies the name of this primitive. The default implementation replies the value
301     * of the tag <code>name</code> or null, if this tag is not present.
302     *
303     * @return the name of this primitive
304     */
305    String getName();
306
307    /**
308     * Replies a localized name for this primitive given by the value of the name tags
309     * accessed from very specific (language variant) to more generic (default name).
310     *
311     * @return the name of this primitive, <code>null</code> if no name exists
312     * @see LanguageInfo#getLanguageCodes
313     */
314    String getLocalName();
315
316    /**
317     * Replies the display name of a primitive formatted by <code>formatter</code>
318     * @param formatter formatter to use
319     *
320     * @return the display name
321     * @since 13564
322     */
323    String getDisplayName(NameFormatter formatter);
324
325    /**
326     * Gets the type this primitive is displayed at
327     * @return A {@link OsmPrimitiveType}
328     * @since 13564
329     */
330    default OsmPrimitiveType getDisplayType() {
331        return getType();
332    }
333
334    /**
335     * Updates the highlight flag for this primitive.
336     * @param highlighted The new highlight flag.
337     * @since 13664
338     */
339    void setHighlighted(boolean highlighted);
340
341    /**
342     * Checks if the highlight flag for this primitive was set
343     * @return The highlight flag.
344     * @since 13664
345     */
346    boolean isHighlighted();
347
348    /**
349     * Determines if this object is considered "tagged". To be "tagged", an object
350     * must have one or more "interesting" tags. "created_by" and "source"
351     * are typically considered "uninteresting" and do not make an object "tagged".
352     * @return true if this object is considered "tagged"
353     * @since 13662
354     */
355    boolean isTagged();
356
357    /**
358     * Determines if this object is considered "annotated". To be "annotated", an object
359     * must have one or more "work in progress" tags, such as "note" or "fixme".
360     * @return true if this object is considered "annotated"
361     * @since 13662
362     */
363    boolean isAnnotated();
364
365    /**
366     * Determines if this object is a relation and behaves as a multipolygon.
367     * @return {@code true} if it is a real multipolygon or a boundary relation
368     * @since 13667
369     */
370    default boolean isMultipolygon() {
371        return false;
372    }
373
374    /**
375     * true if this object has direction dependent tags (e.g. oneway)
376     * @return {@code true} if this object has direction dependent tags
377     * @since 13662
378     */
379    boolean hasDirectionKeys();
380
381    /**
382     * true if this object has the "reversed direction" flag enabled
383     * @return {@code true} if this object has the "reversed direction" flag enabled
384     * @since 13662
385     */
386    boolean reversedDirection();
387}