//----------------------------------------------------------------------------
// Copyright (C) 2011 Ingrid Nunes
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// To contact the authors:
// http://inf.ufrgs.br/prosoft/bdi4jade/
//
//----------------------------------------------------------------------------
package bdi4jade.plan;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.MessageTemplate;
import java.lang.reflect.Modifier;
import bdi4jade.core.BDIAgent;
import bdi4jade.core.Capability;
import bdi4jade.exception.PlanInstantiationException;
import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalTemplate;
import bdi4jade.goal.GoalTemplateFactory;
import bdi4jade.plan.planbody.PlanBody;
/**
* This class represents a plan whose plan body is a class that can be
* instantiated by invoking the {@link Class#newInstance()} method. A class that
* has the {@link Behaviour} class as superclass is provides and it is
* instantiates in the {@link DefaultPlan#createPlanBody()} method.
*
* @author Ingrid Nunes
*/
public class DefaultPlan extends AbstractPlan {
private static String generateId(Class<? extends Goal> goalClass,
GoalTemplate goalTemplate, MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
StringBuffer sb = new StringBuffer("[");
if (goalClass != null) {
sb.append(" ").append(goalClass.getName());
}
if (goalTemplate != null) {
sb.append(" ").append(goalTemplate);
}
if (messageTemplate != null) {
sb.append(" ").append(messageTemplate);
}
sb.append(" ] :: ");
sb.append(planBodyClass.getName());
return sb.toString();
}
protected final Class<? extends PlanBody> planBodyClass;
/**
* Creates a new simple plan, which is able to achieve goals of the given
* goal class, and its body should be instances of the provided plan body
* class. Its identifier is set of the class name of the plan body class.
*
* @param goalClass
* the class of goals that this plan is able to achieve.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(Class<? extends Goal> goalClass,
Class<? extends PlanBody> planBodyClass) {
super(generateId(goalClass, null, null, planBodyClass),
GoalTemplateFactory.goalOfType(goalClass));
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan. Its body should be instances of the provided
* plan body class. Its identifier is set of the class name of the plan body
* class.
*
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(Class<? extends PlanBody> planBodyClass) {
super(generateId(null, null, null, planBodyClass));
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to achieve goals that match the
* provided template. It is a plan whose body is the specified class and its
* id is the plan body class name. It sets that this plan can achieve goals
* of the specified goal template, but more goal templates can be specified
* by overriding the {@link #initGoalTemplates()} method or invoking the
* {@link #addGoalTemplate(GoalTemplate)} method.
*
* @param goalTemplate
* the template of goals that this plan can achieve.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(GoalTemplate goalTemplate,
Class<? extends PlanBody> planBodyClass) {
super(generateId(null, goalTemplate, null, planBodyClass), goalTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to achieve goals that match the
* provided goal template and process messages that match the provided
* message template. It is a plan whose body is the specified class and its
* id is the plan body class name. It sets that this plan can achieve goals
* of the specified goal template, but more goal templates can be specified
* by overriding the {@link #initGoalTemplates()} method or invoking the
* {@link #addGoalTemplate(GoalTemplate)} method, while more message
* templates can be specified by overriding the
* {@link #initMessageTemplates()} method or invoking the
* {@link #addMessageTemplate(MessageTemplate)} method.
*
*
* @param goalTemplate
* the template of goals that this plan can achieve.
* @param messageTemplate
* the template of messages that this plan can process.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(GoalTemplate goalTemplate,
MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
super(generateId(null, goalTemplate, messageTemplate, planBodyClass),
goalTemplate, messageTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to process messages that match
* the provided message template. It is a plan whose body is the specified
* class and its id is the plan body class name. It sets that this plan can
* process messages of the specified message template, but more message
* templates can be specified by overriding the
* {@link #initMessageTemplates()} method or invoking the
* {@link #addMessageTemplate(MessageTemplate)} method.
*
* @param messageTemplate
* the template of messages that this plan can process.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
super(generateId(null, null, messageTemplate, planBodyClass),
messageTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan. It is a plan whose body is the specified class
* and its id is the given id. Goal templates can be specified by overriding
* the {@link #initGoalTemplates()} method or invoking the
* {@link #addGoalTemplate(GoalTemplate)} method, while more message
* templates can be specified by overriding the
* {@link #initMessageTemplates()} method or invoking the
* {@link #addMessageTemplate(MessageTemplate)} method.
*
* @param id
* the plan id.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(String id, Class<? extends PlanBody> planBodyClass) {
super(id);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to achieve goals that match the
* provided template. It is a plan whose body is the specified class and its
* id is the given id. It sets that this plan can achieve goals of the
* specified goal template, but more goal templates can be specified by
* overriding the {@link #initGoalTemplates()} method or invoking the
* {@link #addGoalTemplate(GoalTemplate)} method.
*
* @param id
* the plan id.
* @param goalTemplate
* the template of goals that this plan can achieve.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(String id, GoalTemplate goalTemplate,
Class<? extends PlanBody> planBodyClass) {
super(id, goalTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to achieve goals that match the
* provided goal template and process messages that match the provided
* message template. It is a plan whose body is the specified class and its
* id is the given id. It sets that this plan can achieve goals of the
* specified goal template, but more goal templates can be specified by
* overriding the {@link #initGoalTemplates()} method or invoking the
* {@link #addGoalTemplate(GoalTemplate)} method, while more message
* templates can be specified by overriding the
* {@link #initMessageTemplates()} method or invoking the
* {@link #addMessageTemplate(MessageTemplate)} method.
*
* @param id
* the plan id.
* @param goalTemplate
* the template of goals that this plan can achieve.
* @param messageTemplate
* the template of messages that this plan can process.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(String id, GoalTemplate goalTemplate,
MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
super(id, goalTemplate, messageTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new simple plan, which is able to process messages that match
* the provided message template. It is a plan whose body is the specified
* class and its id is the given id. It sets that this plan can process
* messages of the specified message template, but more message templates
* can be specified by overriding the {@link #initMessageTemplates()} method
* or invoking the {@link #addMessageTemplate(MessageTemplate)} method.
*
* @param id
* the plan id.
* @param messageTemplate
* the template of messages that this plan can process.
* @param planBodyClass
* the class of this plan body.
*/
public DefaultPlan(String id, MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
super(id, messageTemplate);
this.planBodyClass = planBodyClass;
}
/**
* Creates a new instance of the plan body. It invokes the method
* newInstance() from the plan body class.
*
* @see bdi4jade.plan.Plan#createPlanBody()
*/
@Override
public PlanBody createPlanBody() throws PlanInstantiationException {
try {
Class<?> enclosingClass = planBodyClass.getEnclosingClass();
if (!Modifier.isStatic(planBodyClass.getModifiers())
&& enclosingClass != null) {
if (BDIAgent.class.isAssignableFrom(enclosingClass)) {
return planBodyClass.getDeclaredConstructor(enclosingClass)
.newInstance(
getPlanLibrary().getCapability()
.getMyAgent());
} else if (Capability.class.isAssignableFrom(enclosingClass)) {
return planBodyClass.getDeclaredConstructor(enclosingClass)
.newInstance(getPlanLibrary().getCapability());
} else {
assert Plan.class.isAssignableFrom(enclosingClass);
return planBodyClass.getDeclaredConstructor(enclosingClass)
.newInstance(this);
}
} else {
return this.planBodyClass.newInstance();
}
} catch (Exception e) {
throw new PlanInstantiationException(e);
}
}
/**
* Returns the class of plan body of this plan, to be instantiated and
* executed.
*
* @return the planBodyClass
*/
public Class<? extends PlanBody> getPlanBodyClass() {
return planBodyClass;
}
}