eu.esdihumboldt.hale.ui.views.mapping.AlignmentViewContentProvider.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.views.mapping.AlignmentViewContentProvider.java

Source

/*
 * Copyright (c) 2013 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */

package eu.esdihumboldt.hale.ui.views.mapping;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.ui.PlatformUI;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

import eu.esdihumboldt.hale.common.align.model.Alignment;
import eu.esdihumboldt.hale.common.align.model.AlignmentUtil;
import eu.esdihumboldt.hale.common.align.model.Cell;
import eu.esdihumboldt.hale.common.align.model.CellUtil;
import eu.esdihumboldt.hale.common.align.model.Entity;
import eu.esdihumboldt.hale.common.align.model.Type;
import eu.esdihumboldt.hale.ui.common.graph.content.Edge;
import eu.esdihumboldt.hale.ui.common.graph.content.ReverseCellGraphContentProvider;
import eu.esdihumboldt.hale.ui.service.align.AlignmentService;

/**
 * A {@link ReverseCellGraphContentProvider} with the option to add
 * {@link ViewerFilter}s to filter cells. Also if the input is a (incomplete)
 * type cell all its property cells and matching type cells will be shown, and
 * inherited property cells will connect to the correct properties.
 * 
 * @author Kai Schwierczek
 */
public class AlignmentViewContentProvider extends ReverseCellGraphContentProvider {

    private final List<ViewerFilter> filters = new ArrayList<ViewerFilter>();

    /**
     * @see eu.esdihumboldt.hale.ui.common.graph.content.CellGraphContentProvider#getEdges(java.lang.Iterable)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    protected Object[] getEdges(Iterable<?> cells) {
        return super.getEdges(Iterables.filter(cells, new Predicate() {

            @Override
            public boolean apply(Object input) {
                if (input instanceof Cell) {
                    return select((Cell) input);
                } else
                    return false;
            }
        }));
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.graph.content.CellGraphContentProvider#getElements(java.lang.Object)
     */
    @Override
    public Object[] getElements(Object input) {
        // check if the input is a (incomplete) type cell
        if (input instanceof Cell) {
            Cell cell = (Cell) input;
            Entity source = CellUtil.getFirstEntity(cell.getSource());
            Entity target = CellUtil.getFirstEntity(cell.getTarget());
            if ((source == null || source instanceof Type) && (target == null || target instanceof Type))
                return getEdges((Cell) input);
        }

        return super.getElements(input);
    }

    /**
     * Get all edges for the given type cell and its property cells.
     * 
     * @param typeCell the type cell to show
     * @return the array of edges
     */
    private Object[] getEdges(Cell typeCell) {
        List<Edge> edges = new ArrayList<Edge>();

        AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class);
        Alignment alignment = as.getAlignment();

        boolean dummyCell;
        if (typeCell.getId() != null) {
            // XXX really filter type cell out?
            if (select(typeCell)) {
                addEdges(typeCell, edges);
            }
            dummyCell = false;
        } else {
            // dummy cell, look for matching type cells
            for (Cell cell : alignment.getTypeCells(typeCell))
                if (select(cell))
                    addEdges(cell, edges);
            dummyCell = true;
        }

        for (Cell cell : sortCells(as.getAlignment().getPropertyCells(typeCell, true, dummyCell))) {
            if (!select(cell))
                continue;

            Cell reparentCell = AlignmentUtil.reparentCell(cell, typeCell, false);

            // if the cell got changed connect the changed cell's entities
            // to the original cell
            if (reparentCell == cell)
                addEdges(cell, edges);
            else {
                // add edges leading to the cell for each source entity
                if (reparentCell.getSource() != null) {
                    for (Entry<String, ? extends Entity> entry : reparentCell.getSource().entries()) {
                        edges.add(new Edge(entry.getValue(), cell, entry.getKey()));
                    }
                }

                // add edges leading to the target entities from the cell
                for (Entry<String, ? extends Entity> entry : reparentCell.getTarget().entries()) {
                    edges.add(new Edge(cell, entry.getValue(), entry.getKey()));
                }
            }
        }

        return edges.toArray();
    }

    /**
     * sorts Cells alphabetically using the names of their PropertyDefinitions
     * along the property path
     * 
     * @param cells the Cells to sort
     * @return returns the Collection of sorted Cells
     */
    private Collection<? extends Cell> sortCells(Collection<? extends Cell> cells) {
        Cell[] cellArr = cells.toArray(new Cell[cells.size()]);
        Arrays.sort(cellArr, new CellComparator());
        return Arrays.asList(cellArr);
    }

    /**
     * Checks whether the cell makes it through all the filters.
     * 
     * @param cell the cell to check
     * @return <code>true</code> if element is included in the filtered set, and
     *         <code>false</code> if exclude
     */
    private boolean select(Cell cell) {
        for (ViewerFilter filter : filters)
            if (!filter.select(null, null, cell))
                return false;
        return true;
    }

    /**
     * Adds the given filter to the list of registered filters. The filters
     * {@link ViewerFilter#select(org.eclipse.jface.viewers.Viewer, Object, Object)}
     * method will be used with null, null and the cell which is in question.
     * 
     * @param filter the filter to add
     */
    public void addFilter(ViewerFilter filter) {
        filters.add(filter);
    }

    /**
     * Removes one occurrence of <code>filter</code> from the registered filters
     * if possible.
     * 
     * @param filter the filter to be removed
     */
    public void removeFilter(ViewerFilter filter) {
        filters.remove(filter);
    }
}