org.datacleaner.descriptors.AbstractDescriptorProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.datacleaner.descriptors.AbstractDescriptorProvider.java

Source

/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Free Software Foundation, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.descriptors;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.lang.ArrayUtils;
import org.datacleaner.api.Analyzer;
import org.datacleaner.api.ComponentSuperCategory;
import org.datacleaner.api.Filter;
import org.datacleaner.api.Renderer;
import org.datacleaner.api.RenderingFormat;
import org.datacleaner.api.Transformer;

import com.google.common.collect.Iterables;

/**
 * Abstract descriptor provider implementation that implements most trivial
 * methods.
 */
public abstract class AbstractDescriptorProvider implements DescriptorProvider {

    private final boolean _autoDiscover;
    private final Collection<DescriptorProviderListener> _listeners;

    /**
     * Creates an {@link AbstractDescriptorProvider}
     *
     * @param autoLoadDescriptorClasses
     *            whether or not to automatically load descriptors when they are
     *            requested by class names. This typically happens in
     *            {@link #getAnalyzerDescriptorForClass(Class)},
     *            {@link #getTransformerDescriptorForClass(Class)} or
     *            {@link #getFilterDescriptorForClass(Class)}
     */
    public AbstractDescriptorProvider(final boolean autoLoadDescriptorClasses) {
        _autoDiscover = autoLoadDescriptorClasses;
        _listeners = new ArrayList<>();
    }

    @Override
    public final AnalyzerDescriptor<?> getAnalyzerDescriptorByDisplayName(final String name) {
        return getComponentDescriptorByDisplayName(name, getAnalyzerDescriptors(), true, true);
    }

    @Override
    public ComponentDescriptor<?> getComponentDescriptorByDisplayName(final String name) {
        final Iterable<ComponentDescriptor<?>> allComponentDescriptors = Iterables.concat(getAnalyzerDescriptors(),
                getTransformerDescriptors(), getFilterDescriptors());
        ComponentDescriptor<?> match = getComponentDescriptorByDisplayName(name, allComponentDescriptors, true,
                false);
        if (match == null) {
            match = getComponentDescriptorByDisplayName(name, allComponentDescriptors, false, true);
        }
        return match;
    }

    @SuppressWarnings("unchecked")
    @Override
    public final <A extends Analyzer<?>> AnalyzerDescriptor<A> getAnalyzerDescriptorForClass(
            final Class<A> analyzerBeanClass) {
        for (final AnalyzerDescriptor<?> descriptor : getAnalyzerDescriptors()) {
            if (descriptor.getComponentClass() == analyzerBeanClass) {
                return (AnalyzerDescriptor<A>) descriptor;
            }
        }
        return notFoundAnalyzer(analyzerBeanClass);
    }

    @Override
    public final FilterDescriptor<?, ?> getFilterDescriptorByDisplayName(final String name) {
        return getComponentDescriptorByDisplayName(name, getFilterDescriptors(), true, true);
    }

    @SuppressWarnings("unchecked")
    @Override
    public final <F extends Filter<C>, C extends Enum<C>> FilterDescriptor<F, C> getFilterDescriptorForClass(
            final Class<F> filterClass) {
        return (FilterDescriptor<F, C>) getFilterBeanDescriptorForClassUnbounded(filterClass);
    }

    /**
     * Alternative getter method used when sufficient type-information about the
     * class is not available.
     *
     * This method is basically a hack to make the compiler happy, see Ticket
     * #417.
     *
     * @see http://eobjects.org/trac/ticket/417
     *
     * @param filterClass
     * @return
     */
    protected final FilterDescriptor<?, ?> getFilterBeanDescriptorForClassUnbounded(final Class<?> filterClass) {
        for (final FilterDescriptor<?, ?> descriptor : getFilterDescriptors()) {
            if (filterClass == descriptor.getComponentClass()) {
                return descriptor;
            }
        }
        return notFoundFilter(filterClass);
    }

    @Override
    public final <R extends Renderer<?, ?>> RendererBeanDescriptor<R> getRendererBeanDescriptorForClass(
            final Class<R> rendererBeanClass) {
        for (final RendererBeanDescriptor<?> descriptor : getRendererBeanDescriptors()) {
            if (descriptor.getComponentClass() == rendererBeanClass) {
                @SuppressWarnings("unchecked")
                final RendererBeanDescriptor<R> result = (RendererBeanDescriptor<R>) descriptor;
                return result;
            }
        }
        return notFoundRenderer(rendererBeanClass);
    }

    @Override
    public final TransformerDescriptor<?> getTransformerDescriptorByDisplayName(final String name) {
        return getComponentDescriptorByDisplayName(name, getTransformerDescriptors(), true, true);
    }

