This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/migrate-component-policy in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
commit c49167d309b414f8724fabe355d40de6e2acffca Author: Konrad Windszus <[email protected]> AuthorDate: Wed May 13 15:00:11 2026 +0200 feat(migrate_annotations): add support for configurationPolicy migration from SCR annotations --- .../scripts/migrate_annotations.py | 16 ++++++++++ .../scripts/tests/test_migrate_annotations.py | 36 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/skills/osgi-scr-migrator/scripts/migrate_annotations.py b/skills/osgi-scr-migrator/scripts/migrate_annotations.py index 38666311..c8945fa6 100755 --- a/skills/osgi-scr-migrator/scripts/migrate_annotations.py +++ b/skills/osgi-scr-migrator/scripts/migrate_annotations.py @@ -796,6 +796,10 @@ class AnnotationMigrator: immediate = re.search(r'immediate\s*=\s*(true|false)', annotation) name = re.search(r'name\s*=\s*"([^"]*)"', annotation) factory = re.search(r'factory\s*=\s*"([^"]*)"', annotation) + policy = re.search( + r'policy\s*=\s*(?:ConfigurationPolicy\.)?([A-Za-z_][A-Za-z0-9_]*)', + annotation + ) # Build new annotation attrs = [] @@ -806,6 +810,18 @@ class AnnotationMigrator: attrs.append(f'immediate = {immediate.group(1)}') if factory: attrs.append(f'factory = "{factory.group(1)}"') + if policy: + policy_value = policy.group(1).upper() + policy_mapping = { + 'OPTIONAL': 'OPTIONAL', + 'REQUIRE': 'REQUIRE', + 'REQUIRED': 'REQUIRE', + 'IGNORE': 'IGNORE', + } + mapped_policy = policy_mapping.get(policy_value) + if mapped_policy: + attrs.append(f'configurationPolicy = ConfigurationPolicy.{mapped_policy}') + self.imports_to_add.add('org.osgi.service.component.annotations.ConfigurationPolicy') if service_class is not None: if service_class: attrs.append(f'service = {service_class}') diff --git a/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py b/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py index 42c5f2b0..1844900e 100644 --- a/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py +++ b/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py @@ -442,6 +442,42 @@ public class MyService implements MyInterface { self.assertNotIn('@Service', new_content) self.assertIn('org.osgi.service.component.annotations.Component', new_content) + def test_component_policy_migrates_to_configuration_policy(self): + """Test SCR policy attribute migrates to OSGi configurationPolicy.""" + content = '''package com.example; + +import org.apache.felix.scr.annotations.Component; + +@Component(policy = ConfigurationPolicy.REQUIRE) +public class MyService { +} +''' + stats = MigrationStats() + migrator = AnnotationMigrator(content, Path("test.java"), stats) + new_content, changed = migrator.migrate() + + self.assertTrue(changed) + self.assertIn('configurationPolicy = ConfigurationPolicy.REQUIRE', new_content) + self.assertIn('org.osgi.service.component.annotations.ConfigurationPolicy', new_content) + + def test_component_required_policy_alias_maps_to_require(self): + """Test legacy REQUIRED value maps to OSGi REQUIRE.""" + content = '''package com.example; + +import org.apache.felix.scr.annotations.Component; + +@Component(policy = ConfigurationPolicy.REQUIRED) +public class MyService { +} +''' + stats = MigrationStats() + migrator = AnnotationMigrator(content, Path("test.java"), stats) + new_content, changed = migrator.migrate() + + self.assertTrue(changed) + self.assertIn('configurationPolicy = ConfigurationPolicy.REQUIRE', new_content) + self.assertNotIn('configurationPolicy = ConfigurationPolicy.REQUIRED', new_content) + def test_component_with_properties(self): """Test component with properties (now uses property type annotations).""" content = '''package com.example;
