/** Overrides the default method to display the information of the instances */ public String toString() { StringBuffer result = new StringBuffer(); result.append("<" + transitionName + "," + sourceFeature.getName() + ", "); // result.append( sourceClass + " ," + targetClass + ", ["); result.append(transitionData.klass.getName() + ", ["); for (Feature feature : requiringFeatures) { result.append(feature.getName() + " "); } result.append("] >"); return result.toString(); } // of toString
// Used in the table label provider public String getViewerColumnValue(int index) { switch (index) { case 0: // transition name return transitionName; case 1: // qualified name return sourceFeature.getName() + "." + transitionData.stateMachineName + "." + transitionData.regionName; case 2: // requires safe composition return Boolean.toString(needsSAT); case 3: // has error return Boolean.toString(hasError); case 4: // logical proposition if (!needsSAT || hasError) { // if does not need SAT or is an error return empty return ""; } return SCUtils.translatesRequiringImpl(sourceFeature, requiringFeatures); case 5: // is consistent (if satisfiable means is inconsistent, that is why it is negated) if (!needsSAT || hasError) { // if does not need SAT or is an error return empty return ""; } return Boolean.toString(!evaluationValues.get(0)); // case 6: // eval time if (!needsSAT || hasError) { // if does not need SAT or is an error return empty return ""; } return Long.toString(evaluationTime); case 7: // remarks return errorMessage; default: return "unkown " + index; } } // getViewrColumnValue
@Override public Map<Feature, SortedSet<Feature>> apply(SPL spl) { // Obtains the list of features of the SPL where this rule will be applied List<Feature> listFeatures = spl.getFeatures(); // *********************************************************************** // *********************************************************************** // ******************* Gathers the information from the features // **************** Creates necessary data structures StateMachine stateMachine; List<Class> classes; List<TransitionData> transitions; // Maps features to the classes that they define Map<Feature, List<Class>> mapFeatureToClasses = new HashMap<Feature, List<Class>>(); // Maps features to the transition data that they contain Map<Feature, List<TransitionData>> mapFeatureToTransitionData = new HashMap<Feature, List<TransitionData>>(); // Reads the messages of all features for (Feature feature : listFeatures) { // @debug // System.out.println("\n\transition of feature " + feature.getName()); // if the package diagram does not exists, add the entries with no objects and skip if (feature.getClassDiagram() == null) { transitions = new LinkedList<TransitionData>(); mapFeatureToTransitionData.put(feature, transitions); classes = new LinkedList<Class>(); // Adds the collected classes to the feature mapFeatureToClasses.put(feature, classes); continue; } // Gets the classes of a feature classes = SCUtils.filterList( feature.getClassDiagram().getPackagedElements(), UMLPackage.Literals.CLASS); // The list of associations will be sorted by name of association Collections.sort(classes, new ClassComparator()); // maps a feature to its classes mapFeatureToClasses.put(feature, classes); // Resets the list of transitions for the feature transitions = new LinkedList<TransitionData>(); // Gets the state machines out of the classes for (Class klass : classes) { for (Behavior behavior : klass.getOwnedBehaviors()) { // @debug // System.out.println("Behavior name " + behavior.getName()); // if the owned behavior is a state machine record its information if (behavior instanceof StateMachine) { // @debug // System.out.println("It is state machine"); stateMachine = (StateMachine) behavior; // Traverses all regions in the state machine to get their transitions for (Region region : stateMachine.getRegions()) { for (Transition transition : region.getTransitions()) { transitions.add( new TransitionData( transition.getName(), stateMachine.getName(), klass, region.getName())); // @debug // System.out.println("transition " + transition.getName()); } // for all transitions } // for all regions } // of state machine } // for all behaviors in the class } // for all classes // The list of associations will be sorted by name of association Collections.sort(transitions, new TransitionDataComparator()); // maps the transition data to the features mapFeatureToTransitionData.put(feature, transitions); } // for all features // @debug /* System.out.println("Printing collected feature data"); for (Feature feature : listFeatures) { transitions = mapFeatureToTransitionData.get(feature); System.out.println("Feature " + feature.getName()); for (TransitionData transitionData : transitions) { System.out.println(transitionData); } } // of all features */ // *********************************************************************** // *********************************************************************** // ******************* Performs the Safe Composition Checking /* Algorithm to follow 1. For each feature f 2. for each transition t in f 3. if t is an operation of its containing class done --- create instance rule but do not evaluate 4. otherwise, if t is not an operation in containing class create a new rule instance <transition_name, source feature, class_name, requiringFeatures> 5. for each compatible feature g 6. if transition is operation of a class in g 7. add the feature to requiringFeatures of rule instance */ // Map of a feature to the features it is compatible with Map<Feature, SortedSet<Feature>> compatibleFeatures = spl.getCompatibleFeatures(); // List with the rule instances detected List<IRuleInstance<TransitionData>> listRuleInstances = new LinkedList<IRuleInstance<TransitionData>>(); // List of the features that re required by an instance of a rule Set<Feature> requiringFeatures = new TreeSet<Feature>(); // @debug // System.out.println("\n\n Detecting inconsistencies "); // 1. For each feature for (Feature f : listFeatures) { // @debug // System.out.println("\nFeature " + f.getName()); // Get message data transitions = mapFeatureToTransitionData.get(f); // Writes the header of the feature being checked spl.writeAnalysisResult(f.getName()); // 2. for each transition in f for (TransitionData transitionData : transitions) { // 3. if t is an operation of its containing class done ! --- create instance rule but do // not evaluate if (isTransitionInClass(transitionData.name, transitionData.klass)) { // create instance rule that is not evaluated evaluate listRuleInstances.add( new RuleInstance( transitionData.name, f, new TreeSet<Feature>(), false, transitionData)); // @debug // System.out.println("Transition " + transitionData.name + " already defined in class"); continue; } // 4. otherwise, if t is not an operation in containing class // create a new rule instance <transition_name, source feature, class_name, // requiringFeatures> // creates a blank copy for the required features of this message requiringFeatures = new TreeSet<Feature>(); // 5. for each compatible feature g for (Feature g : compatibleFeatures.get(f)) { // 6. if transition is operation of a class in g if (isTransitionInClass( transitionData.name, SCUtils.findClass(transitionData.klass.getName(), mapFeatureToClasses.get(g)))) { // add the feature to requiringFeatures of rule instance requiringFeatures.add(g); // @debug // System.out.println("\t defined in feature " + g.getName()); } } // of compatible features // create a new rule instance <message_name, source feature, source class, target class, // requiringFeatures> listRuleInstances.add( new RuleInstance(transitionData.name, f, requiringFeatures, true, transitionData)); } // for each transition data } // for each feature f // ******************* Computes the propositional logic formulas // Checks safe composition on each of the rule instances SCUtils.checkSafeComposition(this, listRuleInstances, spl); // Displays the result in a table String[] columnNames = { "Transition", "QName", "SC", "Error", "Imp", "Consistent", "msec", "Remarks" }; int[] columnWidths = {100, 300, 100, 100, 100, 100, 100, 100}; int[] columnAlignments = { SWT.LEFT, SWT.LEFT, SWT.LEFT, SWT.LEFT, SWT.LEFT, SWT.LEFT, SWT.LEFT, SWT.LEFT }; RuleInstanceTableViewer<TransitionData> tableViewer = new RuleInstanceTableViewer<TransitionData>( "Rule 6 for product line " + spl.getSPLName(), columnNames, columnWidths, columnAlignments, new RuleLabelProvider(), listRuleInstances); tableViewer.open(); // @debug System.out.println("Rule 6 instances " + listRuleInstances.size()); // TODO Auto-generated method stub return null; } // of apply