    @SuppressWarnings("unchecked")
    @Override
    public final <T extends Transformer> TransformerDescriptor<T> getTransformerDescriptorForClass(
            final Class<T> transformerClass) {
        for (final TransformerDescriptor<?> descriptor : getTransformerDescriptors()) {
            if (descriptor.getComponentClass() == transformerClass) {
                return (TransformerDescriptor<T>) descriptor;
            }
        }
        return notFoundTransformer(transformerClass);
    }

    @Override
    public final Collection<RendererBeanDescriptor<?>> getRendererBeanDescriptorsForRenderingFormat(
            final Class<? extends RenderingFormat<?>> renderingFormat) {
        final List<RendererBeanDescriptor<?>> result = new ArrayList<>();
        final Collection<RendererBeanDescriptor<?>> descriptors = getRendererBeanDescriptors();
        for (final RendererBeanDescriptor<?> descriptor : descriptors) {
            final Class<? extends RenderingFormat<?>> descriptorsRenderingFormat = descriptor.getRenderingFormat();
            if (descriptorsRenderingFormat == renderingFormat) {
                result.add(descriptor);
            }
        }
        return result;
    }

    private <D extends ComponentDescriptor<?>> D getComponentDescriptorByDisplayName(String name,
            final Iterable<D> descriptors, final boolean searchPrimaryNames, final boolean searchAliases) {
        if (name == null) {
            return null;
        }

        // Ticket #951 : trim descriptor names
        name = name.trim();

        if (name.length() == 0) {
            return null;
        }

        if (searchPrimaryNames) {
            for (final D descriptor : descriptors) {
                final String displayName = descriptor.getDisplayName();
                if (name.equals(displayName)) {
                    return descriptor;
                }
            }
        }

        if (searchAliases) {
            for (final D descriptor : descriptors) {
                final String[] aliases = descriptor.getAliases();
                if (ArrayUtils.contains(aliases, name)) {
                    return descriptor;
                }
            }
        }
        return null;
    }

    private <A extends Analyzer<?>> AnalyzerDescriptor<A> notFoundAnalyzer(final Class<A> analyzerClass) {
        if (!_autoDiscover) {
            return null;
        }
        return Descriptors.ofAnalyzer(analyzerClass);
    }

    private FilterDescriptor<?, ?> notFoundFilter(final Class<?> filterClass) {
        if (!_autoDiscover) {
            return null;
        }
        return Descriptors.ofFilterUnbound(filterClass);
    }

    private <R extends Renderer<?, ?>> RendererBeanDescriptor<R> notFoundRenderer(final Class<R> rendererClass) {
        if (!_autoDiscover) {
            return null;
        }
        return Descriptors.ofRenderer(rendererClass);
    }

    private <T extends Transformer> TransformerDescriptor<T> notFoundTransformer(final Class<T> transformerClass) {
        if (!_autoDiscover) {
            return null;
        }
        return Descriptors.ofTransformer(transformerClass);
    }

    @Override
    public Collection<? extends ComponentDescriptor<?>> getComponentDescriptors() {
        final List<ComponentDescriptor<?>> result = new ArrayList<>();
        result.addAll(getTransformerDescriptors());
        result.addAll(getFilterDescriptors());
        result.addAll(getAnalyzerDescriptors());
        return result;
    }

    @Override
    public Set<ComponentSuperCategory> getComponentSuperCategories() {
        final Set<ComponentSuperCategory> result = new TreeSet<>();
        final Collection<? extends ComponentDescriptor<?>> descriptors = getComponentDescriptors();
        for (final ComponentDescriptor<?> componentDescriptor : descriptors) {
            final ComponentSuperCategory superCategory = componentDescriptor.getComponentSuperCategory();
            result.add(superCategory);
        }
        return result;
    }

    @Override
    public Collection<? extends ComponentDescriptor<?>> getComponentDescriptorsOfSuperCategory(
            final ComponentSuperCategory category) {
        if (category == null) {
            return Collections.emptyList();
        }
        final List<ComponentDescriptor<?>> result = new ArrayList<>();
        final Collection<? extends ComponentDescriptor<?>> descriptors = getComponentDescriptors();
        for (final ComponentDescriptor<?> componentDescriptor : descriptors) {
            if (category.equals(componentDescriptor.getComponentSuperCategory())) {
                result.add(componentDescriptor);
            }
        }
        return result;
    }

    protected void notifyListeners() {
        synchronized (_listeners) {
            for (final DescriptorProviderListener listener : _listeners) {
                listener.onDescriptorsUpdated(this);
            }
        }
    }

    @Override
    public void addListener(final DescriptorProviderListener listener) {
        synchronized (_listeners) {
            _listeners.add(listener);
        }
    }

    @Override
    public void removeListener(final DescriptorProviderListener listener) {
        synchronized (_listeners) {
            _listeners.remove(listener);
        }
    }

}