Changeset 2284 in josm for trunk/src/org/openstreetmap/josm


Ignore:
Timestamp:
2009-10-13T19:40:21+02:00 (10 years ago)
Author:
jttt
Message:

Added PrimitiveData classes. Uses PrimitiveData as storage for Command's undo function

Location:
trunk/src/org/openstreetmap/josm
Files:
5 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/command/Command.java

    r2025 r2284  
    1313import org.openstreetmap.josm.data.osm.Node;
    1414import org.openstreetmap.josm.data.osm.OsmPrimitive;
     15import org.openstreetmap.josm.data.osm.PrimitiveData;
    1516import org.openstreetmap.josm.data.osm.Relation;
    1617import org.openstreetmap.josm.data.osm.Way;
     
    2526 *
    2627 * The command remembers the {@see OsmDataLayer} it is operating on.
    27  * 
     28 *
    2829 * @author imi
    2930 */
     
    3132
    3233    private static final class CloneVisitor extends AbstractVisitor {
    33         public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
     34        public Map<OsmPrimitive, PrimitiveData> orig = new HashMap<OsmPrimitive, PrimitiveData>();
    3435
    3536        public void visit(Node n) {
    36             orig.put(n, new Node(n));
     37            orig.put(n, n.save());
    3738        }
    3839        public void visit(Way w) {
    39             orig.put(w, new Way(w));
     40            orig.put(w, w.save());
    4041        }
    4142        public void visit(Relation e) {
    42             orig.put(e, new Relation(e));
     43            orig.put(e, e.save());
    4344        }
    4445    }
    4546
    4647    /** the map of OsmPrimitives in the original state to OsmPrimitives in cloned state */
    47     private Map<OsmPrimitive, OsmPrimitive> cloneMap = new HashMap<OsmPrimitive, OsmPrimitive>();
     48    private Map<OsmPrimitive, PrimitiveData> cloneMap = new HashMap<OsmPrimitive, PrimitiveData>();
    4849
    4950    /** the layer which this command is applied to */
     
    5657    /**
    5758     * Creates a new command in the context of a specific data layer
    58      * 
     59     *
    5960     * @param layer the data layer
    6061     */
     
    8687     */
    8788    public void undoCommand() {
    88         for (Entry<OsmPrimitive, OsmPrimitive> e : cloneMap.entrySet()) {
    89             e.getKey().cloneFrom(e.getValue());
     89        for (Entry<OsmPrimitive, PrimitiveData> e : cloneMap.entrySet()) {
     90            e.getKey().load(e.getValue(), layer.data);
    9091        }
    9192    }
     
    9596     * any buffer if it is not longer applicable to the dataset (e.g. it was part of
    9697     * the removed layer)
    97      * 
     98     *
    9899     * @param oldLayer the old layer
    99100     * @return true if this command
     
    109110     * of the object. Usually for undoing.
    110111     */
    111     public OsmPrimitive getOrig(OsmPrimitive osm) {
    112         OsmPrimitive o = cloneMap.get(osm);
     112    public PrimitiveData getOrig(OsmPrimitive osm) {
     113        PrimitiveData o = cloneMap.get(osm);
    113114        if (o != null)
    114115            return o;
    115116        Main.debug("unable to find osm with id: " + osm.getId() + " hashCode: " + osm.hashCode());
    116117        for (OsmPrimitive t : cloneMap.keySet()) {
    117             OsmPrimitive to = cloneMap.get(t);
     118            PrimitiveData to = cloneMap.get(t);
    118119            Main.debug("now: " + t.getId() + " hashCode: " + t.hashCode());
    119120            Main.debug("orig: " + to.getId() + " hashCode: " + to.hashCode());
     
    124125    /**
    125126     * Replies the layer this command is (or was) applied to.
    126      * 
     127     *
    127128     * @return
    128129     */
  • trunk/src/org/openstreetmap/josm/data/osm/Node.java

    r2070 r2284  
    4646
    4747
     48    protected Node(long id, boolean allowNegative) {
     49        super(id, allowNegative);
     50    }
     51
     52
    4853    /**
    49      * Create a new local node with id 0.
    50      * 
     54     * Create a new local node.
     55     *
    5156     */
    5257    public Node() {
    53         this(0);
     58        this(0, false);
    5459    }
    5560
     
    5964     */
    6065    public Node(long id) {
    61         super(id);
     66        super(id, false);
    6267    }
    6368
     
    6671     */
    6772    public Node(Node clone) {
    68         super(clone.getId());
     73        super(clone.getUniqueId(), true);
    6974        cloneFrom(clone);
    7075    }
    7176
    7277    public Node(LatLon latlon) {
    73         super(0);
     78        super(0, false);
    7479        setCoor(latlon);
    7580    }
    7681
    7782    public Node(EastNorth eastNorth) {
    78         super(0);
     83        super(0, false);
    7984        setEastNorth(eastNorth);
     85    }
     86
     87    public Node(NodeData data, DataSet dataSet) {
     88        super(data);
     89        load(data, dataSet);
    8090    }
    8191
     
    8797        super.cloneFrom(osm);
    8898        setCoor(((Node)osm).coor);
     99    }
     100
     101    @Override public void load(PrimitiveData data, DataSet dataSet) {
     102        super.load(data, dataSet);
     103        setCoor(((NodeData)data).getCoor());
     104    }
     105
     106    @Override public NodeData save() {
     107        NodeData data = new NodeData();
     108        saveCommonAttributes(data);
     109        data.setCoor(getCoor());
     110        return data;
    89111    }
    90112
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r2273 r2284  
    1717import java.util.Set;
    1818import java.util.Map.Entry;
     19import java.util.concurrent.atomic.AtomicLong;
    1920
    2021import org.openstreetmap.josm.Main;
     
    3536abstract public class OsmPrimitive implements Comparable<OsmPrimitive>, Tagged {
    3637
     38    private static AtomicLong idCounter = new AtomicLong(0);
     39
    3740    private static final int FLAG_MODIFIED = 1 << 0;
    3841    private static final int FLAG_VISIBLE  = 1 << 1;
     
    147150
    148151    /**
    149      * Creates a new primitive with id 0.
    150      *
    151      */
    152     public OsmPrimitive() {
    153         this(0);
    154     }
    155 
    156     /**
    157152     * Creates a new primitive for the given id. If the id > 0, the primitive is marked
    158153     * as incomplete.
    159154     *
    160155     * @param id the id. > 0 required
    161      * @throws IllegalArgumentException thrown if id < 0
    162      */
    163     public OsmPrimitive(long id) throws IllegalArgumentException {
    164         if (id < 0)
    165             throw new IllegalArgumentException(tr("Expected ID >= 0. Got {0}.", id));
    166         this.id = id;
     156     * @param allowNegativeId Allows to set negative id. For internal use
     157     * @throws IllegalArgumentException thrown if id < 0 and allowNegativeId is false
     158     */
     159    protected OsmPrimitive(long id, boolean allowNegativeId) throws IllegalArgumentException {
     160        if (allowNegativeId) {
     161            this.id = id;
     162        } else {
     163            if (id < 0) {
     164                throw new IllegalArgumentException(tr("Expected ID >= 0. Got {0}.", id));
     165            } else if (id == 0) {
     166                this.id = idCounter.decrementAndGet();
     167            } else {
     168                this.id = id;
     169            }
     170
     171        }
    167172        this.version = 0;
    168         this.incomplete = id >0;
     173        this.incomplete = id > 0;
     174    }
     175
     176    protected OsmPrimitive(PrimitiveData data) {
     177        version = data.getVersion();
     178        id = data.getId();
    169179    }
    170180
     
    306316     */
    307317    public void setVisible(boolean visible) throws IllegalStateException{
    308         if (id == 0 && visible == false)
     318        if (isNew() && visible == false)
    309319            throw new IllegalStateException(tr("A primitive with ID = 0 can't be invisible."));
    310320        if (visible) {
     
    331341     */
    332342    public long getId() {
     343        return id >= 0?id:0;
     344    }
     345
     346    /**
     347     *
     348     * @return Osm id if primitive already exists on the server. Unique negative value if primitive is new
     349     */
     350    public long getUniqueId() {
    333351        return id;
    334352    }
    335353
    336354    /**
    337      * 
     355     *
    338356     * @return True if primitive is new (not yet uploaded the server, id <= 0)
    339357     */
     
    473491     */
    474492    @Override public boolean equals(Object obj) {
    475         if (id == 0) return obj == this;
     493        if (isNew()) return obj == this;
    476494        if (obj instanceof OsmPrimitive)
    477495            return ((OsmPrimitive)obj).id == id && obj.getClass() == getClass();
     
    660678     */
    661679    public boolean hasEqualSemanticAttributes(OsmPrimitive other) {
    662         if (id != other.id)
     680        if (!isNew() &&  id != other.id)
    663681            return false;
    664682        if (incomplete && ! other.incomplete || !incomplete  && other.incomplete)
     
    782800     */
    783801    public abstract String getDisplayName(NameFormatter formatter);
     802
     803    /**
     804     * Loads (clone) this primitive from provided PrimitiveData
     805     * @param data
     806     * @param dataSet Dataset this primitive is part of. This parameter is used only
     807     * temporarily. OsmPrimitive will have final field dataset in future
     808     */
     809    public void load(PrimitiveData data, DataSet dataSet) {
     810        setKeys(data.getKeys());
     811        timestamp = data.getTimestamp();
     812        user = data.getUser();
     813        setDeleted(data.isDeleted());
     814        setModified(data.isModified());
     815        setVisible(data.isVisible());
     816    }
     817
     818    /**
     819     * Save parameters of this primitive to the transport object
     820     * @return
     821     */
     822    public abstract PrimitiveData save();
     823
     824    protected void saveCommonAttributes(PrimitiveData data) {
     825        data.getKeys().clear();
     826        data.getKeys().putAll(getKeys());
     827        data.setTimestamp(timestamp);
     828        data.setUser(user);
     829        data.setDeleted(isDeleted());
     830        data.setModified(isModified());
     831        data.setVisible(isVisible());
     832    }
     833
    784834}
     835
  • trunk/src/org/openstreetmap/josm/data/osm/Relation.java

    r2083 r2284  
    22
    33import java.util.ArrayList;
     4import java.util.HashMap;
    45import java.util.HashSet;
    56import java.util.List;
     7import java.util.Map;
    68import java.util.Set;
    79
     
    1921     * All members of this relation. Note that after changing this,
    2022     * makeBackReferences and/or removeBackReferences should be called.
    21      * 
     23     *
    2224     */
    2325    private final List<RelationMember> members = new ArrayList<RelationMember>();
     
    106108    }
    107109
     110    protected Relation(long id, boolean allowNegative) {
     111        super(id, allowNegative);
     112    }
     113
    108114    /**
    109115     * Create a new relation with id 0
    110116     */
    111117    public Relation() {
    112         super(0);
     118        super(0, false);
    113119    }
    114120
     
    117123     */
    118124    public Relation(Relation clone) {
    119         super(clone.getId());
     125        super(clone.getUniqueId(), true);
    120126        cloneFrom(clone);
    121127    }
     
    124130     * Creates a new relation for the given id. If the id > 0, the way is marked
    125131     * as incomplete.
    126      * 
     132     *
    127133     * @param id the id. > 0 required
    128134     * @throws IllegalArgumentException thrown if id < 0
    129135     */
    130136    public Relation(long id) throws IllegalArgumentException {
    131         super(id);
     137        super(id, false);
     138    }
     139
     140    public Relation(RelationData data, DataSet dataSet) {
     141        super(data);
     142        load(data, dataSet);
    132143    }
    133144
     
    141152            members.add(new RelationMember(em));
    142153        }
     154    }
     155
     156    @Override public void load(PrimitiveData data, DataSet dataSet) {
     157        super.load(data, dataSet);
     158
     159        RelationData relationData = (RelationData)data;
     160
     161        // TODO Make this faster
     162
     163        Node nodeMarker = new Node();
     164        Way wayMarker = new Way();
     165        Relation relationMarker = new Relation();
     166        Map<Long, Node> nodes = new HashMap<Long, Node>();
     167        Map<Long, Way> ways = new HashMap<Long, Way>();
     168        Map<Long, Relation> relations = new HashMap<Long, Relation>();
     169
     170        for (RelationMemberData member:relationData.getMembers()) {
     171            switch (member.getMemberType()) {
     172            case NODE:
     173                nodes.put(member.getMemberId(), nodeMarker);
     174                break;
     175            case WAY:
     176                ways.put(member.getMemberId(), wayMarker);
     177                break;
     178            case RELATION:
     179                relations.put(member.getMemberId(), relationMarker);
     180                break;
     181            }
     182        }
     183
     184        for (Node node:dataSet.nodes) {
     185            if (nodes.get(node.getUniqueId()) == nodeMarker) {
     186                nodes.put(node.getUniqueId(), node);
     187            }
     188        }
     189        for (Way way:dataSet.ways) {
     190            if (ways.get(way.getUniqueId()) == wayMarker) {
     191                ways.put(way.getUniqueId(), way);
     192            }
     193        }
     194        for (Relation relation:dataSet.relations) {
     195            if (relations.get(relation.getUniqueId()) == relationMarker) {
     196                relations.put(relation.getUniqueId(), relation);
     197            }
     198        }
     199
     200        List<RelationMember> newMembers = new ArrayList<RelationMember>();
     201        for (RelationMemberData member:relationData.getMembers()) {
     202            OsmPrimitive foundMember = null;
     203            switch (member.getMemberType()) {
     204            case NODE:
     205                foundMember = nodes.get(member.getMemberId());
     206                if (foundMember == nodeMarker) {
     207                    foundMember = new Node(member.getMemberId(), true);
     208                }
     209                break;
     210            case WAY:
     211                foundMember = ways.get(member.getMemberId());
     212                if (foundMember == wayMarker) {
     213                    foundMember = new Way(member.getMemberId(), true);
     214                }
     215                break;
     216            case RELATION:
     217                foundMember = relations.get(member.getMemberId());
     218                if (foundMember == relationMarker) {
     219                    foundMember = new Relation(member.getMemberId(), true);
     220                }
     221                break;
     222            }
     223            newMembers.add(new RelationMember(member.getRole(), foundMember));
     224        }
     225        setMembers(newMembers);
     226    }
     227
     228    @Override public RelationData save() {
     229        RelationData data = new RelationData();
     230        saveCommonAttributes(data);
     231        for (RelationMember member:getMembers()) {
     232            data.getMembers().add(new RelationMemberData(member.getRole(), member.getMember()));
     233        }
     234        return data;
    143235    }
    144236
     
    206298     * Replies the set of  {@see OsmPrimitive}s referred to by at least one
    207299     * member of this relation
    208      * 
     300     *
    209301     * @return the set of  {@see OsmPrimitive}s referred to by at least one
    210302     * member of this relation
  • trunk/src/org/openstreetmap/josm/data/osm/User.java

    r2070 r2284  
    7373     */
    7474    public static List<User> getByName(String name) {
    75         name = name == null ? "" : name;
     75        if (name == null) {
     76            name = "";
     77        }
    7678        List<User> ret = new ArrayList<User>();
    7779        for (User user: userMap.values()) {
     
    8486
    8587    /** the user name */
    86     private String name;
     88    private final String name;
    8789    /** the user id */
    88     private long uid;
     90    private final long uid;
    8991
    9092    /**
     
    9496     */
    9597    public String getName() {
    96         return name == null ? "" : name;
     98        return name;
    9799    }
    98100
     
    113115    private User(long uid, String name) {
    114116        this.uid = uid;
    115         this.name = name;
     117        if (name == null) {
     118            this.name = "";
     119        } else {
     120            this.name = name;
     121        }
    116122    }
    117123
     
    128134        final int prime = 31;
    129135        int result = 1;
    130         result = prime * result + ((name == null) ? 0 : name.hashCode());
     136        result = prime * result + name.hashCode();
    131137        result = prime * result + (int) (uid ^ (uid >>> 32));
    132138        return result;
     
    135141    @Override
    136142    public boolean equals(Object obj) {
    137         if (this == obj)
     143        if (obj instanceof User) {
     144            User other = (User) obj;
     145            if (!name.equals(other.name))
     146                return false;
     147            if (uid != other.uid)
     148                return false;
    138149            return true;
    139         if (obj == null)
     150        } else
    140151            return false;
    141         if (getClass() != obj.getClass())
    142             return false;
    143         User other = (User) obj;
    144         if (name == null) {
    145             if (other.name != null)
    146                 return false;
    147         } else if (!name.equals(other.name))
    148             return false;
    149         if (uid != other.uid)
    150             return false;
    151         return true;
    152152    }
    153153}
  • trunk/src/org/openstreetmap/josm/data/osm/Way.java

    r2252 r2284  
    77import java.util.Arrays;
    88import java.util.Collection;
     9import java.util.HashMap;
    910import java.util.List;
     11import java.util.Map;
    1012
    1113import org.openstreetmap.josm.data.osm.visitor.Visitor;
     
    128130    }
    129131
     132    protected Way(long id, boolean allowNegative) {
     133        super(id, allowNegative);
     134    }
     135
    130136    /**
    131137     * Creates a new way with id 0.
     
    133139     */
    134140    public Way(){
    135         super(0);
     141        super(0, false);
    136142    }
    137143
     
    142148     */
    143149    public Way(Way original) {
    144         super(original.getId());
     150        super(original.getUniqueId(), true);
    145151        cloneFrom(original);
    146152    }
     
    154160     */
    155161    public Way(long id) throws IllegalArgumentException {
    156         super(id);
     162        super(id, false);
     163    }
     164
     165    public Way(WayData data, DataSet dataSet) {
     166        super(data);
     167        load(data, dataSet);
     168    }
     169
     170    /**
     171     *
     172     * @param data
     173     * @param dataSet Dataset this way is part of. This parameter will be removed in future
     174     */
     175    public void load(PrimitiveData data, DataSet dataSet) {
     176        super.load(data, dataSet);
     177
     178        WayData wayData = (WayData)data;
     179
     180        // TODO We should have some lookup by id mechanism in future to speed this up
     181        Node marker = new Node(0);
     182        Map<Long, Node> foundNodes = new HashMap<Long, Node>();
     183        for (Long nodeId:wayData.getNodes()) {
     184            foundNodes.put(nodeId, marker);
     185        }
     186        for (Node node:dataSet.nodes) {
     187            if (foundNodes.get(node.getUniqueId()) == marker) {
     188                foundNodes.put(node.getUniqueId(), node);
     189            }
     190        }
     191
     192        List<Node> newNodes = new ArrayList<Node>(wayData.getNodes().size());
     193        for (Long nodeId:wayData.getNodes()) {
     194            Node node = foundNodes.get(nodeId);
     195            if (node != marker) {
     196                newNodes.add(foundNodes.get(nodeId));
     197            } else {
     198                newNodes.add(new Node(nodeId, true));
     199            }
     200        }
     201        setNodes(newNodes);
     202    }
     203
     204    @Override public WayData save() {
     205        WayData data = new WayData();
     206        saveCommonAttributes(data);
     207        for (Node node:getNodes()) {
     208            data.getNodes().add(node.getUniqueId());
     209        }
     210        return data;
    157211    }
    158212
Note: See TracChangeset for help on using the changeset viewer.