|
From: <jom...@us...> - 2014-06-03 18:50:32
|
Revision: 1785
http://sourceforge.net/p/jason/svn/1785
Author: jomifred
Date: 2014-06-03 18:50:24 +0000 (Tue, 03 Jun 2014)
Log Message:
-----------
include option for mindinspector to be seen in a browser
Modified Paths:
--------------
trunk/doc/faq/faq.tex
trunk/examples/auction/auction.mas2j
trunk/src/jason/architecture/MindInspectorAgArch.java
trunk/src/jason/control/ExecutionControlGUI.java
trunk/src/xml/agInspection.xsl
Added Paths:
-----------
trunk/src/jason/architecture/MindInspectorWeb.java
Modified: trunk/doc/faq/faq.tex
===================================================================
--- trunk/doc/faq/faq.tex 2014-06-02 21:28:22 UTC (rev 1784)
+++ trunk/doc/faq/faq.tex 2014-06-03 18:50:24 UTC (rev 1785)
@@ -613,6 +613,13 @@
bob [mindinspector="gui(2000,html,history)"];
\end{verbatim}
+
+You can also see the history of minds in a browser with the following configuration:
+\begin{verbatim}
+ bob [mindinspector="web(cycle,html,history)"];
+\end{verbatim}
+The URL is typically http://<your host up>:3272/.
+
To store the history of minds in files, use the following configuration:
\begin{verbatim}
bob [mindinspector="file(cycle,xml,log)"];
@@ -622,6 +629,7 @@
files with suitable style sheets to be viewed in browsers.
+
% ---------------------------------------------------------------------
\section{\jason Infrastructures}
Modified: trunk/examples/auction/auction.mas2j
===================================================================
--- trunk/examples/auction/auction.mas2j 2014-06-02 21:28:22 UTC (rev 1784)
+++ trunk/examples/auction/auction.mas2j 2014-06-03 18:50:24 UTC (rev 1785)
@@ -6,7 +6,7 @@
agents: ag1;
ag2;
- ag3;
- auctioneer //[mindinspector="gui(cycle,html,history)"]
+ ag3 [mindinspector="web(cycle,html,history)"]; // two agents with web view of their minds
+ auctioneer [mindinspector="web(cycle,html,history)"]
agentArchClass AuctioneerGUI;
}
Modified: trunk/src/jason/architecture/MindInspectorAgArch.java
===================================================================
--- trunk/src/jason/architecture/MindInspectorAgArch.java 2014-06-02 21:28:22 UTC (rev 1784)
+++ trunk/src/jason/architecture/MindInspectorAgArch.java 2014-06-03 18:50:24 UTC (rev 1785)
@@ -84,8 +84,10 @@
// what is currently shown
Document agState = null;
-
-
+
+ MindInspectorWeb webServer = null;
+ boolean hasHistory = false;
+
@Override
public void init() {
setupMindInspector(getTS().getSettings().getUserParameter("mindinspector"));
@@ -123,7 +125,7 @@
try {
sConf = ASSyntax.parseStructure(configuration);
} catch (Exception e) {
- getTS().getLogger().warning("The mindinspector argument does not parse as a predicate! "+configuration+" -- error: "+e);
+ getTS().getLogger().warning("The mindinspector argument does not parse as a predicate! "+configuration+" -- (see Jason FAQ) -- error: "+e);
return;
}
@@ -154,6 +156,8 @@
createGUIMindInspector(sConf);
} else if (sConf.getFunctor().equals("file")) {
createFileMindInspector(sConf);
+ } else if (sConf.getFunctor().equals("web")) {
+ createWebMindInspector(sConf);
}
}
@@ -251,8 +255,6 @@
}
}
-
-
private void setupSlider() {
int size = mindInspectorHistory.size()-1;
if (size < 0)
@@ -292,6 +294,12 @@
new File(mindInspectorDirectory).mkdirs();
}
+ private void createWebMindInspector(Structure sConf) {
+ webServer = MindInspectorWeb.get();
+ hasHistory = sConf.getArity() == 3 && sConf.getTerm(2).toString().equals("history");
+ mindInspectorTransformer = new asl2html("/xml/agInspection.xsl");
+ }
+
private String lastHistoryText = "";
private int fileCounter = 0;
@@ -317,6 +325,8 @@
FileWriter outmind = new FileWriter(new File(mindInspectorDirectory+"/"+filename));
outmind.write(sMind);
outmind.close();
+ } else if (webServer != null) { // output on web
+ webServer.addAgState(getTS().getAg(), state, hasHistory);
}
} catch (Exception e) {
e.printStackTrace();
@@ -350,7 +360,9 @@
mindInspectorTransformer.setParameter("show-"+p, show.get(p)+"");
return mindInspectorTransformer.transform(ag); // transform to HTML
} catch (Exception e) {
- mindInspectorPanel.setText("Error in XML transformation!" + e);
+ if (mindInspectorPanel != null) {
+ mindInspectorPanel.setText("Error in XML transformation!" + e);
+ }
e.printStackTrace();
return "Error XML transformation (MindInspector)";
}
Added: trunk/src/jason/architecture/MindInspectorWeb.java
===================================================================
--- trunk/src/jason/architecture/MindInspectorWeb.java (rev 0)
+++ trunk/src/jason/architecture/MindInspectorWeb.java 2014-06-03 18:50:24 UTC (rev 1785)
@@ -0,0 +1,269 @@
+package jason.architecture;
+
+import jason.asSemantics.Agent;
+import jason.jeditplugin.Config;
+import jason.util.asl2html;
+import jason.util.asl2xml;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.Executors;
+
+import org.w3c.dom.Document;
+
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class MindInspectorWeb {
+
+ private static MindInspectorWeb singleton = null;
+
+ private HttpServer httpServer = null;
+ private String httpServerURL = "http://localhost:3272";
+ private int httpServerPort = 3272;
+ private int refreshInterval = 5;
+
+ //private Map<String,Boolean> agHasHistory = new HashMap<String, Boolean>();
+ private Map<String,List<Document>> histories = new TreeMap<String,List<Document>>();
+ private Map<String,Integer> lastStepSeenByUser = new HashMap<String, Integer>();
+
+ public static synchronized MindInspectorWeb get() {
+ if (singleton == null) {
+ singleton = new MindInspectorWeb();
+ singleton.startHttpServer();
+ singleton.registerRootBrowserView();
+ }
+ return singleton;
+ }
+
+ private MindInspectorWeb() {
+ }
+
+ private synchronized String startHttpServer() {
+ if (httpServer == null) {
+ try {
+ httpServer = HttpServer.create(new InetSocketAddress(httpServerPort), 0);
+ httpServer.setExecutor(Executors.newCachedThreadPool());
+
+ httpServer.start();
+ httpServerURL = "http://"+InetAddress.getLocalHost().getHostAddress()+":"+httpServerPort;
+ System.out.println("Jason Http Server running on "+httpServerURL);
+ } catch (BindException e) {
+ httpServerPort++;
+ return startHttpServer();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ return httpServerURL;
+ }
+
+ private void registerRootBrowserView() {
+ if (httpServer == null)
+ return;
+ try {
+ httpServer.createContext("/", new HttpHandler() {
+ public void handle(HttpExchange exchange) throws IOException {
+ String requestMethod = exchange.getRequestMethod();
+ Headers responseHeaders = exchange.getResponseHeaders();
+ responseHeaders.set("Content-Type", "text/html");
+ exchange.sendResponseHeaders(200, 0);
+ OutputStream responseBody = exchange.getResponseBody();
+
+ if (requestMethod.equalsIgnoreCase("GET")) {
+ responseBody.write(("<html><head><title>Jason Mind Inspector -- Web View</title><meta http-equiv=\"refresh\" content=\""+refreshInterval+"\" ></head><body>").getBytes());
+ responseBody.write(("<h2>Agents</h2><ul>").getBytes());
+ for (String a: histories.keySet()) {
+ responseBody.write( ("<li><a href=\"/agent-mind/"+a+"/latest\">"+a+"</a>").getBytes());
+ //responseBody.write( (" <a href=\"/agent-code/"+a+"\">(code)</a></li>").getBytes());
+ responseBody.write( ("</li>").getBytes());
+ }
+ responseBody.write("</ul><hr/><a href=\"http://jason.sf.net\">Jason</a></body></html>".getBytes());
+ }
+ responseBody.close();
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public synchronized void addAgState(Agent ag, Document mind, boolean hasHistory) {
+ String agName = ag.getTS().getUserAgArch().getAgName();
+ List<Document> h = histories.get(agName);
+ if (h == null) {
+ h = new ArrayList<Document>();
+ registerAgView(agName);
+ //registerAgCodeBrowserView(agName, "not implemented");
+ histories.put(agName, h);
+ }
+ if (hasHistory || h.isEmpty())
+ h.add(mind);
+ else
+ h.set(0, mind);
+ }
+
+ String registerAgView(final String agName) {
+ if (httpServer == null)
+ return null;
+ try {
+ String url = "/agent-mind/"+agName;
+ httpServer.createContext(url, new HttpHandler() {
+ public void handle(HttpExchange exchange) throws IOException {
+ String requestMethod = exchange.getRequestMethod();
+ Headers responseHeaders = exchange.getResponseHeaders();
+ exchange.sendResponseHeaders(200, 0);
+ OutputStream responseBody = exchange.getResponseBody();
+ responseHeaders.set("Content-Type", "text/html");
+
+ if (requestMethod.equalsIgnoreCase("GET")) {
+ try {
+ StringWriter so = new StringWriter();
+ so.append("<html><head><title>"+agName+"</title>");
+ List<Document> h = histories.get(agName);
+ if (h != null) {
+ Document agState;
+ int i = -1;
+ exchange.getRemoteAddress();
+
+ String path = exchange.getRequestURI().getPath();
+ String query = exchange.getRequestURI().getRawQuery(); // what follows ?
+ String remote = exchange.getRemoteAddress().toString();
+
+ if (path.endsWith("hide")) {
+ show.put(query,false);
+ Integer ii = lastStepSeenByUser.get(remote);
+ if (ii != null)
+ i = ii;
+ } else if (path.endsWith("show")) {
+ show.put(query,true);
+ Integer ii = lastStepSeenByUser.get(remote);
+ if (ii != null)
+ i = ii;
+ } else if (path.endsWith("clear")) {
+ agState = h.get(h.size()-1);
+ h.clear();
+ h.add(agState);
+ } else {
+ // see if ends with a number
+ try {
+ int pos = path.lastIndexOf("/");
+ String n = path.substring(pos+1).trim();
+ i = new Integer(n);
+ } catch (Exception e) {}
+ }
+ if (i == -1) {
+ so.append("<meta http-equiv=\"refresh\" content=\""+refreshInterval+"\">");
+ agState = h.get(h.size()-1);
+ } else {
+ agState = h.get(i-1);
+ }
+ try {
+ lastStepSeenByUser.put(remote, i);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ so.append("</head><body>");
+ if (h.size() > 1) {
+ so.append("history: ");
+ so.append("<a href=/agent-mind/"+agName+"/latest>latest state</a> ");
+ for (i=h.size()-1; i>0; i--) {
+ so.append("<a href=\"/agent-mind/"+agName+"/"+i+"\" style=\"text-decoration: none\">"+i+"</a> ");
+ }
+ so.append("<a href=\"/agent-mind/"+agName+"/clear\">clear history</a> ");
+ so.append("<hr/>");
+ }
+ so.append(getAgStateAsString(agState, false));
+ so.append("<hr/><a href=\"/\"> list of agents</a> ");
+ } else {
+ so.append("no register for this agent!");
+ }
+ responseBody.write(so.toString().getBytes());
+
+ //responseBody.write(("<br/><a href=/agent-code/"+agName+">code</a>").getBytes());
+ responseBody.write("</body></html>".getBytes());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ responseBody.close();
+ }
+ });
+ return httpServerURL+url;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ String registerAgCodeBrowserView(String agId, final String agCode) {
+ if (httpServer == null)
+ return null;
+ try {
+ String url="/agent-code/"+agId;
+ httpServer.createContext(url, new HttpHandler() {
+ public void handle(HttpExchange exchange) throws IOException {
+ String requestMethod = exchange.getRequestMethod();
+ Headers responseHeaders = exchange.getResponseHeaders();
+ responseHeaders.set("Content-Type", "text/html");
+ exchange.sendResponseHeaders(200, 0);
+ OutputStream responseBody = exchange.getResponseBody();
+
+ if (requestMethod.equalsIgnoreCase("GET")) {
+ responseBody.write(agCode.getBytes());
+ }
+ responseBody.close();
+ }
+ });
+ return httpServerURL+url;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ */
+
+ protected asl2xml mindInspectorTransformer = null;
+ Map<String,Boolean> show = new HashMap<String,Boolean>();
+
+ synchronized String getAgStateAsString(Document ag, boolean full) { // full means with show all
+ try {
+ if (mindInspectorTransformer == null) {
+ mindInspectorTransformer = new asl2html("/xml/agInspection.xsl");
+
+ show.put("bels", true);
+ show.put("annots", Config.get().getBoolean(Config.SHOW_ANNOTS));
+ show.put("rules", false);
+ show.put("evt", true);
+ show.put("mb", false);
+ show.put("int", false);
+ show.put("int-details", false);
+ show.put("plan", false);
+ show.put("plan-details", false);
+ }
+ for (String p: show.keySet())
+ if (full)
+ mindInspectorTransformer.setParameter("show-"+p, "true");
+ else
+ mindInspectorTransformer.setParameter("show-"+p, show.get(p)+"");
+ return mindInspectorTransformer.transform(ag); // transform to HTML
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error XML transformation (MindInspector)";
+ }
+ }
+
+}
Modified: trunk/src/jason/control/ExecutionControlGUI.java
===================================================================
--- trunk/src/jason/control/ExecutionControlGUI.java 2014-06-02 21:28:22 UTC (rev 1784)
+++ trunk/src/jason/control/ExecutionControlGUI.java 2014-06-03 18:50:24 UTC (rev 1785)
@@ -125,7 +125,7 @@
// Which item is to be shown in HTML interface
Map<String,Boolean> show = new HashMap<String,Boolean>();
- public static String title = ":: Jason Mind Inspector ::";
+ public static String title = "..:: Mind Inspector ::..";
void initComponents() {
frame = new JFrame(title);
Modified: trunk/src/xml/agInspection.xsl
===================================================================
--- trunk/src/xml/agInspection.xsl 2014-06-02 21:28:22 UTC (rev 1784)
+++ trunk/src/xml/agInspection.xsl 2014-06-03 18:50:24 UTC (rev 1785)
@@ -287,11 +287,8 @@
<xsl:apply-templates select="@trigger"/>
<xsl:if test="$show-int-details='true'">
<!-- td valign="top" style="{$td-style}" -->
- <br/>
-
- <font size="-2">
- <pre> <- ... <xsl:apply-templates select="body"/> </pre>
- </font>
+ <br/>
+ <pre> <- ... <xsl:apply-templates select="body"/> </pre>
<!-- /td -->
</xsl:if>
</td>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|