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

org.datacleaner.widgets.DescriptorMenuBuilder Maven / Gradle / Ivy

/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Neopost - Customer Information Management
 *
 * 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.widgets;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import org.apache.metamodel.util.CollectionUtils;
import org.datacleaner.api.ComponentCategory;
import org.datacleaner.api.ComponentSuperCategory;
import org.datacleaner.descriptors.ComponentDescriptor;
import org.datacleaner.descriptors.DescriptorProvider;
import org.datacleaner.job.builder.AnalysisJobBuilder;
import org.datacleaner.user.UsageLogger;
import org.datacleaner.util.CollectionUtils2;
import org.datacleaner.util.DeprecatedComponentPredicate;
import org.datacleaner.util.DisplayNameComparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Builder object that can build menus with {@link ComponentDescriptor} items in
 * it. Click a {@link ComponentDescriptor} will add it to the job
 */
public final class DescriptorMenuBuilder {

    /**
     * Used to get the menu structure. This will be called with all categories
     * first, then all component descriptors.
     *
     */
    public interface MenuCallback {
        /**
         * Will be called once for each descriptor, in sorted order. Always
         * called after {@link #addCategory(ComponentCategory)}, so categories
         * will exist when called.
         * 
         * @param descriptor
         */
        public void addComponentDescriptor(ComponentDescriptor descriptor);

        /**
         * Will be called once for each category, in sorted order.
         * 
         * @param category
         */
        public void addCategory(ComponentCategory category);
    }

    private static final Logger logger = LoggerFactory.getLogger(DescriptorMenuBuilder.class);

    private final AnalysisJobBuilder _analysisJobBuilder;
    private final UsageLogger _usageLogger;
    private final Collection> _componentDescriptors;
    private final boolean _buildSubmenus;
    private final Point2D _coordinate;

    public DescriptorMenuBuilder(final AnalysisJobBuilder analysisJobBuilder, final UsageLogger usageLogger,
            final Collection> descriptors, final Point2D coordinate) {
        this(analysisJobBuilder, usageLogger, descriptors, coordinate, true);
    }

    public DescriptorMenuBuilder(final AnalysisJobBuilder analysisJobBuilder, final UsageLogger usageLogger,
            final ComponentSuperCategory superCategory, final Point2D coordinate) {
        this(analysisJobBuilder, usageLogger, superCategory, coordinate, true);
    }

    public DescriptorMenuBuilder(final AnalysisJobBuilder analysisJobBuilder, final UsageLogger usageLogger,
            final Collection> descriptors, final Point2D coordinate,
            final boolean buildSubmenus) {
        final Collection> filteredDescriptors = CollectionUtils.filter(descriptors,
                new DeprecatedComponentPredicate());
        final List> componentDescriptors = new ArrayList<>(filteredDescriptors);
        Collections.sort(componentDescriptors, new DisplayNameComparator());

        _analysisJobBuilder = analysisJobBuilder;
        _usageLogger = usageLogger;
        _coordinate = coordinate;
        _buildSubmenus = buildSubmenus;
        _componentDescriptors = Collections.unmodifiableCollection(componentDescriptors);
    }

    public DescriptorMenuBuilder(final AnalysisJobBuilder analysisJobBuilder, final UsageLogger usageLogger,
            final ComponentSuperCategory superCategory, final Point2D coordinate, final boolean buildSubmenus) {
        _analysisJobBuilder = analysisJobBuilder;
        _usageLogger = usageLogger;
        _coordinate = coordinate;
        _buildSubmenus = buildSubmenus;

        final DescriptorProvider descriptorProvider = analysisJobBuilder.getConfiguration().getEnvironment().getDescriptorProvider();
        final Collection> componentDescriptors = descriptorProvider
                .getComponentDescriptorsOfSuperCategory(superCategory);
        _componentDescriptors = Collections.unmodifiableCollection(componentDescriptors);
    }

    public void addItemsToMenu(JMenu menu) {
        initialize(menu);
    }

    public void addItemsToPopupMenu(JPopupMenu menu) {
        initialize(menu);
    }

    public static void createMenuStructure(final MenuCallback callback,
            Collection> componentDescriptors, boolean buildSubmenus) {
        final List> sortedComponentDescriptors = CollectionUtils2
                .sorted(componentDescriptors);
        final Collection> filteredDescriptors = CollectionUtils.filter(sortedComponentDescriptors,
                new DeprecatedComponentPredicate());

        final Map>> categories = new HashMap<>();


        // build sub menus
        {
            for (ComponentDescriptor descriptor : filteredDescriptors) {
                final Set componentCategories = descriptor.getComponentCategories();
                for (ComponentCategory componentCategory : componentCategories) {
                    List> categoryList = categories.get(componentCategory);
                    if (categoryList == null) {
                        categoryList = new ArrayList>();
                        categories.put(componentCategory, categoryList);
                    }
                    categoryList.add(descriptor.getComponentClass());
                }
            }
        }

        {
            // place sub menus
            final List sortedCategories = CollectionUtils2.sorted(categories.keySet(),
                    new Comparator() {
                        public int compare(ComponentCategory o1, ComponentCategory o2) {
                            return o1.getName().compareTo(o2.getName());
                        }
                    });

            for (ComponentCategory category : sortedCategories) {
                final int count = categories.get(category).size();
                if (count == 0) {
                    logger.info("Disregarding menu for category '{}' because of no components", category);
                    categories.remove(category);
                } else {
                    // add menu
                    callback.addCategory(category);
                }
            }
        }

        for (ComponentDescriptor descriptor : filteredDescriptors) {
            callback.addComponentDescriptor(descriptor);
        }

    }

    private void initialize(final JComponent outerMenu) {
        final Map descriptorMenus = new HashMap();

        MenuCallback callback = new MenuCallback() {
            @Override
            public void addCategory(ComponentCategory category) {
                DescriptorMenu menu = new DescriptorMenu(category);
                descriptorMenus.put(category, menu);
                outerMenu.add(menu);
            }

            @Override
            public void addComponentDescriptor(ComponentDescriptor descriptor) {
                boolean placedInSubmenu = false;
                for (ComponentCategory category : descriptor.getComponentCategories()) {
                    if (descriptorMenus.containsKey(category)) {
                        placedInSubmenu = true;
                        JMenuItem menuItem = createMenuItem(descriptor);
                        descriptorMenus.get(category).add(menuItem);
                    }
                }

                if (!placedInSubmenu) {
                    outerMenu.add(createMenuItem(descriptor));
                }
            }
        };

        createMenuStructure(callback, _componentDescriptors, _buildSubmenus);
    }

    private JMenuItem createMenuItem(final ComponentDescriptor descriptor) {
        final DescriptorMenuItem menuItem = new DescriptorMenuItem(_analysisJobBuilder, _coordinate, descriptor);
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                _usageLogger.logComponentUsage(descriptor);
            }
        });
        return menuItem;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy