This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch bugfix/fix-metatype-id-escape-rules
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 2d3bb9590198e787a182b737742fe02fff1f655a
Author: Konrad Windszus <[email protected]>
AuthorDate: Mon May 11 11:20:19 2026 +0200

    fix(migrate_annotations): implement method name escape rules for OSGi 
properties and add corresponding unit tests
---
 .../scripts/migrate_annotations.py                 | 23 +++++++++++++++++++++-
 .../scripts/tests/test_migrate_annotations.py      | 15 ++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/skills/osgi-scr-migrator/scripts/migrate_annotations.py 
b/skills/osgi-scr-migrator/scripts/migrate_annotations.py
index 70385722..acccd3f4 100755
--- a/skills/osgi-scr-migrator/scripts/migrate_annotations.py
+++ b/skills/osgi-scr-migrator/scripts/migrate_annotations.py
@@ -113,7 +113,7 @@ class Property:
         if self.description:
             parts.append(f'description = "{self.description}"')
 
-        method_name = self.name.replace('.', '_').replace('-', '_')
+        method_name = self._property_id_to_method_name(self.name)
         java_type = self._get_java_type()
         default_value = self._get_default_value()
 
@@ -122,6 +122,27 @@ class Property:
 
         return f'{indent}{attr_annotation}\n{indent}{java_type} 
{method_name}(){default_value};'
 
+    @staticmethod
+    def _property_id_to_method_name(property_id: str) -> str:
+        """Map an OSGi property id to a method name using metatype escape 
rules.
+
+        This is the inverse of the id generation rules from
+        org.osgi.service.metatype.annotations.AttributeDefinition.
+        """
+        escaped = []
+        for ch in property_id:
+            if ch == '.':
+                escaped.append('_')
+            elif ch == '_':
+                escaped.append('__')
+            elif ch == '-':
+                escaped.append('$_$')
+            elif ch == '$':
+                escaped.append('$$')
+            else:
+                escaped.append(ch)
+        return ''.join(escaped)
+
     def _get_java_type(self) -> str:
         """Get Java type for metatype."""
         type_map = {
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 f15eb00d..23f39628 100644
--- a/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py
+++ b/skills/osgi-scr-migrator/scripts/tests/test_migrate_annotations.py
@@ -153,6 +153,21 @@ class TestPropertyConversion(unittest.TestCase):
         self.assertIn('int my_timeout()', result)
         self.assertIn('default 30', result)
 
+    def test_metatype_method_name_escapes(self):
+        """Test all OSGi method-name escape rules for generated config 
methods."""
+        cases = {
+            "prop.name": "String prop_name()",
+            "prop_name": "String prop__name()",
+            "prop-name": "String prop$_$name()",
+            "prop$name": "String prop$$name()",
+            "a.b_c-d$e": "String a_b__c$_$d$$e()",
+        }
+
+        for prop_name, expected_signature in cases.items():
+            prop = Property(name=prop_name, value="v")
+            result = prop.to_metatype_attribute()
+            self.assertIn(expected_signature, result)
+
 
 class TestSlingServletMigration(unittest.TestCase):
     """Test @SlingServlet migration."""

Reply via email to