Skip to content

Commit 93d2d92

Browse files
committed
Added support for namespaces and multi-namespace models
1 parent 89ec787 commit 93d2d92

29 files changed

Lines changed: 460 additions & 217 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Version 2.36-SNAPSHOT
44

55
**Updates**
6+
* Added support for namespaces and multi-namespace models.
67
* Fixed Sta V2 time interval and time value deserialisation.
78

89

src/main/java/de/fraunhofer/iosb/ilt/frostclient/json/deserialize/EntityDeserializer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,15 @@ public Entity deserialize(JsonParser parser, DeserializationContext ctxt) throws
115115
while (currentToken == JsonToken.PROPERTY_NAME) {
116116
String fieldName = parser.currentName();
117117
parser.nextValue();
118-
if (fieldName.endsWith("@iot.count")) {
118+
if (fieldName.endsWith("@iot.count") || fieldName.endsWith("@count")) {
119119
deserialiseEntitySetCount(parser, fieldName, result);
120-
} else if (fieldName.endsWith("@iot.nextLink")) {
120+
} else if (fieldName.endsWith("@iot.nextLink") || fieldName.endsWith("@nextLink")) {
121121
deserialiseEntitySetNextLink(parser, fieldName, result);
122122
} else {
123123
PropertyData propertyData = propertyByName.get(fieldName);
124124
if (propertyData == null) {
125125
if (failOnUnknown) {
126-
final String message = "Unknown field: " + fieldName + " on " + entityType.entityName + " expected one of: " + propertyByName.keySet();
126+
final String message = "Unknown field: " + fieldName + " on " + entityType.name + " expected one of: " + propertyByName.keySet();
127127
throw new UnrecognizedPropertyException(parser, message, parser.currentLocation(), Entity.class, fieldName, null);
128128
} else {
129129
parser.readValueAsTree();

src/main/java/de/fraunhofer/iosb/ilt/frostclient/json/deserialize/EntitySetDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public EntitySet deserialize(JsonParser parser, DeserializationContext ctxt) thr
9393
} else if ("value".equals(fieldName)) {
9494
deserialiseEntitySet(parser, ctxt, result);
9595
} else if (failOnUnknown) {
96-
final String message = "Unknown field: " + fieldName + " on " + entityType.entityName + " set.";
96+
final String message = "Unknown field: " + fieldName + " on " + entityType.name + " set.";
9797
throw new UnrecognizedPropertyException(parser, message, parser.currentLocation(), EntitySet.class, fieldName, null);
9898
}
9999
currentToken = parser.nextToken();

src/main/java/de/fraunhofer/iosb/ilt/frostclient/model/Entity.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public EntityType getType() {
170170

171171
public Entity setEntityType(EntityType entityType) {
172172
if (this.entityType != null) {
173-
throw new IllegalArgumentException("the type of this entity is alread yet to " + this.entityType.entityName);
173+
throw new IllegalArgumentException("the type of this entity is alread yet to " + this.entityType.name);
174174
}
175175
this.entityType = entityType;
176176
return this;
@@ -221,7 +221,7 @@ public <P> P getProperty(Property<P> property, boolean autoLoad) {
221221
return (P) getSelfLink();
222222
}
223223
if (!entityType.hasProperty(property)) {
224-
throw new IllegalArgumentException(entityType.entityName + " has no property " + property.getName());
224+
throw new IllegalArgumentException(entityType.name + " has no property " + property.getName());
225225
}
226226
if (property instanceof EntityPropertyMain epm) {
227227
return (P) entityProperties.get(epm);
@@ -271,7 +271,7 @@ public <P> Entity setProperty(Property<P> property, P value) {
271271
return this;
272272
}
273273
if (!entityType.hasProperty(property)) {
274-
throw new IllegalArgumentException(entityType.entityName + " has no property " + property.getName());
274+
throw new IllegalArgumentException(entityType.name + " has no property " + property.getName());
275275
}
276276
if (property instanceof EntityPropertyMain epm) {
277277
entityProperties.put(epm, value);

src/main/java/de/fraunhofer/iosb/ilt/frostclient/model/EntityType.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ public class EntityType implements Comparable<EntityType>, ContainerType<EntityT
5050
private static final Logger LOGGER = LoggerFactory.getLogger(EntityType.class.getName());
5151

5252
/**
53-
* The entityName of this entity type as used in URLs.
53+
* The name of this entity type as used in URLs.
5454
*/
55-
public final String entityName;
55+
public final String name;
5656

5757
/**
5858
* The namespace of the Entity Type.
@@ -114,7 +114,7 @@ public class EntityType implements Comparable<EntityType>, ContainerType<EntityT
114114
private ToString toStringMethod;
115115

116116
public EntityType(String singular) {
117-
this.entityName = singular;
117+
this.name = singular;
118118
final int nameIdx = singular.lastIndexOf('.');
119119
if (nameIdx > 0) {
120120
namespace = singular.substring(0, nameIdx);
@@ -131,8 +131,13 @@ public boolean isOpenType() {
131131
return false;
132132
}
133133

134-
public void setNamespace(String namespace) {
134+
public String getNamespace() {
135+
return namespace;
136+
}
137+
138+
public EntityType setNamespace(String namespace) {
135139
this.namespace = namespace;
140+
return this;
136141
}
137142

138143
public void setMainContainer(String entityContainer) {
@@ -142,7 +147,7 @@ public void setMainContainer(String entityContainer) {
142147
if (this.mainSet.equals(entityContainer)) {
143148
return;
144149
}
145-
throw new IllegalStateException("Main EntityContainer for " + entityName + " already set to " + this.mainSet);
150+
throw new IllegalStateException("Main EntityContainer for " + name + " already set to " + this.mainSet);
146151
}
147152
}
148153

@@ -205,15 +210,24 @@ public void setPrimaryKey(PrimaryKey primaryKey) {
205210
}
206211
}
207212

208-
public String getEntityName() {
209-
return entityName;
213+
/**
214+
* Get the name of this entity type.
215+
*
216+
* @return the name of this entity type.
217+
*/
218+
public String getName() {
219+
return name;
210220
}
211221

212-
public String getShortName() {
213-
if (namespace.isEmpty()) {
214-
return entityName;
215-
}
216-
return entityName.substring(namespace.length() + 1);
222+
/**
223+
* Get the name of this entity type.
224+
*
225+
* @return the name of this entity type.
226+
* @deprecated use @{@link #getName()} instead.
227+
*/
228+
@Deprecated
229+
public String getEntityName() {
230+
return getName();
217231
}
218232

219233
public String getMainSetName() {
@@ -339,7 +353,7 @@ public void setModelRegistry(ModelRegistry modelRegistry) {
339353

340354
@Override
341355
public String toString() {
342-
return entityName;
356+
return name;
343357
}
344358

345359
/**
@@ -368,7 +382,7 @@ public String toString(Entity entity) {
368382

369383
@Override
370384
public int compareTo(EntityType o) {
371-
return entityName.compareTo(o.entityName);
385+
return name.compareTo(o.name);
372386
}
373387

374388
@Override
@@ -380,8 +394,8 @@ public boolean equals(Object obj) {
380394
return false;
381395
}
382396
EntityType other = (EntityType) obj;
383-
if (entityName.equals(other.entityName)) {
384-
LOGGER.error("Found other instance of {}", entityName);
397+
if (name.equals(other.name)) {
398+
LOGGER.error("Found other instance of {}", name);
385399
return true;
386400
}
387401
return false;
@@ -390,7 +404,7 @@ public boolean equals(Object obj) {
390404
@Override
391405
public int hashCode() {
392406
int hash = 7;
393-
hash = 67 * hash + Objects.hashCode(this.entityName);
407+
hash = 67 * hash + Objects.hashCode(this.name);
394408
return hash;
395409
}
396410

src/main/java/de/fraunhofer/iosb/ilt/frostclient/model/ModelRegistry.java

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static de.fraunhofer.iosb.ilt.frostclient.model.property.type.TypePrimitive.EDM_STRING;
2626
import static de.fraunhofer.iosb.ilt.frostclient.utils.SpecialNames.AT_IOT_SELF_LINK;
2727

28+
import de.fraunhofer.iosb.ilt.frostclient.exception.Exceptions;
2829
import de.fraunhofer.iosb.ilt.frostclient.model.property.EntityPropertyMain;
2930
import de.fraunhofer.iosb.ilt.frostclient.model.property.type.TypeComplex;
3031
import de.fraunhofer.iosb.ilt.frostclient.model.property.type.TypePrimitive;
@@ -46,13 +47,17 @@ public class ModelRegistry {
4647

4748
private static final Logger LOGGER = LoggerFactory.getLogger(ModelRegistry.class.getName());
4849

50+
public static final String DEFAULT_NAMESPACE = "de.FROST";
51+
52+
private final Set<String> namespaces = new LinkedHashSet<>();
53+
4954
/**
5055
* The global EntityProperty SelfLink.
5156
*/
5257
public static final EntityPropertyMain<String> EP_SELFLINK = new EntityPropertyMain<String>(AT_IOT_SELF_LINK, EDM_STRING).setAliases("selfLink");
5358

5459
/**
55-
* All entity types, by their entityName (both singular and mainSet).
60+
* All entity types, by their name (both singular and mainSet).
5661
*/
5762
private final Map<String, EntityType> entityTypesByName = new TreeMap<>();
5863

@@ -78,6 +83,40 @@ public class ModelRegistry {
7883

7984
private boolean initialised;
8085

86+
private String ensureNamespace(PropertyType type) {
87+
String namespace = type.getNamespace();
88+
if (StringHelper.isNullOrEmpty(namespace)) {
89+
namespace = maybeAddNamespace(namespace);
90+
type.setNamespace(namespace);
91+
return namespace;
92+
}
93+
return maybeAddNamespace(namespace);
94+
}
95+
96+
private String ensureNamespace(EntityType type) {
97+
String namespace = type.getNamespace();
98+
if (StringHelper.isNullOrEmpty(namespace)) {
99+
namespace = maybeAddNamespace(namespace);
100+
type.setNamespace(namespace);
101+
return namespace;
102+
}
103+
return maybeAddNamespace(namespace);
104+
}
105+
106+
public String maybeAddNamespace(String namespace) {
107+
if (StringHelper.isNullOrEmpty(namespace)) {
108+
namespace = DEFAULT_NAMESPACE;
109+
}
110+
if (namespaces.add(namespace)) {
111+
LOGGER.info("Registered namespace {}", namespace);
112+
}
113+
return namespace;
114+
}
115+
116+
public Set<String> getNamespaces() {
117+
return namespaces;
118+
}
119+
81120
/**
82121
* Register a new entity type. Registering the same type twice is a no-op,
83122
* registering a new entity type with a name that already exists causes an
@@ -87,16 +126,15 @@ public class ModelRegistry {
87126
* @return this ModelRegistry.
88127
*/
89128
public final ModelRegistry registerEntityType(EntityType type) {
90-
EntityType existing = entityTypesByName.get(type.entityName);
129+
String namespace = ensureNamespace(type);
130+
String fullName = ModelRegistry.fullName(namespace, type.getEntityName());
131+
EntityType existing = entityTypesByName.get(fullName);
91132
if (existing == type) {
92-
LOGGER.info("Entity type {} already registered.", type.entityName);
133+
LOGGER.info("Entity type {} already registered.", fullName);
93134
return this;
94135
}
95-
if (existing != null) {
96-
LOGGER.error("Duplicate entity type name: {}", type.entityName);
97-
throw new IllegalArgumentException("An entity type named " + type.entityName + " is already registered");
98-
}
99-
entityTypesByName.put(type.entityName, type);
136+
Exceptions.illegalArgumentIf(existing != null, "Duplicate entity type name: {}", fullName);
137+
entityTypesByName.put(fullName, type);
100138
entityTypes.add(type);
101139
type.setModelRegistry(this);
102140
return this;
@@ -107,14 +145,38 @@ public final ModelRegistry registerEntityContainer(String name, EntityType type)
107145
return this;
108146
}
109147

148+
private boolean hasNamespace(String name) {
149+
return name.contains(".");
150+
}
151+
152+
public final EntityType getEntityTypeForName(String namespace, String typeName) {
153+
return getEntityTypeForName(fullName(namespace, typeName));
154+
}
155+
110156
/**
111157
* Get the entity type with the given name.
112158
*
113159
* @param typeName The name of the entity type to find.
114160
* @return the entity type with the given name, or null.
115161
*/
116162
public final EntityType getEntityTypeForName(String typeName) {
117-
final EntityType type = entityTypesByName.get(typeName);
163+
EntityType type = entityTypesByName.get(typeName);
164+
if (type != null) {
165+
return type;
166+
}
167+
if (hasNamespace(typeName)) {
168+
LOGGER.info("No entity type found for name {}", typeName);
169+
return null;
170+
}
171+
for (String namespace : namespaces) {
172+
final String fullName = namespace + '.' + typeName;
173+
type = entityTypesByName.get(fullName);
174+
if (type != null) {
175+
LOGGER.info("Resolved entity type {} to {}", typeName, fullName);
176+
return type;
177+
}
178+
}
179+
LOGGER.info("No entity type found for name {}", typeName);
118180
return type;
119181
}
120182

@@ -131,12 +193,27 @@ public EntityType getEntityTypeForContainer(String name) {
131193
}
132194

133195
public ModelRegistry registerPropertyType(PropertyType type) {
134-
propertyTypes.put(type.getName(), type);
196+
ensureNamespace(type);
197+
String fullName = fullName(type.getNamespace(), type.getName());
198+
propertyTypes.put(fullName, type);
135199
return this;
136200
}
137201

202+
private PropertyType findPropertyType(String name) {
203+
if (name.contains(".")) {
204+
return propertyTypes.get(name);
205+
}
206+
for (var namespace : namespaces) {
207+
PropertyType type = propertyTypes.get(fullName(namespace, name));
208+
if (type != null) {
209+
return type;
210+
}
211+
}
212+
return null;
213+
}
214+
138215
public final PropertyType getPropertyType(String name) {
139-
PropertyType type = propertyTypes.get(name);
216+
PropertyType type = findPropertyType(name);
140217
if (type != null) {
141218
return type;
142219
}
@@ -187,4 +264,7 @@ public boolean isInitialised() {
187264
return initialised;
188265
}
189266

267+
public static final String fullName(String namespace, String name) {
268+
return namespace == null ? name : namespace + '.' + name;
269+
}
190270
}

0 commit comments

Comments
 (0)