test_class.declarator: modifiedFeatures
test_class.modifier: private static
test_class.original_string: private static Features modifiedFeatures;
test_class.type: Features
test_class.var_name: modifiedFeatures
test_class.declarator: underTest
test_class.modifier: private
test_class.original_string: private ModifyFeaturesStrategy underTest;
test_class.type: ModifyFeaturesStrategy
test_class.var_name: underTest
test_class.file: services/things/persistence/src/test/java/org/eclipse/ditto/services/things/persistence/actors/strategies/commands/ModifyFeaturesStrategyTest.java
test_class.identifier: ModifyFeaturesStrategyTest
test_class.superclass: extends AbstractCommandStrategyTest
test_case.body: @Test
      public void modifyFeaturePropertiesSoThatThingGetsTooLarge() {
          final CommandStrategy.Context<ThingId> context = getDefaultContext();
  
          final Feature feature = Feature.newBuilder()
                  .properties(JsonObject.newBuilder().set("foo", false).set("bar", 42).build())
                  .withId("myFeature")
                  .build();
  
          final long staticOverhead = 80;
          final StringBuilder sb = new StringBuilder();
          for (int i = 0; i < THING_SIZE_LIMIT_BYTES - staticOverhead; i++) {
              sb.append('a');
          }
          final JsonObject largeAttributes = JsonObject.newBuilder()
                  .set("a", sb.toString())
                  .build();
          final ThingId thingId = ThingId.of("foo", "bar");
          final Thing thing = Thing.newBuilder()
                  .setId(thingId)
                  .setAttributes(largeAttributes)
                  .build();
  
          // creating the Thing should be possible as we are below the limit:
          CreateThing.of(thing, null, DittoHeaders.empty());
  
          final ModifyFeatures command =
                  ModifyFeatures.of(thingId, Features.newBuilder().set(feature).build(), DittoHeaders.empty());
  
          // but modifying the features which would cause the Thing to exceed the limit should not be allowed:
          assertThatThrownBy(() -> underTest.doApply(context, thing, NEXT_REVISION, command, null))
                  .isInstanceOf(ThingTooLargeException.class);
      }
