/** * Tests whether the refactoring merges the constants of two enumerations correctly. The generated * enumeration must contain the constants from all variants. * * @throws Exception In case of an unexpected exception. */ @Test public void testRefactorCaseEnumerationAddEnumConstant() throws Exception { VariationPoint vp = RefactoringTestUtil.getEnumerationAddEnumConstantCase(VariabilityType.OPTXOR); IfStaticConfigClassEnumerationInMemberContainer refactoring = new IfStaticConfigClassEnumerationInMemberContainer(); refactoring.refactor(vp, null); // location has one member (the enumeration) MemberContainer vpLocation = (MemberContainer) ((JaMoPPJavaSoftwareElement) vp.getLocation()).getJamoppElement(); assertThat(vpLocation.getMembers().size(), equalTo(1)); // member is an enumeration assertThat(vpLocation.getMembers().get(0), instanceOf(Enumeration.class)); Enumeration enumeration = (Enumeration) vpLocation.getMembers().get(0); // enumeration has the correct name and the two constants from the base and the integration assertThat(enumeration.getName(), equalTo("A")); assertThat(enumeration.getConstants().size(), equalTo(2)); assertThat(enumeration.getConstants().get(0).getName(), anyOf(equalTo("A"), equalTo("B"))); assertThat(enumeration.getConstants().get(1).getName(), anyOf(equalTo("A"), equalTo("B"))); assertThat( enumeration.getConstants().get(0).getName(), not(equalTo(enumeration.getConstants().get(1).getName()))); // verify correct VPM RefactoringTestUtil.assertValidVPM(vp); }
/** * Tests whether the refactoring * * @throws Exception In case of an unexpected exception. */ @Test public void testRefactorCaseMethodAddDifferentParam() throws Exception { VariationPoint vp = RefactoringTestUtil.getMethodAddDifferentParamCase(VariabilityType.OPTXOR); IfStaticConfigClassMethod refactoring = new IfStaticConfigClassMethod(); refactoring.refactor(vp, null); // location has two methods Class vpLocation = (Class) ((JaMoPPJavaSoftwareElement) vp.getLocation()).getJamoppElement(); assertThat(vpLocation.getMethods().size(), equalTo(2)); Method firstMethod = vpLocation.getMethods().get(0); Method secondMethod = vpLocation.getMethods().get(1); // assert number of parameters assertThat(firstMethod.getParameters().size(), anyOf(equalTo(1), equalTo(2))); assertThat(secondMethod.getParameters().size(), anyOf(equalTo(1), equalTo(2))); assertThat( firstMethod.getParameters().size(), not(equalTo(secondMethod.getParameters().size()))); // assert method names and return types assertThat(firstMethod.getName(), equalTo("someMethod")); assertThat(secondMethod.getName(), equalTo("someMethod")); assertThat(firstMethod.getTypeReference(), instanceOf(Void.class)); assertThat(secondMethod.getTypeReference(), instanceOf(Void.class)); // verify correct VPM RefactoringTestUtil.assertValidVPM(vp); }
/** * Executes the given replacement associated with the variation point. This is quite time * consuming because the replacement is carried out in a generic way. If possible, try to provide * another specialized implementation for the technology-specific refactorings. * * @param replacement The replacement to be executed. * @param variationPoint The associated variation point. */ protected void executeReplacement( Map.Entry<EObject, EObject> replacement, VariationPoint variationPoint) { LOGGER.debug( String.format("Replacing %s with %s.", replacement.getKey(), replacement.getValue())); ReplacementUtil.replaceCrossReferences( replacement.getKey(), replacement.getValue(), variationPoint.eResource().getResourceSet()); }
/** * Tests whether the refactoring * * @throws Exception In case of an unexpected exception. */ @Test public void testRefactorCaseMethodAddSameParam() throws Exception { VariationPoint vp = RefactoringTestUtil.getMethodAddSameParamCase(VariabilityType.OPTXOR); IfStaticConfigClassMethod refactoring = new IfStaticConfigClassMethod(); refactoring.refactor(vp, null); // location has one method Class vpLocation = (Class) ((JaMoPPJavaSoftwareElement) vp.getLocation()).getJamoppElement(); assertThat(vpLocation.getMethods().size(), equalTo(1)); // assert number of parameters assertThat(vpLocation.getMethods().get(0).getParameters().size(), equalTo(0)); // assert method name and return type assertThat(vpLocation.getMethods().get(0).getTypeReference(), instanceOf(Void.class)); // verify correct VPM RefactoringTestUtil.assertValidVPM(vp); }
@Override public List<Resource> refactor( VariationPoint variationPoint, Map<String, Object> refactoringConfigurations) { new ResourceProcessorService().processVPBeforeFullyAutomatedRefactoring(variationPoint); List<Resource> changedResources = refactorFullyAutomated(variationPoint, refactoringConfigurations); fixVPMAfterRefactoring(variationPoint); variationPoint.setRefactored(true); return changedResources; }
/** * Fixes the VPM after the refactoring has been carried out. This is necessary because the * elements referenced by the VPM might have been replaced during the refactoring. This leads to * dangling references and an invalid VPM. Fixing is done by applying the recorded changes. * Changes are recorded by the protected helper methods of this class. * * @param variationPoint The variation point to fix. */ private void fixVPMAfterRefactoring(VariationPoint variationPoint) { /** * The information we collect: - Replacements between an original and a replacement - Newly * created elements corresponding to a specific variant * * <p>What we do: - calculate the transitive closure of replacements to become independent from * execution order - partition the stored replacements in replacements that - A: shall be * applied - B: are already contained by a newly created element - Apply A - Delete B from the * variation point (as it is already included in a newly created element) - Add the newly * created elements to the VPM */ Map<EObject, EObject> replacementsClosure = calculateTransitiveClosure(replacements); PartitionedReplacements partitionedReplacements = partitionReplacements(replacementsClosure, variantSpecificelements); for (Map.Entry<EObject, EObject> replacement : partitionedReplacements.getApply()) { executeReplacement(replacement, variationPoint); } for (Map.Entry<EObject, EObject> replacement : partitionedReplacements.getDelete()) { LOGGER.debug(String.format("Removing %s from VP.", replacement.getKey())); removeSoftwareElement(replacement.getKey(), variationPoint); } for (Map.Entry<String, Set<EObject>> variantSpecifics : variantSpecificelements.entrySet()) { final String variantId = variantSpecifics.getKey(); Variant variant = Iterables.find( variationPoint.getVariants(), new Predicate<Variant>() { @Override public boolean apply(Variant arg0) { return variantId.equals(arg0.getId()); } }); if (variant == null) { LOGGER.warn( "Elements have been registered to the invalid variant ID " + variantId + ". Ignoring the entries."); continue; } for (EObject eobject : variantSpecifics.getValue()) { SoftwareElement swElement = createSoftwareElement(eobject); if (swElement == null) { LOGGER.warn( "We were unable to create a SoftwareElement for the EObject " + eobject + "."); } variant.getImplementingElements().add(swElement); } } }
private void removeSoftwareElement(EObject eobject, VariationPoint variationPoint) { for (Variant variant : variationPoint.getVariants()) { Iterator<SoftwareElement> swElementIterator = variant.getImplementingElements().iterator(); while (swElementIterator.hasNext()) { if (swElementIterator.next().getWrappedElement() == eobject) { swElementIterator.remove(); return; } } } }
/** * * <!-- begin-user-doc --> * <!-- end-user-doc --> * * @generated */ public VariationPoint getTarget() { if (target != null && target.eIsProxy()) { InternalEObject oldTarget = (InternalEObject) target; target = (VariationPoint) eResolveProxy(oldTarget); if (target != oldTarget) { if (eNotificationRequired()) eNotify( new ENotificationImpl( this, Notification.RESOLVE, RefinementPackage.REFINEMENT_REASON__TARGET, oldTarget, target)); } } return target; }
/** * * <!-- begin-user-doc --> * <!-- end-user-doc --> * * @generated */ public VariationPoint getSource() { if (source != null && source.eIsProxy()) { InternalEObject oldSource = (InternalEObject) source; source = (VariationPoint) eResolveProxy(oldSource); if (source != oldSource) { if (eNotificationRequired()) eNotify( new ENotificationImpl( this, Notification.RESOLVE, RefinementPackage.REFINEMENT_REASON__SOURCE, oldSource, source)); } } return source; }