/** * Copyright 2010 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.config.localsearch.termination; import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import org.drools.planner.core.localsearch.termination.AbstractCompositeTermination; import org.drools.planner.core.localsearch.termination.AndCompositeTermination; import org.drools.planner.core.localsearch.termination.ScoreAttainedTermination; import org.drools.planner.core.localsearch.termination.Termination; import org.drools.planner.core.localsearch.termination.OrCompositeTermination; import org.drools.planner.core.localsearch.termination.StepCountTermination; import org.drools.planner.core.localsearch.termination.TimeMillisSpendTermination; import org.drools.planner.core.localsearch.termination.UnimprovedStepCountTermination; import org.drools.planner.core.score.definition.ScoreDefinition; /** * @author Geoffrey De Smet */ @XStreamAlias("termination") public class TerminationConfig { private Termination termination = null; // TODO make into a list private Class<Termination> terminationClass = null; private TerminationCompositionStyle terminationCompositionStyle = null; private Integer maximumStepCount = null; private Long maximumTimeMillisSpend = null; private Long maximumSecondsSpend = null; private Long maximumMinutesSpend = null; private Long maximumHoursSpend = null; private String scoreAttained = null; private Integer maximumUnimprovedStepCount = null; public Termination getTermination() { return termination; } public void setTermination(Termination termination) { this.termination = termination; } public Class<Termination> getTerminationClass() { return terminationClass; } public void setTerminationClass(Class<Termination> terminationClass) { this.terminationClass = terminationClass; } public TerminationCompositionStyle getTerminationCompositionStyle() { return terminationCompositionStyle; } public void setTerminationCompositionStyle(TerminationCompositionStyle terminationCompositionStyle) { this.terminationCompositionStyle = terminationCompositionStyle; } public Integer getMaximumStepCount() { return maximumStepCount; } public void setMaximumStepCount(Integer maximumStepCount) { this.maximumStepCount = maximumStepCount; } public Long getMaximumTimeMillisSpend() { return maximumTimeMillisSpend; } public void setMaximumTimeMillisSpend(Long maximumTimeMillisSpend) { this.maximumTimeMillisSpend = maximumTimeMillisSpend; } public Long getMaximumSecondsSpend() { return maximumSecondsSpend; } public void setMaximumSecondsSpend(Long maximumSecondsSpend) { this.maximumSecondsSpend = maximumSecondsSpend; } public Long getMaximumMinutesSpend() { return maximumMinutesSpend; } public void setMaximumMinutesSpend(Long maximumMinutesSpend) { this.maximumMinutesSpend = maximumMinutesSpend; } public Long getMaximumHoursSpend() { return maximumHoursSpend; } public void setMaximumHoursSpend(Long maximumHoursSpend) { this.maximumHoursSpend = maximumHoursSpend; } public String getScoreAttained() { return scoreAttained; } public void setScoreAttained(String scoreAttained) { this.scoreAttained = scoreAttained; } public Integer getMaximumUnimprovedStepCount() { return maximumUnimprovedStepCount; } public void setMaximumUnimprovedStepCount(Integer maximumUnimprovedStepCount) { this.maximumUnimprovedStepCount = maximumUnimprovedStepCount; } // ************************************************************************ // Builder methods // ************************************************************************ public Termination buildTermination(ScoreDefinition scoreDefinition) { List<Termination> terminationList = new ArrayList<Termination>(); if (termination != null) { terminationList.add(termination); } if (terminationClass != null) { try { terminationList.add(terminationClass.newInstance()); } catch (InstantiationException e) { throw new IllegalArgumentException("terminationClass (" + terminationClass.getName() + ") does not have a public no-arg constructor", e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("terminationClass (" + terminationClass.getName() + ") does not have a public no-arg constructor", e); } } if (maximumStepCount != null) { StepCountTermination termination = new StepCountTermination(); termination.setMaximumStepCount(maximumStepCount); terminationList.add(termination); } if (maximumTimeMillisSpend != null) { TimeMillisSpendTermination termination = new TimeMillisSpendTermination(); termination.setMaximumTimeMillisSpend(maximumTimeMillisSpend); terminationList.add(termination); } if (maximumSecondsSpend != null) { TimeMillisSpendTermination termination = new TimeMillisSpendTermination(); termination.setMaximumTimeMillisSpend(maximumSecondsSpend * 1000L); terminationList.add(termination); } if (maximumMinutesSpend != null) { TimeMillisSpendTermination termination = new TimeMillisSpendTermination(); termination.setMaximumTimeMillisSpend(maximumMinutesSpend * 60000L); terminationList.add(termination); } if (maximumHoursSpend != null) { TimeMillisSpendTermination termination = new TimeMillisSpendTermination(); termination.setMaximumTimeMillisSpend(maximumHoursSpend * 3600000L); terminationList.add(termination); } if (scoreAttained != null) { ScoreAttainedTermination termination = new ScoreAttainedTermination(); termination.setScoreAttained(scoreDefinition.parseScore(scoreAttained)); terminationList.add(termination); } if (maximumUnimprovedStepCount != null) { UnimprovedStepCountTermination termination = new UnimprovedStepCountTermination(); termination.setMaximumUnimprovedStepCount(maximumUnimprovedStepCount); terminationList.add(termination); } if (terminationList.size() == 1) { return terminationList.get(0); } else if (terminationList.size() > 1) { AbstractCompositeTermination compositeTermination; if (terminationCompositionStyle == null || terminationCompositionStyle == TerminationCompositionStyle.OR) { compositeTermination = new OrCompositeTermination(); } else if (terminationCompositionStyle == TerminationCompositionStyle.AND) { compositeTermination = new AndCompositeTermination(); } else { throw new IllegalStateException("The terminationCompositionStyle (" + terminationCompositionStyle + ") is not implemented"); } compositeTermination.setTerminationList(terminationList); return compositeTermination; } else { TimeMillisSpendTermination termination = new TimeMillisSpendTermination(); termination.setMaximumTimeMillisSpend(60000); return termination; } } public void inherit(TerminationConfig inheritedConfig) { // inherited terminations get compositely added if (termination == null) { termination = inheritedConfig.getTermination(); } if (terminationClass == null) { terminationClass = inheritedConfig.getTerminationClass(); } if (terminationCompositionStyle == null) { terminationCompositionStyle = inheritedConfig.getTerminationCompositionStyle(); } if (maximumStepCount == null) { maximumStepCount = inheritedConfig.getMaximumStepCount(); } if (maximumTimeMillisSpend == null) { maximumTimeMillisSpend = inheritedConfig.getMaximumTimeMillisSpend(); } if (maximumSecondsSpend == null) { maximumSecondsSpend = inheritedConfig.getMaximumSecondsSpend(); } if (maximumMinutesSpend == null) { maximumMinutesSpend = inheritedConfig.getMaximumMinutesSpend(); } if (maximumHoursSpend == null) { maximumHoursSpend = inheritedConfig.getMaximumHoursSpend(); } if (scoreAttained == null) { scoreAttained = inheritedConfig.getScoreAttained(); } if (maximumUnimprovedStepCount == null) { maximumUnimprovedStepCount = inheritedConfig.getMaximumUnimprovedStepCount(); } } public enum TerminationCompositionStyle { AND, OR, } }