Skip to content

Commit

Permalink
PLANNER-746 Rename locateWorkingObject() to lookUpWorkingObject(), re…
Browse files Browse the repository at this point in the history
…locate() to rebase() and Locator to LookUpManager
  • Loading branch information
ge0ffrey committed Feb 22, 2017
1 parent bcbdc53 commit 00516bf
Show file tree
Hide file tree
Showing 50 changed files with 314 additions and 330 deletions.
Expand Up @@ -14,22 +14,22 @@
* limitations under the License.
*/

package org.optaplanner.core.api.domain.locator;
package org.optaplanner.core.api.domain.lookup;

import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.impl.score.director.ScoreDirector;

/**
* Determines how {@link ScoreDirector#locateWorkingObject(Object)} maps
* Determines how {@link ScoreDirector#lookUpWorkingObject(Object)} maps
* a {@link ProblemFactCollectionProperty problem fact} or a {@link PlanningEntity planning entity}
* from an external copy to the internal one.
*/
public enum LocationStrategyType {
public enum LookUpStrategyType {
/**
* Map by the same {@link PlanningId} field or method.
* If there is no such field or method,
* there is no mapping and {@link ScoreDirector#locateWorkingObject(Object)} must not be used.
* there is no mapping and {@link ScoreDirector#lookUpWorkingObject(Object)} must not be used.
* If there is such a field or method, but it returns null, it fails fast.
* <p>
* This is the default.
Expand All @@ -43,12 +43,12 @@ public enum LocationStrategyType {
/**
* Map by {@link Object#equals(Object) equals(Object)} and {@link Object#hashCode() hashCode()}.
* If any of these two methods is not overridden by the working object's class or some of its superclasses,
* {@link ScoreDirector#locateWorkingObject(Object)} must not be used because it cannot work correctly with
* {@link ScoreDirector#lookUpWorkingObject(Object)} must not be used because it cannot work correctly with
* {@link Object}'s equals and hashCode implementations.
*/
EQUALITY,
/**
* There is no mapping and {@link ScoreDirector#locateWorkingObject(Object)} must not be used.
* There is no mapping and {@link ScoreDirector#lookUpWorkingObject(Object)} must not be used.
*/
NONE;

Expand Down
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.optaplanner.core.api.domain.locator;
package org.optaplanner.core.api.domain.lookup;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
Expand All @@ -31,9 +31,9 @@

/**
* Specifies that a bean property (or a field) is the id to match
* when {@link ScoreDirector#locateWorkingObject(Object) locating}
* when {@link ScoreDirector#lookUpWorkingObject(Object) locating}
* an externalObject (often from another {@link Thread} or JVM).
* Used during {@link Move} relocation and in a {@link ProblemFactChange}.
* Used during {@link Move} rebasing and in a {@link ProblemFactChange}.
* <p>
* It is specified on a getter of a java bean property (or directly on a field) of a {@link PlanningEntity} class,
* {@link ValueRangeProvider planning value} class or any {@link ProblemFactCollectionProperty problem fact} class.
Expand Down
Expand Up @@ -19,7 +19,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.optaplanner.core.api.domain.locator.LocationStrategyType;
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;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactProperty;
Expand Down Expand Up @@ -69,6 +69,6 @@ interface NullSolutionCloner extends SolutionCloner {}
/**
* @return never null
*/
LocationStrategyType locationStrategyType() default LocationStrategyType.PLANNING_ID_OR_NONE;
LookUpStrategyType lookUpStrategyType() default LookUpStrategyType.PLANNING_ID_OR_NONE;

}
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.util.Map;

public class EqualsLocationStrategy implements LocationStrategy {
public class EqualsLookUpStrategy implements LookUpStrategy {

@Override
public void addWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object workingObject) {
Expand All @@ -39,7 +39,7 @@ public void removeWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object
}

@Override
public <E> E locateWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
public <E> E lookUpWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
return (E) idToWorkingObjectMap.get(externalObject);
}

Expand Down
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.util.Map;

public class ImmutableLocationStrategy implements LocationStrategy {
public class ImmutableLookUpStrategy implements LookUpStrategy {

@Override
public void addWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object workingObject) {
Expand All @@ -31,7 +31,7 @@ public void removeWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object
}

@Override
public <E> E locateWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
public <E> E lookUpWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
// Because it is immutable, we can use the same one.
return externalObject;
}
Expand Down
Expand Up @@ -14,27 +14,27 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.optaplanner.core.api.domain.locator.PlanningId;
import org.optaplanner.core.api.domain.lookup.PlanningId;
import org.optaplanner.core.impl.score.director.ScoreDirector;

/**
* @see PlanningId
* @see ScoreDirector#locateWorkingObject(Object)
* @see ScoreDirector#lookUpWorkingObject(Object)
*/
public class Locator {
public class LookUpManager {

private final LocationStrategyResolver locationStrategyResolver;
private final LookUpStrategyResolver lookUpStrategyResolver;

private Map<Object, Object> idToWorkingObjectMap;

public Locator(LocationStrategyResolver locationStrategyResolver) {
this.locationStrategyResolver = locationStrategyResolver;
public LookUpManager(LookUpStrategyResolver lookUpStrategyResolver) {
this.lookUpStrategyResolver = lookUpStrategyResolver;
}

public void resetWorkingObjects(Collection<Object> allFacts) {
Expand All @@ -45,33 +45,33 @@ public void resetWorkingObjects(Collection<Object> allFacts) {
}

public void addWorkingObject(Object workingObject) {
LocationStrategy locationStrategy = locationStrategyResolver.determineLocationStrategy(workingObject);
locationStrategy.addWorkingObject(idToWorkingObjectMap, workingObject);
LookUpStrategy lookUpStrategy = lookUpStrategyResolver.determineLookUpStrategy(workingObject);
lookUpStrategy.addWorkingObject(idToWorkingObjectMap, workingObject);
}

public void removeWorkingObject(Object workingObject) {
LocationStrategy locationStrategy = locationStrategyResolver.determineLocationStrategy(workingObject);
locationStrategy.removeWorkingObject(idToWorkingObjectMap, workingObject);
LookUpStrategy lookUpStrategy = lookUpStrategyResolver.determineLookUpStrategy(workingObject);
lookUpStrategy.removeWorkingObject(idToWorkingObjectMap, workingObject);
}

public void clearWorkingObjects() {
idToWorkingObjectMap = null;
}

/**
* As defined by {@link ScoreDirector#locateWorkingObject(Object)}.
* As defined by {@link ScoreDirector#lookUpWorkingObject(Object)}.
* @param externalObject sometimes null
* @return null if externalObject is null or if there is no workingObject for externalObject
* @throws IllegalArgumentException if it cannot be located or if the externalObject's class is not supported
* @throws IllegalStateException if it cannot be located
* @param <E> the object type
*/
public <E> E locateWorkingObject(E externalObject) {
public <E> E lookUpWorkingObject(E externalObject) {
if (externalObject == null) {
return null;
}
LocationStrategy locationStrategy = locationStrategyResolver.determineLocationStrategy(externalObject);
return locationStrategy.locateWorkingObject(idToWorkingObjectMap, externalObject);
LookUpStrategy lookUpStrategy = lookUpStrategyResolver.determineLookUpStrategy(externalObject);
return lookUpStrategy.lookUpWorkingObject(idToWorkingObjectMap, externalObject);
}

}
Expand Up @@ -14,14 +14,14 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.util.Map;

public interface LocationStrategy {
public interface LookUpStrategy {

void addWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object workingObject);
void removeWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object workingObject);
<E> E locateWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject);
<E> E lookUpWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject);

}
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.lang.reflect.Member;
import java.lang.reflect.Method;
Expand All @@ -27,8 +27,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.optaplanner.core.api.domain.locator.LocationStrategyType;
import org.optaplanner.core.api.domain.locator.PlanningId;
import org.optaplanner.core.api.domain.lookup.LookUpStrategyType;
import org.optaplanner.core.api.domain.lookup.PlanningId;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.config.util.ConfigUtils;
import org.optaplanner.core.impl.domain.common.accessor.MemberAccessor;
Expand All @@ -38,56 +38,56 @@
/**
* This class is thread-safe.
*/
public class LocationStrategyResolver {
public class LookUpStrategyResolver {

private final LocationStrategyType locationStrategyType;
private final LookUpStrategyType lookUpStrategyType;

private final ConcurrentMap<Class<?>, LocationStrategy> decisionCache = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, LookUpStrategy> decisionCache = new ConcurrentHashMap<>();

public LocationStrategyResolver(LocationStrategyType locationStrategyType) {
this.locationStrategyType = locationStrategyType;
decisionCache.put(Boolean.class, new ImmutableLocationStrategy());
decisionCache.put(Byte.class, new ImmutableLocationStrategy());
decisionCache.put(Short.class, new ImmutableLocationStrategy());
decisionCache.put(Integer.class, new ImmutableLocationStrategy());
decisionCache.put(Long.class, new ImmutableLocationStrategy());
decisionCache.put(Float.class, new ImmutableLocationStrategy());
decisionCache.put(Double.class, new ImmutableLocationStrategy());
decisionCache.put(BigInteger.class, new ImmutableLocationStrategy());
decisionCache.put(BigDecimal.class, new ImmutableLocationStrategy());
decisionCache.put(Character.class, new ImmutableLocationStrategy());
decisionCache.put(String.class, new ImmutableLocationStrategy());
decisionCache.put(LocalDate.class, new ImmutableLocationStrategy());
decisionCache.put(LocalTime.class, new ImmutableLocationStrategy());
decisionCache.put(LocalDateTime.class, new ImmutableLocationStrategy());
public LookUpStrategyResolver(LookUpStrategyType lookUpStrategyType) {
this.lookUpStrategyType = lookUpStrategyType;
decisionCache.put(Boolean.class, new ImmutableLookUpStrategy());
decisionCache.put(Byte.class, new ImmutableLookUpStrategy());
decisionCache.put(Short.class, new ImmutableLookUpStrategy());
decisionCache.put(Integer.class, new ImmutableLookUpStrategy());
decisionCache.put(Long.class, new ImmutableLookUpStrategy());
decisionCache.put(Float.class, new ImmutableLookUpStrategy());
decisionCache.put(Double.class, new ImmutableLookUpStrategy());
decisionCache.put(BigInteger.class, new ImmutableLookUpStrategy());
decisionCache.put(BigDecimal.class, new ImmutableLookUpStrategy());
decisionCache.put(Character.class, new ImmutableLookUpStrategy());
decisionCache.put(String.class, new ImmutableLookUpStrategy());
decisionCache.put(LocalDate.class, new ImmutableLookUpStrategy());
decisionCache.put(LocalTime.class, new ImmutableLookUpStrategy());
decisionCache.put(LocalDateTime.class, new ImmutableLookUpStrategy());
}

/**
* This method is thread-safe.
* @param object never null
* @return never null
*/
public LocationStrategy determineLocationStrategy(Object object) {
public LookUpStrategy determineLookUpStrategy(Object object) {
Class<?> objectClass = object.getClass();
return decisionCache.computeIfAbsent(objectClass, key -> {
switch (locationStrategyType) {
switch (lookUpStrategyType) {
case PLANNING_ID_OR_NONE:
MemberAccessor memberAccessor1 = findPlanningIdMemberAccessor(objectClass);
if (memberAccessor1 == null) {
return new NoneLocationStrategy();
return new NoneLookUpStrategy();
}
return new PlanningIdLocationStrategy(memberAccessor1);
return new PlanningIdLookUpStrategy(memberAccessor1);
case PLANNING_ID_OR_FAIL_FAST:
MemberAccessor memberAccessor2 = findPlanningIdMemberAccessor(objectClass);
if (memberAccessor2 == null) {
throw new IllegalArgumentException("The class (" + objectClass
+ ") does not have a " + PlanningId.class.getSimpleName() + " annotation,"
+ " but the locationStrategyType (" + locationStrategyType + ") requires it.\n"
+ " but the lookUpStrategyType (" + lookUpStrategyType + ") requires it.\n"
+ "Maybe add the " + PlanningId.class.getSimpleName() + " annotation"
+ " or change the " + PlanningSolution.class.getSimpleName() + " annotation's "
+ LocationStrategyType.class.getSimpleName() + ".");
+ LookUpStrategyType.class.getSimpleName() + ".");
}
return new PlanningIdLocationStrategy(memberAccessor2);
return new PlanningIdLookUpStrategy(memberAccessor2);
case EQUALITY:
Method equalsMethod;
Method hashCodeMethod;
Expand All @@ -107,11 +107,11 @@ public LocationStrategy determineLocationStrategy(Object object) {
+ ") overrides equals() but neither it nor any superclass"
+ " overrides the hashCode() method.");
}
return new EqualsLocationStrategy();
return new EqualsLookUpStrategy();
case NONE:
return new NoneLocationStrategy();
return new NoneLookUpStrategy();
default:
throw new IllegalStateException("The locationStrategyType (" + locationStrategyType
throw new IllegalStateException("The lookUpStrategyType (" + lookUpStrategyType
+ ") is not implemented.");
}
});
Expand Down
Expand Up @@ -14,16 +14,16 @@
* limitations under the License.
*/

package org.optaplanner.core.impl.domain.locator;
package org.optaplanner.core.impl.domain.lookup;

import java.util.Map;

import org.optaplanner.core.api.domain.locator.LocationStrategyType;
import org.optaplanner.core.api.domain.locator.PlanningId;
import org.optaplanner.core.api.domain.lookup.LookUpStrategyType;
import org.optaplanner.core.api.domain.lookup.PlanningId;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.impl.score.director.ScoreDirector;

public class NoneLocationStrategy implements LocationStrategy {
public class NoneLookUpStrategy implements LookUpStrategy {

@Override
public void addWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object workingObject) {
Expand All @@ -36,15 +36,15 @@ public void removeWorkingObject(Map<Object, Object> idToWorkingObjectMap, Object
}

@Override
public <E> E locateWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
public <E> E lookUpWorkingObject(Map<Object, Object> idToWorkingObjectMap, E externalObject) {
throw new IllegalArgumentException("The externalObject (" + externalObject
+ ") cannot be located.\n"
+ "Maybe give the class (" + externalObject.getClass()
+ ") a " + PlanningId.class.getSimpleName() + " annotation"
+ " or change the " + PlanningSolution.class.getSimpleName() + " annotation's "
+ LocationStrategyType.class.getSimpleName()
+ LookUpStrategyType.class.getSimpleName()
+ " or don't rely on functionality that depends on "
+ ScoreDirector.class.getSimpleName() + ".locateWorkingObject().");
+ ScoreDirector.class.getSimpleName() + ".lookUpWorkingObject().");
}

}

0 comments on commit 00516bf

Please sign in to comment.