/* * 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); } }