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