Skip to content

Commit d9c3bc3

Browse files
authored
Merge pull request #13 from fireflyframework/feature/hexagonal-architecture-remediation
refactor: hexagonal architecture remediation — ECM @componentscan removal
2 parents 1a6b84b + de4a9c9 commit d9c3bc3

7 files changed

Lines changed: 96 additions & 19 deletions

File tree

src/main/java/org/fireflyframework/ecm/adapter/AdapterRegistry.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import lombok.extern.slf4j.Slf4j;
2020
import org.springframework.beans.factory.annotation.Autowired;
2121
import org.springframework.context.ApplicationContext;
22-
import org.springframework.stereotype.Component;
22+
2323

2424
import java.util.*;
2525
import java.util.concurrent.ConcurrentHashMap;
@@ -65,7 +65,6 @@
6565
* @see AdapterSelector
6666
*/
6767
@Slf4j
68-
@Component
6968
public class AdapterRegistry {
7069

7170
/** Spring application context for bean discovery. */

src/main/java/org/fireflyframework/ecm/adapter/AdapterSelector.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import lombok.extern.slf4j.Slf4j;
1919
import org.springframework.beans.factory.annotation.Autowired;
20-
import org.springframework.stereotype.Component;
20+
2121

2222
import java.util.Optional;
2323

@@ -51,7 +51,6 @@
5151
* @see EcmPortProvider
5252
*/
5353
@Slf4j
54-
@Component
5554
public class AdapterSelector {
5655

5756
/** The adapter registry containing all available adapters. */

src/main/java/org/fireflyframework/ecm/adapter/local/LocalDocumentSearchAdapter.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import org.fireflyframework.ecm.domain.model.document.Document;
2323
import org.fireflyframework.ecm.port.document.DocumentSearchPort;
2424
import lombok.extern.slf4j.Slf4j;
25-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
26-
import org.springframework.stereotype.Component;
25+
26+
2727
import reactor.core.publisher.Flux;
2828
import reactor.core.publisher.Mono;
2929

@@ -38,13 +38,11 @@
3838
* Stores indexed documents in-memory and supports basic filters.
3939
*/
4040
@Slf4j
41-
@Component
4241
@EcmAdapter(
4342
type = "local-search",
4443
description = "Local in-memory DocumentSearchPort adapter",
4544
supportedFeatures = { AdapterFeature.SEARCH, AdapterFeature.METADATA_SEARCH }
4645
)
47-
@ConditionalOnProperty(name = "firefly.ecm.search.enabled", havingValue = "true", matchIfMissing = false)
4846
public class LocalDocumentSearchAdapter implements DocumentSearchPort {
4947

5048
private final Map<UUID, Document> index = new ConcurrentHashMap<>();

src/main/java/org/fireflyframework/ecm/adapter/local/LocalPermissionAdapter.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import org.fireflyframework.ecm.domain.model.security.Permission;
2525
import org.fireflyframework.ecm.port.security.PermissionPort;
2626
import lombok.extern.slf4j.Slf4j;
27-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
28-
import org.springframework.stereotype.Component;
27+
28+
2929
import reactor.core.publisher.Flux;
3030
import reactor.core.publisher.Mono;
3131

@@ -38,13 +38,11 @@
3838
* Provides a functional, non-stub adapter to satisfy hexagonal port contracts.
3939
*/
4040
@Slf4j
41-
@Component
4241
@EcmAdapter(
4342
type = "local-permissions",
4443
description = "Local in-memory PermissionPort adapter",
4544
supportedFeatures = { AdapterFeature.PERMISSIONS }
4645
)
47-
@ConditionalOnProperty(name = "firefly.ecm.permissions.enabled", havingValue = "true", matchIfMissing = false)
4846
public class LocalPermissionAdapter implements PermissionPort {
4947

5048
private final Map<UUID, Permission> store = new ConcurrentHashMap<>();

src/main/java/org/fireflyframework/ecm/adapter/noop/NoOpAdapterFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.fireflyframework.ecm.port.idp.*;
2525
import org.fireflyframework.ecm.port.security.*;
2626
import lombok.extern.slf4j.Slf4j;
27-
import org.springframework.stereotype.Component;
27+
2828

2929
/**
3030
* Factory for creating no-op adapter implementations for all ECM port interfaces.
@@ -48,7 +48,6 @@
4848
* @see NoOpAdapterBase
4949
*/
5050
@Slf4j
51-
@Component
5251
public class NoOpAdapterFactory {
5352

5453
/**

src/main/java/org/fireflyframework/ecm/config/EcmAutoConfiguration.java

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import org.fireflyframework.ecm.adapter.AdapterRegistry;
1919
import org.fireflyframework.ecm.adapter.AdapterSelector;
20+
import org.fireflyframework.ecm.adapter.local.LocalDocumentSearchAdapter;
21+
import org.fireflyframework.ecm.adapter.local.LocalPermissionAdapter;
2022
import org.fireflyframework.ecm.adapter.noop.NoOpAdapterFactory;
2123
import org.fireflyframework.ecm.port.document.*;
2224
import org.fireflyframework.ecm.port.folder.*;
@@ -27,10 +29,11 @@
2729
import org.fireflyframework.ecm.service.EcmPortProvider;
2830
import lombok.extern.slf4j.Slf4j;
2931
import org.springframework.boot.autoconfigure.AutoConfiguration;
32+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3033
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3134
import org.springframework.boot.context.properties.EnableConfigurationProperties;
35+
import org.springframework.context.ApplicationContext;
3236
import org.springframework.context.annotation.Bean;
33-
import org.springframework.context.annotation.ComponentScan;
3437

3538
/**
3639
* Spring Boot auto-configuration for the Firefly ECM (Enterprise Content Management) system.
@@ -41,7 +44,7 @@
4144
* <li>Adapter discovery and registration</li>
4245
* <li>Port provider configuration</li>
4346
* <li>Conditional bean creation based on feature flags</li>
44-
* <li>Component scanning for ECM-related beans</li>
47+
* <li>Explicit bean registration for ECM infrastructure components</li>
4548
* </ul>
4649
*
4750
* <p>The auto-configuration is activated when the property {@code firefly.ecm.enabled}
@@ -72,10 +75,57 @@
7275
@Slf4j
7376
@AutoConfiguration
7477
@EnableConfigurationProperties(EcmProperties.class)
75-
@ComponentScan(basePackages = "org.fireflyframework.ecm")
7678
@ConditionalOnProperty(prefix = "firefly.ecm", name = "enabled", havingValue = "true", matchIfMissing = true)
7779
public class EcmAutoConfiguration {
7880

81+
/**
82+
* Configures the adapter registry for discovering and managing ECM adapters.
83+
*
84+
* <p>The adapter registry automatically discovers all ECM adapters in the Spring
85+
* application context and provides efficient access to them based on type or
86+
* interface requirements.</p>
87+
*
88+
* @param applicationContext the Spring application context for bean discovery
89+
* @return a configured AdapterRegistry instance
90+
* @see AdapterRegistry
91+
*/
92+
@Bean
93+
@ConditionalOnMissingBean
94+
public AdapterRegistry adapterRegistry(ApplicationContext applicationContext) {
95+
return new AdapterRegistry(applicationContext);
96+
}
97+
98+
/**
99+
* Configures the adapter selector for choosing appropriate ECM adapters.
100+
*
101+
* <p>The adapter selector implements the adapter selection logic, providing
102+
* intelligent fallback mechanisms and validation capabilities.</p>
103+
*
104+
* @param adapterRegistry the registry containing available adapters
105+
* @return a configured AdapterSelector instance
106+
* @see AdapterSelector
107+
*/
108+
@Bean
109+
@ConditionalOnMissingBean
110+
public AdapterSelector adapterSelector(AdapterRegistry adapterRegistry) {
111+
return new AdapterSelector(adapterRegistry);
112+
}
113+
114+
/**
115+
* Configures the no-op adapter factory for creating fallback adapter implementations.
116+
*
117+
* <p>The no-op adapter factory provides a centralized way to create no-op adapters
118+
* that serve as fallbacks when no real adapter implementations are available.</p>
119+
*
120+
* @return a configured NoOpAdapterFactory instance
121+
* @see NoOpAdapterFactory
122+
*/
123+
@Bean
124+
@ConditionalOnMissingBean
125+
public NoOpAdapterFactory noOpAdapterFactory() {
126+
return new NoOpAdapterFactory();
127+
}
128+
79129
/**
80130
* Configures the central ECM port provider that manages adapter selection and port provisioning.
81131
*
@@ -90,11 +140,46 @@ public class EcmAutoConfiguration {
90140
* @see AdapterSelector
91141
*/
92142
@Bean
143+
@ConditionalOnMissingBean
93144
public EcmPortProvider ecmPortProvider(AdapterSelector adapterSelector, EcmProperties ecmProperties) {
94145
log.info("Configuring ECM Port Provider with adapter type: {}", ecmProperties.getAdapterType());
95146
return new EcmPortProvider(adapterSelector, ecmProperties);
96147
}
97148

149+
/**
150+
* Configures the local in-memory document search adapter.
151+
*
152+
* <p>This bean is only created when the {@code firefly.ecm.search.enabled} property
153+
* is set to {@code true}. It provides an in-memory search implementation for
154+
* development and testing purposes.</p>
155+
*
156+
* @return a configured LocalDocumentSearchAdapter instance
157+
* @see LocalDocumentSearchAdapter
158+
*/
159+
@Bean
160+
@ConditionalOnMissingBean
161+
@ConditionalOnProperty(name = "firefly.ecm.search.enabled", havingValue = "true", matchIfMissing = false)
162+
public LocalDocumentSearchAdapter localDocumentSearchAdapter() {
163+
return new LocalDocumentSearchAdapter();
164+
}
165+
166+
/**
167+
* Configures the local in-memory permission adapter.
168+
*
169+
* <p>This bean is only created when the {@code firefly.ecm.permissions.enabled} property
170+
* is set to {@code true}. It provides an in-memory permission management implementation
171+
* for development and testing purposes.</p>
172+
*
173+
* @return a configured LocalPermissionAdapter instance
174+
* @see LocalPermissionAdapter
175+
*/
176+
@Bean
177+
@ConditionalOnMissingBean
178+
@ConditionalOnProperty(name = "firefly.ecm.permissions.enabled", havingValue = "true", matchIfMissing = false)
179+
public LocalPermissionAdapter localPermissionAdapter() {
180+
return new LocalPermissionAdapter();
181+
}
182+
98183
/**
99184
* Configures the document port for basic document CRUD operations.
100185
*

src/main/java/org/fireflyframework/ecm/service/EcmPortProvider.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.fireflyframework.ecm.port.esignature.*;
2626
import org.fireflyframework.ecm.port.idp.*;
2727
import lombok.extern.slf4j.Slf4j;
28-
import org.springframework.stereotype.Service;
28+
2929

3030
import java.util.Optional;
3131

@@ -76,7 +76,6 @@
7676
* @see EcmAutoConfiguration
7777
*/
7878
@Slf4j
79-
@Service
8079
public class EcmPortProvider {
8180

8281
/** The adapter selector responsible for choosing appropriate adapters. */

0 commit comments

Comments
 (0)