package de.FeatureModellingTool.DupHelper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import research.DrawingView;
import research.Figure;
import de.FeatureModellingTool.Customize.Customization;
import de.FeatureModellingTool.Customize.CustomizationVersion;
import de.FeatureModellingTool.DupHelper.ConstraintTransform.Predicate;
import de.FeatureModellingTool.DupHelper.ConstraintTransform.PredicateHelper;
import de.FeatureModellingTool.FeatureModel.CFRModifier;
import de.FeatureModellingTool.FeatureModel.CFRelation;
import de.FeatureModellingTool.FeatureModel.CompositeConstraint;
import de.FeatureModellingTool.FeatureModel.CompositeConstraintEditor;
import de.FeatureModellingTool.FeatureModel.CompositeConstraintPortType;
import de.FeatureModellingTool.FeatureModel.CompositeConstraintType;
import de.FeatureModellingTool.FeatureModel.Constraint;
import de.FeatureModellingTool.FeatureModel.ConstraintModel;
import de.FeatureModellingTool.FeatureModel.ConstraintModelEditor;
import de.FeatureModellingTool.FeatureModel.Feature;
import de.FeatureModellingTool.FeatureModel.FeatureEditor;
import de.FeatureModellingTool.FeatureModel.FeatureModel;
import de.FeatureModellingTool.FeatureModel.FeatureModelEditor;
import de.FeatureModellingTool.FeatureModel.FeatureProperties;
import de.FeatureModellingTool.FeatureModel.FeatureRelation;
import de.FeatureModellingTool.FeatureModel.GroupConstraint;
import de.FeatureModellingTool.FeatureModel.GroupConstraintEditor;
import de.FeatureModellingTool.FeatureModel.GroupConstraintType;
import de.FeatureModellingTool.FeatureModel.Variability;
import de.FeatureModellingTool.GraphicalEditor.GroupConstraintFigure;
import de.FeatureModellingTool.GraphicalEditor.PLConnection;
import de.FeatureModellingTool.GraphicalEditor.PLFigure;
public class ConstraintTransformHelper {
public enum CheckResult {crNone , crRemove , crTransform , crFlood , crError}
public static void updateCFRelation_Revert(CFRelation r , ConstraintModelEditor cme , Figure f) {
cme.removeCFRelation(r.getID());
if (r.getModifier().equals(CFRModifier.Affirmation)) {
r = cme.addCFRelation(r.getID() , r.getFeature() , r.getConstraint() , r.isSource() , CFRModifier.Negation);
} else {
r = cme.addCFRelation(r.getID() , r.getFeature() , r.getConstraint() , r.isSource() , CFRModifier.Affirmation);
}
f.setAttribute("CFRModifier" , r.getModifier().getName());
}
public static void changePredicate(
Collection<Feature> fsSrc , boolean undecidedOnly , CustomizationVersion cvSrc , HashMap<String,Figure> mFigure
, boolean revertCFRelation , Constraint cSrc , ConstraintModel cmSrc
, Figure fSrc
, GroupConstraintType gctDest
, ConstraintModelEditor cmeDest , GroupConstraintEditor gceDest , DrawingView dvDest) {
GroupConstraint gcDest = cmeDest.addGroupConstraint();
gceDest.setType(gcDest , gctDest);
GroupConstraintFigure gcfDest = new GroupConstraintFigure();
gcfDest.setAttribute("id" , gcDest.getID());
gcfDest.setAttribute("GroupType" , gcDest.getType().getName());
// gcfDest.setAttribute("PortPosition" , gcfSrc.getAttribute("PortPosition"));
gcfDest.setAttribute("bounds" , fSrc.getAttribute("bounds"));
gcfDest.setAttribute("frameColor" , fSrc.getAttribute("frameColor"));
gcfDest.moveBy(fSrc.getDisplayBox().x , fSrc.getDisplayBox().y);
for (Iterator<Feature> itFeature=fsSrc.iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
if (undecidedOnly && !cvSrc.getFinalCustomizationById(f.getID()).equals(Customization.Undecided)) {
continue;
}
gceDest.addFeature(gcDest , f);
CFRelation cfrSrc = cmSrc.getCFRelation(f , cSrc , true);
if (cfrSrc==null) {
cfrSrc = cmSrc.getCFRelation(f , cSrc , false);
}
CFRModifier modifier = cfrSrc.getModifier();
if (revertCFRelation) {
if (modifier.equals(CFRModifier.Affirmation)) {
modifier = CFRModifier.Negation;
} else {
modifier = CFRModifier.Affirmation;
}
}
CFRelation cfrDest = cmeDest.addCFRelation(f , gcDest , false , modifier);
PLConnection plc = new PLConnection();
plc.setAttribute("id" , cfrDest.getID());
// result.setAttribute("frameColor" , cfSrc.getAttribute("frameColor"));
// plc.setAttribute("type" , cfSrc.getAttribute("type"));
plc.setAttribute("CFRModifier" , modifier.getName());
plc.startPoint(gcfDest.getDisplayBox().x , gcfDest.getDisplayBox().y);
Figure figureSrc = mFigure.get(f.getID());
plc.endPoint(figureSrc.getDisplayBox().x , figureSrc.getDisplayBox().y);
}
}
/*FeatureRelation*/
public static void removeFeatureRelation(String frID , FeatureModelEditor fme
, Figure f , DrawingView dv) {
dv.remove(f);
fme.removeRelation(frID);
}
public static boolean checkFeatureRelation(FeatureRelation fr , FeatureModelEditor fme , Figure figure , DrawingView dv , CustomizationVersion cv) {
if (!fr.getName().equals(FeatureRelation.REQUIRE) && !fr.getName().equals(FeatureRelation.EXCLUDE)) {
return true;
}
Feature fStart = fr.getStartFeature();
Feature fEnd = fr.getEndFeature();
Customization cStart = cv.getFinalCustomizationById(fStart.getID());
Customization cEnd = cv.getFinalCustomizationById(fEnd.getID());
if (fr.getName().equals(FeatureRelation.REQUIRE)) {
if (Customization.Selected.equals(cStart)) {
if (Customization.Selected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else if (Customization.Unselected.equals(cEnd)) {
return true;
} else {
return false; //CheckResult.crFlood;
}
} else if (Customization.Unselected.equals(cStart)) {
if (Customization.Selected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return false; //CheckResult.crError;
} else if (Customization.Unselected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
}
} else {
if (Customization.Selected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else if (Customization.Unselected.equals(cEnd)) {
return false; //CheckResult.crFlood;
} else {
return false; //CheckResult.crNone;
}
}
} else if (fr.getName().equals(FeatureRelation.EXCLUDE)) {
if (Customization.Selected.equals(cStart)) {
if (Customization.Selected.equals(cEnd)) {
return false; //CheckResult.crError;
} else if (Customization.Unselected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else {
return false; //CheckResult.crFlood;
}
} else if (Customization.Unselected.equals(cStart)) {
if (Customization.Selected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else if (Customization.Unselected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
}
} else {
if (Customization.Selected.equals(cEnd)) {
return false; //CheckResult.crFlood;
} else if (Customization.Unselected.equals(cEnd)) {
removeFeatureRelation(fr.getID() , fme , figure , dv);
return true;
} else {
return true;
}
}
}
return true;
}
/*GroupConstraint*/
public static boolean createGroupConstraint(Constraint c
, Collection<Feature> features , boolean revertCFRelation , GroupConstraintType gct
, ConstraintModel cm , ConstraintModelEditor cme , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
Figure constraintFigure = mFigure.get(c.getID());
GroupConstraint gcDest = cme.addGroupConstraint();
gce.setType(gcDest , gct);
GroupConstraintFigure gcf = new GroupConstraintFigure();
gcf.setAttribute("id" , gcDest.getID());
if (GroupConstraintType.SingleGroup.equals(gct)) {
gcf.setAttribute("GroupType" , GroupConstraintFigure.Single);
} else if (GroupConstraintType.MultiGroup.equals(gct)) {
gcf.setAttribute("GroupType" , GroupConstraintFigure.Multi);
} else {
gcf.setAttribute("GroupType" , GroupConstraintFigure.All);
}
// gcfDest.setAttribute("PortPosition" , gcfSrc.getAttribute("PortPosition"));
gcf.setAttribute("bounds" , constraintFigure.getAttribute("bounds"));
gcf.setAttribute("frameColor" , constraintFigure.getAttribute("frameColor"));
dv.add(gcf);
gcf.setDisplayBox(constraintFigure.getDisplayBox());
for (Iterator<Feature> itFeature=features.iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
gce.addFeature(gcDest , f);
CFRelation cfrSrc = cm.getCFRelation(f , c , true);
if (cfrSrc==null) {
cfrSrc = cm.getCFRelation(f , c , false);
}
CFRModifier modifier = cfrSrc.getModifier();
if (revertCFRelation) {
if (modifier.equals(CFRModifier.Affirmation)) {
modifier = CFRModifier.Negation;
} else {
modifier = CFRModifier.Affirmation;
}
}
CFRelation cfrDest = cme.addCFRelation(f , gcDest , false , modifier);
PLConnection plcOld = (PLConnection)mFigure.get(cfrSrc.getID());
PLConnection plcNew = new PLConnection();
plcNew.setAttribute("id" , cfrDest.getID());
plcNew.setAttribute("frameColor" , plcOld.getAttribute("frameColor"));
plcNew.setAttribute("type" , plcOld.getAttribute("type"));
plcNew.setAttribute("CFRModifier" , modifier.getName());
for (int i=0 ; i<plcOld.pointCount() ; i++) {
plcNew.addPoint(plcOld.pointAt(i).x , plcOld.pointAt(i).y);
}
plcNew.startPoint(gcf.getConnectors()[0].getDisplayBox().x , gcf.getConnectors()[0].getDisplayBox().y);
plcNew.connectStart(gcf.getConnectors()[0]);
Figure featureFigure = mFigure.get(f.getID());
plcNew.endPoint(featureFigure.getConnectors()[3].getDisplayBox().x , featureFigure.getConnectors()[3].getDisplayBox().y);
plcNew.connectEnd(featureFigure.getConnectors()[3]);
dv.add(plcNew);
}
return true;
}
public static void removeGroupConstraint(GroupConstraint gc , ConstraintModel cm , ConstraintModelEditor cme
, DrawingView dv , HashMap<String,Figure> mFigure) {
List<CFRelation> relations = new ArrayList<CFRelation>();
List<Figure> figures = new ArrayList<Figure>();
for (Iterator<Feature> itFeature=gc.getFeatureSet().iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
CFRelation relation = cm.getCFRelation(f , gc , true);
if (relation==null) {
relation = cm.getCFRelation(f , gc , false);
}
relations.add(relation);
figures.add(mFigure.get(relation.getID()));
}
for (int i=0 ; i<relations.size() ; i++) {
CFRelation relation = relations.get(i);
Figure figure = figures.get(i);
dv.remove(figure);
cme.removeCFRelation(relation.getID());
}
dv.remove(mFigure.get(gc.getID()));
cme.removeGroupConstraint(gc);
}
public static void removeGroupConstraintRelations(GroupConstraint gc , ConstraintModel cm , ConstraintModelEditor cme
, DrawingView dv , HashMap<String,Figure> mFigure , CustomizationVersion cv) {
List<Feature> features = new ArrayList<Feature>(gc.getFeatureSet());
for (int i=0 ; i<features.size() ; i++) {
Feature feature = features.get(i);
if (!cv.getFinalCustomizationById(feature.getID()).equals(Customization.Undecided)) {
CFRelation fr = cm.getCFRelation(feature , gc , false);
Figure figure = mFigure.get(fr.getID());
dv.remove(figure);
cme.removeCFRelation(fr.getID());
}
}
}
public static boolean checkGroupConstraint(GroupConstraint gc , ConstraintModel cm , ConstraintModelEditor cme , DrawingView dv
, CustomizationVersion cv
, HashMap<String,Figure> mFigure) {
Predicate pred = PredicateHelper.getPredicateByGroupConstraintType(gc.getType());
PredicateHelper.fillPredicate(gc.getFeatureSet() , gc , cm, cv , pred);
if (gc.getType().equals(GroupConstraintType.SingleGroup)) {
if (pred.getSelectedCount()==0) {
if (pred.getUndecidedCount()==0) {
removeGroupConstraint(gc , cm , cme , dv , mFigure);
return true;
} else {
removeGroupConstraintRelations(gc , cm , cme , dv , mFigure , cv);
return true;
}
} else if (pred.getSelectedCount()==1) {
if (pred.getUndecidedCount()==0) {
removeGroupConstraint(gc , cm , cme , dv , mFigure);
return true;
} else {
return false; //CheckResult.crFlood;
}
} else {
return false; //CheckResult.crError;
}
} else if (gc.getType().equals(GroupConstraintType.AllGroup)) {
if (pred.getSelectedCount()==0) {
if (pred.getUnselectedCount()==0) {
removeGroupConstraintRelations(gc , cm , cme , dv , mFigure , cv);
return true;
} else {
if (pred.getUndecidedCount()==0) {
removeGroupConstraint(gc , cm , cme , dv , mFigure);
return true;
} else {
return false; //CheckResult.crFlood;
}
}
} else {
if (pred.getUnselectedCount()==0) {
if (pred.getUndecidedCount()==0) {
removeGroupConstraint(gc , cm , cme , dv , mFigure);
return true;
} else {
return false; //CheckResult.crFlood;
}
} else {
return false; //CheckResult.crError;
}
}
} else {
if (pred.getUndecidedCount()==0) {
removeGroupConstraint(gc , cm , cme , dv , mFigure);
return true;
} else {
removeGroupConstraintRelations(gc , cm , cme , dv , mFigure , cv);
return true;
}
}
}
/*CompositeConstraint*/
public static void updateCompositeConstraint_RevertRelation(CompositeConstraint cc , Set<Feature> features
, ConstraintModel cm , ConstraintModelEditor cme
, HashMap<String,Figure> mFigure) {
for (Iterator<Feature> itFeature=features.iterator() ; itFeature.hasNext() ; ) {
Feature feature = itFeature.next();
boolean isSource = true;
CFRelation rOld = cm.getCFRelation(feature , cc , true);
if (rOld==null) {
isSource = false;
rOld = cm.getCFRelation(feature , cc , false);
}
cme.removeCFRelation(rOld.getID());
CFRelation rNew = cme.addCFRelation(rOld.getID() , feature , cc , isSource, CFRModifier.Affirmation.equals(rOld.getModifier()) ? CFRModifier.Negation : CFRModifier.Affirmation);
PLConnection fOld = (PLConnection)mFigure.get(rOld.getID());
fOld.setAttribute("CFRModifier" , rNew.getModifier().getName());
}
}
public static void updateCompositeConstraint_UpdatePredicate(CompositeConstraint cc , boolean isSource , CompositeConstraintPortType ccpt
,CompositeConstraintEditor cce
, HashMap<String,Figure> mFigure) {
Figure figure = mFigure.get(cc.getID());
if (isSource) {
cce.setSourceType(cc , ccpt);
figure.setAttribute("SourceType" , ccpt.getName());
} else {
cce.setSinkType(cc , ccpt);
figure.setAttribute("SinkType" , ccpt.getName());
}
}
public static void removeCompositeConstraint(CompositeConstraint cc , ConstraintModel cm , ConstraintModelEditor cme
, DrawingView dv , HashMap<String,Figure> mFigure) {
List<Feature> features = new ArrayList<Feature>();
features.addAll(cc.getSourceFeatureSet());
features.addAll(cc.getSinkFeatureSet());
List<CFRelation> relations = new ArrayList<CFRelation>();
for (Iterator<Feature> itFeature=features.iterator() ; itFeature.hasNext() ; ) {
Feature feature = itFeature.next();
CFRelation relation = cm.getCFRelation(feature , cc , true);
if (relation==null) {
relation = cm.getCFRelation(feature , cc , false);
}
}
for (int i=0 ; i<relations.size() ; i++) {
CFRelation relation = relations.get(i);
Figure figure = mFigure.get(relation.getID());
dv.remove(figure);
cme.removeCFRelation(relation.getID());
}
dv.remove(mFigure.get(cc.getID()));
cme.removeCompositeConstraint(cc);
}
public static void removeCompositeConstraintRelation(CompositeConstraint cc , ConstraintModel cm , ConstraintModelEditor cme
, CustomizationVersion cv , DrawingView dv , HashMap<String,Figure> mFigure) {
List<Feature> features = new ArrayList<Feature>();
features.addAll(cc.getSourceFeatureSet());
features.addAll(cc.getSinkFeatureSet());
for (int i=0 ; i<features.size() ; i++) {
Feature feature = features.get(i);
if (!Customization.Undecided.equals(cv.getFinalCustomizationById(feature.getID()))) {
CFRelation relation = cm.getCFRelation(feature , cc , true);
if (relation==null) {
relation = cm.getCFRelation(feature , cc , false);
}
dv.remove(mFigure.get(relation.getID()));
cme.removeCFRelation(relation.getID());
}
}
}
public static boolean createCompositeConstraint(Constraint cOld
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce
, DrawingView dv , HashMap<String,Figure> mFigure
, Collection<Feature> fSources , Collection<Feature> fSinks , CompositeConstraintType cct
, CompositeConstraintPortType ccptSource , CompositeConstraintPortType ccptSink
, boolean revertSourceRelation , boolean revertSinkRelation) {
Figure fOld = mFigure.get(cOld.getID());
CompositeConstraint ccNew = cme.addCompositeConstraint();
cce.setPLType(ccNew , cct);
cce.setSourceType(ccNew , ccptSource);
cce.setSinkType(ccNew , ccptSink);
PLFigure plfNew = new PLFigure();
plfNew.setAttribute("id" , ccNew.getID());
plfNew.setAttribute("bounds" , fOld.getAttribute("bounds"));
plfNew.setAttribute("frameColor" , fOld.getAttribute("frameColor"));
if (CompositeConstraintType.L2R_Implication.equals(cct)) {
plfNew.setAttribute("PLType" , PLFigure.L2R_REQUIRE);
} else if (CompositeConstraintType.R2L_Implication.equals(cct)) {
plfNew.setAttribute("PLType" , PLFigure.R2L_REQUIRE);
} else if (CompositeConstraintType.Equivalence.equals(cct)) {
plfNew.setAttribute("PLType" , PLFigure.EQUIVALENCE);
} else {
plfNew.setAttribute("PLType" , PLFigure.MUTEX);
}
plfNew.setAttribute("SourceType" , ccptSource.getName());
plfNew.setAttribute("SinkType" , ccptSink.getName());
dv.add(plfNew);
plfNew.setDisplayBox(fOld.getDisplayBox());
for (Iterator<Feature> itFeature=fSources.iterator() ; itFeature.hasNext() ; ) {
Feature fSource = itFeature.next();
Figure figureSource = mFigure.get(fSource.getID());
CFRelation rOld = cm.getCFRelation(fSource , cOld , true);
if (rOld==null) {
rOld = cm.getCFRelation(fSource , cOld , false);
}
PLConnection plcOld = (PLConnection)mFigure.get(rOld.getID());
CFRelation rNew = cme.addCFRelation(fSource , ccNew , true
, rOld.getModifier().equals(CFRModifier.Affirmation) ? (revertSourceRelation ? CFRModifier.Negation : CFRModifier.Affirmation) : (revertSourceRelation ? CFRModifier.Affirmation : CFRModifier.Negation));
PLConnection plcNew = new PLConnection();
plcNew.setAttribute("id" , rNew.getID());
plcNew.setAttribute("frameColor" , plcOld.getAttribute("frameColor"));
plcNew.setAttribute("type" , plcOld.getAttribute("type"));
plcNew.setAttribute("CFRModifier" , rNew.getModifier().getName());
for (int i=0 ; i<plcOld.pointCount() ; i++) {
plcNew.addPoint(plcOld.pointAt(i).x , plcOld.pointAt(i).y);
}
plcNew.startPoint(plfNew.getConnectors()[0].getDisplayBox().x , plfNew.getConnectors()[0].getDisplayBox().y);
plcNew.connectStart(plfNew.getConnectors()[0]);
plcNew.endPoint(figureSource.getConnectors()[4].getDisplayBox().x , figureSource.getConnectors()[4].getDisplayBox().y);
plcNew.connectEnd(figureSource.getConnectors()[4]);
dv.add(plcNew);
}
for (Iterator<Feature> itFeature=fSinks.iterator() ; itFeature.hasNext() ; ) {
Feature fSink = itFeature.next();
Figure figureSink = mFigure.get(fSink.getID());
CFRelation rOld = cm.getCFRelation(fSink , cOld , true);
if (rOld==null) {
rOld = cm.getCFRelation(fSink , cOld , false);
}
CFRelation rNew = cme.addCFRelation(fSink , ccNew , true
, rOld.getModifier().equals(CFRModifier.Affirmation) ? (revertSinkRelation ? CFRModifier.Negation : CFRModifier.Affirmation) : (revertSinkRelation ? CFRModifier.Affirmation : CFRModifier.Negation));
PLConnection plcOld = (PLConnection)mFigure.get(rOld.getID());
PLConnection plcNew = new PLConnection();
plcNew.setAttribute("id" , rNew.getID());
plcNew.setAttribute("frameColor" , plcOld.getAttribute("frameColor"));
plcNew.setAttribute("type" , plcOld.getAttribute("type"));
plcNew.setAttribute("CFRModifier" , rNew.getModifier().getName());
for (int i=0 ; i<plcOld.pointCount() ; i++) {
plcNew.addPoint(plcOld.pointAt(i).x , plcOld.pointAt(i).y);
}
plcNew.startPoint(plfNew.getConnectors()[1].getDisplayBox().x , plfNew.getConnectors()[1].getDisplayBox().y);
plcNew.connectStart(plfNew.getConnectors()[1]);
plcNew.endPoint(figureSink.getConnectors()[3].getDisplayBox().x , figureSink.getConnectors()[3].getDisplayBox().y);
plcNew.connectEnd(figureSink.getConnectors()[3]);
dv.add(plcNew);
}
return true;
}
public static boolean checkCompositeConstraint_TransformSingle(Predicate predicate , Set<Feature> sFeatures , boolean isSource , CompositeConstraint cc
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (predicate.getUndecidedCount()==0) {
return false; // it isn't changable
}
if (predicate.getSelectedCount()==0) {
return true; // do nothing
} else if (predicate.getSelectedCount()==1) {
// add all group and revert relation
updateCompositeConstraint_UpdatePredicate(cc , isSource , CompositeConstraintPortType.All , cce , mFigure);
updateCompositeConstraint_RevertRelation(cc , sFeatures , cm , cme , mFigure);
return true;
} else {
return false; // more than 1 is selected, predicate state is unselected
}
}
public static boolean checkCompositeConstraint_TransformMulti(Predicate predicate , Set<Feature> sFeatures , boolean isSource , CompositeConstraint cc
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (predicate.getUndecidedCount()==0) {
return false; // it isn't changable
}
if (predicate.getSelectedCount()==0) {
return true; // do nothing
} else {
return false; // some one is selected, predicate state is unselected
}
}
public static boolean checkCompositeConstraint_TransformAll(Predicate predicate , Set<Feature> sFeatures , boolean isSource , CompositeConstraint cc
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (predicate.getUndecidedCount()==0) {
return false; // it isn't changable
}
if (predicate.getSelectedCount()==0) {
return true; // do nothing
} else {
return true; // some one is selected, keep the others in all predicate
}
}
public static boolean checkCompositeConstraint_TransformDualSide(Predicate predicate , Set<Feature> sFeatures , boolean isSource , CompositeConstraint cc , CompositeConstraintPortType ccpt
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (CompositeConstraintPortType.Single.equals(ccpt)) {
return checkCompositeConstraint_TransformSingle(predicate , sFeatures , isSource , cc , cm , cme , cce , gce , dv , mFigure);
} else if (CompositeConstraintPortType.Multi.equals(ccpt)) {
return checkCompositeConstraint_TransformMulti(predicate , sFeatures , isSource , cc , cm , cme , cce , gce , dv , mFigure);
} else {
return checkCompositeConstraint_TransformAll(predicate , sFeatures , isSource , cc , cm , cme , cce , gce , dv , mFigure);
}
}
public static boolean checkCompositeConstraint_DualSide(Predicate pSource , Predicate pSink , CompositeConstraint cc
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, CustomizationVersion cv , DrawingView dv , HashMap<String,Figure> mFigure) {
Set<Feature> sourceFeatures = new HashSet<Feature>(cc.getSourceFeatureSet());
Set<Feature> sinkFeatures = new HashSet<Feature>(cc.getSinkFeatureSet());
for (Iterator<Feature> itFeature=cc.getSourceFeatureSet().iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
if (!Customization.Undecided.equals(cv.getFinalCustomizationById(f.getID()))) {
sourceFeatures.remove(f);
}
}
for (Iterator<Feature> itFeature=cc.getSinkFeatureSet().iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
if (!Customization.Undecided.equals(cv.getFinalCustomizationById(f.getID()))) {
sinkFeatures.remove(f);
}
}
return checkCompositeConstraint_TransformDualSide(pSource , sourceFeatures , true , cc , cc.getSourceType() , cm , cme , cce , gce , dv , mFigure)
&& checkCompositeConstraint_TransformDualSide(pSink , sinkFeatures , false , cc , cc.getSinkType() , cm , cme , cce , gce , dv , mFigure);
}
public static boolean addCompositeconstraint_NotOne(Set<Feature> sFeatures , Constraint c
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (sFeatures.size()<=1) {
return false;
}
List<Feature> fSource = new ArrayList<Feature>(sFeatures);
List<Feature> fSink = new ArrayList<Feature>();
fSink.add(fSource.get(0));
fSource.remove(0);
boolean result = createCompositeConstraint(c , cm , cme , cce , dv , mFigure
, fSource , fSink , CompositeConstraintType.L2R_Implication
, CompositeConstraintPortType.Single , CompositeConstraintPortType.Multi
, false , false);
result &= createCompositeConstraint(c , cm , cme , cce , dv , mFigure
, fSink , fSink , CompositeConstraintType.R2L_Implication
, CompositeConstraintPortType.Multi , CompositeConstraintPortType.Single
, false , false);
return result;
}
public static boolean addCompositeconstraint_AtLeastOne(Set<Feature> sFeatures , Constraint c , boolean needRevert
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (sFeatures.size()<=1) {
return false;
}
List<Feature> fSource = new ArrayList<Feature>(sFeatures);
List<Feature> fSink = new ArrayList<Feature>();
fSink.add(fSource.get(0));
fSource.remove(0);
if (needRevert) {
return createCompositeConstraint(c , cm , cme , cce , dv , mFigure
, fSource , fSink , CompositeConstraintType.L2R_Implication
, CompositeConstraintPortType.All , CompositeConstraintPortType.Multi
, false , true);
} else {
return createCompositeConstraint(c , cm , cme , cce , dv , mFigure
, fSource , fSink , CompositeConstraintType.L2R_Implication
, CompositeConstraintPortType.All , CompositeConstraintPortType.Multi
, true , false);
}
}
public static boolean checkCompositeConstraint_AddConstraintToSingle(Predicate p
, Set<Feature> sFeatures , Constraint c , boolean constraint
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (p.getUndecidedCount()==0) {
return false; // error, cuz it is unchangable
}
if (p.getSelectedCount()==0) {
if (p.getUndecidedCount()==1) {
return false; // flood
} else {
if (constraint) {
return createGroupConstraint(c , sFeatures , false , GroupConstraintType.SingleGroup , cm , cme , gce , dv , mFigure)
&& addCompositeconstraint_AtLeastOne(sFeatures , c , false , cm , cme , cce , dv , mFigure);
} else {
return addCompositeconstraint_NotOne(sFeatures , c , cm , cme , cce , dv , mFigure);
}
}
} else if (p.getSelectedCount()==1) {
if (constraint) {
return false; // flood
} else {
if (p.getUndecidedCount()==1) {
return false; // flood
} else {
return addCompositeconstraint_AtLeastOne(sFeatures , c , false , cm , cme , cce , dv , mFigure);
}
}
} else {
return false; // error
}
}
public static boolean checkCompositeConstraint_AddConstraintToMulti(Predicate p
, Set<Feature> sFeatures , Constraint c , boolean constraint
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (p.getUndecidedCount()==0) {
return false; // error, it isn't changable
}
if (p.getSelectedCount()==0) {
if (constraint) {
return addCompositeconstraint_AtLeastOne(sFeatures , c , false , cm , cme , cce , dv , mFigure);
} else {
return false; //flood
}
} else {
if (constraint) {
return true; // permantly true
} else {
return false; // error
}
}
}
public static boolean checkCompositeConstraint_AddConstraintToAll(Predicate p
, Set<Feature> sFeatures , Constraint c , boolean constraint
, ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (p.getUndecidedCount()==0) {
return false; // error, it isn't changable
}
if (p.getSelectedCount()==0) {
if (constraint) {
if (p.getUnselectedCount()==0) {
return false; // flood
} else {
return false; // error
}
} else {
if (p.getUnselectedCount()==0) {
return addCompositeconstraint_AtLeastOne(sFeatures , c , true , cm , cme , cce , dv , mFigure);
} else {
return false; // permantly true
}
}
} else {
if (constraint) {
if (p.getUnselectedCount()==0) {
return false; // flood
} else {
return false; // error
}
} else {
if (p.getUnselectedCount()==0) {
return false; // flood
} else {
return addCompositeconstraint_AtLeastOne(sFeatures , c , true , cm , cme , cce , dv , mFigure);
}
}
}
}
public static boolean checkCompositeConstraint_AddConstraintToOneSide(Predicate p
, Set<Feature> sFeatures , Constraint c , boolean constraint
, ConstraintModel cm , ConstraintModelEditor cme
, CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView dv , HashMap<String,Figure> mFigure) {
if (CompositeConstraintPortType.Single.equals(p.getCCType())) {
return checkCompositeConstraint_AddConstraintToSingle(p , sFeatures , c , constraint , cm , cme , cce , gce , dv , mFigure);
} else if (CompositeConstraintPortType.Multi.equals(p.getCCType())) {
return checkCompositeConstraint_AddConstraintToMulti(p , sFeatures , c , constraint , cm , cme , cce , dv , mFigure);
} else {
return checkCompositeConstraint_AddConstraintToAll(p , sFeatures , c , constraint , cm , cme , cce , dv , mFigure);
}
}
public static boolean checkCompositeConstraint_OneSide(CompositeConstraint cc
, Predicate pSource , Predicate pSink , ConstraintModel cm
, ConstraintModelEditor cme , CompositeConstraintEditor cce
, GroupConstraintEditor gce , CustomizationVersion cv
, DrawingView dv , HashMap<String,Figure> mFigure) {
Set<Feature> sourceFeatures = new HashSet<Feature>(cc.getSourceFeatureSet());
Set<Feature> sinkFeatures = new HashSet<Feature>(cc.getSinkFeatureSet());
for (Iterator<Feature> itFeature=cc.getSourceFeatureSet().iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
if (!Customization.Undecided.equals(cv.getFinalCustomizationById(f.getID()))) {
sourceFeatures.remove(f);
}
}
for (Iterator<Feature> itFeature=cc.getSinkFeatureSet().iterator() ; itFeature.hasNext() ; ) {
Feature f = itFeature.next();
if (!Customization.Undecided.equals(cv.getFinalCustomizationById(f.getID()))) {
sinkFeatures.remove(f);
}
}
if (CompositeConstraintType.L2R_Implication.equals(cc.getPLType())) {
if (pSource.isChangable()) {
if (Customization.Selected.equals(pSink.getValue())) {
return true; // permantly true
} else {
// add false constraint to left
return checkCompositeConstraint_AddConstraintToOneSide(pSource , sourceFeatures , cc , false , cm , cme , cce , gce , dv , mFigure);
}
} else {
if (Customization.Selected.equals(pSource.getValue())) {
// add true constraint to right
return checkCompositeConstraint_AddConstraintToOneSide(pSink , sinkFeatures , cc , true , cm , cme , cce , gce , dv , mFigure);
} else {
return true; // permantly true
}
}
} else if (CompositeConstraintType.R2L_Implication.equals(cc.getPLType())) {
if (pSource.isChangable()) {
if (Customization.Selected.equals(pSink.getValue())) {
// add true constraint to left
return checkCompositeConstraint_AddConstraintToOneSide(pSource , sourceFeatures , cc , true , cm , cme , cce , gce , dv , mFigure);
} else {
return true; // permantly true
}
} else {
if (Customization.Selected.equals(pSource.getValue())) {
return true; // permantly true
} else {
// add true constraint to right
return checkCompositeConstraint_AddConstraintToOneSide(pSink , sinkFeatures , cc , true , cm , cme , cce , gce , dv , mFigure);
}
}
} else if (CompositeConstraintType.Equivalence.equals(cc.getPLType())) {
if (pSource.isChangable()) {
if (Customization.Selected.equals(pSink.getValue())) {
// add true constraint to left
return checkCompositeConstraint_AddConstraintToOneSide(pSource , sourceFeatures , cc , true , cm , cme , cce , gce , dv , mFigure);
} else {
// add false constraint to left
return checkCompositeConstraint_AddConstraintToOneSide(pSource , sourceFeatures , cc , false , cm , cme , cce , gce , dv , mFigure);
}
} else {
if (Customization.Selected.equals(pSource.getValue())) {
// add true constraint to right
return checkCompositeConstraint_AddConstraintToOneSide(pSink , sinkFeatures , cc , true , cm , cme , cce , gce , dv , mFigure);
} else {
// add false constraint to right
return checkCompositeConstraint_AddConstraintToOneSide(pSink , sinkFeatures , cc , false , cm , cme , cce , gce , dv , mFigure);
}
}
} else {
if (pSource.isChangable()) {
if (Customization.Selected.equals(pSink.getValue())) {
// add false constraint to left
return checkCompositeConstraint_AddConstraintToOneSide(pSource , sourceFeatures , cc , false , cm , cme , cce , gce , dv , mFigure);
} else {
return true; // permantly true
}
} else {
if (Customization.Selected.equals(pSource.getValue())) {
// add false constraint to right
return checkCompositeConstraint_AddConstraintToOneSide(pSink , sinkFeatures , cc , false , cm , cme , cce , gce , dv , mFigure);
} else {
return true; // permantly true
}
}
}
}
public static boolean checkCompositeConstraint(CompositeConstraint cc , ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce , DrawingView dv
, CustomizationVersion cv
, HashMap<String,Figure> mFigure) {
Predicate pSource = PredicateHelper.getPredicateByCompositeConstraintPortType(cc.getSourceType());
PredicateHelper.fillPredicate(cc.getSourceFeatureSet() , cc , cm, cv , pSource);
Predicate pSink = PredicateHelper.getPredicateByCompositeConstraintPortType(cc.getSinkType());
PredicateHelper.fillPredicate(cc.getSinkFeatureSet() , cc , cm, cv , pSink);
if (pSource.isChangable()) {
if (pSink.isChangable()) {
if (checkCompositeConstraint_DualSide(pSource , pSink , cc , cm , cme , cce , gce , cv , dv , mFigure)) {
removeCompositeConstraintRelation(cc , cm , cme , cv , dv , mFigure);
}
} else {
if (checkCompositeConstraint_OneSide(cc , pSource , pSink , cm , cme , cce , gce , cv , dv , mFigure)) {
removeCompositeConstraint(cc , cm , cme , dv , mFigure);
}
}
} else {
if (pSink.isChangable()) {
if (checkCompositeConstraint_OneSide(cc , pSource , pSink , cm , cme , cce , gce , cv , dv , mFigure)) {
removeCompositeConstraint(cc , cm , cme , dv , mFigure);
}
} else {
// both side is unchangable, remove it directly
removeCompositeConstraint(cc , cm , cme , dv , mFigure);
}
}
return true;
}
public static boolean removeUnselectedFeature(FeatureModel fm , FeatureModelEditor fme , CustomizationVersion cv
, HashMap<String,Figure> mFigure , HashMap<Figure,DrawingView> mDrawingView) {
List<Feature> features = new ArrayList<Feature>(fm.getAllFeature().values());
HashSet<Feature> removeFeatures = new HashSet<Feature>();
for (int i=0 ; i<features.size() ; i++) {
Feature feature = features.get(i);
if (Customization.Unselected.equals(cv.getFinalCustomizationById(feature.getID()))) {
removeFeatures.add(feature);
}
}
if (fm.getAllFeatureRelation()!=null) {
List<FeatureRelation> relations = new ArrayList<FeatureRelation>(fm.getAllFeatureRelation().values());
for (int i=relations.size()-1 ; i>=0 ; i--) {
FeatureRelation relation = relations.get(i);
if (removeFeatures.contains(relation.getStartFeature()) || removeFeatures.contains(relation.getEndFeature())) {
Figure f = mFigure.get(relation.getID());
DrawingView dv = mDrawingView.get(f);
dv.remove(f);
fme.removeRelation(relation);
}
}
}
for (int i=0 ; i<features.size() ; i++) {
Feature feature = features.get(i);
if (removeFeatures.contains(feature)) {
Figure f = mFigure.get(feature.getID());
DrawingView dv = mDrawingView.get(f);
dv.remove(f);
fme.removeFeature(feature);
}
}
return true;
}
public static boolean updateSelectedFeature(FeatureModel fm , FeatureEditor fe , CustomizationVersion cv
, HashMap<String,Figure> mFigure) {
List<Feature> features = new ArrayList<Feature>(fm.getAllFeature().values());
for (int i=0 ; i<features.size() ; i++) {
Feature feature = features.get(i);
if (Customization.Selected.equals(cv.getFinalCustomizationById(feature.getID()))) {
fe.setVariability(feature , Variability.Mandatory);
Figure figure = mFigure.get(feature.getID());
figure.setAttribute(FeatureProperties.VARIABILITY , feature.getVariability().getName());
}
}
return true;
}
public static boolean transformConstraint(FeatureModel fm , FeatureEditor fe , FeatureModelEditor fme , ConstraintModel cm , ConstraintModelEditor cme , CompositeConstraintEditor cce , GroupConstraintEditor gce
, DrawingView[] dvs , CustomizationVersion cv
, HashMap<String,Figure> mFigure , HashMap<Figure,DrawingView> mDrawingView) {
if (fm.getAllFeatureRelation()!=null) {
List<FeatureRelation> frs = new ArrayList<FeatureRelation>();
frs.addAll(fm.getAllFeatureRelation().values());
for (int i=0 ; i<frs.size() ; i++) {
FeatureRelation fr = frs.get(i);
if (FeatureRelation.REQUIRE.equals(fr.getName()) || FeatureRelation.EXCLUDE.equals(fr.getName())) {
Figure f = mFigure.get(fr.getID());
DrawingView dv = mDrawingView.get(f);
if (!checkFeatureRelation(fr , fme , f , dv , cv)) {
// return false;
}
}
}
}
if (cm.getAllGroupConstraint()!=null) {
List<GroupConstraint> gcs = new ArrayList<GroupConstraint>();
gcs.addAll(cm.getAllGroupConstraint().values());
for (int i=0 ; i<gcs.size() ; i++) {
GroupConstraint gc = gcs.get(i);
Figure f = mFigure.get(gc.getID());
DrawingView dv = mDrawingView.get(f);
if (!checkGroupConstraint(gc , cm , cme , dv , cv , mFigure)) {
// return false;
}
}
}
if (cm.getAllCompositeConstraint()!=null) {
List<CompositeConstraint> ccs = new ArrayList<CompositeConstraint>();
ccs.addAll(cm.getAllCompositeConstraint().values());
for (int i=0 ; i<ccs.size() ; i++) {
CompositeConstraint cc = ccs.get(i);
Figure f = mFigure.get(cc.getID());
DrawingView dv = mDrawingView.get(f);
if (!checkCompositeConstraint(cc , cm , cme , cce , gce , dv , cv , mFigure)) {
// return false;
}
}
}
removeUnselectedFeature(fm , fme , cv , mFigure , mDrawingView);
updateSelectedFeature(fm , fe , cv , mFigure);
return true;
}
}