@@ -239,33 +239,60 @@ private static boolean addProperty(ObjectNode whereToAdd, String key, JsonNode v
239239 * @param id the "id" of the property.
240240 */
241241 public void addIdProperty (String name , String id ) {
242- JsonNode jsonNode = addToIdProperty ( name , id , this .properties .get (name ));
243- if ( jsonNode != null ) {
244- this .linkedTo .add (id );
245- this .properties .set (name , jsonNode );
246- this .notifyObservers ();
247- }
242+ mergeIdIntoValue ( id , this .properties .get (name ))
243+ . ifPresent ( newValue -> {
244+ this .linkedTo .add (id );
245+ this .properties .set (name , newValue );
246+ this .notifyObservers ();
247+ });
248248 }
249249
250- private static JsonNode addToIdProperty (String name , String id , JsonNode property ) {
251- ObjectMapper objectMapper = MyObjectMapper .getMapper ();
252- if (name != null && id != null ) {
253- if (property == null ) {
254- return objectMapper .createObjectNode ().put ("@id" , id );
255- } else {
256- if (property .isArray ()) {
257- ArrayNode ns = (ArrayNode ) property ;
258- ns .add (objectMapper .createObjectNode ().put ("@id" , id ));
259- return ns ;
260- } else {
261- ArrayNode newNodes = objectMapper .createArrayNode ();
262- newNodes .add (property );
263- newNodes .add (objectMapper .createObjectNode ().put ("@id" , id ));
264- return newNodes ;
265- }
266- }
250+ /**
251+ * Merges the given id into the current value,
252+ * using this representation: {"@id" : "id"}.
253+ * <p>
254+ * The current value can be null without errors.
255+ * Only the id will be considered in this case.
256+ * <p>
257+ * If the id is null-ish, it will not be added, similar to a null-ish value.
258+ * If the id is already present, nothing will be done.
259+ * If it is not an array and the id is not present, an array will be applied.
260+ *
261+ * @param id the id to add.
262+ * @param currentValue the current value of the property.
263+ * @return The updated value of the property.
264+ * Empty if value does not change!
265+ */
266+ private static Optional <JsonNode > mergeIdIntoValue (String id , JsonNode currentValue ) {
267+ if (id == null || id .isBlank ()) { return Optional .empty (); }
268+
269+ ObjectMapper jsonBuilder = MyObjectMapper .getMapper ();
270+ ObjectNode newIdObject = jsonBuilder .createObjectNode ().put ("@id" , id );
271+ if (currentValue == null || currentValue .isNull () || currentValue .isMissingNode ()) {
272+ return Optional .ofNullable (newIdObject );
273+ }
274+
275+ boolean isIdAlready = currentValue .asText ().equals (id );
276+ boolean isIdObjectAlready = currentValue .path ("@id" ).asText ().equals (id );
277+ boolean isArrayWithIdPresent = currentValue .valueStream ()
278+ .anyMatch (node -> node
279+ .path ("@id" )
280+ .asText ()
281+ .equals (id ));
282+ if (isIdAlready || isIdObjectAlready || isArrayWithIdPresent ) {
283+ return Optional .empty ();
284+ }
285+
286+ if (currentValue .isArray () && currentValue instanceof ArrayNode currentValueAsArray ) {
287+ currentValueAsArray .add (newIdObject );
288+ return Optional .of (currentValueAsArray );
289+ } else {
290+ // property is not an array, so we make it an array
291+ ArrayNode newNodes = jsonBuilder .createArrayNode ();
292+ newNodes .add (currentValue );
293+ newNodes .add (newIdObject );
294+ return Optional .of (newNodes );
267295 }
268- return null ;
269296 }
270297
271298 /**
@@ -369,6 +396,11 @@ protected String getId() {
369396 /**
370397 * Setting the id property of the entity, if the given value is not
371398 * null. If the id is not encoded, the encoding will be done.
399+ * <p>
400+ * <b>NOTE: IDs are not just names!</b> The ID may have effects
401+ * on parts of your crate! For example: If the entity represents a
402+ * file which will be copied into the crate, writers must use the
403+ * ID as filename.
372404 *
373405 * @param id the String representing the id.
374406 * @return the generic builder.
@@ -486,11 +518,11 @@ public T addProperty(String key, boolean value) {
486518 * @return the generic builder
487519 */
488520 public T addIdProperty (String name , String id ) {
489- JsonNode jsonNode = AbstractEntity .addToIdProperty ( name , id , this .properties .get (name ));
490- if ( jsonNode != null ) {
491- this .properties .set (name , jsonNode );
492- this .relatedItems .add (id );
493- }
521+ AbstractEntity .mergeIdIntoValue ( id , this .properties .get (name ))
522+ . ifPresent ( newValue -> {
523+ this .properties .set (name , newValue );
524+ this .relatedItems .add (id );
525+ });
494526 return self ();
495527 }
496528
0 commit comments