From e104693defd5e1b4bdbde209f6d204dae94fa09f Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <yannick.lecaillez@forgerock.com>
Date: Mon, 15 Jun 2015 12:19:18 +0000
Subject: [PATCH] OPENDJ-2139: Setup fails while importing data

---
 opendj-server-legacy/src/test/java/org/opends/server/ConfigurationMock.java |  198 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 188 insertions(+), 10 deletions(-)

diff --git a/opendj-server-legacy/src/test/java/org/opends/server/ConfigurationMock.java b/opendj-server-legacy/src/test/java/org/opends/server/ConfigurationMock.java
index e77a32f..a7e0572 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/ConfigurationMock.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/ConfigurationMock.java
@@ -21,7 +21,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2013-2014 ForgeRock AS.
+ *      Copyright 2013-2015 ForgeRock AS.
  */
 package org.opends.server;
 
@@ -65,6 +65,8 @@
 
     private static final ConfigAnswer CONFIG_ANSWER = new ConfigAnswer();
 
+    private static final LegacyConfigAnswer LEGACY_CONFIG_ANSWER = new LegacyConfigAnswer();
+
     /**
      * Returns a mock for the provided configuration class.
      * <p>
@@ -85,6 +87,25 @@
     }
 
     /**
+     * Returns a mock for the provided configuration class.
+     * <p>
+     * If a setting has a default value, the mock automatically returns the
+     * default value when the getter is called on the setting.
+     * <p>
+     * It is possible to override this default behavior with the usual methods
+     * calls with Mockito (e.g, {@code when} method).
+     *
+     * @param <T>
+     *            The type of configuration.
+     * @param configClass
+     *            The configuration class.
+     * @return a mock
+     */
+    public static <T extends org.opends.server.admin.Configuration> T legacyMockCfg(Class<T> configClass) {
+        return mock(configClass, LEGACY_CONFIG_ANSWER);
+    }
+
+    /**
      * A stubbed answer for Configuration objects, allowing to return default
      * value for settings when available.
      */
@@ -121,11 +142,11 @@
             return super.answer(invocation);
         }
 
