All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.zalando.sprocwrapper.globalvaluetransformer.GlobalValueTransformerLoader Maven / Gradle / Ivy

package de.zalando.sprocwrapper.globalvaluetransformer;

import java.util.Set;

import org.reflections.Reflections;

import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;

import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Predicate;
import com.google.common.base.Strings;

import de.zalando.sprocwrapper.globalvaluetransformer.annotation.GlobalValueTransformer;

import de.zalando.typemapper.core.ValueTransformer;
import de.zalando.typemapper.core.fieldMapper.GlobalValueTransformerRegistry;

public class GlobalValueTransformerLoader {

    private static final String GLOBAL_VALUE_TRANSFORMER_SEARCH_NAMESPACE = "global.value.transformer.search.namespace";

    // you need to set the namespace to a valid value like: org.doodlejump
    private static String namespaceToScan = "de.zalando";

    private static final Logger LOG = LoggerFactory.getLogger(GlobalValueTransformerLoader.class);
    private static boolean scannedClasspath = false;

    public static synchronized ValueTransformer getValueTransformerForClass(final Class genericType)
        throws InstantiationException, IllegalAccessException {

        // did we already scanned the classpath for global value transformers?
        if (scannedClasspath == false) {
            final Predicate filter = new Predicate() {
                @Override
                public boolean apply(final String input) {
                    return GlobalValueTransformer.class.getCanonicalName().equals(input);
                }
            };

            // last to get the namespace from the system environment
            String myNameSpaceToScan = null;
            try {
                myNameSpaceToScan = System.getenv(GLOBAL_VALUE_TRANSFORMER_SEARCH_NAMESPACE);
            } catch (final Exception e) {
                // ignore - e.g. if a security manager exists and permissions are denied.
            }

            if (Strings.isNullOrEmpty(myNameSpaceToScan)) {

                // last to use the given namespace
                myNameSpaceToScan = namespaceToScan;
            }

            if (!Strings.isNullOrEmpty(myNameSpaceToScan)) {
                final Reflections reflections = new Reflections(new ConfigurationBuilder().filterInputsBy(
                            new FilterBuilder.Include(FilterBuilder.prefix(myNameSpaceToScan))).setUrls(
                            ClasspathHelper.forPackage(myNameSpaceToScan)).setScanners(new TypeAnnotationsScanner()
                                .filterResultsBy(filter), new SubTypesScanner()));
                final Set> typesAnnotatedWith = reflections.getTypesAnnotatedWith(
                        GlobalValueTransformer.class);
                for (final Class foundGlobalValueTransformer : typesAnnotatedWith) {
                    final Class valueTransformerReturnType = ValueTransformerUtils.getUnmarshalFromDbClass(
                            foundGlobalValueTransformer);
                    if (valueTransformerReturnType != null) {
                        GlobalValueTransformerRegistry.register(valueTransformerReturnType,
                            (ValueTransformer) foundGlobalValueTransformer.newInstance());
                        LOG.debug("Global Value Transformer [{}] for type [{}] registered. ",
                            foundGlobalValueTransformer.getSimpleName(), valueTransformerReturnType.getSimpleName());
                    } else {
                        LOG.error(
                            "Could add global transformer [{}] to global registry. Could not find method unmarshalFromDb.",
                            foundGlobalValueTransformer);
                    }
                }
            }

            scannedClasspath = true;
        }

        return GlobalValueTransformerRegistry.getValueTransformerForClass(genericType);
    }

    /**
     * Use this static function to set the namespace to scan.
     *
     * @param  newNamespace  the new namespace to be searched for {@link GlobalValueTransformer}
     */
    public static void changeNamespaceToScan(final String newNamespace) {
        namespaceToScan = newNamespace;
        scannedClasspath = false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy