SLING-6308 - support explicit class names in bundle header
authorJustin Edelson <justin@apache.org>
Sat, 19 Nov 2016 22:09:27 +0000 (22:09 +0000)
committerJustin Edelson <justin@apache.org>
Sat, 19 Nov 2016 22:09:27 +0000 (22:09 +0000)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/impl@1770520 13f79535-47bb-0310-9956-ffa450edef68

src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java
src/test/java/org/apache/sling/models/impl/ImplementsExtendsTest.java

index b0d8683..99d7743 100644 (file)
@@ -49,7 +49,8 @@ import javax.servlet.Servlet;
 
 public class ModelPackageBundleListener implements BundleTrackerCustomizer {
 
-    static final String HEADER = "Sling-Model-Packages";
+    static final String PACKAGE_HEADER = "Sling-Model-Packages";
+    static final String CLASSES_HEADER = "Sling-Model-Classes";
     
     /**
      * Service registration property for the adapter condition.
@@ -86,9 +87,8 @@ public class ModelPackageBundleListener implements BundleTrackerCustomizer {
         List<ServiceRegistration> regs = new ArrayList<ServiceRegistration>();
 
         Dictionary<?, ?> headers = bundle.getHeaders();
-        String packageList = PropertiesUtil.toString(headers.get(HEADER), null);
+        String packageList = PropertiesUtil.toString(headers.get(PACKAGE_HEADER), null);
         if (packageList != null) {
-
             packageList = StringUtils.deleteWhitespace(packageList);
             String[] packages = packageList.split(",");
             for (String singlePackage : packages) {
@@ -104,60 +104,73 @@ public class ModelPackageBundleListener implements BundleTrackerCustomizer {
                 while (classUrls.hasMoreElements()) {
                     URL url = classUrls.nextElement();
                     String className = toClassName(url);
-                    try {
-                        Class<?> implType = bundle.loadClass(className);
-                        Model annotation = implType.getAnnotation(Model.class);
-                        if (annotation != null) {
-                            
-                            // get list of adapters from annotation - if not given use annotated class itself
-                            Class<?>[] adapterTypes = annotation.adapters();
-                            if (adapterTypes.length == 0) {
-                                adapterTypes = new Class<?>[] { implType };
-                            }
-                            // register adapter only if given adapters are valid
-                            if (validateAdapterClasses(implType, adapterTypes)) {
-                                for (Class<?> adapterType : adapterTypes) {
-                                    adapterImplementations.add(adapterType, implType);
+                    analyzeClass(bundle, className, regs);
+
+                }
+            }
+        }
+        String classesList = PropertiesUtil.toString(headers.get(CLASSES_HEADER), null);
+        if (classesList != null) {
+            classesList = StringUtils.deleteWhitespace(classesList);
+            String[] classes = classesList.split(",");
+            for (String className : classes) {
+                analyzeClass(bundle, className, regs);
+            }
+        }
+
+        return regs.toArray(new ServiceRegistration[0]);
+    }
+
+    private void analyzeClass(Bundle bundle, String className, List<ServiceRegistration> regs) {
+        try {
+            Class<?> implType = bundle.loadClass(className);
+            Model annotation = implType.getAnnotation(Model.class);
+            if (annotation != null) {
+
+                // get list of adapters from annotation - if not given use annotated class itself
+                Class<?>[] adapterTypes = annotation.adapters();
+                if (adapterTypes.length == 0) {
+                    adapterTypes = new Class<?>[] { implType };
+                }
+                // register adapter only if given adapters are valid
+                if (validateAdapterClasses(implType, adapterTypes)) {
+                    for (Class<?> adapterType : adapterTypes) {
+                        adapterImplementations.add(adapterType, implType);
+                    }
+                    ServiceRegistration reg = registerAdapterFactory(adapterTypes, annotation.adaptables(), implType, annotation.condition());
+                    regs.add(reg);
+
+                    String[] resourceTypes = annotation.resourceType();
+                    for (String resourceType : resourceTypes) {
+                        if (StringUtils.isNotEmpty(resourceType)) {
+                            for (Class<?> adaptable : annotation.adaptables()) {
+                                adapterImplementations.registerModelToResourceType(bundle, resourceType, adaptable, adapterTypes[0]);
+                                ExportServlet.ExportedObjectAccessor accessor = null;
+                                if (adaptable == Resource.class) {
+                                    accessor = ExportServlet.RESOURCE;
+                                } else if (adaptable == SlingHttpServletRequest.class) {
+                                    accessor = ExportServlet.REQUEST;
+                                }
+                                Exporter exporterAnnotation = implType.getAnnotation(Exporter.class);
+                                if (exporterAnnotation != null) {
+                                    registerExporter(bundle, implType, resourceType, exporterAnnotation, regs, accessor);
                                 }
-                                ServiceRegistration reg = registerAdapterFactory(adapterTypes, annotation.adaptables(), implType, annotation.condition());
-                                regs.add(reg);
-
-                                String[] resourceTypes = annotation.resourceType();
-                                for (String resourceType : resourceTypes) {
-                                    if (StringUtils.isNotEmpty(resourceType)) {
-                                        for (Class<?> adaptable : annotation.adaptables()) {
-                                            adapterImplementations.registerModelToResourceType(bundle, resourceType, adaptable, adapterTypes[0]);
-                                            ExportServlet.ExportedObjectAccessor accessor = null;
-                                            if (adaptable == Resource.class) {
-                                                accessor = ExportServlet.RESOURCE;
-                                            } else if (adaptable == SlingHttpServletRequest.class) {
-                                                accessor = ExportServlet.REQUEST;
-                                            }
-                                            Exporter exporterAnnotation = implType.getAnnotation(Exporter.class);
-                                            if (exporterAnnotation != null) {
-                                                registerExporter(bundle, implType, resourceType, exporterAnnotation, regs, accessor);
-                                            }
-                                            Exporters exportersAnnotation = implType.getAnnotation(Exporters.class);
-                                            if (exportersAnnotation != null) {
-                                                for (Exporter ann : exportersAnnotation.value()) {
-                                                    registerExporter(bundle, implType, resourceType, ann, regs, accessor);
-                                                }
-                                            }
-
-                                        }
+                                Exporters exportersAnnotation = implType.getAnnotation(Exporters.class);
+                                if (exportersAnnotation != null) {
+                                    for (Exporter ann : exportersAnnotation.value()) {
+                                        registerExporter(bundle, implType, resourceType, ann, regs, accessor);
                                     }
                                 }
-                            }
 
+                            }
                         }
-                    } catch (ClassNotFoundException e) {
-                        log.warn("Unable to load class", e);
                     }
-
                 }
+
             }
+        } catch (ClassNotFoundException e) {
+            log.warn("Unable to load class", e);
         }
-        return regs.toArray(new ServiceRegistration[0]);
     }
 
     @Override
index f01a5c1..014282c 100644 (file)
@@ -117,7 +117,7 @@ public class ImplementsExtendsTest {
 
         // simulate bundle add for ModelPackageBundleListener
         Dictionary<String, String> headers = new Hashtable<String,String>();
-        headers.put(ModelPackageBundleListener.HEADER, "org.apache.sling.models.testmodels.classes.implextend");
+        headers.put(ModelPackageBundleListener.PACKAGE_HEADER, "org.apache.sling.models.testmodels.classes.implextend");
         when(bundle.getHeaders()).thenReturn(headers);
 
         Vector<URL> classUrls = new Vector<URL>();