-        private boolean isGetterMethod(String invokedMethodName) {
+        private static boolean isGetterMethod(String invokedMethodName) {
             return invokedMethodName.startsWith("get") || invokedMethodName.startsWith("is");
         }
 
-        private Method getPropertyDefinitionMethod(Class<?> definitionClass, String invokedMethodName)
+        private static Method getPropertyDefinitionMethod(Class<?> definitionClass, String invokedMethodName)
                 throws SecurityException, NoSuchMethodException {
             // Methods for boolean starts with "is" in Cfg class but with "get" in CfgDefn class.
             return definitionClass.getMethod(invokedMethodName.replaceAll("^is", "get") + "PropertyDefinition");
@@ -134,7 +155,7 @@
         /**
          * Returns the type of values returned by the property.
          */
-        private Class<?> getPropertyReturnType(Method getPropertyDefMethod) {
+        private static Class<?> getPropertyReturnType(Method getPropertyDefMethod) {
             Class<?> returnClass = getPropertyDefMethod.getReturnType();
             return ((ParameterizedType) returnClass.getGenericSuperclass())
                     .getActualTypeArguments()[0].getClass();
@@ -145,7 +166,7 @@
          * <p>
          * Convert class name "[package].server.FooCfg" to "[package].meta.FooCfgDef"
          */
-        private String toDefinitionClassName(String configClassName) {
+        private static String toDefinitionClassName(String configClassName) {
             int finalDot = configClassName.lastIndexOf('.');
             return configClassName.substring(0, finalDot - 6) + "meta."
                     + configClassName.substring(finalDot + 1) + "Defn";
@@ -171,13 +192,12 @@
          *             If an error occurs.
          */
         @SuppressWarnings("unchecked")
-        private <T> Object getDefaultValue(ManagedObjectDefinition<?, ?> definition,
-                Method getPropertyDefMethod, Class<T> propertyReturnClass)
-                throws Exception {
+        private static <T> Object getDefaultValue(ManagedObjectDefinition<?, ?> definition,
+                Method getPropertyDefMethod, Class<T> propertyReturnClass) throws Exception {
             PropertyDefinition<T> propertyDefinition = (PropertyDefinition<T>) getPropertyDefMethod.invoke(definition);
             DefaultBehaviorProvider<T> defaultBehaviorProvider = (DefaultBehaviorProvider<T>) propertyDefinition
                     .getClass().getMethod("getDefaultBehaviorProvider").invoke(propertyDefinition);
-            MockProviderVisitor<T> visitor = new MockProviderVisitor<T>(propertyDefinition);
+            MockProviderVisitor<T> visitor = new MockProviderVisitor<>(propertyDefinition);
             Collection<T> values = defaultBehaviorProvider.accept(visitor, null);
 
             if (values == null) {
@@ -193,6 +213,113 @@
 
     }
 
+    /**
+     * A stubbed answer for Configuration objects, allowing to return default
+     * value for settings when available.
+     */
+    private static class LegacyConfigAnswer extends ReturnsEmptyValues {
+
+        private static final long serialVersionUID = 1L;
+
+        /** {@inheritDoc} */
+        @Override
+        public Object answer(InvocationOnMock invocation) {
+            try {
+                String definitionClassName =
+                    toDefinitionClassName(invocation.getMethod().getDeclaringClass().getName());
+                Class<?> definitionClass = Class.forName(definitionClassName);
+                org.opends.server.admin.ManagedObjectDefinition<?, ?> definition =
+                    (org.opends.server.admin.ManagedObjectDefinition<?, ?>) definitionClass.getMethod("getInstance").invoke(null);
+                String invokedMethodName = invocation.getMethod().getName();
+                if (!isGetterMethod(invokedMethodName)) {
+                    return answerFromDefaultMockitoBehavior(invocation);
+                }
+                Method getPropertyDefMethod = getPropertyDefinitionMethod(definitionClass, invokedMethodName);
+                Class<?> propertyReturnType = getPropertyReturnType(getPropertyDefMethod);
+                Object defaultValue = getDefaultValue(definition, getPropertyDefMethod, propertyReturnType);
+                if (defaultValue == null) {
+                    return answerFromDefaultMockitoBehavior(invocation);
+                }
+                return defaultValue;
+            } catch (Exception e) {
+                return answerFromDefaultMockitoBehavior(invocation);
+            }
+        }
+
+        private Object answerFromDefaultMockitoBehavior(InvocationOnMock invocation) {
+            return super.answer(invocation);
+        }
+
+        private static boolean isGetterMethod(String invokedMethodName) {
+            return invokedMethodName.startsWith("get") || invokedMethodName.startsWith("is");
+        }
+
+        private static Method getPropertyDefinitionMethod(Class<?> definitionClass, String invokedMethodName)
+                throws SecurityException, NoSuchMethodException {
+            // Methods for boolean starts with "is" in Cfg class but with "get" in CfgDefn class.
+            return definitionClass.getMethod(invokedMethodName.replaceAll("^is", "get") + "PropertyDefinition");
+        }
+
+        /**
+         * Returns the type of values returned by the property.
+         */
+        private static Class<?> getPropertyReturnType(Method getPropertyDefMethod) {
+            Class<?> returnClass = getPropertyDefMethod.getReturnType();
+            return ((ParameterizedType) returnClass.getGenericSuperclass()).getActualTypeArguments()[0].getClass();
+        }
+
+        /**
+         * Retrieve class name of definition from class name of configuration.
+         * <p>
+         * Convert class name "[package].server.FooCfg" to "[package].meta.FooCfgDef"
+         */
+        private static String toDefinitionClassName(String configClassName) {
+            int finalDot = configClassName.lastIndexOf('.');
+            return configClassName.substring(0, finalDot - 6) + "meta." + configClassName.substring(finalDot + 1)
+                    + "Defn";
+        }
+
+        /**
+         * Returns the default value corresponding to the provided property
+         * definition getter method from the provided managed object definition.
+         *
+         * @param <T>
+         *            The data type of values provided by the property
+         *            definition.
+         * @param definition
+         *            The definition of the managed object.
+         * @param getPropertyDefMethod
+         *            The method to retrieve the property definition from the
+         *            definition.
+         * @param propertyReturnClass
+         *            The class of values provided by the property definition.
+         * @return the default value of property definition, or
+         *         {@code null} if there is no default value.
+         * @throws Exception
+         *             If an error occurs.
+         */
+        @SuppressWarnings("unchecked")
+        private static <T> Object getDefaultValue(org.opends.server.admin.ManagedObjectDefinition<?, ?> definition,
+                Method getPropertyDefMethod, Class<T> propertyReturnClass) throws Exception {
+            org.opends.server.admin.PropertyDefinition<T> propertyDefinition = (org.opends.server.admin.PropertyDefinition<T>) getPropertyDefMethod.invoke(definition);
+            org.opends.server.admin.DefaultBehaviorProvider<T> defaultBehaviorProvider = (org.opends.server.admin.DefaultBehaviorProvider<T>) propertyDefinition
+                    .getClass().getMethod("getDefaultBehaviorProvider").invoke(propertyDefinition);
+            LegacyMockProviderVisitor<T> visitor = new LegacyMockProviderVisitor<>(propertyDefinition);
+            Collection<T> values = defaultBehaviorProvider.accept(visitor, null);
+
+            if (values == null) {
+                // No default behavior defined
+                return null;
+            } else if (propertyDefinition.hasOption(org.opends.server.admin.PropertyOption.MULTI_VALUED)) {
+                return values;
+            } else {
+                // Single value returned
+                return values.iterator().next();
+            }
+        }
+
+    }
+
     /** Visitor used to retrieve the default value. */
     private static class MockProviderVisitor<T> implements DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
 
@@ -222,7 +349,7 @@
          */
         @Override
         public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> provider, Void p) {
-            SortedSet<T> values = new TreeSet<T>();
+            SortedSet<T> values = new TreeSet<>();
             for (String stringValue : provider.getDefaultValues()) {
                 values.add(propertyDef.decodeValue(stringValue));
             }
@@ -243,4 +370,55 @@
             return null;
         }
     }
+
+    /** Visitor used to retrieve the default value. */
+    private static class LegacyMockProviderVisitor<T> implements org.opends.server.admin.DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
+
+        /** The property definition used to decode the values. */
+        private org.opends.server.admin.PropertyDefinition<T> propertyDef;
+
+        LegacyMockProviderVisitor(org.opends.server.admin.PropertyDefinition<T> propertyDef) {
+            this.propertyDef = propertyDef;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Collection<T> visitAbsoluteInherited(org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider<T> provider, Void p) {
+            // not handled
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Collection<T> visitAlias(org.opends.server.admin.AliasDefaultBehaviorProvider<T> provider, Void p) {
+            // not handled
+            return null;
+        }
+
+        /**
+         * Returns the default value for the property as a collection.
+         */
+        @Override
+        public Collection<T> visitDefined(org.opends.server.admin.DefinedDefaultBehaviorProvider<T> provider, Void p) {
+            SortedSet<T> values = new TreeSet<>();
+            for (String stringValue : provider.getDefaultValues()) {
+                values.add(propertyDef.decodeValue(stringValue));
+            }
+            return values;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Collection<T> visitRelativeInherited(org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
+            // not handled
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Collection<T> visitUndefined(org.opends.server.admin.UndefinedDefaultBehaviorProvider<T> d, Void p) {
+            // not handled
+            return null;
+        }
+    }
 }

--
Gitblit v1.10.0