All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.mf.transform.MfChildTransformer Maven / Gradle / Ivy

There is a newer version: 0.41.0
Show newest version
package cdc.mf.transform;

import java.util.function.BiFunction;
import java.util.function.Function;

import cdc.mf.model.MfAbstractChildElement;
import cdc.mf.model.MfAggregation;
import cdc.mf.model.MfAssociation;
import cdc.mf.model.MfClass;
import cdc.mf.model.MfComposition;
import cdc.mf.model.MfConnector;
import cdc.mf.model.MfConnectorOwner;
import cdc.mf.model.MfConstraint;
import cdc.mf.model.MfConstraintOwner;
import cdc.mf.model.MfDocumentation;
import cdc.mf.model.MfElement;
import cdc.mf.model.MfEnumeration;
import cdc.mf.model.MfEnumerationValue;
import cdc.mf.model.MfImplementation;
import cdc.mf.model.MfImplementationOwner;
import cdc.mf.model.MfInterface;
import cdc.mf.model.MfMemberOwner;
import cdc.mf.model.MfOperation;
import cdc.mf.model.MfPackage;
import cdc.mf.model.MfPackageOwner;
import cdc.mf.model.MfParameter;
import cdc.mf.model.MfParameterOwner;
import cdc.mf.model.MfProperty;
import cdc.mf.model.MfSpecialization;
import cdc.mf.model.MfSpecializationOwner;
import cdc.mf.model.MfTag;
import cdc.mf.model.MfTagOwner;
import cdc.mf.model.MfTip;
import cdc.mf.model.MfTypeOwner;

/**
 * Interface used to locally transform a {@link MfAbstractChildElement child element}.
 * 

* For a deep transformation, use {@link MfTransformer}. *

* Note: at most one element is returned, but one can create several target children for one source child. * * @author Damien Carbonne * * @param The child element type. * @param

The parent element type. */ public interface MfChildTransformer, P extends MfElement> { /** * @return The child element class. */ public Class getChildClass(); /** * Converts a source child element to a target one, possibly none. * * @param srcChild The source child. * @param tgtParent The target parent. * @return A target child, transformation of {@code srcChild}. */ public E transform(E srcChild, P tgtParent); public default E transformRaw(MfElement srcChild, MfElement tgtParent) { @SuppressWarnings("unchecked") final P tmp = (P) tgtParent; return transform(getChildClass().cast(srcChild), tmp); } /** * @param The element type. * @param

The element parent type. * @param cls The element class. * @return An instance of {@link MfChildTransformer} that duplicates the source element. */ public static , P extends MfElement> MfChildTransformer cloner(Class cls) { return new MfChildTransformer<>() { @Override public Class getChildClass() { return cls; } @Override public E transform(E srcChild, P tgtParent) { return cls.cast(srcChild.duplicate(tgtParent)); } }; } /** * @param The element type. * @param

The element parent type. * @param cls The element class. * @return An instance of {@link MfChildTransformer} that ignores a source element. */ public static , P extends MfElement> MfChildTransformer ignorer(Class cls) { return new MfChildTransformer<>() { @Override public Class getChildClass() { return cls; } @Override public E transform(E srcChild, P tgtParent) { return null; } }; } /** * Creates an instance of {@link MfChildTransformer} from an {@link MfElementFixer}. * * @param The builder type. * @param The element type. * @param

The element parent type. * @param cls The element class. * @param fixer The element fixer. * @return A new instance of {@link MfChildTransformer} built from {@code fixer}. * @throws IllegalArgumentException When {@code cls} is not recognized. */ public static , E extends MfAbstractChildElement

, P extends MfElement> MfChildTransformer of(Class cls, MfElementFixer fixer) { final MfChildTransformer x; if (cls.equals(MfAggregation.class)) { x = builder1(MfAggregation.class, MfConnectorOwner::aggregation, fixer); } else if (cls.equals(MfAssociation.class)) { x = builder1(MfAssociation.class, MfConnectorOwner::association, fixer); } else if (cls.equals(MfClass.class)) { x = builder1(MfClass.class, MfTypeOwner::cls, fixer); } else if (cls.equals(MfComposition.class)) { x = builder1(MfComposition.class, MfConnectorOwner::composition, fixer); } else if (cls.equals(MfConstraint.class)) { x = builder1(MfConstraint.class, MfConstraintOwner::constraint, fixer); } else if (cls.equals(MfDocumentation.class)) { x = builder1(MfDocumentation.class, MfElement::documentation, fixer); } else if (cls.equals(MfEnumeration.class)) { x = builder1(MfEnumeration.class, MfTypeOwner::enumeration, fixer); } else if (cls.equals(MfEnumerationValue.class)) { x = builder1(MfEnumerationValue.class, MfEnumeration::value, fixer); } else if (cls.equals(MfImplementation.class)) { x = builder1(MfImplementation.class, y -> ((MfImplementationOwner) y).implementation(), fixer); } else if (cls.equals(MfInterface.class)) { x = builder1(MfInterface.class, MfTypeOwner::xface, fixer); } else if (cls.equals(MfOperation.class)) { x = builder1(MfOperation.class, MfMemberOwner::operation, fixer); } else if (cls.equals(MfPackage.class)) { x = builder1(MfPackage.class, MfPackageOwner::pack, fixer); } else if (cls.equals(MfParameter.class)) { x = builder1(MfParameter.class, MfParameterOwner::parameter, fixer); } else if (cls.equals(MfProperty.class)) { x = builder1(MfProperty.class, MfMemberOwner::property, fixer); } else if (cls.equals(MfSpecialization.class)) { x = builder1(MfSpecialization.class, y -> ((MfSpecializationOwner) y).specialization(), fixer); } else if (cls.equals(MfTag.class)) { x = builder1(MfTag.class, MfTagOwner::tag, fixer); } else if (cls.equals(MfTip.class)) { final BiFunction> createBuilder = (tgtParent, srcChild) -> tgtParent.tip(srcChild.getSide()); x = builder2(MfTip.class, createBuilder, fixer); } else { throw new IllegalArgumentException("Unexpected class: " + cls); } @SuppressWarnings("unchecked") final MfChildTransformer tmp = (MfChildTransformer) x; return tmp; } private static , E extends MfAbstractChildElement

, P extends MfElement> MfChildTransformer builder1(Class cls, Function createBuilder, MfElementFixer fixer) { return new MfChildTransformer() { @Override public Class getChildClass() { return cls; } @SuppressWarnings("unchecked") @Override public E transform(E srcChild, P tgtParent) { final B tgtBuilder = createBuilder.apply(tgtParent); srcChild.setRaw(tgtBuilder); ((MfElementFixer) fixer).fix(srcChild, tgtBuilder); return tgtBuilder.build(); } }; } private static , E extends MfAbstractChildElement

, P extends MfElement> MfChildTransformer builder2(Class cls, BiFunction createBuilder, MfElementFixer fixer) { return new MfChildTransformer() { @Override public Class getChildClass() { return cls; } @SuppressWarnings("unchecked") @Override public E transform(E srcChild, P tgtParent) { final B tgtBuilder = createBuilder.apply(tgtParent, srcChild); srcChild.setRaw(tgtBuilder); ((MfElementFixer) fixer).fix(srcChild, tgtBuilder); return tgtBuilder.build(); } }; } }