mirror of
https://github.com/balkian/SOJA.git
synced 2024-12-27 04:08:12 +00:00
Initial commit
This commit is contained in:
commit
0017e5efda
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build.properties
|
19
Web40SOJason.mas2j
Normal file
19
Web40SOJason.mas2j
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Jason Project
|
||||
|
||||
-- create on March 19, 2012
|
||||
*/
|
||||
|
||||
MAS web40sojason {
|
||||
infrastructure: Centralised
|
||||
|
||||
environment: es.upm.dit.gsi.sojason.SOEnvironment
|
||||
|
||||
agents:
|
||||
userAgent;
|
||||
travelAgent;
|
||||
commonSenseAgent;
|
||||
nluAgent;
|
||||
|
||||
aslSourcePath: "src/asl";
|
||||
}
|
107
bin/build.xml
Normal file
107
bin/build.xml
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!--
|
||||
|
||||
This file was generated by Jason 1.3.6a
|
||||
http://jason.sf.net
|
||||
|
||||
March 20, 2012 - 16:30:55
|
||||
-->
|
||||
|
||||
<project name ="web40sojason"
|
||||
basedir=".."
|
||||
default="run">
|
||||
|
||||
<property name="mas2j.project.file" value="Web40SOJason.mas2j"/>
|
||||
<property name="debug" value=""/> <!-- use "-debug" to run in debug mode -->
|
||||
<property name="build.dir" value="${basedir}/bin/classes" />
|
||||
|
||||
<property name="jasonJar" value="/home/miguel/trabajo/Jason-1.3.6a/lib/jason.jar"/>
|
||||
|
||||
<path id="project.classpath">
|
||||
<pathelement location="${basedir}"/>
|
||||
<pathelement location="${build.dir}"/>
|
||||
<pathelement location="${jasonJar}"/>
|
||||
<fileset dir="${basedir}/lib" > <include name="*.jar" /> </fileset>
|
||||
|
||||
</path>
|
||||
|
||||
<!-- tasks the user can override in his/her c-build.xml script -->
|
||||
<target name="user-init">
|
||||
</target>
|
||||
<target name="user-end">
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${build.dir}" />
|
||||
<antcall target="user-init" />
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<condition property="srcdir" value="${basedir}/src/java" else="${basedir}" >
|
||||
<available file="${basedir}/src/java" />
|
||||
</condition>
|
||||
<javac srcdir="${srcdir}" destdir="${build.dir}" debug="true" optimize="true" includeantruntime="false" >
|
||||
<classpath refid="project.classpath"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile">
|
||||
<delete file="${ant.project.name}.jar" />
|
||||
<copy file="${jasonJar}" tofile="${ant.project.name}.jar" />
|
||||
<copy file="${mas2j.project.file}" tofile="default.mas2j" />
|
||||
<jar update="yes" jarfile="${ant.project.name}.jar" >
|
||||
<fileset dir="${basedir}">
|
||||
<include name="**/*.asl" />
|
||||
<include name="**/*.mas2j" />
|
||||
</fileset>
|
||||
<fileset dir="${build.dir}">
|
||||
<include name="**/*.class" />
|
||||
</fileset>
|
||||
</jar>
|
||||
<delete file="default.mas2j" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="jnlp" depends="jar" >
|
||||
<mkdir dir="${basedir}/${ant.project.name}-jws"/>
|
||||
<java classname="jason.infra.centralised.CreateJNLP"
|
||||
failonerror="true" fork="yes" dir="${basedir}/${ant.project.name}-jws" >
|
||||
<classpath refid="project.classpath"/>
|
||||
<arg line="${ant.project.name} ${mas2j.project.file}"/>
|
||||
</java>
|
||||
<copy todir="${basedir}/${ant.project.name}-jws" failonerror="no">
|
||||
<fileset dir="${basedir}/lib" includes="**/*.jar" />
|
||||
<fileset dir="${basedir}" includes="${ant.project.name}.jar" />
|
||||
<fileset dir="/home/miguel/trabajo/Jason-1.3.6a/src/images" includes="Jason-GMoreau-Icon.jpg" />
|
||||
</copy>
|
||||
<signjar jar="${basedir}/${ant.project.name}-jws/${ant.project.name}.jar" alias="jason"
|
||||
storepass="rbjhja" keypass="rbjhja" keystore="/home/miguel/trabajo/Jason-1.3.6a/src/jasonKeystore" />
|
||||
<echo message="**" />
|
||||
<echo message="** Java Web Start application created in directory ${ant.project.name}-jws" />
|
||||
<echo message="** Update the codebase (in the second line of the .jnlp file)" />
|
||||
<echo message="** with the URL where you will upload the application." />
|
||||
<echo message="**" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="run" depends="compile" >
|
||||
<echo message="Running project ${ant.project.name}" />
|
||||
<java classname="jason.infra.centralised.RunCentralisedMAS"
|
||||
failonerror="true" fork="yes" dir="${basedir}" >
|
||||
<classpath refid="project.classpath"/>
|
||||
<arg line="${mas2j.project.file} ${debug} "/>
|
||||
<!-- jvmarg line="-Xmx500M -Xss8M"/ -->
|
||||
</java>
|
||||
<antcall target="user-end" />
|
||||
</target>
|
||||
|
||||
<target name="clean" >
|
||||
<delete failonerror="no" includeEmptyDirs="true" verbose="true">
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
</project>
|
BIN
bin/classes/es/upm/dit/gsi/jason/utils/CollectionUtils.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/jason/utils/CollectionUtils.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/jason/utils/NotationUtils.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/jason/utils/NotationUtils.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/SOEnvironment.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/SOEnvironment.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/SOModel.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/SOModel.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/Web40Model.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/Web40Model.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/ErrorReport.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/ErrorReport.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/Journey.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/Journey.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/NLUTravel.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/NLUTravel.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/Perceptable.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/Perceptable.class
Normal file
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/TravelType.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/beans/TravelType.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/classes/es/upm/dit/gsi/sojason/services/nlu/NLUModel.class
Normal file
BIN
bin/classes/es/upm/dit/gsi/sojason/services/nlu/NLUModel.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
152
conf/cities.xml
Normal file
152
conf/cities.xml
Normal file
@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
|
||||
<properties>
|
||||
<comment>Renfe city codes</comment>
|
||||
<entry key="ciudad real">37200</entry>
|
||||
<entry key="bilbao">13200 </entry>
|
||||
<entry key="almeria">56312</entry>
|
||||
<entry key="lisboa">LISBO</entry>
|
||||
<entry key="león">15100</entry>
|
||||
<entry key="bardonecchia">83005</entry>
|
||||
<entry key="puerto santa maría">51400</entry>
|
||||
<entry key="a coruña">31412 </entry>
|
||||
<entry key="monforte de lemos">20300</entry>
|
||||
<entry key="pontevedra">23004</entry>
|
||||
<entry key="albacete">60911 </entry>
|
||||
<entry key="berna">85031</entry>
|
||||
<entry key="valdepeñas">50102</entry>
|
||||
<entry key="benicassim">65318</entry>
|
||||
<entry key="málaga">54413</entry>
|
||||
<entry key="linares-baeza">50300</entry>
|
||||
<entry key="tarragona">82100</entry>
|
||||
<entry key="teruel">67200</entry>
|
||||
<entry key="cartagena">61307</entry>
|
||||
<entry key="cádiz">51405</entry>
|
||||
<entry key="jaen">03100</entry>
|
||||
<entry key="cuenca">CUENC</entry>
|
||||
<entry key="turín">83002</entry>
|
||||
<entry key="córdoba">50500</entry>
|
||||
<entry key="entroncamento">94428</entry>
|
||||
<entry key="burgos rosa de lima">11014 </entry>
|
||||
<entry key="alacant">60911</entry>
|
||||
<entry key="marvao-beira">94401</entry>
|
||||
<entry key="malaga">54413</entry>
|
||||
<entry key="sahagún">15009</entry>
|
||||
<entry key="gasteiz">11208</entry>
|
||||
<entry key="ginebra">85444</entry>
|
||||
<entry key="cordoba">50500</entry>
|
||||
<entry key="irún">11600</entry>
|
||||
<entry key="ferrol">21010</entry>
|
||||
<entry key="santander">14223</entry>
|
||||
<entry key="toledo">92102</entry>
|
||||
<entry key="caceres">35400</entry>
|
||||
<entry key="cáceres">35400</entry>
|
||||
<entry key="lugo">20309</entry>
|
||||
<entry key="friburgo">85410</entry>
|
||||
<entry key="la coruña">31412</entry>
|
||||
<entry key="utiel">03213</entry>
|
||||
<entry key="zaragoza">ZARAG</entry>
|
||||
<entry key="burgos">11014 </entry>
|
||||
<entry key="figueres">04307</entry>
|
||||
<entry key="salamanca">SALAM</entry>
|
||||
<entry key="elda-petrer">60905</entry>
|
||||
<entry key="alicante">60911</entry>
|
||||
<entry key="oviedo">15211</entry>
|
||||
<entry key="mérida">37500</entry>
|
||||
<entry key="lorca">06006</entry>
|
||||
<entry key="bern">85031</entry>
|
||||
<entry key="puente genil">PTE G</entry>
|
||||
<entry key="milano">83111</entry>
|
||||
<entry key="beira">94401</entry>
|
||||
<entry key="abrantes">94707</entry>
|
||||
<entry key="barcelona">BARCE </entry>
|
||||
<entry key="almería">56312</entry>
|
||||
<entry key="valencia">VALEN</entry>
|
||||
<entry key="castello">65300</entry>
|
||||
<entry key="figueres vilafant">04307</entry>
|
||||
<entry key="gandia">69110</entry>
|
||||
<entry key="requena">03213</entry>
|
||||
<entry key="badajoz">37606 </entry>
|
||||
<entry key="cadiz">51405</entry>
|
||||
<entry key="castellon">65300</entry>
|
||||
<entry key="zurich">85200</entry>
|
||||
<entry key="jaén">03100</entry>
|
||||
<entry key="orleans-les aubrais">87004</entry>
|
||||
<entry key="valladolid">10600</entry>
|
||||
<entry key="blois">87546 </entry>
|
||||
<entry key="lleida">78400</entry>
|
||||
<entry key="gijon">GIJON</entry>
|
||||
<entry key="algeciras">55020 </entry>
|
||||
<entry key="vigo">Guixar=22308</entry>
|
||||
<entry key="logroño">81100</entry>
|
||||
<entry key="monzon-rio cinca">78301</entry>
|
||||
<entry key="merida">37500</entry>
|
||||
<entry key="paris austerlitz">87011</entry>
|
||||
<entry key="reus">71400</entry>
|
||||
<entry key="fribourg">85410</entry>
|
||||
<entry key="san sebastián">11511</entry>
|
||||
<entry key="tudela de navarra">81202</entry>
|
||||
<entry key="milán">83111</entry>
|
||||
<entry key="palencia">14100</entry>
|
||||
<entry key="málaga maría zambrano">54413</entry>
|
||||
<entry key="coruña">31412</entry>
|
||||
<entry key="bilbao-abando">13200 </entry>
|
||||
<entry key="lorca-sutullena">06006</entry>
|
||||
<entry key="paris">87011</entry>
|
||||
<entry key="madrid">MADRI</entry>
|
||||
<entry key="monzón-río cinca">78301</entry>
|
||||
<entry key="guadalajara">GUADA</entry>
|
||||
<entry key="xàtiva">64100</entry>
|
||||
<entry key="murcia">61200</entry>
|
||||
<entry key="navalmoral de la mata">35206</entry>
|
||||
<entry key="torino">83002</entry>
|
||||
<entry key="segovia">SEGOV</entry>
|
||||
<entry key="geneve">85444</entry>
|
||||
<entry key="parís austerlitz">87011</entry>
|
||||
<entry key="gandía">69110</entry>
|
||||
<entry key="bobadilla">54400 </entry>
|
||||
<entry key="orleans">87004</entry>
|
||||
<entry key="leon">15100</entry>
|
||||
<entry key="castellón">65300</entry>
|
||||
<entry key="puerto santa maria">51400</entry>
|
||||
<entry key="alcázar de san juan">60400 </entry>
|
||||
<entry key="zamora">30200</entry>
|
||||
<entry key="santiago de compostela">31400</entry>
|
||||
<entry key="antequera">ANTEQ</entry>
|
||||
<entry key="montpellier">87173</entry>
|
||||
<entry key="donostia">11511</entry>
|
||||
<entry key="pamplona">80100</entry>
|
||||
<entry key="villena">60902</entry>
|
||||
<entry key="orpesa">65304</entry>
|
||||
<entry key="novara">83008</entry>
|
||||
<entry key="avila">10400 </entry>
|
||||
<entry key="iruña">80100</entry>
|
||||
<entry key="granada">05000</entry>
|
||||
<entry key="gijón">GIJON</entry>
|
||||
<entry key="ourense">22100</entry>
|
||||
<entry key="turin">83002</entry>
|
||||
<entry key="soria">82100</entry>
|
||||
<entry key="puertollano">37300</entry>
|
||||
<entry key="oropesa">65304</entry>
|
||||
<entry key="huesca">74200</entry>
|
||||
<entry key="san sebastian">11511</entry>
|
||||
<entry key="hendaya">11602</entry>
|
||||
<entry key="milan">83111</entry>
|
||||
<entry key="ponferrada">20200</entry>
|
||||
<entry key="huelva">43019</entry>
|
||||
<entry key="portbou">79315</entry>
|
||||
<entry key="alcazar de san juan">60400 </entry>
|
||||
<entry key="parís">87011</entry>
|
||||
<entry key="malaga maria zambrano">54413</entry>
|
||||
<entry key="vitoria">11208</entry>
|
||||
<entry key="sahagun">15009</entry>
|
||||
<entry key="miranda de ebro">11200</entry>
|
||||
<entry key="irun">11600</entry>
|
||||
<entry key="medina del campo">10500</entry>
|
||||
<entry key="calatayud">70600</entry>
|
||||
<entry key="girona">79300</entry>
|
||||
<entry key="sevilla">51003</entry>
|
||||
<entry key="jerez de la frontera">51300</entry>
|
||||
<entry key="limoges">87034</entry>
|
||||
<entry key="castelló">65300</entry>
|
||||
</properties>
|
BIN
lib/jackson-all-1.8.8.jar
Normal file
BIN
lib/jackson-all-1.8.8.jar
Normal file
Binary file not shown.
BIN
lib/json-lib-2.4-jdk15.jar
Normal file
BIN
lib/json-lib-2.4-jdk15.jar
Normal file
Binary file not shown.
BIN
lib/jsoup-1.6.1.jar
Normal file
BIN
lib/jsoup-1.6.1.jar
Normal file
Binary file not shown.
8
src/asl/commonSenseAgent.asl
Normal file
8
src/asl/commonSenseAgent.asl
Normal file
@ -0,0 +1,8 @@
|
||||
// Agent userAgent in project Web40
|
||||
|
||||
/* Initial beliefs and rules */
|
||||
|
||||
/* Initial goals */
|
||||
|
||||
|
||||
/* Plans */
|
40
src/asl/nluAgent.asl
Normal file
40
src/asl/nluAgent.asl
Normal file
@ -0,0 +1,40 @@
|
||||
// Agent nluAgent in project Web40SOJason
|
||||
|
||||
/* Initial beliefs and rules */
|
||||
|
||||
/* Initial goals */
|
||||
|
||||
/* Plans */
|
||||
|
||||
@in_msg
|
||||
+user_msg(Msg, Query) : true
|
||||
<- sendNLU(Query, Msg);
|
||||
-user_msg(Msg, Query). // clear the memory
|
||||
|
||||
|
||||
/* Tell the user agent what the NLU system understood */
|
||||
+price(Terms, Price)[query(Query), domain(travel)] : true
|
||||
<- .send(userAgent, tell, price(Terms, Price)[query(Query)], domain(travel));
|
||||
.print("Percibido: price ",Terms, " ", Price ).
|
||||
|
||||
+date(Terms, Day, Month, Year)[query(Query), domain(travel)] : true
|
||||
<- .send(userAgent, tell, date(Terms, Day, Month, Year)[query(Query), domain(travel)]);
|
||||
.print("Percibido: date ",Terms, " ", Day, " ", Month, " ", Year).
|
||||
|
||||
+time(Terms, Hours, Minutes)[query(Query), domain(travel)] : true
|
||||
<- .send(userAgent, tell, time(Terms, Hours, Minutes)[query(Query), domain(travel)]);
|
||||
.print("Percibido: time ",Terms, " ", Hours, " ", Minutes).
|
||||
|
||||
+location(Terms, Place)[query(Query), domain(travel)] : true
|
||||
<- .send(userAgent, tell, location(Terms, Place)[query(Query), domain(travel)]);
|
||||
.print("Percibido: location ",Terms, " ", Place).
|
||||
|
||||
+type(Terms)[query(Query), domain(travel)] : true
|
||||
<- .send(userAgent, tell, type(Terms)[query(Query), domain(travel)]);
|
||||
.print("Percibido: type ",Terms).
|
||||
|
||||
@sendFindTravel
|
||||
+done[query(Query), domain(Domain)] : true
|
||||
<- .wait(1000); // wait until all other information is sent
|
||||
.print("Percepcion completada");
|
||||
.send(userAgent, achieve, find(Domain, Query)).
|
60
src/asl/travelAgent.asl
Normal file
60
src/asl/travelAgent.asl
Normal file
@ -0,0 +1,60 @@
|
||||
// Agent travelAgent in project Web40
|
||||
|
||||
/* Initial beliefs and rules */
|
||||
canFindTravel(Query)
|
||||
:- location(from,_)[query(Query)] &
|
||||
location(to,_)[query(Query)] &
|
||||
date(departure,_,_,_)[query(Query)].
|
||||
|
||||
/* Initial goals */
|
||||
contact(userAgent).
|
||||
my_service(travel).
|
||||
my_service(train).
|
||||
|
||||
/************** Plans *****************/
|
||||
|
||||
/* Introduce myself to the user agent */
|
||||
@introduce_myself
|
||||
+my_service(Domain)
|
||||
: contact(Agent) & .my_name(Me)
|
||||
<- .send(Agent, tell, service(Me, Domain)).
|
||||
|
||||
@introduction_rety
|
||||
+my_service(Domain) : not contact(Agent)
|
||||
<- -+my_service(Domain).
|
||||
|
||||
|
||||
/* Find travel plans */
|
||||
@findTravel1
|
||||
+!find(travel, Query) : not canFindTravel(Query) & not delay(Query)
|
||||
<- .print("Not enought data. Lets wait some time");
|
||||
.wait(3000);
|
||||
+delay(Query);
|
||||
!find(travel, Query).
|
||||
|
||||
@findTravel2
|
||||
+!find(travel, Query) : not canFindTravel(Query) & delay(Query)
|
||||
<- -delay(Query);
|
||||
.print("Not enought data. Lets ask!").
|
||||
|
||||
@findTravel3
|
||||
+!find(travel, Query) : canFindTravel(Query)
|
||||
<- ?location(to, To);
|
||||
?location(from, From);
|
||||
?date(departure, Day, Month, Year);
|
||||
findTravel(From, To, Day, Month, Year);
|
||||
.print("ok").
|
||||
|
||||
@findTravelFailureRety
|
||||
-!find(travel, Query) : not error(Msg, Query)<- !findTravel(Query).
|
||||
|
||||
@findTravelFailureError
|
||||
-!find(travel, Query) : error(Msg, Query)
|
||||
<- .print("Problema al encontrar viajes:", Msg);
|
||||
!findTravel(Query).
|
||||
|
||||
|
||||
/* log results */
|
||||
@log_the_journey
|
||||
+journey(From, To, Departure, Arrival, Fares) : true
|
||||
<- .print("Travel found: From ", From,"<", Departure, "> to ", To, "<", Arrival, "> for ", Fares).
|
56
src/asl/userAgent.asl
Normal file
56
src/asl/userAgent.asl
Normal file
@ -0,0 +1,56 @@
|
||||
// Agent userAgent in project Web40
|
||||
|
||||
/* Initial beliefs and rules */
|
||||
new_query(Query) :- .random(R) & Query = (1000*R)+1.
|
||||
|
||||
!start.
|
||||
|
||||
/* Initial goals */
|
||||
|
||||
/******* Plans ***************************/
|
||||
|
||||
/* Wait for service introduction (temporal plan, to erase) */
|
||||
+!start : true
|
||||
<- .wait(1000);
|
||||
+user_msg("I want to travel from Madrid to Cuenca in the morning that costs no more than 200€ and dinner in a romantic restaurant").
|
||||
|
||||
|
||||
/* Ask the nlu agent */
|
||||
+user_msg(Msg) : new_query(Query)
|
||||
<- .send(nluAgent, tell, user_msg(Msg, Query) ).
|
||||
|
||||
/* Log the received data */
|
||||
+price(Terms, Price)[query(Query), domain(Domain)] : true
|
||||
<- .print("Percibido: price ",Terms, " ", Price );
|
||||
+data(price(Terms), Query, Domain).
|
||||
|
||||
+date(Terms, Day, Month, Year)[query(Query), domain(Domain)] : true
|
||||
<- .print("Percibido: date ",Terms, " ", Day, " ", Month, " ", Year);
|
||||
+data(date(Terms, Day, Month, Year), Query, Domain).
|
||||
|
||||
+time(Terms, Hours, Minutes)[query(Query), domain(Domain)] : true
|
||||
<- .print("Percibido: time ",Terms, " ", Hours, " ", Minutes);
|
||||
+data(time(Terms, Hours, Minutes), Query, Domain).
|
||||
|
||||
+location(Terms, Place)[query(Query), domain(Domain)] : true
|
||||
<- .print("Percibido: location ",Terms, " ", Place);
|
||||
+data(location(Terms, Place), Query, Domain).
|
||||
|
||||
+type(Terms)[query(Query), domain(Domain)] : true
|
||||
<- .print("Percibido: type ",Terms).
|
||||
|
||||
/* find travel */
|
||||
/*@find_travel
|
||||
+!find(travel, Query) : true
|
||||
<- .println("lets find travel ", Query);
|
||||
.findall(Name, service(Name, travel), List);
|
||||
.send(List, achieve, find(travel, Query)).
|
||||
*/
|
||||
|
||||
@do_search
|
||||
+!find(Domain, Query) : true
|
||||
<- .print("Perform find ", Domain, " ", Query);
|
||||
.findall(Name, service(Name, Domain), AgList);
|
||||
.findall(Atom[query(Query)], data(Atom, Query, Domain), DataList);
|
||||
.send(AgList, tell, DataList);
|
||||
.send(AgList, achieve, find(Domain, Query)).
|
87
src/java/es/upm/dit/gsi/jason/utils/CollectionUtils.java
Normal file
87
src/java/es/upm/dit/gsi/jason/utils/CollectionUtils.java
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.jason.utils;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
*
|
||||
* Project: Web40SOJason
|
||||
* Package: es.upm.dit.gsi.jason.utils
|
||||
* Class: CollectionUtils
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Mar 9, 2012
|
||||
*
|
||||
*/
|
||||
public abstract class CollectionUtils {
|
||||
|
||||
/**
|
||||
* This wraps a Literal in a collection
|
||||
* @param literal The literal
|
||||
* @return Collection containing the literal given
|
||||
*/
|
||||
public static Collection<Literal> wrapList(Literal literal) {
|
||||
Collection<Literal> res = new LinkedList<Literal>();
|
||||
res.add(literal);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* This wraps a Literal in a collection
|
||||
* @param literal The string that represents a literal
|
||||
* @return Collection containing the literal given
|
||||
*/
|
||||
public static Collection<Literal> wrapList(String literal) {
|
||||
Collection<Literal> res = new LinkedList<Literal>();
|
||||
res.add(Literal.parseLiteral(literal));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* This
|
||||
* @param collection
|
||||
* @return
|
||||
*/
|
||||
public static String[] toStringArray (Collection<? extends Object> collection){
|
||||
String[] strArray = new String[collection.size()];
|
||||
|
||||
int index = 0;
|
||||
for(Object obj : collection){
|
||||
if(obj == null) {
|
||||
strArray[index] = "null";
|
||||
}
|
||||
else {
|
||||
strArray[index] = obj.toString();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return strArray;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param items
|
||||
* @return
|
||||
*/
|
||||
public static String[] toStringArray (Object[] items){
|
||||
String[] strArray = new String[items.length];
|
||||
|
||||
for(int index = 0; index < items.length; index++){
|
||||
Object obj = items[index];
|
||||
if(obj == null){
|
||||
strArray[index] = "null";
|
||||
}
|
||||
else{
|
||||
strArray[index] = items[index].toString();
|
||||
}
|
||||
}
|
||||
|
||||
return strArray;
|
||||
}
|
||||
}
|
83
src/java/es/upm/dit/gsi/jason/utils/NotationUtils.java
Normal file
83
src/java/es/upm/dit/gsi/jason/utils/NotationUtils.java
Normal file
@ -0,0 +1,83 @@
|
||||
package es.upm.dit.gsi.jason.utils;
|
||||
|
||||
|
||||
/**
|
||||
* This Utils class is used to validate string according to the Jason atom
|
||||
* notation criteria, and transform an invalid notation into a valid one
|
||||
* and vice versa.
|
||||
*
|
||||
* This is useful in some context where the agents need to interact with an
|
||||
* uncontrollable environment such as the Web.
|
||||
*
|
||||
* In Jason notation, white-spaces are not allowed, neither, words that starts
|
||||
* with capital letter.
|
||||
*
|
||||
* @author gsi.dit.upm.es
|
||||
*
|
||||
*/
|
||||
public class NotationUtils {
|
||||
|
||||
/**
|
||||
* @param toCheck
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidAtom (String toCheck) {
|
||||
String lowerCase = toCheck.toLowerCase();
|
||||
return !toCheck.contains(" ") && !toCheck.contains(",") && toCheck.equals(lowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param toCheck
|
||||
* @return
|
||||
*/
|
||||
public static boolean isCompactable (String toCheck) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String compact(String str) {
|
||||
|
||||
if (isValidAtom (str)) {return str;}
|
||||
if (!isCompactable(str)) {return null;}
|
||||
|
||||
str = str.replace("_", "___");
|
||||
str = str.replace(" ", "_");
|
||||
str = str.replace("ñ", "n");
|
||||
return str.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String uncompact(String str) {
|
||||
str = str.replace("___", "#");
|
||||
str = str.replace("_", " ");
|
||||
str = str.replace("#", " ");
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This removes the quotation mark from the string given. If that
|
||||
* string has no quotation marks it returned trimmed.</p>
|
||||
*
|
||||
* <p>The quotation marks are only removed from the beginning and the
|
||||
* end of the string, so any quotation mark inserted in the middle of
|
||||
* the string will be kept.</p>
|
||||
*
|
||||
* @return the string without the quotation marks
|
||||
*/
|
||||
public static String removeQuotation (String str) {
|
||||
String message = str.trim();
|
||||
if(message.startsWith("\"")) message = message.substring(1);
|
||||
if(message.endsWith("\"")) message = message.substring(0, message.length()-1);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
94
src/java/es/upm/dit/gsi/sojason/SOEnvironment.java
Normal file
94
src/java/es/upm/dit/gsi/sojason/SOEnvironment.java
Normal file
@ -0,0 +1,94 @@
|
||||
package es.upm.dit.gsi.sojason;
|
||||
// Environment code for project Web40SOJason
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
import jason.asSyntax.Structure;
|
||||
import jason.asSyntax.Term;
|
||||
import jason.environment.Environment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This represents a Software Oriented Environment.
|
||||
* It overrides the getPercepts method so every time the agent perceives
|
||||
* it checks the model to update the percepts for the particular agent.
|
||||
*
|
||||
* Project: Web40SOJason
|
||||
* Package: es.upm.dit.gsi.sojason
|
||||
* Class: SOEnvironment
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Mar 9, 2012
|
||||
*
|
||||
*/
|
||||
public class SOEnvironment extends Environment {
|
||||
|
||||
/** The logger */
|
||||
private Logger logger = Logger.getLogger("Web40SOJason." + SOEnvironment.class.getName());
|
||||
|
||||
/** The model */
|
||||
public Web40Model model;
|
||||
|
||||
/** Called before the MAS execution with the args informed in .mas2j */
|
||||
@Override
|
||||
public void init(String[] args) {
|
||||
super.init(args);
|
||||
try {
|
||||
this.model = new Web40Model();
|
||||
} catch (IOException e) {
|
||||
addPercept(Literal.parseLiteral("error(\"Could not inatantiate the model\")"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeAction(String agName, Structure action) {
|
||||
logger.info("executing: " + action + " (" + agName + ")");
|
||||
|
||||
// select the external action
|
||||
boolean result = false;
|
||||
String functor = action.getFunctor();
|
||||
List<Term> terms = action.getTerms();
|
||||
|
||||
if (functor.equals("sendNLU")) {
|
||||
result = this.model.sendNlu(agName, terms);
|
||||
}
|
||||
else if (functor.equals("findTravel")) {
|
||||
result = this.model.findTravel(agName, terms);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
logger.info(action + " was not implemented.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Called before the end of MAS execution */
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
}
|
||||
|
||||
/** */
|
||||
@Override
|
||||
public List<Literal> getPercepts(String agName) {
|
||||
updatePerceptsForAg(agName);
|
||||
return super.getPercepts(agName);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param agName
|
||||
*/
|
||||
public void updatePerceptsForAg (String agName) {
|
||||
clearPercepts(agName);
|
||||
Collection<Literal> literals = model.getDataFromInbox(agName);
|
||||
for(Literal literal : literals){
|
||||
addPercept(agName, literal);
|
||||
}
|
||||
}
|
||||
}
|
106
src/java/es/upm/dit/gsi/sojason/SOModel.java
Normal file
106
src/java/es/upm/dit/gsi/sojason/SOModel.java
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.sojason;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Project: Web40SOJason
|
||||
* Package: es.upm.dit.gsi.sojason
|
||||
* Class: SOModel
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Mar 9, 2012
|
||||
*
|
||||
*/
|
||||
abstract public class SOModel {
|
||||
|
||||
/**
|
||||
* This contains the data that will be
|
||||
*/
|
||||
private Map<String, Set<Literal>> serviceDataInbox;
|
||||
|
||||
/**
|
||||
* Constructor. Just initializes attributes.
|
||||
*/
|
||||
public SOModel(){
|
||||
this.serviceDataInbox = Collections.synchronizedMap(new HashMap<String, Set<Literal>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This puts data into the <code>serviceDataInbox</code> for a
|
||||
* particular agent. The data loaded will be appended into the already
|
||||
* existing data if any.</p>
|
||||
*
|
||||
* <p>The data from the <code>serviceDataInbox</code> is removed as
|
||||
* described in the documentation of {@link #getDataFromInbox(String)}</p>
|
||||
*
|
||||
* @param agName The name of the agent.
|
||||
* @param serviceData The service-data.
|
||||
*/
|
||||
public void setDataInbox (String agName, Collection<Literal> serviceData){
|
||||
|
||||
synchronized (serviceDataInbox) {
|
||||
if (!this.serviceDataInbox.containsKey(agName)) {
|
||||
Set<Literal> set = new HashSet<Literal>();
|
||||
set.addAll(serviceData); // create a set and add all the collection
|
||||
this.serviceDataInbox.put(agName, set);
|
||||
return;
|
||||
}
|
||||
|
||||
// There is no data in the inbox for the agent given
|
||||
Set<Literal> set = this.serviceDataInbox.get(agName);
|
||||
set.addAll(serviceData);
|
||||
this.serviceDataInbox.put(agName, set);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This provides a different way to call the method
|
||||
* {@linkplain #setDataInbox(String, Collection)} with a single literal
|
||||
* instead of a collection of literals.</p>
|
||||
*
|
||||
* @param agName the name of the agent.
|
||||
* @param literal the literal.
|
||||
*/
|
||||
public void setDataInbox (String agName, Literal literal) {
|
||||
Set <Literal> set = new HashSet<Literal>();
|
||||
set.add(literal);
|
||||
setDataInbox(agName, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This gets from the <code>serviceDataInbox</code> the data stored for
|
||||
* the agent given. It will remove the data from the inbox, so two consequent
|
||||
* invocations of this method will return different results, actually, if no
|
||||
* new data is put, the second invocation will return no data.</p>
|
||||
*
|
||||
* <p>So, it is important to point out this method empties the
|
||||
* <code>serviceDataInbox</code>.</p>
|
||||
*
|
||||
* <p>This method never returns null to avoid null pointer</p>
|
||||
*
|
||||
* @param agName the name of the agent who data will be retrieved from
|
||||
* the inbox
|
||||
* @return The data retrieved
|
||||
*/
|
||||
public Collection<Literal> getDataFromInbox (String agName) {
|
||||
if (!this.serviceDataInbox.containsKey(agName)){
|
||||
return new HashSet<Literal>();
|
||||
}
|
||||
// return this.serviceDataInbox.get(agName);
|
||||
return this.serviceDataInbox.remove(agName);
|
||||
}
|
||||
|
||||
}
|
98
src/java/es/upm/dit/gsi/sojason/Web40Model.java
Normal file
98
src/java/es/upm/dit/gsi/sojason/Web40Model.java
Normal file
@ -0,0 +1,98 @@
|
||||
package es.upm.dit.gsi.sojason;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
import jason.asSyntax.Term;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.CollectionUtils;
|
||||
import es.upm.dit.gsi.sojason.services.nlu.NLUConnector;
|
||||
import es.upm.dit.gsi.sojason.services.travel.RenfeScrapper;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Project: Web40
|
||||
* Package: es.upm.dit.gsi.qa
|
||||
* Class: Web40Model
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Feb 29, 2012
|
||||
*
|
||||
*/
|
||||
public class Web40Model extends SOModel{
|
||||
|
||||
/** */
|
||||
public final static String NLU_SERVICE_URL = "http://46.4.52.82:3333/nlu";
|
||||
/** */
|
||||
private NLUConnector nluConnector;
|
||||
/** */
|
||||
private RenfeScrapper renfeScrapper;
|
||||
/** */
|
||||
private Logger logger = Logger.getLogger("Web40SOJason." + Web40Model.class.getName());
|
||||
|
||||
/** Constructor
|
||||
* @throws IOException */
|
||||
public Web40Model () throws IOException {
|
||||
super();
|
||||
this.nluConnector = new NLUConnector(NLU_SERVICE_URL);
|
||||
this.renfeScrapper = new RenfeScrapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* This calls the NLU service
|
||||
*
|
||||
* Internally this modifies the model so it reports the agent
|
||||
*
|
||||
* @param agName the name of the agent that will be reported with the
|
||||
* results of the call.
|
||||
* @param terms The parameters
|
||||
* @return
|
||||
*/
|
||||
public boolean sendNlu (String agName, Collection<Term> params) {
|
||||
|
||||
logger.info("Entering sendNLU...");
|
||||
try{
|
||||
String[] strParams = CollectionUtils.toStringArray(params);
|
||||
Collection<Literal> serviceData = nluConnector.call(strParams);
|
||||
if(serviceData == null){
|
||||
logger.info("Could not complete action sendNLU: no service data found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// put data into mailbox
|
||||
this.setDataInbox(agName, serviceData);
|
||||
}
|
||||
catch (Exception e){
|
||||
logger.info("Could not complete action sendNLU:" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("NLU call completed successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param agName
|
||||
* @param terms
|
||||
* @return
|
||||
*/
|
||||
public boolean findTravel (String agName, Collection<Term> params) {
|
||||
|
||||
try{
|
||||
String[] strParams = CollectionUtils.toStringArray(params);
|
||||
Collection<Literal> serviceData = renfeScrapper.call(strParams);
|
||||
if(serviceData == null){ return false; }
|
||||
|
||||
// put data into mailbox
|
||||
this.setDataInbox(agName, serviceData);
|
||||
}
|
||||
catch (Exception e){ return false; }
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
38
src/java/es/upm/dit/gsi/sojason/beans/ErrorReport.java
Normal file
38
src/java/es/upm/dit/gsi/sojason/beans/ErrorReport.java
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.sojason.beans;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.NotationUtils;
|
||||
|
||||
/**
|
||||
* @author miguel
|
||||
*
|
||||
*/
|
||||
public class ErrorReport extends HashMap<String, String> implements Perceptable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see es.upm.dit.gsi.qa.beans.Perceptable#toPercepts()
|
||||
*/
|
||||
public List<Literal> toPercepts() {
|
||||
|
||||
List<Literal> res = new LinkedList<Literal>();
|
||||
for (String key : this.keySet()){
|
||||
if(!NotationUtils.isCompactable(key)) continue;
|
||||
res.add(Literal.parseLiteral("error(" + NotationUtils.compact(key) + ", \"" + get(key) + "\")"));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
217
src/java/es/upm/dit/gsi/sojason/beans/Journey.java
Normal file
217
src/java/es/upm/dit/gsi/sojason/beans/Journey.java
Normal file
@ -0,0 +1,217 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.sojason.beans;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.NotationUtils;
|
||||
|
||||
/**
|
||||
* @author miguel
|
||||
*
|
||||
*/
|
||||
public class Journey implements Perceptable{
|
||||
|
||||
/** The departure time of the journey */
|
||||
private String departureTime;
|
||||
|
||||
/** The arrival time of the journey */
|
||||
private String arrivalTime;
|
||||
|
||||
/**
|
||||
* The duration of the journey. This is not simply the difference of the
|
||||
* departure and arrival time because of timezone considerations.
|
||||
*/
|
||||
private String duration;
|
||||
|
||||
/** The origin */
|
||||
private String origin;
|
||||
|
||||
/** The destination */
|
||||
private String destination;
|
||||
|
||||
/** The fee map that contains the different available fee */
|
||||
private Map<String, String> fares;
|
||||
|
||||
/**
|
||||
* @return the departureTime
|
||||
*/
|
||||
public String getDepartureTime() {
|
||||
return departureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param departureTime the departureTime to set
|
||||
*/
|
||||
public void setDepartureTime(String departureTime) {
|
||||
this.departureTime = departureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the arrivalTime
|
||||
*/
|
||||
public String getArrivalTime() {
|
||||
return arrivalTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arrivalTime the arrivalTime to set
|
||||
*/
|
||||
public void setArrivalTime(String arrivalTime) {
|
||||
this.arrivalTime = arrivalTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration
|
||||
*/
|
||||
public String getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param duration the duration to set
|
||||
*/
|
||||
public void setDuration(String duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the oringin
|
||||
*/
|
||||
public String getOringin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param oringin the oringin to set
|
||||
*/
|
||||
public void setOrigin(String origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the destination
|
||||
*/
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param destination the destination to set
|
||||
*/
|
||||
public void setDestination(String destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fares
|
||||
*/
|
||||
public Map<String, String> getFares() {
|
||||
return fares;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fares the fares to set
|
||||
*/
|
||||
public void setFares(Map<String, String> fares) {
|
||||
this.fares = fares;
|
||||
}
|
||||
|
||||
/** Textual representation of the journey. Use for debuging purposes inly.*/
|
||||
public String toString() {
|
||||
|
||||
String toString = "From: ";
|
||||
toString = toString.concat(origin);
|
||||
toString = toString.concat(" (");
|
||||
toString = toString.concat(departureTime);
|
||||
toString = toString.concat(") to: ");
|
||||
toString = toString.concat(destination);
|
||||
toString = toString.concat(" (");
|
||||
toString = toString.concat(arrivalTime);
|
||||
toString = toString.concat(") in ");
|
||||
toString = toString.concat(duration);
|
||||
toString = toString.concat(" for ");
|
||||
if(fares != null)
|
||||
toString = toString.concat(fares.toString());
|
||||
else
|
||||
toString += null;
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* journey(madrid, ciudad_real, 10.15, 11.5, [fare(turista, 22.5), fare(preferente, 35)]
|
||||
* journey(madrid, ciudad_real, time(10,15), time(11,5), [fare(turista, 22.5), fare(preferente, 35)]
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Literal> toPercepts() {
|
||||
|
||||
// if (this.fares.size() == 0){ return null; }
|
||||
//
|
||||
// String percept = "journey(";
|
||||
// percept = percept.concat(this.origin);
|
||||
// percept = percept.concat(", ");
|
||||
// percept = percept.concat(this.destination);
|
||||
// percept = percept.concat(", ");
|
||||
// percept = percept.concat(this.departureTime);
|
||||
// percept = percept.concat(", ");
|
||||
// percept = percept.concat(this.arrivalTime);
|
||||
//
|
||||
// percept = percept.concat(", [");
|
||||
// for(String fareName : fares.keySet()) {
|
||||
// percept = percept.concat("fare(");
|
||||
// percept = percept.concat(fareName);
|
||||
// percept = percept.concat(", ");
|
||||
// percept = percept.concat(fares.get(fareName));
|
||||
// percept = percept.concat("), ");
|
||||
// }
|
||||
// percept = percept.substring(0, percept.lastIndexOf(","));
|
||||
// percept = percept.concat("])");
|
||||
//
|
||||
// LinkedList<Literal> ret = new LinkedList<Literal>();
|
||||
// ret.add(Literal.parseLiteral(percept));
|
||||
//
|
||||
// return ret;
|
||||
|
||||
if (this.fares.size() == 0){ return null; }
|
||||
|
||||
String percept = "journey(";
|
||||
percept = percept.concat(NotationUtils.compact(this.origin));
|
||||
percept = percept.concat(", ");
|
||||
percept = percept.concat(NotationUtils.compact(this.destination));
|
||||
|
||||
percept = percept.concat(", time(");
|
||||
String digits[] = this.departureTime.split("[\\x2E\\x3A]"); // [.:]
|
||||
percept = percept.concat(digits[0]);
|
||||
percept = percept.concat(", ");
|
||||
percept = percept.concat(digits[1]);
|
||||
|
||||
percept = percept.concat("), time(");
|
||||
digits = this.arrivalTime.split("[\\x2E\\x3A]"); // [.:]
|
||||
percept = percept.concat(digits[0]);
|
||||
percept = percept.concat(", ");
|
||||
percept = percept.concat(digits[1]);
|
||||
|
||||
percept = percept.concat("), [");
|
||||
for(String fareName : fares.keySet()) {
|
||||
percept = percept.concat("fare(");
|
||||
percept = percept.concat(NotationUtils.compact(fareName));
|
||||
percept = percept.concat(", ");
|
||||
percept = percept.concat(fares.get(fareName));
|
||||
percept = percept.concat("), ");
|
||||
}
|
||||
percept = percept.substring(0, percept.lastIndexOf(","));
|
||||
percept = percept.concat("])");
|
||||
|
||||
LinkedList<Literal> ret = new LinkedList<Literal>();
|
||||
ret.add(Literal.parseLiteral(percept));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
347
src/java/es/upm/dit/gsi/sojason/beans/NLUTravel.java
Normal file
347
src/java/es/upm/dit/gsi/sojason/beans/NLUTravel.java
Normal file
@ -0,0 +1,347 @@
|
||||
package es.upm.dit.gsi.sojason.beans;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.NotationUtils;
|
||||
import es.upm.dit.gsi.sojason.services.nlu.NLUModel;
|
||||
|
||||
public class NLUTravel implements Perceptable {
|
||||
|
||||
/** */
|
||||
public final static String TRAVEL_DOMAIN = "travel";
|
||||
|
||||
/** The departure date. */
|
||||
private String departureDate = null;
|
||||
/** The return date. It may be null. */
|
||||
private String returnDate = null;
|
||||
|
||||
/** The maximum price the user is willing to pay */
|
||||
private double priceMin = -1;
|
||||
/** The minimum price */
|
||||
private double priceMax = -1;
|
||||
/** The currency */
|
||||
private String currency = null;
|
||||
|
||||
/** The departure location */
|
||||
private String locationFrom = null;
|
||||
/** The destination location */
|
||||
private String locationTo = null;
|
||||
|
||||
/** The preferred departure Time */
|
||||
private String departureTime = null;
|
||||
/** the preferred return Time*/
|
||||
private String returnTime = null;
|
||||
|
||||
/** the number of people is traveling */
|
||||
private int number = 1;
|
||||
|
||||
/** */
|
||||
private TravelType type = null;
|
||||
/** */
|
||||
private boolean scales = false;
|
||||
|
||||
/** The unique id for the dialog. It is used to group dialog entries */
|
||||
private String queryId = null;
|
||||
|
||||
/**
|
||||
* @return the departureDate
|
||||
*/
|
||||
public String getDepartureDate() {
|
||||
return departureDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param departureDate the departureDate to set
|
||||
*/
|
||||
public void setDepartureDate(String departureDate) {
|
||||
this.departureDate = departureDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the returnDate
|
||||
*/
|
||||
public String getReturnDate() {
|
||||
return returnDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param returnDate the returnDate to set
|
||||
*/
|
||||
public void setReturnDate(String returnDate) {
|
||||
this.returnDate = returnDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the priceMin
|
||||
*/
|
||||
public double getPriceMin() {
|
||||
return priceMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priceMin the priceMin to set
|
||||
*/
|
||||
public void setPriceMin(double priceMin) {
|
||||
this.priceMin = priceMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priceMax the priceMax to set
|
||||
*/
|
||||
public void setPriceMin(String priceMin) {
|
||||
if (priceMin == null){ return; }
|
||||
|
||||
try{
|
||||
this.priceMin = Double.parseDouble(priceMin);
|
||||
}
|
||||
catch (NumberFormatException nfe){
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the priceMax
|
||||
*/
|
||||
public double getPriceMax() {
|
||||
return priceMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priceMax the priceMax to set
|
||||
*/
|
||||
public void setPriceMax(double priceMax) {
|
||||
this.priceMax = priceMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priceMax the priceMax to set
|
||||
*/
|
||||
public void setPriceMax(String priceMax) {
|
||||
if (priceMax == null){ return; }
|
||||
|
||||
try{
|
||||
this.priceMax = Double.parseDouble(priceMax);
|
||||
}
|
||||
catch (NumberFormatException nfe){
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the currency
|
||||
*/
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currency the currency to set
|
||||
*/
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the locationFrom
|
||||
*/
|
||||
public String getLocationFrom() {
|
||||
return locationFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locationFrom the locationFrom to set
|
||||
*/
|
||||
public void setLocationFrom(String locationFrom) {
|
||||
this.locationFrom = locationFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the locationTo
|
||||
*/
|
||||
public String getLocationTo() {
|
||||
return locationTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locationTo the locationTo to set
|
||||
*/
|
||||
public void setLocationTo(String locationTo) {
|
||||
this.locationTo = locationTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the departureTime
|
||||
*/
|
||||
public String getDepartureTime() {
|
||||
return departureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param departureTime the departureTime to set
|
||||
*/
|
||||
public void setDepartureTime(String departureTime) {
|
||||
this.departureTime = departureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the returnReturn
|
||||
*/
|
||||
public String getReturnTime() {
|
||||
return returnTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param returnReturn the returnReturn to set
|
||||
*/
|
||||
public void setReturnTime(String returnTime) {
|
||||
this.returnTime = returnTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public TravelType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(TravelType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the scales
|
||||
*/
|
||||
public boolean isScales() {
|
||||
return scales;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scales the scales to set
|
||||
*/
|
||||
public void setScales(boolean scales) {
|
||||
this.scales = scales;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number the number to set
|
||||
*/
|
||||
public void setNumber(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public void setNumber(String number){
|
||||
if(number == null){ return; }
|
||||
try{
|
||||
this.number = Integer.parseInt(number);
|
||||
}
|
||||
catch(NumberFormatException nfe){
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the queryId
|
||||
*/
|
||||
public String getQueryId() {
|
||||
return queryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryId the queryId to set
|
||||
*/
|
||||
public void setQueryId(String queryId) {
|
||||
this.queryId = queryId;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
|
||||
String toString = queryId + number;
|
||||
toString += "ticket(s) from: ";
|
||||
toString += locationFrom;
|
||||
toString += " to: ";
|
||||
toString += locationTo;
|
||||
toString += " the day ";
|
||||
toString += departureDate;
|
||||
toString += " at ";
|
||||
toString += departureTime;
|
||||
toString += " returning the day ";
|
||||
toString += returnTime;
|
||||
toString += " at ";
|
||||
toString += returnTime;
|
||||
toString += " for ";
|
||||
toString += priceMax + "->" + priceMin;
|
||||
toString += " ";
|
||||
toString += currency;
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public List<Literal> toPercepts() {
|
||||
|
||||
List<Literal> list = new LinkedList<Literal>();
|
||||
|
||||
if(departureDate != null){
|
||||
list.add(NLUModel.getLiteralDateDeparture(queryId, TRAVEL_DOMAIN, "03", "04", "2012"));
|
||||
}
|
||||
|
||||
if(returnDate != null){
|
||||
list.add(NLUModel.getLiteralDateReturn(queryId, TRAVEL_DOMAIN, "03", "04", "2012"));
|
||||
}
|
||||
|
||||
if(departureTime != null){
|
||||
list.add(NLUModel.getLiteralTimeDeparture(queryId, TRAVEL_DOMAIN, "09", "00"));
|
||||
}
|
||||
|
||||
if(returnTime != null){
|
||||
list.add(NLUModel.getLiteralTimeReturn(queryId, TRAVEL_DOMAIN, "09", "00"));
|
||||
}
|
||||
|
||||
if(priceMax >= 0){
|
||||
list.add(NLUModel.getLiteralPriceMax(queryId, TRAVEL_DOMAIN, priceMax));
|
||||
}
|
||||
|
||||
if(priceMin >= 0){
|
||||
list.add(NLUModel.getLiteralPriceMin(queryId, TRAVEL_DOMAIN, priceMin));
|
||||
}
|
||||
|
||||
if(currency != null){
|
||||
list.add(NLUModel.getLiteralCurrency(queryId, TRAVEL_DOMAIN, NotationUtils.compact(currency)));
|
||||
}
|
||||
|
||||
if(locationFrom != null){
|
||||
list.add(NLUModel.getLiteralLocationFrom(queryId, TRAVEL_DOMAIN, NotationUtils.compact(locationFrom)));
|
||||
}
|
||||
|
||||
if(locationTo != null){
|
||||
list.add(NLUModel.getLiteralLocationTo(queryId, TRAVEL_DOMAIN, NotationUtils.compact(locationTo)));
|
||||
}
|
||||
|
||||
if(scales){
|
||||
list.add(Literal.parseLiteral("scales[query(" + queryId + "), domain(" + TRAVEL_DOMAIN + ")]"));
|
||||
}
|
||||
else{
|
||||
list.add(Literal.parseLiteral("~scales[query(" + queryId + "), domain(" + TRAVEL_DOMAIN + ")]"));
|
||||
}
|
||||
|
||||
list.add(Literal.parseLiteral("done[query(" + queryId + "), domain(" + TRAVEL_DOMAIN + ")]"));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
14
src/java/es/upm/dit/gsi/sojason/beans/Perceptable.java
Normal file
14
src/java/es/upm/dit/gsi/sojason/beans/Perceptable.java
Normal file
@ -0,0 +1,14 @@
|
||||
package es.upm.dit.gsi.sojason.beans;
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author miguel
|
||||
*
|
||||
*/
|
||||
public interface Perceptable {
|
||||
|
||||
public List<Literal> toPercepts();
|
||||
|
||||
}
|
11
src/java/es/upm/dit/gsi/sojason/beans/TravelType.java
Normal file
11
src/java/es/upm/dit/gsi/sojason/beans/TravelType.java
Normal file
@ -0,0 +1,11 @@
|
||||
package es.upm.dit.gsi.sojason.beans;
|
||||
|
||||
/**
|
||||
* This defines the different means of transport.
|
||||
* @author gsi.dit.upm.es
|
||||
*/
|
||||
public enum TravelType {
|
||||
flight,
|
||||
train,
|
||||
coach
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.sojason.services;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This interface defines a standard way to connect to a web service in
|
||||
* the definition of an external action in Jason.
|
||||
*
|
||||
* Project: Web40SOJason
|
||||
* Package: es.upm.dit.gsi.sojason.services
|
||||
* Class: WebServiceConnector
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Feb 27, 2012
|
||||
*
|
||||
*/
|
||||
public interface WebServiceConnector {
|
||||
|
||||
/**
|
||||
* This calls the service including in the request the parameters given.
|
||||
* The URL of the service, the method to use and any other particularity
|
||||
* of the transaction to connect to the service must be determined in the
|
||||
* implementation of the method.
|
||||
*
|
||||
* @param params The list of parameters to include in the service
|
||||
* request. Due to this is not a <code>Dictionary</code>
|
||||
* the order of the parameters it is important and will be
|
||||
* determined by the implementation of the extendee
|
||||
* classes.
|
||||
*/
|
||||
public Collection<Literal> call(String... params);
|
||||
|
||||
/**
|
||||
* This validates the set of parameters provided. Typically, this method
|
||||
* should use some regex exprsesions to check whether a parameter is valid
|
||||
* or not, due to the nature of the parameter cannot be checked because of
|
||||
* the type of the parameters has been unified to String.
|
||||
*
|
||||
* @param params The list of parameters to validate
|
||||
*/
|
||||
public boolean validateParams(String... params);
|
||||
|
||||
/**
|
||||
* This generates a set of error <code>Literal</code>s that describes the
|
||||
* errors committed when trying to call the given service with the set of
|
||||
* parameters given.
|
||||
*
|
||||
* @param params The list of parameters
|
||||
*/
|
||||
// public Set<Literal> checkForErrors(String... params);
|
||||
|
||||
}
|
163
src/java/es/upm/dit/gsi/sojason/services/nlu/NLUConnector.java
Normal file
163
src/java/es/upm/dit/gsi/sojason/services/nlu/NLUConnector.java
Normal file
@ -0,0 +1,163 @@
|
||||
package es.upm.dit.gsi.sojason.services.nlu;
|
||||
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_CURRENCY_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_DATES_DEPART_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_DATES_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_DATES_RETURN_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_DOMAINS_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_FROM_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_TO_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_LOCATIONS_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_MAX_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_MIN_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_NUMBER_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_PRICE_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_TIME_DEPART_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_TIME_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_TIME_RETURN_NODENAME;
|
||||
import static es.upm.dit.gsi.sojason.services.nlu.NLUModel.JSON_TRAVEL_NODENAME;
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.NotationUtils;
|
||||
import es.upm.dit.gsi.sojason.Web40Model;
|
||||
import es.upm.dit.gsi.sojason.beans.NLUTravel;
|
||||
import es.upm.dit.gsi.sojason.services.WebServiceConnector;
|
||||
|
||||
/**
|
||||
* Project: Web40SOJason
|
||||
* Package: es.upm.dit.gsi.sojason.services.nlu
|
||||
* Class: NLUConnector
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Feb 27, 2012
|
||||
*
|
||||
*/
|
||||
public class NLUConnector implements WebServiceConnector{
|
||||
|
||||
/** The url of the service */
|
||||
private String serviceUrl;
|
||||
/** */
|
||||
private Logger logger = Logger.getLogger("Web40SOJason." + NLUConnector.class.getName());
|
||||
|
||||
|
||||
/** Constructor */
|
||||
public NLUConnector(String serviceUrl) {
|
||||
this.serviceUrl = serviceUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Collection<Literal> call(String... params) {
|
||||
|
||||
/* Are parameters correct */
|
||||
if (!validateParams(params)){
|
||||
logger.info("Parameters are not valid:" + Arrays.toString(params));
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Prepare the request
|
||||
String urlRequest = prepareRequest(params[0], params[1]);
|
||||
|
||||
URL url = new URL(urlRequest);
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.connect();
|
||||
|
||||
// Parse the data received (using Jackson lib)
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode rootNode = mapper.readValue(connection.getInputStream(), JsonNode.class); // src can be a File, URL, InputStream etc
|
||||
JsonNode travelNode = rootNode.with(JSON_DOMAINS_NODENAME).get(JSON_TRAVEL_NODENAME);
|
||||
|
||||
NLUTravel travel = new NLUTravel();
|
||||
travel.setDepartureDate(travelNode.with(JSON_DATES_NODENAME).get(JSON_DATES_DEPART_NODENAME).getTextValue());
|
||||
travel.setReturnDate(travelNode.with(JSON_DATES_NODENAME).get(JSON_DATES_RETURN_NODENAME).getTextValue());
|
||||
|
||||
travel.setCurrency(travelNode.with(JSON_PRICE_NODENAME).get(JSON_CURRENCY_NODENAME).getTextValue());
|
||||
travel.setPriceMax(travelNode.with(JSON_PRICE_NODENAME).get(JSON_MAX_NODENAME).getTextValue());
|
||||
travel.setPriceMin(travelNode.with(JSON_PRICE_NODENAME).get(JSON_MIN_NODENAME).getTextValue());
|
||||
|
||||
travel.setLocationFrom(travelNode.with(JSON_LOCATIONS_NODENAME).get(JSON_FROM_NODENAME).getTextValue());
|
||||
travel.setLocationTo(travelNode.with(JSON_LOCATIONS_NODENAME).get(JSON_TO_NODENAME).getTextValue());
|
||||
|
||||
travel.setNumber(travelNode.get(JSON_NUMBER_NODENAME).getTextValue());
|
||||
|
||||
travel.setReturnTime(travelNode.with(JSON_TIME_NODENAME).get(JSON_TIME_RETURN_NODENAME).getTextValue());
|
||||
travel.setDepartureTime(travelNode.with(JSON_TIME_NODENAME).get(JSON_TIME_DEPART_NODENAME).getTextValue());
|
||||
|
||||
travel.setQueryId(params[0]);
|
||||
|
||||
// System.out.println(travel);
|
||||
|
||||
return travel.toPercepts();
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
// return CollectionUtils.wrapList("error(malformed_url, \"The given url is not valid\")");
|
||||
logger.info("MalformedURLException:" + e.getMessage()); return null;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// return CollectionUtils.wrapList("error(undupported_encodig, \"The encoding given is not supported\")");
|
||||
logger.info("UnsupportedEncodingException:" + e.getMessage()); return null;
|
||||
} catch (IOException e) {
|
||||
// return CollectionUtils.wrapList("error(io_exception, \"Someio exception ocurr\")");
|
||||
logger.info("IOException:" + e.getMessage()); return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates a String used as http GET request to access the service
|
||||
* including the parameters given by the user
|
||||
*
|
||||
* @param queryid
|
||||
* @param message
|
||||
* @return the url service string (utf-8 encoded)
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
String prepareRequest(String queryid, String message) throws UnsupportedEncodingException {
|
||||
String urlRequest = this.serviceUrl;
|
||||
urlRequest = urlRequest.concat("?text=");
|
||||
message = NotationUtils.removeQuotation(message);
|
||||
urlRequest = urlRequest.concat(URLEncoder.encode(message, "utf-8"));
|
||||
// urlRequest = urlRequest.concat(URLEncoder.encode("&query_id=", "utf-8"));
|
||||
urlRequest = urlRequest.concat("&query_id=");
|
||||
urlRequest = urlRequest.concat(URLEncoder.encode(queryid, "utf-8"));
|
||||
|
||||
logger.info(urlRequest);
|
||||
return urlRequest ;
|
||||
}
|
||||
|
||||
/**
|
||||
* This validates the parameters received. The
|
||||
* {@link NLUConnector#call(String...)} method expects to receive two
|
||||
* parameters of the nature and characteristics described below:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The first parameter is que query id. It is an alphanumeric string
|
||||
* which normally will contain numbers, but other non-digit characters
|
||||
* are permitted. <b>No alphanumeric values are not allowed</b></li>
|
||||
* <li></li>
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
public boolean validateParams(String... params) {
|
||||
if (params.length != 2){
|
||||
return false;
|
||||
}
|
||||
// TODO: check other things
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
92
src/java/es/upm/dit/gsi/sojason/services/nlu/NLUModel.java
Normal file
92
src/java/es/upm/dit/gsi/sojason/services/nlu/NLUModel.java
Normal file
@ -0,0 +1,92 @@
|
||||
package es.upm.dit.gsi.sojason.services.nlu;
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Project: Web40
|
||||
* Package: es.upm.dit.gsi.qa.services.nlu
|
||||
* Class:
|
||||
*
|
||||
* @author Miguel Coronado (miguelcb@dit.upm.es)
|
||||
* @version Feb 28, 2012
|
||||
*
|
||||
*/
|
||||
public class NLUModel {
|
||||
|
||||
|
||||
public final static String JSON_DOMAINS_NODENAME = "domains";
|
||||
|
||||
public final static String JSON_TRAVEL_NODENAME = "travel";
|
||||
|
||||
public final static String JSON_DATES_NODENAME = "dates";
|
||||
|
||||
public final static String JSON_DATES_DEPART_NODENAME = "depart";
|
||||
|
||||
public final static String JSON_DATES_RETURN_NODENAME = "return";
|
||||
|
||||
public final static String JSON_PRICE_NODENAME = "price";
|
||||
|
||||
public final static String JSON_CURRENCY_NODENAME = "currency";
|
||||
|
||||
public final static String JSON_MAX_NODENAME = "max";
|
||||
|
||||
public final static String JSON_MIN_NODENAME = "min";
|
||||
|
||||
public final static String JSON_LOCATIONS_NODENAME = "locations";
|
||||
|
||||
public final static String JSON_FROM_NODENAME = "from";
|
||||
|
||||
public final static String JSON_TO_NODENAME = "to";
|
||||
|
||||
public final static String JSON_NUMBER_NODENAME = "number";
|
||||
|
||||
public final static String JSON_TIME_NODENAME = "time";
|
||||
|
||||
public final static String JSON_TIME_DEPART_NODENAME = "depart";
|
||||
|
||||
public final static String JSON_TIME_RETURN_NODENAME = "return";
|
||||
|
||||
|
||||
|
||||
public static Literal getLiteralPriceMin (String query, String domain, double price) {
|
||||
return Literal.parseLiteral("price(min," + price + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralPriceMax (String query, String domain, double price) {
|
||||
return Literal.parseLiteral("price(max," + price + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralCurrency (String query, String domain, String currency) {
|
||||
return Literal.parseLiteral("currency(" + currency + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralLocationFrom (String query, String domain, String place) {
|
||||
return Literal.parseLiteral("location(from," + place + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralLocationTo (String query, String domain, String place) {
|
||||
return Literal.parseLiteral("location(to," + place + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralDateDeparture (String query, String domain, String day, String month, String year) {
|
||||
return Literal.parseLiteral("date(departure," + day + "," + month + "," + year + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralDateReturn (String query, String domain, String day, String month, String year) {
|
||||
return Literal.parseLiteral("date(return," + day + "," + month + "," + year + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralTimeDeparture (String query, String domain, String hour, String min) {
|
||||
return Literal.parseLiteral("time(departure," + hour + "," + min + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralTimeReturn (String query, String domain, String hour, String min) {
|
||||
return Literal.parseLiteral("time(return," + hour + "," + min + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
public static Literal getLiteralType (String query, String domain, String type) {
|
||||
return Literal.parseLiteral("type(" + type + ")[query("+ query +"),domain("+ domain +")]");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package es.upm.dit.gsi.sojason.services.travel;
|
||||
|
||||
import jason.asSyntax.Literal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import es.upm.dit.gsi.sojason.beans.Journey;
|
||||
import es.upm.dit.gsi.sojason.beans.Perceptable;
|
||||
import es.upm.dit.gsi.sojason.services.WebServiceConnector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author miguel
|
||||
*
|
||||
*/
|
||||
public class RenfeScrapper implements WebServiceConnector {
|
||||
|
||||
/**
|
||||
* It contains all the information about the <i>Renfe</i>
|
||||
* web service URL convenion.
|
||||
*/
|
||||
RenfeServiceConvenion queryGenerator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @throws IOException if there is any error while loading the station ids.
|
||||
*/
|
||||
public RenfeScrapper() throws IOException {
|
||||
this.queryGenerator = new RenfeServiceConvenion();
|
||||
}
|
||||
|
||||
|
||||
public Collection<Literal> call(String... params) {
|
||||
|
||||
if(!validateParams(params)){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
List<Perceptable> schedule = getSchedule ( params[0].toString(),
|
||||
params[1].toString(),
|
||||
params[2].toString(),
|
||||
params[3].toString(),
|
||||
params[4].toString());
|
||||
|
||||
// prepare response
|
||||
Collection<Literal> res = new LinkedList<Literal>();
|
||||
for (Perceptable travel : schedule){
|
||||
res.addAll(travel.toPercepts());
|
||||
}
|
||||
return res;
|
||||
|
||||
} catch (IOException e) {
|
||||
// return CollectionUtils.wrapList("error(io_exception, \"Someio exception ocurr\")");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean validateParams(String... params) {
|
||||
if(params.length != 5){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: filter by time
|
||||
*
|
||||
*
|
||||
* @param origin
|
||||
* @param destination
|
||||
* @param day
|
||||
* @param month
|
||||
* @param year
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<Perceptable> getSchedule (String origin, String destination,
|
||||
String day, String month, String year) throws IOException {
|
||||
|
||||
// The list with the journeys that matches the given criteria
|
||||
List<Perceptable> retList = new LinkedList<Perceptable>();
|
||||
|
||||
// Get the html
|
||||
String queryUrl = "";
|
||||
try{
|
||||
queryUrl = queryGenerator.generateQuery(origin, destination, day, month, year);
|
||||
}
|
||||
catch(IllegalArgumentException iae){
|
||||
retList.add( queryGenerator.reportParamErrors(origin, destination, day, month, year) );
|
||||
return retList;
|
||||
}
|
||||
Document doc = Jsoup.connect(queryUrl).get();
|
||||
|
||||
// Get the rows of the schedule table
|
||||
Elements rows = doc.select("table#row > tbody > tr");
|
||||
// Each row has the information of a different journey
|
||||
for (Element row : rows) {
|
||||
Elements cells = row.getElementsByTag("td");
|
||||
if(cells.size() > 2){
|
||||
|
||||
// get and fill the journey information
|
||||
Journey journey = new Journey();
|
||||
journey.setOrigin(origin);
|
||||
journey.setDestination(destination);
|
||||
journey.setDepartureTime(cells.get(1).text());
|
||||
journey.setArrivalTime(cells.get(2).text());
|
||||
journey.setDuration(cells.get(3).text());
|
||||
|
||||
// the fee map for the particular journey
|
||||
Map<String, String> feeMap = new HashMap<String,String>();
|
||||
// get the fares
|
||||
Elements feeRows = cells.get(4).select("tbody tr");
|
||||
|
||||
/* According to Renfe's website we select the following sublist */
|
||||
int fromIndex = 1; // skip the header row
|
||||
/* They present 2 set of fares (Internet and station) so we skip
|
||||
* the header rows and divide by 2 to get the amount of fares to
|
||||
* parse */
|
||||
int toIndex = 1+(feeRows.size()-2)/2;
|
||||
|
||||
for(Element feeRow : feeRows.subList(fromIndex, toIndex)) {
|
||||
Elements feeCells = feeRow.getElementsByTag("td");
|
||||
// String feeName = feeCells.get(1).text().toLowerCase().replace(" ", "").replace(":", "").replace("ñ", "n");
|
||||
String feeName = feeCells.get(1).text().replace(":", "");
|
||||
String price = feeCells.get(2).text().replace(",", ".");
|
||||
// Set the fee
|
||||
feeMap.put(feeName, price);
|
||||
}
|
||||
|
||||
// Set the fares
|
||||
journey.setFares(feeMap);
|
||||
retList.add(journey);
|
||||
}
|
||||
}
|
||||
|
||||
return retList;
|
||||
}
|
||||
|
||||
/**
|
||||
* try it
|
||||
* @param args
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void main(String [] args) throws IOException{
|
||||
RenfeScrapper rs = new RenfeScrapper();
|
||||
List<Perceptable> list = rs.getSchedule ("Madrid", "ciudad real", "16", "04", "2012");
|
||||
for(Perceptable journey : list){
|
||||
System.out.println(journey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,210 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package es.upm.dit.gsi.sojason.services.travel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import es.upm.dit.gsi.jason.utils.NotationUtils;
|
||||
import es.upm.dit.gsi.sojason.beans.ErrorReport;
|
||||
|
||||
/**
|
||||
* This class describes the
|
||||
* @author gsi.dit.upm.es
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RenfeServiceConvenion {
|
||||
|
||||
public final static String SERVICE_URL = "http://horarios.renfe.com/HIRRenfeWeb/buscar.do";
|
||||
public final static String ORIGIN_PARAM = "O";
|
||||
public final static String DESTINATION_PARAM = "D";
|
||||
public final static String YEAR_PARAM = "AF";
|
||||
public final static String MONTH_PARAM = "MF";
|
||||
public final static String DAY_PARAM = "DF";
|
||||
public final static String DEFAULT_PATH_TO_CITY_CODES_FILE = "conf/cities.xml";
|
||||
|
||||
private Properties cityCodes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cityCodesFile
|
||||
* @throws IOException
|
||||
*/
|
||||
public RenfeServiceConvenion (File cityCodesFile) throws IOException {
|
||||
this.cityCodes = new Properties();
|
||||
this.cityCodes.loadFromXML(new FileInputStream(cityCodesFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* @throws IOException
|
||||
*/
|
||||
public RenfeServiceConvenion () throws IOException {
|
||||
this(new File(DEFAULT_PATH_TO_CITY_CODES_FILE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param origin
|
||||
* @param destination
|
||||
* @param day
|
||||
* @param month
|
||||
* @param year
|
||||
* @return
|
||||
*/
|
||||
public String generateQuery (String origin, String destination,
|
||||
String day, String month, String year){
|
||||
|
||||
origin = NotationUtils.uncompact(origin);
|
||||
destination = NotationUtils.uncompact(destination);
|
||||
|
||||
if(!validateParams(origin, destination, day, month, year)){
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
String res = SERVICE_URL;
|
||||
res = res.concat("?");
|
||||
res = res.concat(ORIGIN_PARAM);
|
||||
res = res.concat("=");
|
||||
res = res.concat(this.cityCodes.getProperty(origin.toLowerCase()));
|
||||
res = res.concat("&");
|
||||
res = res.concat(DESTINATION_PARAM);
|
||||
res = res.concat("=");
|
||||
res = res.concat(this.cityCodes.getProperty(destination.toLowerCase()));
|
||||
res = res.concat("&");
|
||||
res = res.concat(YEAR_PARAM);
|
||||
res = res.concat("=");
|
||||
res = res.concat(year);
|
||||
res = res.concat("&");
|
||||
res = res.concat(MONTH_PARAM);
|
||||
res = res.concat("=");
|
||||
res = res.concat(month);
|
||||
res = res.concat("&");
|
||||
res = res.concat(DAY_PARAM);
|
||||
res = res.concat("=");
|
||||
res = res.concat(day);
|
||||
// 'concat' is faster than '+' operator
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param origin
|
||||
* @param destination
|
||||
* @param day
|
||||
* @param month
|
||||
* @param year
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
protected boolean validateParams(String origin, String destination, String day,
|
||||
String month, String year) {
|
||||
|
||||
if(!Pattern.matches("\\d{4}", year)){
|
||||
return false;
|
||||
}
|
||||
if(!Pattern.matches("\\d{1,2}", month)){
|
||||
return false;
|
||||
}
|
||||
if(!Pattern.matches("\\d{1,2}", day)){
|
||||
return false;
|
||||
}
|
||||
|
||||
int monthI = Integer.parseInt(month);
|
||||
int dayI = Integer.parseInt(day);
|
||||
int monthNumberOfDays[] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
||||
if(monthI < 1 || monthI > 12){
|
||||
return false;
|
||||
}
|
||||
if(dayI < 1 || dayI > monthNumberOfDays[monthI-1]){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(origin == null || !this.cityCodes.containsKey(origin.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(destination == null || !this.cityCodes.containsKey(destination.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ErrorReport reportParamErrors (String origin, String destination, String day,
|
||||
String month, String year) {
|
||||
|
||||
ErrorReport errors = new ErrorReport();
|
||||
|
||||
if(!Pattern.matches("\\d{4}", year)){
|
||||
errors.put("year", "invalid format");
|
||||
}
|
||||
if(!Pattern.matches("\\d{1,2}", month)){
|
||||
errors.put("month", "invalid format");
|
||||
}
|
||||
if(!Pattern.matches("\\d{1,2}", day)){
|
||||
errors.put("day", "invalid format");
|
||||
}
|
||||
|
||||
int monthI = Integer.parseInt(month);
|
||||
int dayI = Integer.parseInt(day);
|
||||
int monthNumberOfDays[] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
||||
if(monthI < 1 || monthI > 12){
|
||||
errors.put("month", "out of range");
|
||||
monthI = 1; // this lets check the day
|
||||
}
|
||||
if(dayI < 1 || dayI > monthNumberOfDays[monthI-1]){
|
||||
errors.put("day", "out of range");
|
||||
}
|
||||
|
||||
if(origin == null || !this.cityCodes.containsKey(origin.toLowerCase())) {
|
||||
errors.put("origin", "no such location");
|
||||
}
|
||||
|
||||
if(destination == null || !this.cityCodes.containsKey(destination.toLowerCase())) {
|
||||
errors.put("destination", "no such location");
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arga
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void main(String [] arga) throws IOException{
|
||||
|
||||
// RenfeServiceConvenion rsc = new RenfeServiceConvenion();
|
||||
// Properties newProperties = new Properties();
|
||||
//
|
||||
// for (Object key : rsc.cityCodes.keySet() ){
|
||||
// String keyStr = (String)key;
|
||||
// keyStr = keyStr.toLowerCase();
|
||||
// newProperties.put(keyStr, rsc.cityCodes.get(key));
|
||||
// if (keyStr.contains("á") ||
|
||||
// keyStr.contains("é") ||
|
||||
// keyStr.contains("í") ||
|
||||
// keyStr.contains("ó") ||
|
||||
// keyStr.contains("ú")) {
|
||||
//
|
||||
// keyStr = keyStr.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u");
|
||||
// newProperties.put(keyStr, rsc.cityCodes.get(key));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// newProperties.storeToXML(new FileOutputStream(DEFAULT_PATH_TO_CITY_CODES_FILE), "comment");
|
||||
|
||||
RenfeServiceConvenion rsc = new RenfeServiceConvenion();
|
||||
String res = rsc.generateQuery("Madrid", "Ciudad Real", "15", "02", "2012");
|
||||
System.out.println(res);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user