📄 dfservice.java
字号:
@see #search(Agent a, AID dfName, DFAgentDescription dfd, SearchConstraints constraints)
**/
public static DFAgentDescription[] search(Agent a, DFAgentDescription dfd, SearchConstraints constraints) throws FIPAException {
return search(a,null,dfd,constraints);
}
/**
* The default DF is used.
* The default SearchConstraints are used. According to FIPA they are
* defaulted to null value for all slots.
@exception FIPAException
@see #search(Agent a, AID dfName, DFAgentDescription dfd, SearchConstraints constraints)
**/
public static DFAgentDescription[] search(Agent a, DFAgentDescription dfd) throws FIPAException {
return search(a,null,dfd,null);
}
/**
* The default SearchConstraints are used. According to FIPA they are
* defaulted to null value for all slots.
@exception FIPAException
@see #search(Agent a, AID dfName, DFAgentDescription dfd, SearchConstraints constraints)
**/
public static DFAgentDescription[] search(Agent a, AID dfName, DFAgentDescription dfd) throws FIPAException {
return search(a,dfName,dfd,null);
}
/**
Searches the DF and remains blocked until a result is found or the
specified timeout has expired.
@param a The agent that is performing the search
@param dfName The AID of the <b>DF</b> agent where to search into.
@param template A <code>DFAgentDescription</code> object that is used
as a template to identify the DF descriptions to search for.
@param constraints The constraints to limit the number of results to be
sent back.
@param timeout The maximum amount of time that we want to remain blocked
waiting for results.
@return The DF agent descriptions matching the specified template or
<code>null</code> if the timeout expires.
@exception FIPAException If a <code>REFUSE</code>,
<code>FAILURE</code> or <code>NOT_UNDERSTOOD</code>
message is received from the DF (to indicate some error condition)
or if the supplied DF-Description template is not valid.
*/
public static DFAgentDescription[] searchUntilFound(Agent a, AID dfName, DFAgentDescription dfd, SearchConstraints constraints, long timeout) throws FIPAException {
ACLMessage subscribe = createSubscriptionMessage(a, dfName, dfd, constraints);
ACLMessage inform = doFipaRequestClient(a, subscribe, timeout);
// Send the CANCEL message
ACLMessage cancel = createCancelMessage(a, dfName, subscribe);
a.send(cancel);
DFAgentDescription[] result = null;
if (inform != null) {
result = decodeNotification(inform.getContent());
}
return result;
}
///////////////////////////////////
// Message preparation methods
///////////////////////////////////
/**
Utility method that creates a suitable message to be used
to REQUEST a DF agent to perform a given action of the
FIPA-Management-ontology.
<p>
This method can be fruitfully used in combination with
the <code>jade.proto.AchieveREInitiator</code> protocol and with
the <code>decodeDone()</code> and <code>decodeResult()</code> methods
to interact with a DF in a non-blocking way.
@param a The agent that is requesting the DF
@param dfName The AID of the <b>DF</b> agent to send the request to.
@param action The name of the requested action. This must be one of
<ul>
<li><code>FIPAManagementVocabulary.REGISTER</code></li>
<li><code>FIPAManagementVocabulary.DEREGISTER</code></li>
<li><code>FIPAManagementVocabulary.MODIFY</code></li>
<li><code>FIPAManagementVocabulary.SEARCH</code></li>
</ul>
@param dfd A <code>DFAgentDescription</code> object. Depending on the
requested action, this is the description to register/deregister/modify
or a template to match data against during a search.
@param constraints The constraints to limit the number of results to be
notified. This is meaningful only if the requested action is SEARCH.
@return the request message.
@see jade.proto.AchieveREInitiator
@see #decodeDone(String)
@see #decodeResult(String)
*/
public static ACLMessage createRequestMessage(Agent a, AID dfName, String action, DFAgentDescription dfd, SearchConstraints constraints) {
ACLMessage request = createRequestMessage(a, dfName);
request.setContent(encodeAction(dfName, action, dfd, constraints));
return request;
}
/**
Utility method that creates a suitable message to be used
to SUBSCRIBE to a DF agent in order to receive notifications when a new
DF-Description matching the indicated template is registererd
with that DF.
<p>
This method can be fruitfully used in combination with
the <code>jade.proto.SubscriptionInitiator</code> protocol and with
the <code>createCancelMessage()</code> and <code>decodeNotification()</code>
methods to interact with a DF in a non-blocking way.
@param a The agent that is subscribing to the DF
@param dfName The AID of the <b>DF</b> agent to subscribe to.
@param template A <code>DFAgentDescription</code> object that is used
as a template to identify DF description that will be notified
@param constraints The constraints to limit the number of results to be
notified.
@return the subscription message.
@see jade.proto.SubscriptionInitiator
@see #createCancelMessage(Agent, AID, ACLMessage)
@see #decodeNotification(String)
*/
public static ACLMessage createSubscriptionMessage(Agent a, AID dfName, DFAgentDescription template, SearchConstraints constraints) {
ACLMessage subscribe = createRequestMessage(a, dfName);
subscribe.setPerformative(ACLMessage.SUBSCRIBE);
subscribe.setProtocol(FIPANames.InteractionProtocol.FIPA_SUBSCRIBE);
// Note that iota is not included in SL0
subscribe.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
subscribe.setContent(encodeIota(dfName, template, constraints));
return subscribe;
}
/**
@deprecated Use <code>createSubscriptionMessage()</code> instead
*/
public static ACLMessage getSubscriptionMessage(Agent a, AID dfName, DFAgentDescription template, SearchConstraints constraints) throws FIPAException {
return createSubscriptionMessage(a, dfName, template, constraints);
}
/**
Utility method that creates a suitable message to be used
to CANCEL a subscription to a DF agent.
@param a The agent that wants to cancel its subscription to the DF
@param dfName The AID of the <b>DF</b> agent.
@param subscribe The subscription message previously sent to the DF
@return the cancel message.
@see jade.proto.SubscriptionInitiator
@see #createSubscriptionMessage(Agent, AID, DFAgentDescription, SearchConstraints)
@see #decodeNotification(String)
*/
public static ACLMessage createCancelMessage(Agent a, AID dfName, ACLMessage subscribe) {
ACLMessage cancel = new ACLMessage(ACLMessage.CANCEL);
cancel.addReceiver(dfName);
cancel.setLanguage(subscribe.getLanguage());
cancel.setOntology(subscribe.getOntology());
cancel.setProtocol(subscribe.getProtocol());
cancel.setConversationId(subscribe.getConversationId());
cancel.setContent(encodeCancel(dfName, subscribe));
return cancel;
}
///////////////////////////////////
// Decoding methods
///////////////////////////////////
/**
Process the content of the final <code>inform (Done)</code> message
resulting from a <code>register</code> or <code>deregister</code>
action requested to a DF agent, extracting the
<code>df-agent-description</code> contained within.
@return The <code>DFAgentDescription</code> object included
in the "done" expression used as the content of the INFORM message
send back by the DF in response to a REQUEST to perform a register,
deregister or modify action.
@exception FIPAException If some error occurs while decoding
*/
public static DFAgentDescription decodeDone(String s) throws FIPAException {
// S has the form:
// ((done (action (AID...) (register (df-agent-description ....) ) ) ) )
// We skip until we find "df-agent-description" and start decoding from there.
try {
int start = s.indexOf(FIPAManagementVocabulary.DFAGENTDESCRIPTION);
return parseDfd(new SimpleSLTokenizer(s.substring(start)));
}
catch (Exception e) {
throw new FIPAException("Error decoding INFORM Done. "+e.getMessage());
}
}
/**
Process the content of the final <code>inform (result)</code> message resulting
from a <code>search</code> action requested to a DF agent, extracting the array of
<code>df-agent-description</code> contained within.
@return The <code>DFAgentDescription</code> objects (as an array) included
in the "result" expression used as the content of the INFORM message
send back by the DF in response to a REQUEST to perform a search action.
@exception FIPAException If some error occurs while decoding
*/
public static DFAgentDescription[] decodeResult(String s) throws FIPAException {
// S has the form:
// ((result (action...) (sequence (DFD...) (DFD...)) ) )
// We skip until we find "action", skip until the end of (action...) and start decoding from there.
try {
int start = s.indexOf(SL0Vocabulary.ACTION);
start += countUntilEnclosing(s, start);
return decodeDfdSequence(s.substring(start));
}
catch (Exception e) {
throw new FIPAException("Error decoding INFORM Result. "+e.getMessage());
}
}
/**
Process the content of the <code>inform</code> message resulting
from a subscription with a DF agent, extracting the array of
<code>df-agent-description</code> objects contained within.
@return The <code>DFAgentDescription</code> objects (as an array) included
in the "(= (iota...) ...)" expression used as the content of an INFORM message
sent back by the DF as a subscription notification.
@exception FIPAException If some error occurs while decoding
*/
public static DFAgentDescription[] decodeNotification(String s) throws FIPAException {
// S has the form:
// ((= (iota...) (sequence (DFD...) (DFD...)) ) )
// We skip until we find "iota", skip until the end of (iota...) and start decoding from there.
try {
int start = s.indexOf("iota");
start += countUntilEnclosing(s, start);
return decodeDfdSequence(s.substring(start));
}
catch (Exception e) {
throw new FIPAException("Error decoding INFORM Equals. "+e.getMessage());
}
}
/**
The parser content has the form:
df-agent-description ......) <possibly something else>
*/
private static DFAgentDescription parseDfd(SimpleSLTokenizer parser) throws Exception {
DFAgentDescription dfd = new DFAgentDescription();
// Skip "df-agent-description"
parser.getElement();
while (parser.nextToken().startsWith(":")) {
String slotName = parser.getElement();
// Name
if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_NAME)) {
parser.consumeChar('(');
dfd.setName(parseAID(parser));
}
// Lease time
else if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_LEASE_TIME)) {
dfd.setLeaseTime(ISO8601.toDate(parser.getElement()));
}
// Protocols
else if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_PROTOCOLS)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
dfd.addProtocols((String) it.next());
}
}
// Languages
else if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_LANGUAGES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
dfd.addLanguages((String) it.next());
}
}
// Ontologies
else if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_ONTOLOGIES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
dfd.addOntologies((String) it.next());
}
}
// Services
else if (slotName.equals(FIPAManagementVocabulary.DFAGENTDESCRIPTION_SERVICES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
dfd.addServices((ServiceDescription) it.next());
}
}
}
parser.consumeChar(')');
return dfd;
}
/**
The parser content has the form:
service-description ......) <possibly something else>
*/
private static ServiceDescription parseServiceDescription(SimpleSLTokenizer parser) throws Exception {
ServiceDescription sd = new ServiceDescription();
// Skip "service-description"
parser.getElement();
while (parser.nextToken().startsWith(":")) {
String slotName = parser.getElement();
// Name
if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_NAME)) {
sd.setName(parser.getElement());
}
// Type
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_TYPE)) {
sd.setType(parser.getElement());
}
// Ownership
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_OWNERSHIP)) {
sd.setOwnership(parser.getElement());
}
// Protocols
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_PROTOCOLS)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
sd.addProtocols((String) it.next());
}
}
// Languages
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_LANGUAGES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
sd.addLanguages((String) it.next());
}
}
// Ontologies
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_ONTOLOGIES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
sd.addOntologies((String) it.next());
}
}
// Properties
else if (slotName.equals(FIPAManagementVocabulary.SERVICEDESCRIPTION_PROPERTIES)) {
Iterator it = parseAggregate(parser).iterator();
while (it.hasNext()) {
sd.addProperties((Property) it.next());
}
}
}
parser.consumeChar(')');
return sd;
}
/**
The parser content has the form:
property ......) <possibly something else>
*/
private static Property parseProperty(SimpleSLTokenizer parser) throws Exception {
Property p = new Property();
// Skip "property"
parser.getElement();
while (parser.nextToken().startsWith(":")) {
String slotName = parser.getElement();
// Name
if (slotName.equals(FIPAManagementVocabulary.PROPERTY_NAME)) {
p.setName(parser.getElement());
}
// Name
if (slotName.equals(FIPAManagementVocabulary.PROPERTY_VALUE)) {
p.setValue(parser.getElement());
}
}
parser.consumeChar(')');
return p;
}
/**
The parser content has the form:
agent-identifier ......) <possibly something else>
*/
public static AID parseAID(SimpleSLTokenizer parser) throws Exception {
AID id = new AID("", AID.ISGUID); // Dummy temporary name
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -