/** * */ package org.feature.multi.perspective.model.editor.editors; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.util.EcoreUtil; import org.feature.model.utilities.FeatureModelInit; import org.js.model.feature.Attribute; import org.js.model.feature.AttributeConstraint; import org.js.model.feature.AttributeOperand; import org.js.model.feature.AttributeReference; import org.js.model.feature.AttributeValue; import org.js.model.feature.Constraint; import org.js.model.feature.Exclude; import org.js.model.feature.Feature; import org.js.model.feature.FeatureConstraint; import org.js.model.feature.FeatureModel; import org.js.model.feature.Group; import org.js.model.feature.Imply; import org.js.model.feature.Relop; import org.js.model.feature.edit.FeatureModelHelper; /** * @author winkelti * */ public class Filter { FeatureModel newFeatureModel; private Map<String, Feature> featureMap; private FeatureModel orgFeatureModel; private static Logger log = Logger.getLogger(Filter.class); public Filter(FeatureModel org, Map<String, Feature> featureMap) { this.featureMap = featureMap; orgFeatureModel = org; Feature orgRoot = orgFeatureModel.getRoot(); if (featureMap.containsKey(orgRoot.getId())) { newFeatureModel = EcoreUtil.copy(orgFeatureModel); newFeatureModel.setRoot(copyFeature(orgRoot, null)); FeatureModelHelper helper = new FeatureModelHelper(newFeatureModel); assert (helper.getAllFeatures().size() == featureMap.size()); EList<EAttribute> eAllAttributes = org.eClass().getEAllAttributes(); for (EAttribute eAttribute : eAllAttributes) { newFeatureModel.eSet(eAttribute, org.eGet(eAttribute)); } newFeatureModel.getConstraints().clear(); // checkConstraints(orgFeatureModel.getConstraints(), fm.getAllFeatures()); filterConstraints(orgFeatureModel); } // root feature not selected } private void filterConstraints(FeatureModel featureModel) { FeatureModelHelper helper = new FeatureModelHelper(featureModel); EList<Constraint> constraints = featureModel.getConstraints(); for (Constraint constraint : constraints) { if (isRelevant(constraint)) { try { addConstraintToModel(constraint, helper.getAllFeatures()); } catch (IOException e) { log.error("Error while printing expression." + e.getLocalizedMessage()); } } } } /** * removes every constraints which contains features that are not in the new {@link FeatureModel}. * * @param constraints * @param featureModelFeatures */ private void addConstraintToModel(Constraint constraint, Set<Feature> newFeatures) throws IOException { Constraint copiedconstraint = copyConstraint(constraint, newFeatures); this.newFeatureModel.getConstraints().add(copiedconstraint); } private boolean isRelevant(Constraint constraint) { boolean relevant = true; Set<Feature> constrainedFeatures = FeatureModelHelper.getConstrainedFeatures(constraint); for (Feature feature : constrainedFeatures) { String id = feature.getId(); relevant = this.featureMap.containsKey(id); if (!relevant) { break; } } return relevant; } private Constraint copyConstraint(Constraint origConstraint, Set<Feature> newFeatures) { Constraint copy = null; if (origConstraint instanceof FeatureConstraint) { FeatureConstraint featureConstraint = (FeatureConstraint) origConstraint; copy = copyFeatureConstraint(featureConstraint, newFeatures); } else if (origConstraint instanceof AttributeConstraint) { AttributeConstraint origAttributeConstraint = (AttributeConstraint) origConstraint; copy = copyAttributeConstraint(origAttributeConstraint, newFeatures); } return copy; } private Constraint copyAttributeConstraint(AttributeConstraint origAttributeConstraint, Set<Feature> newFeatures) { Constraint copy = null; AttributeOperand leftOperand = origAttributeConstraint.getLeftOperand(); AttributeOperand rightOperand = origAttributeConstraint.getRightOperand(); AttributeOperand newLeft = copyAttributeOperand(leftOperand); AttributeOperand newRight = copyAttributeOperand(rightOperand); String id = origAttributeConstraint.getId(); Relop operator = origAttributeConstraint.getOperator(); copy = FeatureModelInit.createAttributeConstraint(newLeft, newRight, id, operator); return copy; } private AttributeOperand copyAttributeOperand(AttributeOperand attributeOperand) { AttributeOperand copy = null; if (attributeOperand instanceof AttributeReference) { AttributeReference attrReference = (AttributeReference) attributeOperand; Attribute attribute = attrReference.getAttribute(); copy = FeatureModelInit.createAttibuteOperand(attribute); } else if (attributeOperand instanceof AttributeValue) { AttributeValue attrValue = (AttributeValue) attributeOperand; String value = attrValue.getName(); int intValue = attrValue.getInt(); copy = FeatureModelInit.createAttibuteOperand(value, intValue); } return copy; } private Constraint copyFeatureConstraint(FeatureConstraint featureConstraint, Set<Feature> newFeatures) { Constraint copy = null; Feature origLeft = featureConstraint.getLeftOperand(); String origLeftFeatureId = origLeft.getId(); Feature newLeft = getFeature(origLeftFeatureId, newFeatures); Feature origRight = featureConstraint.getRightOperand(); String origRightFeatureId = origRight.getId(); Feature newRight = getFeature(origRightFeatureId, newFeatures); String id = featureConstraint.getId(); if (featureConstraint instanceof Imply) { copy = FeatureModelInit.createImplyConstraint(newLeft, newRight, id); } else if (featureConstraint instanceof Exclude) { copy = FeatureModelInit.createExcludeConstraint(newLeft, newRight, id); } return copy; } private Feature getFeature(String featureId, Set<Feature> features) { Feature result = null; for (Feature feature : features) { if (featureId.equals(feature.getId())) { result = feature; break; } } return result; } /** * * @param orgFeature * @param parentGroup * @return */ private Feature copyFeature(Feature orgFeature, Group parentGroup) { Feature feature = EcoreUtil.copy(orgFeature); copyGroups(feature.getGroups(), feature); if (parentGroup != null) { parentGroup.getChildFeatures().add(feature); } return feature; } /** * * @param groups * @return */ private void copyGroups(EList<Group> groups, Feature parentFeature) { List<Feature> features = null; boolean removeGroups = false; List<Group> removeGroupsList = new LinkedList<Group>(); for (Group group : groups) { features = new LinkedList<Feature>(); int numberOfOriginalFeatures = group.getChildFeatures().size(); List<Feature> childFeatures = new LinkedList<Feature>(); childFeatures.addAll(group.getChildFeatures()); for (Feature feature : childFeatures) { if (featureMap.containsKey(feature.getId())) { Feature copyFeature = copyFeature(feature, group); features.add(copyFeature); } } group.getChildFeatures().clear(); group.getChildFeatures().addAll(features); parentFeature.getGroups().add(group); if (group.getChildFeatures().isEmpty()) { removeGroups = true;// memory a group for removal. removeGroupsList.add(group); continue; } int numberCurrentChildFeatures = group.getChildFeatures().size(); int min = group.getMinCardinality(); int max = group.getMaxCardinality(); if (numberOfOriginalFeatures == min){ group.setMinCardinality(numberCurrentChildFeatures); } if (numberOfOriginalFeatures == max){ group.setMaxCardinality(numberCurrentChildFeatures); } // // if (group.getMaxCardinality() >= 0) { // max could be -1 // group.setMaxCardinality(group.getMaxCardinality() - (numberOfOriginalFeatures - group.getChildFeatures().size())); // if (group.getMaxCardinality() < group.getMinCardinality()) { // group.setMaxCardinality(group.getMinCardinality()); // } // } // System.out.println(group.getMinCardinality() + ":" + group.getMaxCardinality()); } if (removeGroups) { groups.removeAll(removeGroupsList); } } }