test_case.class_method_signature: ModifyFeaturesStrategyTest.modifyFeaturePropertiesSoThatThingGetsTooLarge()
test_case.full_signature: @Test public void modifyFeaturePropertiesSoThatThingGetsTooLarge()
test_case.identifier: modifyFeaturePropertiesSoThatThingGetsTooLarge
test_case.invocations: getDefaultContext build withId properties newBuilder build set set newBuilder append build set newBuilder toString of build setAttributes setId newBuilder of empty of build set newBuilder empty isInstanceOf assertThatThrownBy doApply
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void modifyFeaturePropertiesSoThatThingGetsTooLarge()
focal_class.file: services/things/persistence/src/main/java/org/eclipse/ditto/services/things/persistence/actors/strategies/commands/ModifyFeaturesStrategy.java
focal_class.identifier: ModifyFeaturesStrategy
focal_class.class_method_signature: ModifyFeaturesStrategy.ModifyFeaturesStrategy()
focal_class.full_signature:   ModifyFeaturesStrategy()
focal_class.identifier: ModifyFeaturesStrategy
focal_class.parameters: ()
focal_class.signature:  ModifyFeaturesStrategy()
focal_class.class_method_signature: ModifyFeaturesStrategy.doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_class.full_signature: @Override protected Result<ThingEvent> doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_class.identifier: doApply
focal_class.modifiers: @Override protected
focal_class.parameters: (final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_class.return: Result<ThingEvent>
focal_class.signature: Result<ThingEvent> doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_class.class_method_signature: ModifyFeaturesStrategy.getModifyResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.full_signature: private Result<ThingEvent> getModifyResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.identifier: getModifyResult
focal_class.modifiers: private
focal_class.parameters: (final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.return: Result<ThingEvent>
focal_class.signature: Result<ThingEvent> getModifyResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.class_method_signature: ModifyFeaturesStrategy.getCreateResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.full_signature: private Result<ThingEvent> getCreateResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.identifier: getCreateResult
focal_class.modifiers: private
focal_class.parameters: (final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.return: Result<ThingEvent>
focal_class.signature: Result<ThingEvent> getCreateResult(final Context<ThingId> context, final long nextRevision,
              final ModifyFeatures command, @Nullable final Thing thing, @Nullable final Metadata metadata)
focal_class.class_method_signature: ModifyFeaturesStrategy.previousEntityTag(final ModifyFeatures command, @Nullable final Thing previousEntity)
focal_class.full_signature: @Override public Optional<EntityTag> previousEntityTag(final ModifyFeatures command, @Nullable final Thing previousEntity)
focal_class.identifier: previousEntityTag
focal_class.modifiers: @Override public
focal_class.parameters: (final ModifyFeatures command, @Nullable final Thing previousEntity)
focal_class.return: Optional<EntityTag>
focal_class.signature: Optional<EntityTag> previousEntityTag(final ModifyFeatures command, @Nullable final Thing previousEntity)
focal_class.class_method_signature: ModifyFeaturesStrategy.nextEntityTag(final ModifyFeatures command, @Nullable final Thing newEntity)
focal_class.full_signature: @Override public Optional<EntityTag> nextEntityTag(final ModifyFeatures command, @Nullable final Thing newEntity)
focal_class.identifier: nextEntityTag
focal_class.modifiers: @Override public
focal_class.parameters: (final ModifyFeatures command, @Nullable final Thing newEntity)
focal_class.return: Optional<EntityTag>
focal_class.signature: Optional<EntityTag> nextEntityTag(final ModifyFeatures command, @Nullable final Thing newEntity)
focal_class.superclass: extends AbstractThingCommandStrategy<ModifyFeatures>
focal_method.body: @Override
      protected Result<ThingEvent> doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata) {
  
          final Thing nonNullThing = getEntityOrThrow(thing);
  
          final JsonObject thingWithoutFeaturesJsonObject = nonNullThing.removeFeatures().toJson();
          final JsonObject featuresJsonObject = command.getFeatures().toJson();
  
          ThingCommandSizeValidator.getInstance().ensureValidSize(
                  () -> {
                      final long lengthWithOutFeatures = thingWithoutFeaturesJsonObject.getUpperBoundForStringSize();
                      final long featuresLength = featuresJsonObject.getUpperBoundForStringSize() + "features".length() + 5L;
                      return lengthWithOutFeatures + featuresLength;
                  },
                  () -> {
                      final long lengthWithOutFeatures = thingWithoutFeaturesJsonObject.toString().length();
                      final long featuresLength = featuresJsonObject.toString().length() + "features".length() + 5L;
                      return lengthWithOutFeatures + featuresLength;
                  },
                  command::getDittoHeaders);
  
          return nonNullThing.getFeatures()
                  .map(features -> getModifyResult(context, nextRevision, command, thing, metadata))
                  .orElseGet(() -> getCreateResult(context, nextRevision, command, thing, metadata));
      }
focal_method.class_method_signature: ModifyFeaturesStrategy.doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_method.full_signature: @Override protected Result<ThingEvent> doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_method.identifier: doApply
focal_method.invocations: getEntityOrThrow toJson removeFeatures toJson getFeatures ensureValidSize getInstance getUpperBoundForStringSize getUpperBoundForStringSize length length toString length toString length orElseGet map getFeatures getModifyResult getCreateResult
focal_method.modifiers: @Override protected
focal_method.parameters: (final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)
focal_method.return: Result<ThingEvent>
focal_method.signature: Result<ThingEvent> doApply(final Context<ThingId> context,
              @Nullable final Thing thing,
              final long nextRevision,
              final ModifyFeatures command,
              @Nullable final Metadata metadata)