Skip to content

Commit

Permalink
PLANNER-793 Autodiscover problem facts without annotations through fl…
Browse files Browse the repository at this point in the history
…ag on @Planningsolution

 (AKA deprecate AbstractSolution)
  • Loading branch information
ge0ffrey committed May 15, 2017
1 parent 16959f6 commit d499d41
Show file tree
Hide file tree
Showing 10 changed files with 442 additions and 98 deletions.
@@ -0,0 +1,35 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.optaplanner.core.api.domain.autodetect;

import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningEntityProperty;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactProperty;

/**
* Determines if and how to automatically presume
* {@link ProblemFactCollectionProperty}, {@link ProblemFactProperty},
* {@link PlanningEntityCollectionProperty} and {@link PlanningEntityProperty} annotations
* on a {@link PlanningSolution}.
*/
public enum AutoDiscoverMemberType {
NONE,
FIELD,
GETTER;
}
Expand Up @@ -19,6 +19,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.optaplanner.core.api.domain.autodetect.AutoDiscoverMemberType;
import org.optaplanner.core.api.domain.lookup.LookUpStrategyType;
import org.optaplanner.core.api.domain.solution.cloner.SolutionCloner;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
Expand Down Expand Up @@ -53,6 +54,11 @@
@Retention(RUNTIME)
public @interface PlanningSolution {

/**
* @return never null
*/
AutoDiscoverMemberType autoDiscoverMemberType() default AutoDiscoverMemberType.NONE;

/**
* Overrides the default {@link SolutionCloner} to implement a custom {@link PlanningSolution} cloning implementation.
* <p>
Expand Down
Expand Up @@ -22,6 +22,8 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -37,6 +39,7 @@
import javax.script.ScriptException;

import org.optaplanner.core.api.domain.lookup.PlanningId;
import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
import org.optaplanner.core.config.AbstractConfig;
import org.optaplanner.core.impl.domain.common.AlphabeticMemberComparator;
import org.optaplanner.core.impl.domain.common.ReflectionHelper;
Expand Down Expand Up @@ -338,6 +341,46 @@ public static Class<? extends Annotation> extractAnnotationClass(Member member,
return annotationClass;
}

public static Class<?> extractCollectionGenericTypeParameter(
String parentClassConcept, Class<?> parentClass,
Class<?> type, Type genericType,
Class<? extends Annotation> annotationClass, String memberName) {
if (!(genericType instanceof ParameterizedType)) {
throw new IllegalArgumentException("The " + parentClassConcept + " (" + parentClass + ") has a "
+ (annotationClass == null ? "auto discovered" : annotationClass.getSimpleName() + " annotated")
+ " member (" + memberName
+ ") with a member type (" + type
+ ") that returns a " + Collection.class.getSimpleName()
+ " which has no generic parameters.\n"
+ "Maybe the member (" + memberName + ") should return a typed "
+ Collection.class.getSimpleName() + ".");
}
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
if (typeArguments.length != 1) {
throw new IllegalArgumentException("The " + parentClassConcept + " (" + parentClass + ") has a "
+ (annotationClass == null ? "auto discovered" : annotationClass.getSimpleName() + " annotated")
+ " member (" + memberName
+ ") with a member type (" + type
+ ") which is parameterized collection with an unsupported number of generic parameters ("
+ typeArguments.length + ").");
}
Type typeArgument = typeArguments[0];
if (typeArgument instanceof ParameterizedType) {
// Remove the type parameters so it can be cast to a Class
typeArgument = ((ParameterizedType) typeArgument).getRawType();
}
if (!(typeArgument instanceof Class)) {
throw new IllegalArgumentException("The " + parentClassConcept + " (" + parentClass + ") has a "
+ (annotationClass == null ? "auto discovered" : annotationClass.getSimpleName() + " annotated")
+ " member (" + memberName
+ ") with a member type (" + type
+ ") which is parameterized collection with an unsupported type argument ("
+ typeArgument + ").");
}
return ((Class) typeArgument);
}

public static MemberAccessor buildMemberAccessor(Member member, MemberAccessorType memberAccessorType, Class<? extends Annotation> annotationClass) {
if (member instanceof Field) {
Field field = (Field) member;
Expand Down

0 comments on commit d499d41

Please sign in to comment.