SLING-7049 - MissingExporterException thrown when the desired ModelExporter is not...
authorJustin Edelson <justin@apache.org>
Mon, 14 Aug 2017 21:04:43 +0000 (21:04 +0000)
committerJustin Edelson <justin@apache.org>
Mon, 14 Aug 2017 21:04:43 +0000 (21:04 +0000)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1805037 13f79535-47bb-0310-9956-ffa450edef68

src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
src/test/java/org/apache/sling/models/impl/AdapterFactoryTest.java

index 8e36be4..c37d73b 100644 (file)
@@ -1210,8 +1210,6 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
             if (exporter.getName().equals(name) && exporter.isSupported(targetClass)) {
                 T resultObject = exporter.export(model, targetClass, options);
                 return resultObject;
-            } else {
-                throw new MissingExporterException(name, targetClass);
             }
         }
         throw new MissingExporterException(name, targetClass);
@@ -1239,17 +1237,9 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         return handleAndExportResult(result, name, targetClass, options);
     }
 
-    private <T> T handleAndExportResult(Result<?> result, String name, Class<T> targetClass, Map<String, String> options) throws ExportException, MissingExporterException {
+    protected <T> T handleAndExportResult(Result<?> result, String name, Class<T> targetClass, Map<String, String> options) throws ExportException, MissingExporterException {
         if (result.wasSuccessful()) {
-            for (ModelExporter exporter : modelExporters) {
-                if (exporter.getName().equals(name) && exporter.isSupported(targetClass)) {
-                    T resultObject = exporter.export(result.getValue(), targetClass, options);
-                    return resultObject;
-                } else {
-                    throw new MissingExporterException(name, targetClass);
-                }
-            }
-            throw new MissingExporterException(name, targetClass);
+            return exportModel(result.getValue(), name, targetClass, options);
         } else {
             throw result.getThrowable();
         }
index f114b81..a08be88 100644 (file)
  */
 package org.apache.sling.models.impl;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
@@ -28,8 +30,11 @@ import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.annotations.injectorspecific.Self;
+import org.apache.sling.models.export.spi.ModelExporter;
+import org.apache.sling.models.factory.ExportException;
 import org.apache.sling.models.factory.InvalidAdaptableException;
 import org.apache.sling.models.factory.MissingElementsException;
+import org.apache.sling.models.factory.MissingExporterException;
 import org.apache.sling.models.factory.ModelClassException;
 import org.apache.sling.models.impl.injectors.SelfInjector;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
@@ -46,6 +51,9 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentContext;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
 @RunWith(MockitoJUnitRunner.class)
 public class AdapterFactoryTest {
     @Mock
@@ -71,6 +79,9 @@ public class AdapterFactoryTest {
         factory.activate(componentCtx);
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(0, 0));
         factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(1, 1));
+        factory.bindModelExporter(new FirstStringExporter(), new ServicePropertiesMap(2, 0));
+        factory.bindModelExporter(new SecondStringExporter(), new ServicePropertiesMap(3, 1));
+        factory.bindModelExporter(new FirstIntegerExporter(), new ServicePropertiesMap(4, 2));
         
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(DefaultStringModel.class, ConstructorWithExceptionModel.class, NestedModel.class, NestedModelWithInvalidAdaptable.class, NestedModelWithInvalidAdaptable2.class, ResourceModelWithRequiredField.class) ;
     }
@@ -164,4 +175,102 @@ public class AdapterFactoryTest {
 
         factory.createModel(resource, NestedModel.class);
     }
+
+    @Test
+    public void testSelectExporterByName() throws Exception {
+        Result<Object> result = mock(Result.class);
+        when(result.wasSuccessful()).thenReturn(true);
+        when(result.getValue()).thenReturn(new Object());
+
+        String exported = factory.handleAndExportResult(result, "second", String.class, Collections.<String, String>emptyMap());
+        Assert.assertEquals("Export from second", exported);
+    }
+
+    @Test
+    public void testSelectExporterByType() throws Exception {
+        Result<Object> result = mock(Result.class);
+        when(result.wasSuccessful()).thenReturn(true);
+        when(result.getValue()).thenReturn(new Object());
+
+        Integer exported = factory.handleAndExportResult(result, "first", Integer.class, Collections.<String, String>emptyMap());
+        Assert.assertEquals(Integer.valueOf(42), exported);
+    }
+
+    @Test(expected = MissingExporterException.class)
+    public void testSelectExporterByNameAndWrongType() throws Exception {
+        Result<Object> result = mock(Result.class);
+        when(result.wasSuccessful()).thenReturn(true);
+        when(result.getValue()).thenReturn(new Object());
+
+        factory.handleAndExportResult(result, "second", Integer.class, Collections.<String, String>emptyMap());
+    }
+
+    private static class FirstStringExporter implements ModelExporter {
+        @Override
+        public boolean isSupported(@Nonnull Class<?> aClass) {
+            return aClass == String.class;
+        }
+
+        @CheckForNull
+        @Override
+        public <T> T export(@Nonnull Object o, @Nonnull Class<T> aClass, @Nonnull Map<String, String> map) throws ExportException {
+            if (aClass == String.class) {
+                return (T) "Export from first";
+            } else {
+                throw new ExportException(String.format("%s is not supported.", aClass));
+            }
+        }
+
+        @Nonnull
+        @Override
+        public String getName() {
+            return "first";
+        }
+    }
+
+    private static class SecondStringExporter implements ModelExporter {
+        @Override
+        public boolean isSupported(@Nonnull Class<?> aClass) {
+            return aClass == String.class;
+        }
+
+        @CheckForNull
+        @Override
+        public <T> T export(@Nonnull Object o, @Nonnull Class<T> aClass, @Nonnull Map<String, String> map) throws ExportException {
+            if (aClass == String.class) {
+                return (T) "Export from second";
+            } else {
+                throw new ExportException(String.format("%s is not supported.", aClass));
+            }
+        }
+
+        @Nonnull
+        @Override
+        public String getName() {
+            return "second";
+        }
+    }
+
+    private static class FirstIntegerExporter implements ModelExporter {
+        @Override
+        public boolean isSupported(@Nonnull Class<?> aClass) {
+            return aClass == Integer.class;
+        }
+
+        @CheckForNull
+        @Override
+        public <T> T export(@Nonnull Object o, @Nonnull Class<T> aClass, @Nonnull Map<String, String> map) throws ExportException {
+            if (aClass == Integer.class) {
+                return (T) Integer.valueOf(42);
+            } else {
+                throw new ExportException(String.format("%s is not supported.", aClass));
+            }
+        }
+
+        @Nonnull
+        @Override
+        public String getName() {
+            return "first";
+        }
+    }
 }