001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.io.IOException;
005import java.io.ObjectInputStream;
006import java.io.ObjectOutputStream;
007import java.io.Serializable;
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.Collection;
011import java.util.Collections;
012import java.util.List;
013import java.util.Map;
014
015import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
016import org.openstreetmap.josm.gui.mappaint.StyleCache;
017
018/**
019 * This class can be used to save properties of OsmPrimitive.
020 *
021 * The main difference between PrimitiveData
022 * and OsmPrimitive is that PrimitiveData is not part of the dataset and changes in PrimitiveData are not
023 * reported by events
024 */
025public abstract class PrimitiveData extends AbstractPrimitive implements Serializable {
026
027    private static final long serialVersionUID = -1044837092478109138L;
028
029    /**
030     * Constructs a new {@code PrimitiveData}.
031     */
032    public PrimitiveData() {
033        this(OsmPrimitive.generateUniqueId());
034    }
035
036    /**
037     * Constructs a new {@code PrimitiveData} with given id.
038     * @param id id
039     * @since 12017
040     */
041    public PrimitiveData(long id) {
042        this.id = id;
043    }
044
045    /**
046     * Constructs a new {@code PrimitiveData} from an existing one.
047     * @param data the data to copy
048     */
049    public PrimitiveData(PrimitiveData data) {
050        cloneFrom(data);
051    }
052
053    /**
054     * Sets the primitive identifier.
055     * @param id primitive identifier
056     */
057    public void setId(long id) {
058        this.id = id;
059    }
060
061    /**
062     * Sets the primitive version.
063     * @param version primitive version
064     */
065    public void setVersion(int version) {
066        this.version = version;
067    }
068
069    /**
070     * override to make it public
071     */
072    @Override
073    public void setIncomplete(boolean incomplete) {
074        super.setIncomplete(incomplete);
075    }
076
077    /**
078     * Returns a copy of this primitive data.
079     * @return a copy of this primitive data
080     */
081    public abstract PrimitiveData makeCopy();
082
083    @Override
084    public String toString() {
085        StringBuilder builder = new StringBuilder();
086        builder.append(id).append(' ').append(Arrays.toString(keys)).append(' ').append(getFlagsAsString());
087        return builder.toString();
088    }
089
090    /**
091     * Returns a filtered list for a given primitive type.
092     * @param <T> primitive type
093     * @param list list to filter
094     * @param type primitive type
095     * @return a filtered list for given primitive type
096     */
097    @SuppressWarnings("unchecked")
098    public static <T extends PrimitiveData> List<T> getFilteredList(Collection<T> list, OsmPrimitiveType type) {
099        List<T> ret = new ArrayList<>();
100        for (PrimitiveData p: list) {
101            if (type.getDataClass().isInstance(p)) {
102                ret.add((T) p);
103            }
104        }
105        return ret;
106    }
107
108    @Override
109    protected final void keysChangedImpl(Map<String, String> originalKeys) {
110    }
111
112    private void writeObject(ObjectOutputStream oos) throws IOException {
113        // since super class is not Serializable
114        oos.writeLong(id);
115        oos.writeLong(user == null ? -1 : user.getId());
116        oos.writeInt(version);
117        oos.writeInt(changesetId);
118        oos.writeInt(timestamp);
119        oos.writeObject(keys);
120        oos.writeShort(flags);
121        oos.defaultWriteObject();
122    }
123
124    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
125        // since super class is not Serializable
126        id = ois.readLong();
127        final long userId = ois.readLong();
128        user = userId == -1 ? null : User.getById(userId);
129        version = ois.readInt();
130        changesetId = ois.readInt();
131        timestamp = ois.readInt();
132        keys = (String[]) ois.readObject();
133        flags = ois.readShort();
134        ois.defaultReadObject();
135    }
136
137    @Override
138    public boolean isTagged() {
139        return hasKeys();
140    }
141
142    @Override
143    public boolean isAnnotated() {
144        return false;
145    }
146
147    @Override
148    public boolean hasDirectionKeys() {
149        return false;
150    }
151
152    @Override
153    public boolean reversedDirection() {
154        return false;
155    }
156
157    @Override
158    public void setHighlighted(boolean highlighted) {
159        // Override if needed
160    }
161
162    @Override
163    public boolean isHighlighted() {
164        return false;
165    }
166
167    @Override
168    public final List<PrimitiveData> getReferrers(boolean allowWithoutDataset) {
169        return Collections.emptyList();
170    }
171
172    @Override
173    public void visitReferrers(PrimitiveVisitor visitor) {
174        // Override if needed
175    }
176
177    @Override
178    public OsmData<?, ?, ?, ?> getDataSet() {
179        return null;
180    }
181
182    @Override
183    public StyleCache getCachedStyle() {
184        return null;
185    }
186
187    @Override
188    public void setCachedStyle(StyleCache mappaintStyle) {
189        // Override if needed
190    }
191
192    @Override
193    public boolean isCachedStyleUpToDate() {
194        return false;
195    }
196
197    @Override
198    public void declareCachedStyleUpToDate() {
199        // Override if needed
200    }
201}