org.drools.planner.core.domain.solution.SolutionDescriptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drools-planner-core Show documentation
Show all versions of drools-planner-core Show documentation
Drools Planner optimizes automated planning by combining metaheuristic search algorithms with rule
engine powered score calculation. This is the drools-planner-core module which contains metaheuristic
algorithms.
/*
* Copyright 2011 JBoss Inc
*
* 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.drools.planner.core.domain.solution;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.drools.planner.api.domain.solution.PlanningEntityCollectionProperty;
import org.drools.planner.api.domain.solution.PlanningEntityProperty;
import org.drools.planner.core.domain.common.DescriptorUtils;
import org.drools.planner.core.domain.entity.PlanningEntityDescriptor;
import org.drools.planner.core.solution.Solution;
public class SolutionDescriptor {
private final Class solutionClass;
private final BeanInfo solutionBeanInfo;
private final Map propertyDescriptorMap;
private final Map entityPropertyDescriptorMap;
private final Map entityCollectionPropertyDescriptorMap;
private final Map, PlanningEntityDescriptor> planningEntityDescriptorMap;
public SolutionDescriptor(Class solutionClass) {
this.solutionClass = solutionClass;
try {
solutionBeanInfo = Introspector.getBeanInfo(solutionClass);
} catch (IntrospectionException e) {
throw new IllegalStateException("The solutionClass (" + solutionClass + ") is not a valid java bean.", e);
}
int mapSize = solutionBeanInfo.getPropertyDescriptors().length;
propertyDescriptorMap = new HashMap(mapSize);
entityPropertyDescriptorMap = new HashMap(mapSize);
entityCollectionPropertyDescriptorMap = new HashMap(mapSize);
planningEntityDescriptorMap = new HashMap, PlanningEntityDescriptor>(mapSize);
}
public void processAnnotations() {
processPropertyAnnotations();
}
private void processPropertyAnnotations() {
boolean noPlanningEntityPropertyAnnotation = true;
for (PropertyDescriptor propertyDescriptor : solutionBeanInfo.getPropertyDescriptors()) {
propertyDescriptorMap.put(propertyDescriptor.getName(), propertyDescriptor);
Method propertyGetter = propertyDescriptor.getReadMethod();
if (propertyGetter != null) {
if (propertyGetter.isAnnotationPresent(PlanningEntityProperty.class)) {
noPlanningEntityPropertyAnnotation = false;
entityPropertyDescriptorMap.put(propertyDescriptor.getName(), propertyDescriptor);
} else if (propertyGetter.isAnnotationPresent(PlanningEntityCollectionProperty.class)) {
noPlanningEntityPropertyAnnotation = false;
if (!Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
throw new IllegalStateException("The solutionClass (" + solutionClass
+ ") has a PlanningEntityCollection annotated property ("
+ propertyDescriptor.getName() + ") that does not return a Collection.");
}
entityCollectionPropertyDescriptorMap.put(propertyDescriptor.getName(), propertyDescriptor);
}
}
}
if (noPlanningEntityPropertyAnnotation) {
throw new IllegalStateException("The solutionClass (" + solutionClass
+ ") should have at least 1 getter with a PlanningEntityCollection or PlanningEntityProperty"
+ " annotation.");
}
}
public Class getSolutionClass() {
return solutionClass;
}
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return propertyDescriptorMap.get(propertyName);
}
public void addPlanningEntityDescriptor(PlanningEntityDescriptor planningEntityDescriptor) {
planningEntityDescriptorMap.put(planningEntityDescriptor.getPlanningEntityClass(), planningEntityDescriptor);
}
public Set> getPlanningEntityImplementationClassSet() {
return planningEntityDescriptorMap.keySet();
}
public Collection getPlanningEntityDescriptors() {
return planningEntityDescriptorMap.values();
}
public boolean hasPlanningEntityDescriptor(Class planningEntityImplementationClass) {
PlanningEntityDescriptor planningEntityDescriptor = null;
Class planningEntityClass = planningEntityImplementationClass;
while (planningEntityClass != null) {
planningEntityDescriptor = planningEntityDescriptorMap.get(planningEntityClass);
if (planningEntityDescriptor != null) {
return true;
}
planningEntityClass = planningEntityClass.getSuperclass();
}
return false;
}
public PlanningEntityDescriptor getPlanningEntityDescriptor(Class planningEntityImplementationClass) {
PlanningEntityDescriptor planningEntityDescriptor = null;
Class planningEntityClass = planningEntityImplementationClass;
while (planningEntityClass != null) {
planningEntityDescriptor = planningEntityDescriptorMap.get(planningEntityClass);
if (planningEntityDescriptor != null) {
return planningEntityDescriptor;
}
planningEntityClass = planningEntityClass.getSuperclass();
}
throw new IllegalArgumentException("A planningEntity is an instance of a planningEntityImplementationClass ("
+ planningEntityImplementationClass + ") that is not configured as a planningEntity.\n" +
"If that class (" + planningEntityImplementationClass.getSimpleName() + ") is not a " +
"planningEntityClass (or subclass thereof), check your Solution implementation's annotated methods.\n" +
"If it is, check your solver configuration.");
}
public Collection