diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/.ratings b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/.ratings index c7b17b8424252d2ea6d76aeab93acbe35cab06fd..d54f5164837b0919fed952abba078c72bc4a8b0b 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/.ratings +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/.ratings @@ -1,3 +1,3 @@ Opt4JExplorationSolutionSet.java fd1ca946198990604ea7a521e9d0335bef4ad8e1 RED Opt4JExplorerBackend.java b647535f92ebdf1e428757f6fe1e918964feb4f2 RED -Opt4JSingleExplorationSolution.java 6086e36a5b48b9f3ea68b6e50e2ac20758942d0a RED +Opt4JSingleExplorationSolution.java 5b9e6ccdb887605faaa4d2a8b17b8fa1350fbafd RED diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/Opt4JSingleExplorationSolution.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/Opt4JSingleExplorationSolution.java index 283b0d17c0798f38d24b781d7254480b6da2be66..48630805e5b935759a7cb18dbc3147667b4c0d66 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/Opt4JSingleExplorationSolution.java +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/backend/opt4j/Opt4JSingleExplorationSolution.java @@ -15,7 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.af3.exploration.alg.dse.backend.opt4j; -import static org.fortiss.af3.exploration.alg.util.ExplorationAlgUtils.getSubstitutionTypeOfGenericIface; +import static org.fortiss.af3.exploration.util.ExplorationUtils.getReturnTypeOf; import java.util.Map; import java.util.Map.Entry; @@ -51,8 +51,7 @@ public class Opt4JSingleExplorationSolution extends SolutionQuantification { // Determine the ExplorationTarget class to identify the correct return value type. Objective objective = problemModule.getObjectiveOf(targetAssoc.getValue()); ExplorationTarget<?> concreteExpTarget = targetAssoc.getKey(); - Class<?> expectedResultType = - getSubstitutionTypeOfGenericIface(concreteExpTarget, ExplorationTarget.class); + Class<?> expectedResultType = getReturnTypeOf(concreteExpTarget); // FIXME: throw an exception here. assert (expectedResultType != null) : "Could not determine the result type of the exploration target " + concreteExpTarget.getName() + diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/.ratings b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/.ratings index e03bb0c00ce50d3a412aa846fc5fcc09cd40e03a..7e82944391be39c0f539fb17dbeffd44c6be2e74 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/.ratings +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/.ratings @@ -1,7 +1,7 @@ AF3Utils.java ae4bb78f77989e3a5689bfff80298c1bdeccdb3a RED DesignSpaceExplorationModelElementFactory.java 9dc330973f132c4b936e4dc7ee8407614faf2ff6 RED ExplorationAlgDebugUtils.java ff9feee46a3d00dd21d007a53f71f2de1ce10a94 RED -ExplorationAlgUtils.java 5915fd72f26cf5d7ef49e62a8e304a63da71d8dc RED +ExplorationAlgUtils.java 1deb317ed1d276e778fb64d207a1784a4919518b RED ExplorationEcoreUtils.java 48ed07aec3cd93e66d37abc10d50636d591f1c71 RED GraphUtils.java a1cec037a4d54bcf196dc5eebddc72b033993d6f RED TransformationUtils.java b077f7a695cecd66bfdb5c265e8875900bee137c RED diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/ExplorationAlgUtils.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/ExplorationAlgUtils.java index 7ee5be1d2239e5e2b356d9be43ab35f948f9c89e..aa8b955b2a6d1fb154661d6db0d749d0ce4aa123 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/ExplorationAlgUtils.java +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/util/ExplorationAlgUtils.java @@ -23,10 +23,7 @@ import static org.fortiss.tooling.kernel.utils.EcoreUtils.getParentsWithType; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -35,8 +32,6 @@ import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; -import java.util.Stack; -import java.util.function.Predicate; import org.conqat.lib.commons.reflect.ReflectionUtils; import org.eclipse.emf.common.util.BasicEList; @@ -681,157 +676,6 @@ public class ExplorationAlgUtils { return getSuperClassOfImplementingInterface(goal, IProblemDimension.class); } - /** - * Given an object that directly or indirectly inherits from the given interface, this method - * returns the substitution class type of the generic parameter of the given interface. - * <p> - * <b>NOTE:</b> This method works only for interfaces that have a single generic type parameter. - * <p> - * This method makes no assumptions about the location of the substitution in the class - * hierarchy. - * <p> - * <p> - * This method first identifies the path from the given object's class to the given interface in - * the class hierarchy. This path is then traversed and each found generic substitution is - * examined whether it substitutes the generic of the given interface. - * - * @param object - * Object for which the substitution type defined in the given class shall be found. - * @param interfaceClass - * Interface defining or redefining the generic type of interest. - * @return Class type substituting the generic parameter of the given interface. - */ - public static Class<?> getSubstitutionTypeOfGenericIface(Object object, - Class<?> interfaceClass) { - // First, identify the "hierarchy path" from the given object to the target interface. - LinkedList<Class<?>> inheritancePath = getClassPathToIface(object, interfaceClass); - - Stack<Type> paramTypeStack = new Stack<>(); - LinkedList<Class<?>> hierTraversalList = new LinkedList<>(); - hierTraversalList.addAll(inheritancePath); - - Type currParamRawType = null; - Predicate<Class<?>> targetIfaceFound = t -> t != null && t.isAssignableFrom(interfaceClass); - // Outer loop: Inspect the "hierarchy path". - do { - Class<?> hierStackElem = hierTraversalList.poll(); - Type[] genTypes = hierStackElem.getGenericInterfaces(); - LinkedList<Type> typesToTraverse = new LinkedList<>(); - typesToTraverse.addAll(Arrays.asList(genTypes)); - - // Inner loop: Inspect a single generic substitution. - while(!typesToTraverse.isEmpty() && - !targetIfaceFound.test((Class<?>)currParamRawType)) { - Type currTraversedType = typesToTraverse.poll(); - paramTypeStack.add(currTraversedType); - - // Skip non-parameterized types (like other interfaces): Would be a wrong path. - if(currTraversedType instanceof ParameterizedType) { - currParamRawType = ((ParameterizedType)currTraversedType).getRawType(); - // Only follow the "path" of this generic parameter if it matches the previously - // identified path to the given interface. - if(inheritancePath.contains(currParamRawType)) { - Collection<Type> matchedTypes = processParentParamerType(currParamRawType); - typesToTraverse.addAll(0, matchedTypes); - } - } else { - // Otherwise, remove the current parameter type from the "path" stack: It would - // lead to the generic of the interface. - paramTypeStack.pop(); - } - } - if(!targetIfaceFound.test((Class<?>)currParamRawType)) { - // This generic substitution was not the right one --> clean the "path". - paramTypeStack.clear(); - } - } while(!hierTraversalList.isEmpty() && !targetIfaceFound.test((Class<?>)currParamRawType)); - - // Return the class of the substituting parameter type. - if(targetIfaceFound.test((Class<?>)currParamRawType)) { - // get(0): The above if clause implicitly guarantees the existence of one element. - Type paramType = paramTypeStack.get(0); - if(paramType instanceof ParameterizedType) { - Type actParamType = ((ParameterizedType)paramType).getActualTypeArguments()[0]; - if(actParamType instanceof Class<?>) { - return (Class<?>)actParamType; - } else if(actParamType instanceof ParameterizedType) { - return (Class<?>)((ParameterizedType)actParamType).getRawType(); - } - } - } - - return null; - } - - /** Collects and returns all parent interface that are parameterized by the given type. */ - private static Collection<Type> processParentParamerType(Type rawType) { - Collection<Type> matchingTypes = new ArrayList<>(); - Type[] typeParams = ((Class<?>)rawType).getGenericInterfaces(); - Collection<Type> xT = Arrays.asList(((Class<?>)rawType).getTypeParameters()); - for(Type parentType : typeParams) { - if(parentType instanceof ParameterizedType) { - Type[] typeArgs = ((ParameterizedType)parentType).getActualTypeArguments(); - if(typeArgs.length == 1 && xT.contains(typeArgs[0])) { - matchingTypes.add(parentType); - } - } - } - return matchingTypes; - } - - /** - * Determines the path in the class hierarchy from the given object's class to the interface. It - * returns a list view on the identified path. - * <p> - * <b>NOTE:</b> The given object's class must be always below the given interface's class in the - * class hierarchy. Although this property is enforced if the second class is an interface, it - * is specifically noted here since normal classes and interface cannot be differentiated here. - * - * @param object - * Object inheriting from {@code interfaceClass}. - * @param interfaceClass - * Interface forming the top of the stack and defining the end of the path. - * @return Path between the given object's class and the given interface as a linked list. - */ - private static LinkedList<Class<?>> getClassPathToIface(Object object, - Class<?> interfaceClass) { - LinkedList<Class<?>> traversalList = new LinkedList<>(); - Stack<Class<?>> hierarchyBrachStack = new Stack<>(); - LinkedList<Class<?>> ifacesTraversalList = new LinkedList<>(); - - ifacesTraversalList.addAll(Arrays.asList(object.getClass().getInterfaces())); - while(!ifacesTraversalList.isEmpty()) { - Class<?> currIface = ifacesTraversalList.poll(); - traversalList.add(currIface); - if(currIface.equals(interfaceClass)) { - break; - } - - Class<?>[] parentIfaces = currIface.getInterfaces(); - if(parentIfaces.length > 0) { - // Add candidate paths to the classes to traverse. If multiple candidate paths are - // found, remember the branch point. - // Note: always insert the parent interface at the top of the traversal list. - ifacesTraversalList.addAll(0, Arrays.asList(parentIfaces)); - if(parentIfaces.length > 1) { - hierarchyBrachStack.add(currIface); - } - } else { - // No more parent classes: Remove invalid path fragment from the stack (does not - // lead to the target interface). - int lastBranchIdx = 1; - if(!hierarchyBrachStack.isEmpty()) { - Class<?> lastHierBranch = hierarchyBrachStack.lastElement(); - traversalList.indexOf(lastHierBranch); - } - List<Class<?>> rmFromTravStrack = new ArrayList<>(); - rmFromTravStrack.addAll(traversalList.subList(lastBranchIdx, traversalList.size())); - traversalList.removeAll(rmFromTravStrack); - } - } - return traversalList; - } - /** * Returns the typed key from the map which is the best match for the given * class. The best match is defined by the first match occurring in a breath