org.lightadmin.core.util.DomainConfigurationUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.lightadmin.core.util.DomainConfigurationUtils.java

Source

/*
 * Copyright 2012-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.lightadmin.core.util;

import org.lightadmin.api.config.AdministrationConfiguration;
import org.lightadmin.api.config.annotation.Administration;
import org.lightadmin.core.config.domain.unit.ConfigurationUnit;
import org.lightadmin.core.config.domain.unit.ConfigurationUnitBuilder;
import org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

import static org.springframework.beans.BeanUtils.instantiateClass;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import static org.springframework.util.ClassUtils.getConstructorIfAvailable;
import static org.springframework.util.ClassUtils.getMethodIfAvailable;
import static org.springframework.util.ReflectionUtils.invokeMethod;

public abstract class DomainConfigurationUtils {

    public static Class<?> configurationDomainType(Class clazz) {
        if (isAnnotationBasedConfigurationCandidate(clazz)) {
            final Administration annotation = findAnnotation(clazz, Administration.class);

            return annotation == null ? null : annotation.value();
        }

        if (isSuperClassBasedConfigurationCandidate(clazz)) {
            final ParameterizedType genericSuperclass = (ParameterizedType) clazz.getGenericSuperclass();

            return (Class<?>) genericSuperclass.getActualTypeArguments()[0];
        }

        throw new RuntimeException("Unknown configuration candidate");
    }

    public static boolean isAnnotationBasedConfigurationCandidate(Class clazz) {
        return hasAdministrationAnnotation(clazz);
    }

    public static boolean isSuperClassBasedConfigurationCandidate(Class clazz) {
        return ClassUtils.isAssignable(AdministrationConfiguration.class, clazz);
    }

    private static boolean hasAdministrationAnnotation(Class clazz) {
        return findAnnotation(clazz, Administration.class) != null;
    }

    @SuppressWarnings({ "unchecked" })
    public static <T extends ConfigurationUnit> T initializeConfigurationUnitWithBuilder(
            final AdministrationConfiguration configurationInstance,
            DomainConfigurationUnitType configurationUnitType,
            Class<? extends ConfigurationUnitBuilder<T>> builderInterface,
            Class<? extends ConfigurationUnitBuilder<T>> concreteBuilderClass) {
        final Class<? extends AdministrationConfiguration> configurationClass = configurationInstance.getClass();
        final Class<?> domainType = configurationDomainType(configurationClass);

        final Method method = getMethodIfAvailable(configurationClass, configurationUnitType.getName(),
                builderInterface);

        final ConfigurationUnitBuilder<T> builder = instantiateBuilder(concreteBuilderClass, domainType,
                configurationUnitType);

        try {
            return (T) invokeMethod(method, configurationInstance, builder);
        } catch (Exception ex) {
            return instantiateBuilder(concreteBuilderClass, domainType, configurationUnitType).build();
        }
    }

    @SuppressWarnings({ "unchecked" })
    public static <T extends ConfigurationUnit> T initializeConfigurationUnitWithBuilder(
            final Class<?> configurationClass, DomainConfigurationUnitType configurationUnitType,
            Class<? extends ConfigurationUnitBuilder<T>> builderInterface,
            Class<? extends ConfigurationUnitBuilder<T>> concreteBuilderClass) {
        final Class<?> domainType = configurationDomainType(configurationClass);

        final Method method = getMethodIfAvailable(configurationClass, configurationUnitType.getName(),
                builderInterface);

        final ConfigurationUnitBuilder<T> builder = instantiateBuilder(concreteBuilderClass, domainType,
                configurationUnitType);
        if (method != null) {
            try {
                return (T) invokeMethod(method, null, builder);
            } catch (Exception ex) {
                return instantiateBuilder(concreteBuilderClass, domainType, configurationUnitType).build();
            }
        }

        return builder.build();
    }

    private static <T extends ConfigurationUnit> ConfigurationUnitBuilder<T> instantiateBuilder(
            final Class<? extends ConfigurationUnitBuilder<T>> concreteBuilderClass, final Class domainType,
            DomainConfigurationUnitType configurationUnitType) {
        Constructor<? extends ConfigurationUnitBuilder<T>> extendedConstructor = getConstructorIfAvailable(
                concreteBuilderClass, Class.class, DomainConfigurationUnitType.class);

        if (extendedConstructor != null) {
            return instantiateClass(extendedConstructor, domainType, configurationUnitType);
        }

        Constructor<? extends ConfigurationUnitBuilder<T>> constructor = getConstructorIfAvailable(
                concreteBuilderClass, Class.class);
        if (constructor != null) {
            return instantiateClass(constructor, domainType);
        }

        return instantiateClass(concreteBuilderClass);
    }
}