From 05df9a03ab8d958c2c0a8271b97617e13260c2c4 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 23 Jan 2026 18:40:07 +0000 Subject: [PATCH 1/2] refactor and enhance entity app classes for clarity and robustness --- .../app/EntityDataDefaultsStoreImpl.java | 10 ++-- .../entities/app/EntityDataStoreImpl.java | 49 ++++++++++++------- .../entities/app/EntityDeserialization.java | 44 +++++++++-------- .../entities/app/EntityRegistryImpl.java | 4 +- .../entities/app/EventSourcing.java | 38 +++++++++----- .../entities/app/EventSourcingCache.java | 11 ++--- .../entities/app/EventStoreDefault.java | 31 ++++++++---- .../entities/app/EventSubscriptionsImpl.java | 7 +++ .../xtraplatform/entities/app/MapAligner.java | 6 ++- .../xtraplatform/entities/app/MapDiffer.java | 10 ++-- .../entities/app/MapSubtractor.java | 29 +++++------ 11 files changed, 144 insertions(+), 95 deletions(-) diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataDefaultsStoreImpl.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataDefaultsStoreImpl.java index c887298d..0db2d2a1 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataDefaultsStoreImpl.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataDefaultsStoreImpl.java @@ -66,6 +66,7 @@ @Singleton @AutoBind(interfaces = {EntityDataDefaultsStore.class, AppLifeCycle.class}) +@SuppressWarnings("PMD.TooManyMethods") public class EntityDataDefaultsStoreImpl extends AbstractMergeableKeyValueStore> implements EntityDataDefaultsStore, AppLifeCycle { @@ -87,6 +88,7 @@ public EntityDataDefaultsStoreImpl( Jackson jackson, Substitutions substitutions, Lazy> entityFactories) { + super(); StoreConfiguration store = appContext.getConfiguration().getStore(); this.entityFactories = new EntityFactoriesImpl(entityFactories); this.eventStore = eventStore; @@ -152,7 +154,7 @@ public boolean has(Predicate keyMatcher) { @Override public Map get(Identifier identifier) { - return null; + return new LinkedHashMap<>(); } })); @@ -290,7 +292,7 @@ public Map subtractDefaults( data, defaults, factory.getIgnoreKeys(), factory.getListEntryKeys()); } catch (Throwable e) { - boolean br = true; + // ignore } return data; @@ -346,7 +348,7 @@ public Optional> getAllDefaults( return Optional.ofNullable(defaults); } catch (Throwable e) { - boolean br = true; + // ignore } } @@ -375,7 +377,7 @@ private Map getDefaults(Identifier identifier) { return deserialize; } catch (IOException e) { - throw new RuntimeException(e); + throw new IllegalStateException("Error deserializing defaults", e); } } } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataStoreImpl.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataStoreImpl.java index c688ebc2..0b3f3c7d 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataStoreImpl.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDataStoreImpl.java @@ -74,6 +74,7 @@ */ @Singleton @AutoBind(interfaces = {EntityDataStore.class, AppLifeCycle.class}) +@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods"}) public class EntityDataStoreImpl extends AbstractMergeableKeyValueStore implements EntityDataStore, AppLifeCycle { @@ -125,6 +126,7 @@ public EntityDataStoreImpl( ResourceStore blobStore, ValueStore valueStore, boolean noDefaults) { + super(); StoreConfiguration store = appContext.getConfiguration().getStore(); this.isEventStoreReadOnly = eventStore.isReadOnly(); this.entityFactories = new EntityFactoriesImpl(entityFactories); @@ -184,7 +186,7 @@ public boolean has(Predicate keyMatcher) { @Override public Map get(Identifier identifier) { - return null; + return new LinkedHashMap<>(); } })); } @@ -229,6 +231,12 @@ protected Map modifyPatch(Map partialData) { } // TODO: onEmit middleware + @SuppressWarnings({ + "PMD.CyclomaticComplexity", + "PMD.NPathComplexity", + "PMD.CognitiveComplexity", + "PMD.CollapsibleIfStatements" + }) private List processEvent(ReplayEvent event) { if (valueEncoding.isEmpty(event.payload()) || !valueEncoding.isSupported(event.format())) { @@ -236,26 +244,29 @@ private List processEvent(ReplayEvent event) { } if (!event.isDelete() - && event.type().equals(EntityDataStore.EVENT_TYPE_ENTITIES) + && EntityDataStore.EVENT_TYPE_ENTITIES.equals(event.type()) && eventSourcing.has(isDuplicate(event.identifier()))) { - LOGGER.warn( - "Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single group.", - event.asPathNoType(), - event.source().orElse("UNKNOWN")); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn( + "Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single group.", + event.asPathNoType(), + event.source().orElse("UNKNOWN")); + } return List.of(); } if (!event.isDelete() - && event.type().equals(EntityDataStore.EVENT_TYPE_ENTITIES) + && EntityDataStore.EVENT_TYPE_ENTITIES.equals(event.type()) && eventSourcing.has(event.identifier())) { - LOGGER.warn( - "Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single source, use overrides to update it from another source.", - event.asPathNoType(), - event.source().orElse("UNKNOWN")); - return List.of(); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn( + "Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single source, use overrides to update it from another source.", + event.asPathNoType(), + event.source().orElse("UNKNOWN")); + } } - if (!event.type().equals(EntityDataStore.EVENT_TYPE_OVERRIDES)) { + if (!EntityDataStore.EVENT_TYPE_OVERRIDES.equals(event.type())) { return List.of(event); } @@ -266,8 +277,10 @@ private List processEvent(ReplayEvent event) { // override without matching entity if (!eventSourcing.has(cacheKey)) { - LOGGER.warn("Ignoring override '{}', no matching entity found", event.asPath()); - return List.of(); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Ignoring override '{}', no matching entity found", event.asPath()); + return List.of(); + } } ImmutableReplayEvent.Builder builder = @@ -484,10 +497,8 @@ protected CompletableFuture onCreate(Identifier identifier, EntityData ent .createInstance(hydratedData) .whenComplete( (entity, throwable) -> { - if (Objects.nonNull(entity)) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Entity created: {}", identifier); - } + if (Objects.nonNull(entity) && LOGGER.isTraceEnabled()) { + LOGGER.trace("Entity created: {}", identifier); } }) .thenAccept(ignore -> CompletableFuture.completedFuture(null)); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDeserialization.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDeserialization.java index aca87cb0..6f42f99c 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDeserialization.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityDeserialization.java @@ -36,12 +36,9 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; // TODO: public class EntityDeserialization { - private static final Logger LOGGER = LoggerFactory.getLogger(EntityDeserialization.class); public static final Module DESERIALIZE_MERGEABLE_MAP_BUILDER_WRAPPER = new SimpleModule() @@ -75,6 +72,7 @@ public JsonDeserializer modifyDeserializer( public static class ImmutableBuilderMapWrapperDeserializer extends BeanDeserializer { + private static final long serialVersionUID = 1L; private final String wrappedPropertyName; ImmutableBuilderMapWrapperDeserializer( @@ -83,7 +81,16 @@ public static class ImmutableBuilderMapWrapperDeserializer extends BeanDeseriali this.wrappedPropertyName = wrappedPropertyName; } + private List remapBeanProperties( + BeanDeserializer unwrapping, SettableBeanProperty mapProp, String wrappedPropertyName) { + Iterable iterable = unwrapping::properties; + return StreamSupport.stream(iterable.spliterator(), false) + .map(prop -> prop == mapProp ? mapProp.withSimpleName(wrappedPropertyName) : prop) + .collect(Collectors.toList()); + } + @Override + @SuppressWarnings("PMD.AvoidDeeplyNestedIfStmts") public void resolve(DeserializationContext ctxt) throws JsonMappingException { super.resolve(ctxt); @@ -97,20 +104,13 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException { JsonDeserializer orig = prop.getValueDeserializer(); JsonDeserializer unwrapping = orig.unwrappingDeserializer(xform); - if (unwrapping != orig && unwrapping != null && unwrapping instanceof BeanDeserializer) { + if (!Objects.equals(unwrapping, orig) + && unwrapping != null + && unwrapping instanceof BeanDeserializer) { SettableBeanProperty mapProp = ((BeanDeserializer) unwrapping).findProperty("map"); if (mapProp != null) { - Iterable iterable = ((BeanDeserializer) unwrapping)::properties; List beanProperties = - StreamSupport.stream(iterable.spliterator(), false) - .map( - settableBeanProperty -> { - if (settableBeanProperty == mapProp) { - return mapProp.withSimpleName(wrappedPropertyName); - } - return settableBeanProperty; - }) - .collect(Collectors.toList()); + remapBeanProperties((BeanDeserializer) unwrapping, mapProp, wrappedPropertyName); BeanPropertyMap beanPropertyMap = new BeanPropertyMap( false, beanProperties, Collections.>emptyMap()); @@ -121,6 +121,10 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException { _unwrappedPropertyHandler.addProperty(prop); _beanProperties.remove(prop); } + + prop = prop.withValueDeserializer(unwrapping); + _unwrappedPropertyHandler.addProperty(prop); + _beanProperties.remove(prop); } } } @@ -139,7 +143,8 @@ public Version version() { } @Override - public void setupModule(com.fasterxml.jackson.databind.Module.SetupContext context) { + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CloseResource"}) + public void setupModule(Module.SetupContext context) { context.addDeserializationProblemHandler( new DeserializationProblemHandler() { @Override @@ -157,8 +162,6 @@ public JavaType handleMissingTypeId( JsonLocation currentLocation = p.getCurrentLocation(); byte[] sourceRef = (byte[]) currentLocation.getSourceRef(); - long line = currentLocation.getLineNr(); - long column = currentLocation.getColumnNr(); JsonParser parser2 = p.getCodec().getFactory().createParser(sourceRef); parser2.nextToken(); @@ -184,6 +187,8 @@ public JavaType handleMissingTypeId( long currentLine = parser2.getCurrentLocation().getLineNr(); long currentColumn = parser2.getCurrentLocation().getColumnNr(); + long line = currentLocation.getLineNr(); + long column = currentLocation.getColumnNr(); String lastExtensionType = null; @@ -192,9 +197,8 @@ public JavaType handleMissingTypeId( for (; currentToken != JsonToken.END_OBJECT; currentToken = parser2.nextToken()) { - if (currentToken == JsonToken.FIELD_NAME - && parser2.getCurrentName().equals("extensionType")) { - currentToken = parser2.nextToken(); + if (JsonToken.FIELD_NAME == currentToken + && "extensionType".equals(parser2.getCurrentName())) { lastExtensionType = parser2.getValueAsString(); } } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityRegistryImpl.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityRegistryImpl.java index a799aa09..6edcc141 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityRegistryImpl.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EntityRegistryImpl.java @@ -48,7 +48,7 @@ public List getEntitiesForType(Class type) { .flatMap(entityFactory -> entityFactory.instances().stream()) .filter( persistentEntity -> - (async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED) + async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED || ((EntityState) persistentEntity).isActive()) .map(type::cast) .collect(ImmutableList.toImmutableList()); @@ -62,7 +62,7 @@ public Optional getEntity(Class type, String .map(Optional::get) .filter( persistentEntity -> - (async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED) + async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED || ((EntityState) persistentEntity).isActive()) .map(type::cast) .findFirst(); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcing.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcing.java index 0cb138b6..541488f9 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcing.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcing.java @@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory; // TODO: should this really be a facade for EventStore? or can we make it plain ValueCache? +@SuppressWarnings({"PMD.GodClass", "PMD.CogntitiveComplexity", "PMD.CyclomaticComplexity"}) public class EventSourcing implements EventStoreSubscriber, ValueCache { private static final Logger LOGGER = LoggerFactory.getLogger(EventSourcing.class); @@ -128,6 +129,7 @@ public List getEventTypes() { } @Override + @SuppressWarnings("PMD.CognitiveComplexity") public void onEmit(Event event) { if (event instanceof EntityEvent) { EntityEvent entityEvent = (EntityEvent) event; @@ -139,9 +141,8 @@ public void onEmit(Event event) { } else if (mutationEventProcessor.isPresent() && event instanceof MutationEvent) { CompletableFuture completableFuture = null; // TODO - if (queue.containsKey(entityEvent.identifier()) - && entityEvent.type().equals("defaults") - && entityEvent.identifier().id().equals("services.ogc_api")) { + if ("defaults".equals(entityEvent.type()) + && "services.ogc_api".equals(entityEvent.identifier().id())) { completableFuture = queue.get(entityEvent.identifier()); queue.remove(entityEvent.identifier()); } @@ -155,10 +156,8 @@ public void onEmit(Event event) { } else { onEmit(entityEvent); } - } catch (Throwable e) { - if (e instanceof NoSuchElementException - && Objects.nonNull(e.getMessage()) - && e.getMessage().contains("providers/feature/")) { + } catch (NoSuchElementException e) { + if (Objects.nonNull(e.getMessage()) && e.getMessage().contains("providers/feature/")) { LOGGER.error( "Cannot load '{}', feature provider type not supported: {}", entityEvent.asPath(), @@ -168,20 +167,32 @@ public void onEmit(Event event) { } else { LogContext.error(LOGGER, e, "Cannot load '{}'", entityEvent.asPath()); } + } catch (Throwable e) { + LogContext.error(LOGGER, e, "Cannot load '{}'", entityEvent.asPath()); } - } else if (event instanceof StateChangeEvent) { - switch (((StateChangeEvent) event).state()) { + StateChangeEvent stateChangeEvent = (StateChangeEvent) event; + switch (stateChangeEvent.state()) { case REPLAYING: - LOGGER.debug("Loading {}", ((StateChangeEvent) event).type()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Loading {}", stateChangeEvent.type()); + } break; case LISTENING: - started.add(((StateChangeEvent) event).type()); - + started.add(stateChangeEvent.type()); if (started.containsAll(getEventTypes())) { - onStart.get().thenRun(() -> LOGGER.debug("Loaded {}", String.join(" and ", started))); + onStart + .get() + .thenRun( + () -> { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Loaded {}", String.join(" and ", started)); + } + }); } break; + default: + break; } } else if (event instanceof ReloadEvent) { Optional>> hook = @@ -273,6 +284,7 @@ private CompletableFuture pushMutationEventRaw( return completableFuture; } + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.NPathComplexity"}) private void onEmit(EntityEvent event) throws Throwable { Identifier key = event.identifier(); FORMAT payloadFormat = FORMAT.fromString(event.format()); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcingCache.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcingCache.java index 608eb34f..a66861c2 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcingCache.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSourcingCache.java @@ -25,12 +25,6 @@ public class EventSourcingCache { - public interface Deserializer { - T deserialize(Identifier identifier, byte[] payload, String format); - } - - private static final Logger LOGGER = LoggerFactory.getLogger(EventSourcingCache.class); - private final Map cache; private final Map> queue; private final EventStore eventStore; @@ -38,6 +32,11 @@ public interface Deserializer { private final Function serializer; private final Deserializer deserializer; private final String defaultFormat; + private static final Logger LOGGER = LoggerFactory.getLogger(EventSourcingCache.class); + + public interface Deserializer { + T deserialize(Identifier identifier, byte[] payload, String format); + } public EventSourcingCache( EventStore eventStore, diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventStoreDefault.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventStoreDefault.java index 039bd76a..cd540872 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventStoreDefault.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventStoreDefault.java @@ -58,6 +58,7 @@ public class EventStoreDefault implements EventStore, AppLifeCycle { private final EventSubscriptions subscriptions; private Optional writableSource; private final boolean isReadOnly; + private static final String EVENT_TYPE_ENTITIES = "entities"; @Inject EventStoreDefault(Store store, Lazy> drivers, Reactive reactive) { @@ -170,7 +171,7 @@ private Optional findDriver(StoreSource storeSource, boolean w .filter( d -> { if (!d.isAvailable(storeSource)) { - if (warn) { + if (warn && LOGGER.isWarnEnabled()) { LOGGER.warn("Store source {} not found.", storeSource.getLabel()); } foundUnavailable[0] = true; @@ -201,23 +202,28 @@ private List findSources() { } @Override + @SuppressWarnings("PMD.CyclomaticComplexity") public void push(EntityEvent event) { if (isReadOnly) { LOGGER.warn("Store is operating in read-only mode, write operations are not allowed."); return; } if (writableSource.isEmpty()) { - LOGGER.warn("Ignoring write event for '{}', no writable source found.", event.asPath()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Ignoring write event for '{}', no writable source found.", event.asPath()); + } return; } Optional driver = findDriver(writableSource.get(), false); if (driver.isEmpty()) { - LOGGER.warn( - "Ignoring write event for '{}', no driver found for source {}.", - event.asPath(), - writableSource.get().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn( + "Ignoring write event for '{}', no driver found for source {}.", + event.asPath(), + writableSource.get().getLabel()); + } return; } if (!driver.get().canWrite()) { @@ -264,9 +270,14 @@ public void replay(EventFilter filter, boolean force, List addition // TODO: type subscriptions.emitEvent( - ImmutableReloadEvent.builder().type("entities").filter(filter).force(force).build()); + ImmutableReloadEvent.builder() + .type(EVENT_TYPE_ENTITIES) + .filter(filter) + .force(force) + .build()); } + @SuppressWarnings("PMD.CognitiveComplexity") private void reload( StoreSource storeSource, EventStoreDriver driver, EventFilter filter, boolean doDelete) { Set deleteEvents = new HashSet<>(); @@ -282,12 +293,12 @@ private void reload( if (LOGGER.isTraceEnabled()) { LOGGER.trace("ALLOW {}", event.asPath()); } - if (Objects.equals(event.type(), "entities") + if (Objects.equals(event.type(), EVENT_TYPE_ENTITIES) || Objects.equals(event.type(), "overrides")) { boolean deleted = deleteEvents.add( ImmutableReplayEvent.builder() - .type("entities") + .type(EVENT_TYPE_ENTITIES) .deleted(true) .identifier(event.identifier()) .payload(ValueEncodingJackson.YAML_NULL) @@ -367,7 +378,7 @@ private void reload( private EventFilter getStartupFilter() { return ImmutableEventFilter.builder() - .addEventTypes("entities") + .addEventTypes(EVENT_TYPE_ENTITIES) .entityTypes( store .getFilter() diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSubscriptionsImpl.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSubscriptionsImpl.java index c84c55fb..40248598 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSubscriptionsImpl.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/EventSubscriptionsImpl.java @@ -48,6 +48,11 @@ protected EventSubscriptionsImpl(Reactive.Runner streamRunner) { } @Override + @SuppressWarnings({ + "PMD.CyclomaticComplexity", + "PMD.AvoidInstantiatingObjectsInLoops", + "PMD.CognitiveComplexity" + }) public void addSubscriber(EventStoreSubscriber subscriber) { executorService.submit( () -> { @@ -100,6 +105,7 @@ public void addSubscriber(EventStoreSubscriber subscriber) { } @Override + @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") public synchronized void emitEvent(TypedEvent event) { if (LOGGER.isTraceEnabled() && event instanceof EntityEvent) { LOGGER.trace("Emitting event: {} {}", event.type(), ((EntityEvent) event).identifier()); @@ -120,6 +126,7 @@ public void startListening() { this.isStarted = true; } + @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") private synchronized EventStream getEventStream(String eventType) { Objects.requireNonNull(eventType, "eventType may not be null"); return eventStreams.computeIfAbsent(eventType, prefix -> createEventStream(eventType)); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapAligner.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapAligner.java index f98dcffe..6bd4e84b 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapAligner.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapAligner.java @@ -18,8 +18,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -public class MapAligner { +public final class MapAligner { + private MapAligner() {} + + @SuppressWarnings("PMD.CognitiveComplexity") public static Map align( Map source, Map alignTo, @@ -71,7 +74,6 @@ private static List align( return source; } - List result = new ArrayList<>(); KeyPathAliasUnwrap aliasUnwrap = entityFactory.getKeyPathAliasReverse(parentKey).get(); Map aligned = diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapDiffer.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapDiffer.java index fb756ede..1f782791 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapDiffer.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapDiffer.java @@ -12,8 +12,11 @@ import java.util.Map; import java.util.Objects; -public class MapDiffer { +public final class MapDiffer { + private MapDiffer() {} + + @SuppressWarnings("PMD.ConfusingTernary") public static Map diff(Map source, Map other) { Map result = new LinkedHashMap<>(); @@ -27,8 +30,6 @@ public static Map diff(Map source, Map) value, (Map) other.get(key))); } else if (value instanceof List && other.get(key) instanceof List) { result.putAll(diff((List) value, (List) other.get(key), key)); - } else if (value instanceof List && other.get(key) instanceof Map) { - // List diff = diff((List) value, (Map) other.get(key)); } else { result.put(key, String.format("%s != %s", value, other.get(key))); } @@ -44,6 +45,7 @@ public static Map diff(Map source, Map diff( List source, List other, String parentKey) { @@ -61,8 +63,6 @@ private static Map diff( result.putAll(diff((Map) value, (Map) other.get(i))); } else if (value instanceof List && other.get(i) instanceof List) { result.putAll(diff((List) value, (List) other.get(i), key)); - } else if (value instanceof List && other.get(i) instanceof Map) { - // List diff = diff((List) value, (Map) other.get(i)); } else { result.put(key, String.format("%s != %s", value, other.get(i))); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapSubtractor.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapSubtractor.java index bcbb0cc1..187c31c7 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapSubtractor.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/MapSubtractor.java @@ -8,12 +8,10 @@ package de.ii.xtraplatform.entities.app; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.MapDifference; import com.google.common.collect.MapDifference.ValueDifference; import com.google.common.collect.Maps; -import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; @@ -23,7 +21,9 @@ import java.util.Optional; import java.util.stream.Collectors; -public class MapSubtractor { +public final class MapSubtractor { + + private MapSubtractor() {} public static Map subtract( Map data, @@ -33,6 +33,11 @@ public static Map subtract( return subtract(data, defaults, ignoreKeys, listEntryKeys, false); } + @SuppressWarnings({ + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.AvoidDeeplyNestedIfStmts" + }) public static Map subtract( Map data, Map defaults, @@ -130,6 +135,12 @@ public static Map subtract( return result; } + @SuppressWarnings({ + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.AvoidDeeplyNestedIfStmts", + "PMD.CollapsibleIfStatements" + }) private static Collection subtract( Collection left, Collection right, @@ -180,7 +191,7 @@ private static Collection subtract( // ignore entries that only have key if (subtracted.size() == 1 && Objects.equals(subtracted.keySet().iterator().next(), listEntryKey)) { - subtracted = null; + diff.remove(leftMatch.get()); } diff.set(diff.indexOf(leftMatch.get()), subtracted); @@ -191,14 +202,4 @@ private static Collection subtract( return diff.stream().filter(Objects::nonNull).collect(Collectors.toList()); } - - private Map entriesDiffering(MapDifference difference) { - return difference.entriesDiffering().entrySet().stream() - .map(entry -> new SimpleEntry<>(entry.getKey(), entry.getValue().rightValue())) - .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - private boolean containsMaps(Collection collection) { - return !collection.isEmpty() && collection.iterator().next() instanceof Map; - } } From 0330d33b64a0bff6331465eb5161f166daacc0b0 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Mon, 26 Jan 2026 13:38:12 +0000 Subject: [PATCH 2/2] refactor entities module, remove unused migration class --- .../entities/app/StoreReloadTask.java | 23 ++-- .../app/ValueDecoderEntityDataMigration.java | 108 ------------------ .../app/ValueDecoderEntityPreHash.java | 8 +- .../domain/AbstractKeyValueStore.java | 12 +- .../AbstractMergeableKeyValueStore.java | 5 - .../domain/AbstractPersistentEntity.java | 11 +- .../xtraplatform/entities/domain/Entity.java | 2 +- .../domain/EntityDataDefaultsPath.java | 47 +++++--- .../domain/EntityDataOverridesPath.java | 1 + .../entities/domain/EntityDataStore.java | 13 ++- .../entities/domain/EntityEvent.java | 1 + .../entities/domain/EntityFactoriesImpl.java | 3 +- .../entities/domain/EntityFactory.java | 1 + .../entities/domain/EntityMigration.java | 2 + .../entities/domain/EntityState.java | 2 +- .../entities/domain/EntityStoreDecorator.java | 1 + .../entities/domain/EventFilter.java | 34 +++--- .../entities/domain/EventSource.java | 103 +++++++++-------- .../domain/EventSourcedKeyValueStore.java | 1 + .../domain/maptobuilder/BuildableMap.java | 1 + .../encoding/BuildableMapEncoding.java | 2 +- .../encoding/MergeableMapEncoding.java | 4 +- .../entities/infra/EventReaderDir.java | 4 - .../entities/infra/EventReaderZip.java | 8 +- .../entities/infra/EventStoreDriverFs.java | 39 ++++--- 25 files changed, 178 insertions(+), 258 deletions(-) delete mode 100644 xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityDataMigration.java diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/StoreReloadTask.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/StoreReloadTask.java index b6373b41..defceef3 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/StoreReloadTask.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/StoreReloadTask.java @@ -62,8 +62,11 @@ public void init(AppConfiguration configuration, Environment environment) { } @Override + @SuppressWarnings({"PMD.NPathComplexity", "PMD.CyclomaticComplexity", "PMD.CognitiveComplexity"}) public void execute(Map> parameters, PrintWriter output) throws Exception { - if (LOGGER.isTraceEnabled()) LOGGER.trace("Reload request: {}", parameters); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Reload request: {}", parameters); + } List entityTypes = getEntityTypes(parameters); @@ -80,15 +83,6 @@ public void execute(Map> parameters, PrintWriter output) th return; } - ImmutableEventFilter filter = - ImmutableEventFilter.builder() - .addEventTypes("entities") - .entityTypes(entityTypes) - .ids(ids) - .build(); - - boolean force = getForce(parameters); - List additionalEvents = new ArrayList<>(); Optional enabledOverride = getEnabled(parameters); @@ -129,6 +123,15 @@ public void execute(Map> parameters, PrintWriter output) th } } + ImmutableEventFilter filter = + ImmutableEventFilter.builder() + .addEventTypes("entities") + .entityTypes(entityTypes) + .ids(ids) + .build(); + + boolean force = getForce(parameters); + eventStore.replay(filter, force, additionalEvents); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityDataMigration.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityDataMigration.java deleted file mode 100644 index 334adcc5..00000000 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityDataMigration.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2020 interactive instruments GmbH - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package de.ii.xtraplatform.entities.app; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import de.ii.xtraplatform.entities.domain.EntityData; -import de.ii.xtraplatform.values.domain.Identifier; -import de.ii.xtraplatform.values.domain.ValueDecoderMiddleware; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.OptionalLong; -import java.util.function.BiConsumer; - -public class ValueDecoderEntityDataMigration implements ValueDecoderMiddleware { - - private final EventSourcing eventSourcing; - // private final EntityFactory3 entityFactory; - private final BiConsumer addAdditionalEvent; - - public ValueDecoderEntityDataMigration( - EventSourcing eventSourcing, - // EntityFactory3 entityFactory, - BiConsumer addAdditionalEvent) { - this.eventSourcing = eventSourcing; - // this.entityFactory = entityFactory; - this.addAdditionalEvent = addAdditionalEvent; - } - - @Override - public EntityData process( - Identifier identifier, - byte[] payload, - ObjectMapper objectMapper, - EntityData entityData, - boolean ignoreCache) - throws IOException { - if (entityData.getEntityStorageVersion() < entityData.getEntitySchemaVersion()) { - migrateSchema( - identifier, - payload, - objectMapper, - entityData.getEntityStorageVersion(), - entityData.getEntitySubType(), - OptionalLong.of(entityData.getEntitySchemaVersion())); - - return null; - } - - return entityData; - } - - @Override - public boolean canRecover() { - return true; - } - - // TODO: entitySubType - @Override - public EntityData recover(Identifier identifier, byte[] payload, ObjectMapper objectMapper) - throws IOException { - TypeReference> typeRef = - new TypeReference>() {}; - Map map = objectMapper.readValue(payload, typeRef); - - if (!map.containsKey("id")) { - throw new IllegalArgumentException("not a valid entity, no id found"); - } - - long storageVersion = ((Number) map.getOrDefault("entityStorageVersion", 1)).longValue(); - - migrateSchema( - identifier, payload, objectMapper, storageVersion, Optional.empty(), OptionalLong.empty()); - - return null; - } - - private void migrateSchema( - Identifier identifier, - byte[] payload, - ObjectMapper objectMapper, - long storageVersion, - Optional entitySubType, - OptionalLong targetVersion) - throws IOException { - /*EntityDataBuilder builderOld = - entityFactory.getDataBuilders(identifier.path().get(0), storageVersion, entitySubType); - ValueDecoderWithBuilder valueDecoderWithBuilder = - new ValueDecoderWithBuilder<>(identifier1 -> builderOld, eventSourcing); - EntityData entityDataOld = - valueDecoderWithBuilder.process(identifier, payload, objectMapper, null, false); - - String entityType = identifier.path().get(0); - - Map entityDataNew = - entityFactory.migrateSchema( - identifier, entityType, entityDataOld, entitySubType, targetVersion); - - entityDataNew.forEach(addAdditionalEvent);*/ - } -} diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityPreHash.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityPreHash.java index f9a32f18..e404e7e0 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityPreHash.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/app/ValueDecoderEntityPreHash.java @@ -15,13 +15,9 @@ import java.io.IOException; import java.util.function.BiFunction; import java.util.function.Function; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ValueDecoderEntityPreHash implements ValueDecoderMiddleware { - private static final Logger LOGGER = LoggerFactory.getLogger(ValueDecoderEntityPreHash.class); - private final BiFunction> newBuilderSupplier; private final Function hasher; @@ -42,8 +38,6 @@ public EntityData process( boolean ignoreCache) throws IOException { if (data.getEntitySubType().isPresent()) { - String hash = hasher.apply(data); - EntityDataBuilder builder = newBuilderSupplier.apply(identifier, data.getEntitySubType().get()); @@ -53,6 +47,8 @@ public EntityData process( return data; } + String hash = hasher.apply(data); + builder.from(data); builder.stableHash(hash); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractKeyValueStore.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractKeyValueStore.java index 8a496063..ca4caa17 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractKeyValueStore.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractKeyValueStore.java @@ -16,14 +16,11 @@ import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@SuppressWarnings("PMD.TooManyMethods") public abstract class AbstractKeyValueStore extends AbstractVolatile implements KeyValueStore { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractKeyValueStore.class); - protected AbstractKeyValueStore() { super(null); } @@ -77,8 +74,11 @@ public CompletableFuture put(Identifier identifier, T value) { if (Objects.nonNull(throwable)) { onFailure(identifier, throwable); } else if (Objects.nonNull(entityData)) { - if (exists) onUpdate(identifier, entityData, false); - else onCreate(identifier, entityData).join(); + if (exists) { + onUpdate(identifier, entityData, false); + } else { + onCreate(identifier, entityData).join(); + } } }); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractMergeableKeyValueStore.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractMergeableKeyValueStore.java index 0cfa739c..31755e4b 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractMergeableKeyValueStore.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractMergeableKeyValueStore.java @@ -13,15 +13,10 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public abstract class AbstractMergeableKeyValueStore extends AbstractKeyValueStore implements MergeableKeyValueStore { - private static final Logger LOGGER = - LoggerFactory.getLogger(AbstractMergeableKeyValueStore.class); - protected abstract ValueEncoding getValueEncoding(); // TODO: an in-progress event (e.g. drop) might invalidate this one, do we need distributed diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractPersistentEntity.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractPersistentEntity.java index 56f0ec94..8efdc584 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractPersistentEntity.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/AbstractPersistentEntity.java @@ -30,6 +30,7 @@ /** * @author zahnen */ +@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods", "PMD.AvoidUsingVolatile"}) public abstract class AbstractPersistentEntity extends AbstractVolatileComposed implements PersistentEntity, Reloadable, EntityState, VolatileComposed { @@ -45,7 +46,6 @@ public abstract class AbstractPersistentEntity value = true, specification = EntityState.class) // is ignored here, but added by @Entity handler */ - private boolean registerState; // @ServiceController(value = false) // is ignored here, but added by @Entity handler public volatile boolean register; @@ -68,11 +68,9 @@ public AbstractPersistentEntity( this.stateChangeListeners = new CopyOnWriteArrayList<>(); this.changingData = new ChangingDataImpl(); this.data = data; - this.startup = null; - this.state = STATE.UNKNOWN; this.previousState = STATE.UNKNOWN; this.forceReload = false; - setState(STATE.LOADING); + this.state = STATE.LOADING; } @Override @@ -86,6 +84,7 @@ public ChangingData getChangingData() { } // @Property(name = Entity.DATA_KEY) // is ignored here, but added by @Entity handler + @SuppressWarnings("PMD.InvalidLogMessageFormat") public final void setData(T data, boolean force) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("GOT DATA {}" /*, data*/); @@ -95,7 +94,7 @@ public final void setData(T data, boolean force) { this.forceReload = force; if (force - || (Objects.nonNull(previous) && !Objects.equals(previous.hashCode(), data.hashCode()))) { + || Objects.nonNull(previous) && !Objects.equals(previous.hashCode(), data.hashCode())) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("RELOAD DATA {} {}", previous.hashCode(), data.hashCode()); } @@ -225,6 +224,7 @@ private void afterReload() { } } + @SuppressWarnings("PMD.CognitiveComplexity") private void triggerStartup(boolean wait, Runnable then) { this.startup = executorService.submit( @@ -262,6 +262,7 @@ private void triggerStartup(boolean wait, Runnable then) { } } + @SuppressWarnings("PMD.UnusedLocalVariable") private void cancelStartup() { if (Objects.nonNull(startup)) { boolean canceled = startup.cancel(true); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/Entity.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/Entity.java index 3bbf3961..98c71c0c 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/Entity.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/Entity.java @@ -25,7 +25,7 @@ boolean auxiliary() default false; - public @interface SubType { + @interface SubType { String key(); String value(); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataDefaultsPath.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataDefaultsPath.java index 752ae5f9..b1c33a32 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataDefaultsPath.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataDefaultsPath.java @@ -26,34 +26,45 @@ public interface EntityDataDefaultsPath { static EntityDataDefaultsPath from(Identifier identifier, Set entityTypes) { ModifiableEntityDataDefaultsPath defaultsPath = ModifiableEntityDataDefaultsPath.create(); - List pathSegments = ImmutableList.of(); boolean found = false; + List pathSegments = new ArrayList<>(); for (int i = 0; i < identifier.path().size(); i++) { - if (entityTypes.contains(identifier.path().get(i))) { + String segment = identifier.path().get(i); + + if (entityTypes.contains(segment)) { found = true; - defaultsPath.setEntityType(identifier.path().get(i)); + defaultsPath.setEntityType(segment); if (i > 0) { defaultsPath.setGroups(identifier.path().subList(0, i)); } + pathSegments.clear(); if (identifier.path().size() > i + 1) { - pathSegments = identifier.path().subList(i + 1, identifier.path().size()); - } - } else if (identifier.path().get(i).contains(".")) { - int firstDot = identifier.path().get(i).indexOf("."); - if (entityTypes.contains(identifier.path().get(i).substring(0, firstDot))) { - found = true; - defaultsPath.setEntityType(identifier.path().get(i).substring(0, firstDot)); - pathSegments = DOT_SPLITTER.splitToList(identifier.path().get(i).substring(firstDot + 1)); - if (i > 0) { - defaultsPath.setGroups(identifier.path().subList(0, i)); - } - if (identifier.path().size() > i + 1) { - pathSegments = new ArrayList<>(pathSegments); - pathSegments.addAll(identifier.path().subList(i + 1, identifier.path().size())); - } + pathSegments.addAll(identifier.path().subList(i + 1, identifier.path().size())); } + continue; + } + + if (!segment.contains(".")) { + continue; + } + + int firstDot = segment.indexOf('.'); + String beforeDot = segment.substring(0, firstDot); + if (!entityTypes.contains(beforeDot)) { + continue; + } + + found = true; + defaultsPath.setEntityType(beforeDot); + pathSegments.clear(); + pathSegments.addAll(DOT_SPLITTER.splitToList(segment.substring(firstDot + 1))); + if (i > 0) { + defaultsPath.setGroups(identifier.path().subList(0, i)); + } + if (identifier.path().size() > i + 1) { + pathSegments.addAll(identifier.path().subList(i + 1, identifier.path().size())); } } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataOverridesPath.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataOverridesPath.java index f963800d..2aca5063 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataOverridesPath.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataOverridesPath.java @@ -17,6 +17,7 @@ // TODO: unit tests for all cases @Value.Modifiable +@SuppressWarnings("PMD.PrematureDeclaration") public interface EntityDataOverridesPath { Splitter DOT_SPLITTER = Splitter.on('.'); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataStore.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataStore.java index 0beec980..7ebe6e56 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataStore.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityDataStore.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -28,24 +29,26 @@ * * @author zahnen */ +@SuppressWarnings("PMD.TooManyMethods") public interface EntityDataStore extends MergeableKeyValueStore { String EVENT_TYPE_ENTITIES = "entities"; String EVENT_TYPE_OVERRIDES = "overrides"; List EVENT_TYPES = ImmutableList.of(EVENT_TYPE_ENTITIES, EVENT_TYPE_OVERRIDES); + String TILES_SUFFIX = "-tiles"; Comparator COMPARATOR = (id1, id2) -> { int compareType = entityType(id1).compareTo(entityType(id2)); if (compareType == 0) { - if (id1.id().endsWith("-tiles") && id2.id().endsWith("-tiles")) { + if (id1.id().endsWith(TILES_SUFFIX) && id2.id().endsWith(TILES_SUFFIX)) { return 0; } - if (id2.id().endsWith("-tiles")) { + if (id2.id().endsWith(TILES_SUFFIX)) { return -1; } - if (id1.id().endsWith("-tiles")) { + if (id1.id().endsWith(TILES_SUFFIX)) { return 1; } } @@ -71,7 +74,7 @@ static Identifier defaults(Identifier identifier, String subType) { .id(EntityDataDefaultsStore.EVENT_TYPE) .path(entityGroup(identifier)) .addPath(entityType(identifier)) - .addPath(subType.toLowerCase()) + .addPath(subType.toLowerCase(Locale.ROOT)) .build(); } @@ -106,6 +109,7 @@ default Identifier fullIdentifier(String id) { EntityData fromBytes(Identifier identifier, byte[] entityData) throws IOException; + @Override CompletableFuture patch(String id, Map partialData, String... path); CompletableFuture patch( @@ -115,6 +119,7 @@ CompletableFuture patch( EntityDataBuilder getBuilder(Identifier identifier, Optional entitySubtype); + @Override EntityDataStore forType(Class type); EntityDataStore forType(String type); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityEvent.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityEvent.java index 4954131f..ee3c4297 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityEvent.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityEvent.java @@ -15,6 +15,7 @@ public interface EntityEvent extends TypedEvent, Comparable { + @Override String type(); Identifier identifier(); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactoriesImpl.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactoriesImpl.java index 38c42997..56b80465 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactoriesImpl.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactoriesImpl.java @@ -13,6 +13,7 @@ import com.google.common.collect.ImmutableSet; import dagger.Lazy; import java.util.List; +import java.util.Locale; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; @@ -115,7 +116,7 @@ public Set getTypes() { private String getSpecificEntityType(String entityType, Optional entitySubType) { return entitySubType.isPresent() - ? String.format("%s/%s", entityType, entitySubType.get().toLowerCase()) + ? String.format("%s/%s", entityType, entitySubType.get().toLowerCase(Locale.ROOT)) : entityType; } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactory.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactory.java index 487de847..37f49d09 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactory.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityFactory.java @@ -16,6 +16,7 @@ import java.util.function.Consumer; @AutoMultiBind +@SuppressWarnings("PMD.TooManyMethods") public interface EntityFactory { String type(); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityMigration.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityMigration.java index 9a8776d2..ba8abbfa 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityMigration.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityMigration.java @@ -27,10 +27,12 @@ public interface EntityMigrationContext extends MigrationContext { boolean exists(Predicate matcher); } + @Override public final EntityMigrationContext getContext() { return context; } + @Override public boolean isApplicable(EntityData entityData) { return isApplicable(entityData, Optional.empty()); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityState.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityState.java index b8b85d1b..bd582147 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityState.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityState.java @@ -33,6 +33,6 @@ enum STATE { default boolean isActive() { return getEntityState() == STATE.ACTIVE - || (getEntityState() == STATE.RELOADING && getPreviousState() == STATE.ACTIVE); + || getEntityState() == STATE.RELOADING && getPreviousState() == STATE.ACTIVE; } } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityStoreDecorator.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityStoreDecorator.java index 1a2eaee5..cdea47aa 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityStoreDecorator.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EntityStoreDecorator.java @@ -20,6 +20,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +@SuppressWarnings("PMD.TooManyMethods") public interface EntityStoreDecorator extends EntityDataStore, Volatile2 { diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventFilter.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventFilter.java index ff97cde5..7daf77e1 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventFilter.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventFilter.java @@ -24,15 +24,14 @@ public interface EventFilter { List getIds(); + @SuppressWarnings("PMD.CyclomaticComplexity") default boolean matches(EntityEvent event) { Identifier identifier = event.identifier(); - if (!getEntityTypes().contains(WILDCARD)) { - if (identifier.path().isEmpty() || !containsEntityType(identifier.path())) { - if ((!isDefault(event) || !containsEntityType(identifier.id()))) { - return false; - } - } + if (!getEntityTypes().contains(WILDCARD) + && (identifier.path().isEmpty() || !containsEntityType(identifier.path())) + && (!isDefault(event) || !containsEntityType(identifier.id()))) { + return false; } if (!getIds().isEmpty() && !isDefault(event)) { @@ -49,12 +48,10 @@ default boolean matches(EntityEvent event) { } default boolean matches(Identifier identifier) { - if (!getEntityTypes().contains(WILDCARD)) { - if (identifier.path().isEmpty() || !containsEntityType(identifier.path())) { - if (!getEntityTypes().contains(identifier.id())) { - return false; - } - } + if (!getEntityTypes().contains(WILDCARD) + && (identifier.path().isEmpty() || !containsEntityType(identifier.path())) + && !getEntityTypes().contains(identifier.id())) { + return false; } if (!getIds().isEmpty()) { @@ -89,8 +86,8 @@ default int indexOfEntityType(List path) { default boolean containsEntityType(String id) { if (getEntityTypes().contains(id)) { return true; - } else if (id.contains(".")) { - String entityType = id.substring(0, id.indexOf(".")); + } else if (id.indexOf('.') != -1) { + String entityType = id.substring(0, id.indexOf('.')); if (getEntityTypes().contains(entityType)) { return true; } @@ -106,19 +103,20 @@ static EventFilter fromPath(Path path) { String eventType = path.getName(0).toString(); String entityType = path.getName(1).toString(); - if (entityType.contains(".")) { - entityType = entityType.substring(0, entityType.indexOf(".")); + int dotIdx = entityType.indexOf('.'); + if (dotIdx != -1) { + entityType = entityType.substring(0, dotIdx); } ImmutableEventFilter.Builder builder = ImmutableEventFilter.builder().addEventTypes(eventType).addEntityTypes(entityType); // TODO - if (eventType.equals("defaults")) { + if ("defaults".equals(eventType)) { builder.addIds(WILDCARD); } else if (path.getNameCount() > 2) { String id = path.getName(2).toString(); if (id.contains(".")) { - id = id.substring(0, id.indexOf(".")); + id = id.substring(0, id.indexOf('.')); } builder.addIds(id); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSource.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSource.java index 44336513..75f4b86a 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSource.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSource.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.function.Function; @@ -52,6 +53,7 @@ public class EventSource { private final StoreSource source; private final Pattern mainPathPatternRead; private final String mainPathPatternWrite; + private static final String NAME_GROUP = "name"; public EventSource(Path path, StoreSource source, Function pathAdjuster) { this.path = @@ -112,56 +114,58 @@ private Path getEventPath(String type, Identifier identifier, String format, Str Paths.get( String.format( pathPattern, type, Joiner.on('/').join(identifier.path()), identifier.id()) - + (Objects.nonNull(format) ? "." + format.toLowerCase() : ""))); + + (Objects.nonNull(format) ? "." + format.toLowerCase(Locale.ROOT) : ""))); } + @SuppressWarnings("PMD.CognitiveComplexity") public EntityEvent pathToEvent(Pattern pathPattern, Path path, Supplier readPayload) { Path relPath = rootPath.relativize(path); Path fullRelPath = applyPrefixes(relPath); Matcher pathMatcher = pathPattern.matcher(fullRelPath.toString()); - if (pathMatcher.find()) { - String eventType = pathMatcher.group(TYPE_GROUP); - String eventPath = pathMatcher.group(PATH_GROUP); - String eventId = pathMatcher.group(ID_GROUP); - Optional eventPayloadFormat; - try { - eventPayloadFormat = Optional.ofNullable(pathMatcher.group(FORMAT_GROUP)); - } catch (Throwable e) { - eventPayloadFormat = Optional.empty(); - } - - if (Objects.nonNull(eventType) - && /*Objects.nonNull(eventPath) &&*/ Objects.nonNull(eventId)) { - - if (!Content.isEvent(eventType)) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace( - "Skipping non-event {type: {}, path: {}, id: {}}", eventType, eventPath, eventId); - } - return null; - } + if (!pathMatcher.find()) { + return null; + } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Reading event {type: {}, path: {}, id: {}}", eventType, eventPath, eventId); - } + String eventType = pathMatcher.group(TYPE_GROUP); + String eventId = pathMatcher.group(ID_GROUP); + Optional eventPayloadFormat; + try { + eventPayloadFormat = Optional.ofNullable(pathMatcher.group(FORMAT_GROUP)); + } catch (Throwable e) { + eventPayloadFormat = Optional.empty(); + } - byte[] bytes = readPayload.get(); + if (Objects.isNull(eventType) || Objects.isNull(eventId)) { + return null; + } - Iterable eventPathSegments = - Strings.isNullOrEmpty(eventPath) ? ImmutableList.of() : PATH_SPLITTER.split(eventPath); + String eventPath = pathMatcher.group(PATH_GROUP); - return ImmutableReplayEvent.builder() - .type(eventType) - .identifier(ImmutableIdentifier.builder().id(eventId).path(eventPathSegments).build()) - .payload(bytes) - .format(eventPayloadFormat.orElse(null)) - .source(source.getLabel()) - .build(); + if (!Content.isEvent(eventType)) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace( + "Skipping non-event {type: {}, path: {}, id: {}}", eventType, eventPath, eventId); } + return null; + } + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Reading event {type: {}, path: {}, id: {}}", eventType, eventPath, eventId); } - return null; + byte[] bytes = readPayload.get(); + + Iterable eventPathSegments = + Strings.isNullOrEmpty(eventPath) ? ImmutableList.of() : PATH_SPLITTER.split(eventPath); + + return ImmutableReplayEvent.builder() + .type(eventType) + .identifier(ImmutableIdentifier.builder().id(eventId).path(eventPathSegments).build()) + .payload(bytes) + .format(eventPayloadFormat.orElse(null)) + .source(source.getLabel()) + .build(); } private Path applyPrefixes(Path path) { @@ -192,21 +196,22 @@ public Stream getPathPatternStream() { return Stream.of(mainPathPatternRead); } + @SuppressWarnings("PMD.CyclomaticComplexity") private Pattern pathToPattern(String path, Function pathAdjuster) { Matcher matcher = PATH_PATTERN.matcher(path); - StringBuilder pattern = new StringBuilder(); + StringBuilder pattern = new StringBuilder(64); List names = new ArrayList<>(); while (matcher.find()) { // LOGGER.debug("PATH REGEX {} {} {} {} {}", matcher.group(), matcher.groupCount(), - // matcher.group("name"), matcher.group("separator"), matcher.group("glob")); + // matcher.group(NAME_GROUP), matcher.group("separator"), matcher.group("glob")); if (Objects.isNull(matcher.group("glob"))) { - names.add(matcher.group("name")); + names.add(matcher.group(NAME_GROUP)); pattern.append(matcher.group("separator").replaceAll("/", "\\\\/")); pattern.append("(?<"); - pattern.append(matcher.group("name")); + pattern.append(matcher.group(NAME_GROUP)); pattern.append(">[\\w][\\w-\\.]+?)"); - if (Objects.equals(matcher.group("name"), "id")) { + if (Objects.equals(matcher.group(NAME_GROUP), "id")) { names.add(FORMAT_GROUP); pattern.append("(?:\\.(?<"); pattern.append(FORMAT_GROUP); @@ -217,17 +222,17 @@ private Pattern pathToPattern(String path, Function pathAdjuster throw new IllegalArgumentException( "unknown store path expression: " + matcher.group("glob")); } - names.add(matcher.group("name")); - pattern.append("(?:"); - pattern.append(matcher.group("separator").replaceAll("/", "\\\\/")); - pattern.append("(?<"); - pattern.append(matcher.group("name")); - pattern.append(">(?:[\\w-_](?:[\\w-_]|\\.|\\/(?!\\.))+[\\w-_]))"); - pattern.append(")?"); + names.add(matcher.group(NAME_GROUP)); + pattern + .append("(?:") + .append(matcher.group("separator").replaceAll("/", "\\\\/")) + .append("(?<") + .append(matcher.group(NAME_GROUP)) + .append(">(?:[\\w-_](?:[\\w-_]|\\.|\\/(?!\\.))+[\\w-_]))?)"); } } pattern.insert(0, "^"); - pattern.append("$"); + pattern.append('$'); if (!(names.contains("type") && names.contains("path") && names.contains("id"))) { throw new IllegalArgumentException("store path expression must contain type, path and id"); diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSourcedKeyValueStore.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSourcedKeyValueStore.java index 47aa7669..4ccf5025 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSourcedKeyValueStore.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/EventSourcedKeyValueStore.java @@ -23,6 +23,7 @@ public interface EventSourcedKeyValueStore extends EventSourcedStore, KeyV EventSourcingCache getEventSourcing(); @Override + @SuppressWarnings("PMD.TooFewBranchesForASwitchStatement") default void onEmit(Event event) { // TODO: when isReplay switches, notify EntityInstantiator if (event instanceof EntityEvent) { diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/BuildableMap.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/BuildableMap.java index 56dfcb64..33b9131d 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/BuildableMap.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/BuildableMap.java @@ -20,6 +20,7 @@ public abstract class BuildableMap, U extends BuildableBuilder> extends ForwardingMap { + @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") public abstract static class Builder {} @Value.Derived diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/BuildableMapEncoding.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/BuildableMapEncoding.java index c33dcfcd..122bd906 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/BuildableMapEncoding.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/BuildableMapEncoding.java @@ -46,7 +46,7 @@ public void set(Map values) { } @JsonProperty - @Encoding.Naming(value = "get*") + @Encoding.Naming("get*") public Map get() { // return buildValue.build().getBuilders(); return builderMap; diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/MergeableMapEncoding.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/MergeableMapEncoding.java index 1f577194..0a660bc1 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/MergeableMapEncoding.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/domain/maptobuilder/encoding/MergeableMapEncoding.java @@ -37,7 +37,7 @@ public void set(Map values) { } @JsonProperty - @Encoding.Naming(value = "get*") + @Encoding.Naming("get*") public Map get() { return mergeableMap; } @@ -56,7 +56,7 @@ void putAll(Map values) { @JsonProperty @Encoding.Init - @Encoding.Naming(value = "set*") + @Encoding.Naming("set*") void putAllJackson(Map values) { values.forEach(this::put); } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderDir.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderDir.java index 000da429..f85d8355 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderDir.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderDir.java @@ -19,13 +19,9 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; class EventReaderDir implements EventReader { - private static final Logger LOGGER = LoggerFactory.getLogger(EventReaderDir.class); - @Override public Stream>> load( Path sourcePath, List includes, List excludes) throws IOException { diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderZip.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderZip.java index 53a996af..0b745d85 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderZip.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventReaderZip.java @@ -18,13 +18,9 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class EventReaderZip implements EventReader { - private static final Logger LOGGER = LoggerFactory.getLogger(EventReaderZip.class); - @Override public Stream>> load( Path sourcePath, List includes, List excludes) throws IOException { @@ -36,8 +32,8 @@ public Stream>> load( ZipWalker.walkEntries( sourcePath, (zipEntry, payload) -> { - if ((!includeMatchers.isEmpty() - && includeMatchers.stream().noneMatch(exclude -> exclude.matches(zipEntry))) + if (!includeMatchers.isEmpty() + && includeMatchers.stream().noneMatch(exclude -> exclude.matches(zipEntry)) || excludeMatchers.stream().anyMatch(exclude -> exclude.matches(zipEntry))) { return; } diff --git a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventStoreDriverFs.java b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventStoreDriverFs.java index 3ea8377b..9f26bbc4 100644 --- a/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventStoreDriverFs.java +++ b/xtraplatform-entities/src/main/java/de/ii/xtraplatform/entities/infra/EventStoreDriverFs.java @@ -52,6 +52,7 @@ @Singleton @AutoBind +@SuppressWarnings("PMD.TooManyStaticImports") public class EventStoreDriverFs implements EventStoreDriver, Watcher, Writer { private static final Logger LOGGER = LoggerFactory.getLogger(EventStoreDriverFs.class); @@ -86,19 +87,26 @@ public boolean isAvailable(StoreSource storeSource) { } @Override + @SuppressWarnings("PMD.CyclomaticComplexity") public Stream load(StoreSource storeSource) { EventSource source = from(storeSource); if (!Files.exists(source.getPath()) && !source.getPath().startsWith(dataDirectory)) { - LOGGER.warn("Store source {} not found.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Store source {} not found.", source.getSource().getLabel()); + } return Stream.empty(); } if (!storeSource.isArchive() && !Files.isDirectory(source.getPath())) { - LOGGER.warn("Store source {} is not a directory.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Store source {} is not a directory.", source.getSource().getLabel()); + } return Stream.empty(); } if (storeSource.isArchive() && !Files.isRegularFile(source.getPath())) { - LOGGER.warn("Store source {} is not an archive.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Store source {} is not an archive.", source.getSource().getLabel()); + } return Stream.empty(); } @@ -109,16 +117,18 @@ public Stream load(StoreSource storeSource) { // TODO: stopWatching, move watchService to class, watch new directories, file extension filter @Override + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.CognitiveComplexity"}) public void listen(StoreSource storeSource, Consumer> watchEventConsumer) { EventSource source = from(storeSource); if (!source.getSource().isWatchable() || source.getSource().isArchive()) { - LOGGER.warn("Watching is disabled for source {}.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Watching is disabled for source {}.", source.getSource().getLabel()); + } return; } - try { - WatchService watchService = FileSystems.getDefault().newWatchService(); + try (WatchService watchService = FileSystems.getDefault().newWatchService()) { final Map> keys = new HashMap<>(); try { @@ -131,12 +141,13 @@ public void listen(StoreSource storeSource, Consumer> watchEventConsu LogContext.error(LOGGER, e, "Cannot watch source {}", source.getSource().getLabel()); } - WatchKey key; - while ((key = watchService.take()) != null) { + WatchKey key = watchService.take(); + while (key != null) { if (!keys.containsKey(key)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("WatchKey " + key + " not recognized!"); } + key = watchService.take(); continue; } final Path rootDir = keys.get(key).get(0); @@ -193,7 +204,9 @@ public void push(StoreSource storeSource, EntityEvent event) throws IOException EventSource source = from(storeSource); if (source.getSource().getMode() == Mode.RO) { - LOGGER.warn("Writing is disabled for source {}.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Writing is disabled for source {}.", source.getSource().getLabel()); + } return; } @@ -218,7 +231,9 @@ public void deleteAll(StoreSource storeSource, String type, Identifier identifie EventSource source = from(storeSource); if (source.getSource().getMode() == Mode.RO) { - LOGGER.warn("Writing is disabled for source {}.", source.getSource().getLabel()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Writing is disabled for source {}.", source.getSource().getLabel()); + } return; } @@ -227,6 +242,7 @@ public void deleteAll(StoreSource storeSource, String type, Identifier identifie } } + @SuppressWarnings("PMD.CognitiveComplexity") private void deleteEvent(Path eventPath) throws IOException { if (!Files.isDirectory(eventPath.getParent())) { return; @@ -243,7 +259,6 @@ private void deleteEvent(Path eventPath) throws IOException { .toString() .startsWith(eventPath.getFileName().toString() + "."))) { String fileName = file.getFileName().toString(); - String name = file.toFile().getName(); Path backup; if (file.getParent().endsWith("#overrides#")) { backup = file.getParent().getParent().resolve(".backup/#overrides#"); @@ -264,8 +279,6 @@ private void deleteEvent(Path eventPath) throws IOException { // ignore } } - - boolean stop = true; } })); }