AbstractEntity.java (3703B) download
1package osm.message;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.List;
6
7import osm.common.ConsumingIterator;
8import osm.common.TagMap;
9import protobuf.Message;
10import protobuf.ProtobufReader;
11
12/**
13 * An abstract base class representing a generic entity with common properties
14 * for OSM data.
15 *
16 * @param <T> The type of the concrete entity extending this abstract class.
17 */
18abstract class AbstractEntity<T> implements Message<T>, Entity {
19 // required int64 id = 1;
20 // repeated uint32 keys = 2 [packed = true];
21 // repeated uint32 vals = 3 [packed = true];
22
23 /**
24 * The PrimitiveBlock associated with this entity.
25 */
26 public final PrimitiveBlock block;
27
28 /**
29 * The unique identifier for the entity.
30 */
31 protected long id;
32
33 /**
34 * The list of keys associated with the entity's tags.
35 */
36 protected List<String> keys = new ArrayList<>();
37
38 /**
39 * The list of values associated with the entity's tags.
40 */
41 protected List<String> values = new ArrayList<>();
42
43 /**
44 * The TagMap representing the tags associated with the entity.
45 */
46 protected final TagMap tags = new TagMap(keys, values);
47
48 /**
49 * Constructs an AbstractEntity with the specified PrimitiveBlock.
50 *
51 * @param block The PrimitiveBlock associated with this entity.
52 */
53 public AbstractEntity(PrimitiveBlock block) {
54 this.block = block;
55 }
56
57 /**
58 * Gets the unique identifier of the entity.
59 *
60 * @return The entity's unique identifier.
61 */
62 @Override
63 public long getID() {
64 return id;
65 }
66
67 /**
68 * Gets the TagMap representing the tags associated with the entity.
69 *
70 * @return The TagMap containing the entity's tags.
71 */
72 @Override
73 public TagMap getTags() {
74 return tags;
75 }
76
77 /**
78 * Parses Protobuf data for the entity using a custom iterator.
79 *
80 * @param tags The iterator providing Protobuf data elements.
81 * @return The parsed entity.
82 */
83 @Override
84 public T parse(Iterator<ProtobufReader> tags) {
85 return parseRemaining(
86 new ConsumingIterator<>(tags, message -> {
87 switch (message.tag()) {
88 case 1 -> id = message.varint64();
89 case 2 -> message.packed(message::varint32, block.stringtable::get)
90 .forEachRemaining(keys::add);
91 case 3 -> message.packed(message::varint32, block.stringtable::get)
92 .forEachRemaining(values::add);
93 default -> {
94 return false;
95 }
96 }
97 return true;
98 }));
99 }
100
101 /**
102 * Checks if the current entity is equal to another object.
103 *
104 * @param other The object to compare with.
105 * @return {@code true} if the entities are equal, {@code false} otherwise.
106 */
107 @Override
108 public boolean equals(Object other) {
109 if (other instanceof Entity otherEntity)
110 return otherEntity.getID() == id;
111
112 return false;
113 }
114
115 /**
116 * Generates a hash code for the entity based on its unique identifier.
117 *
118 * @return The hash code for the entity.
119 */
120 @Override
121 public int hashCode() {
122 return Long.hashCode(id);
123 }
124
125 /**
126 * Parses the remaining Protobuf data specific to the concrete entity.
127 *
128 * @param tags The iterator providing Protobuf data elements.
129 * @return The parsed entity.
130 */
131 protected abstract T parseRemaining(Iterator<ProtobufReader> tags);
132}