blob: 8b4ca1d64e8a794683c72db2b8b1b54a4bf72708 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Zoltan Ujhelyi and Daniel Varro.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Zoltan Ujhelyi - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra2.visualisation.modelspace.datasource.filter;
import java.util.Collection;
import org.eclipse.viatra2.core.IEntity;
import org.eclipse.viatra2.core.IModelElement;
import org.eclipse.viatra2.core.IRelation;
/**
* This class contains filters usable during the generation of the graph
* contents.
* @author Zoltan Ujhelyi
*/
public class PreFilter {
private FilterCondition positiveConditions = new FilterCondition();
private FilterCondition negativeConditions = new FilterCondition();
/**
* Makes sure that both ends of the relation are included
* @param relation
* the relation to watch
*/
private void includeRelationEnds(IRelation relation) {
includeElement(relation.getFrom());
includeElement(relation.getTo());
}
private void removeLinkedRelations(IModelElement element) {
for (IModelElement relatedElement : element.getRelations()) {
if (relatedElement instanceof IRelation && !isFiltered(relatedElement)) {
IRelation relation = (IRelation)relatedElement;
IModelElement from = relation.getFrom();
IModelElement to = relation.getTo();
if (isFiltered(from) || isFiltered(to)) excludeElement(relation);
}
}
}
/**
* Stores a condition to include a single model element
* @param element
* the element to include
*/
public void includeElement(IModelElement element) {
if (isFiltered(element)) {
String name = element.getFullyQualifiedName();
positiveConditions.addElementFilterCondition(name);
negativeConditions.removeFilter(name, false);
/*if (element instanceof IEntity)
for (IModelElement subElement : ((IEntity)element).getContents()) {
if (!isFiltered(subElement)) excludeSubtree(subElement);
}*/
}
if (element instanceof IRelation)
includeRelationEnds((IRelation) element);
}
/**
* Stores a condition to exlude a single model element
* @param element
* the model element to exclude
*/
public void excludeElement(IModelElement element) {
if (!isFiltered(element)) {
String name = element.getFullyQualifiedName();
if (element instanceof IEntity)
for (IModelElement subElement : ((IEntity)element).getContents()) {
if (!isFiltered(subElement)) includeSubtree(subElement);
}
negativeConditions.addElementFilterCondition(name);
positiveConditions.removeFilter(name, false);
removeLinkedRelations(element);
}
}
/**
* Stores a condition to include a selected model element (and it's
* descendants) in the view
* @param element
* the element to include
*/
public void includeSubtree(IModelElement element) {
String name = element.getFullyQualifiedName();
negativeConditions.removeFilter(name, true);
positiveConditions.addSubtreeFilterCondition(name);
if (element instanceof IRelation)
includeRelationEnds((IRelation) element);
for (IModelElement subElement : element.getAllElementsInNamespace()) {
if (subElement instanceof IRelation) {
includeRelationEnds((IRelation) subElement);
}
}
}
/**
* Stores a condition to exclude a selected model element (and it's
* descendants) in the view
* @param element
* the element to exclude
*/
public void excludeSubtree(IModelElement element) {
String name = element.getFullyQualifiedName();
positiveConditions.removeFilter(name, true);
negativeConditions.addSubtreeFilterCondition(name);
removeLinkedRelations(element);
for (IModelElement subElement : element.getAllElementsInNamespace()) {
removeLinkedRelations(subElement);
}
}
/**
* Decides whether the given model element should be filtered or not.
* @param element
* the model element to check
* @return true, if the element should be filtered from the view (hidden)
*/
public boolean isFiltered(IModelElement element) {
String name = element.getFullyQualifiedName();
boolean negative = negativeConditions.isMatched(name);
boolean positive = positiveConditions.isMatched(name);
if (negative && positive) {
boolean negElement = negativeConditions.elementContainsID(name);
boolean posElement = positiveConditions.elementContainsID(name);
if (negElement && posElement) {
String posMatch = positiveConditions.getMostSpecificMatch(name);
String negMatch = negativeConditions.getMostSpecificMatch(name);
return posMatch.length() < negMatch.length();
} else return !posElement || negElement;
}
return !positive || negative;
}
/**
* Updates the filter by removing an elements. For this both the positive and negative conditions are matched.
* @param elements the elements to clear from the filter
*/
public void removeDeletedElements(Collection<IModelElement> elements) {
for (IModelElement element : elements) {
String name = element.getFullyQualifiedName();
if (name != null && positiveConditions.elementContainsID(name)){
positiveConditions.removeFilter(name, false);
}
if (name != null && negativeConditions.elementContainsID(name)){
negativeConditions.removeFilter(name, false);
}
}
}
}