Skip to content
This repository has been archived by the owner on Jul 11, 2021. It is now read-only.

Commit

Permalink
Merge branch 'event_process_update'
Browse files Browse the repository at this point in the history
  • Loading branch information
Faterou committed Apr 12, 2017
2 parents a4b4a62 + 768c642 commit 571bae5
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public CornipickleServer(String server_name, int port)
registerCallback(new StatusPageCallback(m_interpreter, this));
registerCallback(new GetProbe(m_interpreter, m_serverName, m_port));
registerCallback(new DummyImage(m_interpreter));
registerCallback(new PreEvaluation(m_interpreter));
registerCallback(new JsonGetState(m_interpreter, this));
registerCallback(new JsonPutState(m_interpreter, this));
registerCallback(new FiddleCallback());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@
*/
class DummyImage extends InterpreterCallback
{
/**
* The name of the cookie used to pass info back to the probe
*/
protected static final String s_cookieName = "cornipickle";

/**
* Dummy image made of one white pixel
*/
Expand Down
224 changes: 224 additions & 0 deletions Source/Server/src/ca/uqac/lif/cornipickle/server/PreEvaluation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package ca.uqac.lif.cornipickle.server;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.DatatypeConverter;

import com.sun.net.httpserver.HttpExchange;

import ca.uqac.lif.cornipickle.Interpreter;
import ca.uqac.lif.cornipickle.Verdict;
import ca.uqac.lif.cornipickle.Interpreter.StatementMetadata;
import ca.uqac.lif.jerrydog.CallbackResponse;
import ca.uqac.lif.jerrydog.InnerFileServer;
import ca.uqac.lif.jerrydog.RequestCallback;
import ca.uqac.lif.json.JsonElement;
import ca.uqac.lif.json.JsonList;
import ca.uqac.lif.json.JsonMap;
import ca.uqac.lif.json.JsonNumber;
import ca.uqac.lif.json.JsonParser;
import ca.uqac.lif.json.JsonString;
import ca.uqac.lif.json.JsonParser.JsonParseException;

public class PreEvaluation extends InterpreterCallback {

/**
* Dummy image made of one white pixel
*/
static final byte[] s_dummyImage = InnerFileServer.readBytes(
CornipickleServer.class.getResourceAsStream("resource/dummy-image.png"));

/**
* Dummy image made of one red pixel
*/
static final byte[] s_dummyImageRed = InnerFileServer.readBytes(
CornipickleServer.class.getResourceAsStream("resource/dummy-image-red.png"));

/**
* Dummy image made of one green pixel
*/
static final byte[] s_dummyImageGreen = InnerFileServer.readBytes(
CornipickleServer.class.getResourceAsStream("resource/dummy-image-green.png"));

static JsonParser s_jsonParser;

public PreEvaluation(Interpreter i)
{
super(i, RequestCallback.Method.POST, "/preevaluate/");
s_jsonParser = new JsonParser();
}

/**
* Process like DummyImage but returns the original interpreter instead of the updated one.
*/
@Override
public CallbackResponse process(HttpExchange t)
{
Map<String,String> attributes = getParameters(t);

JsonElement j = null;
String memento = "";
try {
j = s_jsonParser.parse(URLDecoder.decode(attributes.get("contents"), "UTF-8"));
if(attributes.get("interpreter") != null)
{
memento = URLDecoder.decode(attributes.get("interpreter"), "UTF-8");
m_interpreter = m_interpreter.restoreFromMemento(memento);
}
} catch (JsonParseException e) {
e.printStackTrace(); //Never supposed to happen....
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if (j != null)
{
m_interpreter.evaluateAll(j);
//m_server.setLastProbeContact();
}

// Select the dummy image to send back
Map<StatementMetadata,Verdict> verdicts = m_interpreter.getVerdicts();
byte[] image_to_return = selectImage(verdicts);
// Create response
CallbackResponse cbr = new CallbackResponse(t);
cbr.setHeader("Access-Control-Allow-Origin", "*");
cbr.setContents(createResponseBody(verdicts, memento, image_to_return));
cbr.setContentType(CallbackResponse.ContentType.JSON);
m_interpreter.clear();
// DEBUG: print state
//com.google.gson.GsonBuilder builder = new com.google.gson.GsonBuilder();
//com.google.gson.Gson gson = builder.create();
//System.out.println(gson.toJson(m_interpreter));
return cbr;
}

/**
* Determines which of the three images (red, white, blue) to send back
* to the browser. The image is chosen as follows:
* <ul>
* <li>All properties evaluate to true: green</li>
* <li>No property to evaluate: white</li>
* <li>At least one property evaluates to false: red</li>
* </ul>
* @param verdicts A map from the metadata for each property to
* its current verdict
* @return The byte array with the contents of the selected image
*/
protected static byte[] selectImage(Map<StatementMetadata,Verdict> verdicts)
{
int num_errors = 0;
byte[] image_out = s_dummyImage;
for (StatementMetadata key : verdicts.keySet())
{
Verdict v = verdicts.get(key);
if (v.is(Verdict.Value.FALSE))
{
num_errors++;
}
}
if (num_errors == 0)
{
if (verdicts.isEmpty())
{
// Cornipickle has no property to evaluate
}
else
{
// All's well! All properties evaluate to true
}
}
else
{
// Errors found
image_out = s_dummyImageRed;
}
return image_out;
}

/**
* Creates the response body out of the verdict of each property handled by the
* interpreter. This response contains, for each property, its caption,
* a list of element IDs to highlight (if any), as well as the total
* number of true/false/inconclusive properties.
* In addition, it contains the serialized state of the current interpreter
* @param verdicts A map from the metadata for each property to
* its current verdict
* @param interpreter String in base 64 representing the state of the interpreter
* @param image The image to return as an array of bytes
* @return A JSON string to be passed as the response to
* the browser
*/
protected static String createResponseBody(Map<StatementMetadata,Verdict> verdicts, String interpreter, byte[] image)
{
int num_false = 0;
int num_true = 0;
int num_inconclusive = 0;
Verdict outcome = new Verdict(Verdict.Value.TRUE);
JsonList highlight_ids = new JsonList();
for (StatementMetadata key : verdicts.keySet())
{
JsonMap element = new JsonMap();
JsonList id_to_highlight = new JsonList();
Verdict v = verdicts.get(key);
outcome.conjoin(v);
if (v.is(Verdict.Value.FALSE))
{
num_false++;
id_to_highlight.addAll(getIdsToHighlight(v));
}
else if (v.is(Verdict.Value.TRUE))
{
num_true++;
}
else
{
num_inconclusive++;
}
element.put("ids", id_to_highlight);
element.put("caption", new JsonString(CornipickleServer.escapeQuotes(key.get("description"))));
highlight_ids.add(element);
}
JsonMap result = new JsonMap();
result.put("global-verdict", outcome.toPlainString());
result.put("num-true", num_true);
result.put("num-false", num_false);
result.put("num-inconclusive", num_inconclusive);
result.put("highlight-ids", highlight_ids);
result.put("interpreter", interpreter);
result.put("image", "data:image/png;base64," + DatatypeConverter.printBase64Binary(image));
// Below, we use true to get a compact JSON string without CF/LF
// (otherwise the cookie won't be passed correctly to the browser)
return result.toString("", true);
}

protected static JsonList getIdsToHighlight(Verdict v)
{
JsonList ids = new JsonList();
Set<Set<JsonElement>> tuples = v.getWitness().flatten();
for (Set<JsonElement> tuple : tuples)
{
JsonList out = new JsonList();
for (JsonElement e : tuple)
{
if (!(e instanceof JsonMap))
{
continue;
}
JsonMap m = (JsonMap) e;
JsonElement id = m.get("cornipickleid");
if (id == null || !(id instanceof JsonNumber))
{
continue;
}
out.add((JsonNumber) id);
}
ids.add(out);
}
return ids;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="/cornipickle.js"></script>
<script type="text/javascript" src="/probe"></script>
<script type="text/javascript" src="/cornipickle.js"></script>
<title>Misaligned menu elements - Cornipickle</title>
<script type="text/javascript">
// <![CDATA[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@ var dynamicProbe = function()
cp_probe.setProbeId( "1" );
cp_probe.setProbeHash( "interpreter" );
document.getElementById("cp-witness").innerHTML = "%%WITNESS_CODE%%";

if(document.getElementsByClassName("cornipickle-code"))
{
var codestring = "";
var codes = document.getElementsByClassName("cornipickle-code");
for(var i = 0; i < codes.length; i++)
{
codestring = codestring + codes[i].textContent.replace(/\u00A0/g, ' ');
}

$.ajax({
url : "/add",
type : "POST",
data : encodeURIComponent(codestring),
success : function(result) {
//$("#to-cornipickle").prop('disabled', true);
cp_probe.setAttributesToInclude(result.attributes);
cp_probe.setTagNamesToInclude(result.tagnames);
sessionStorage.interpreter = result.interpreter;
cp_probe.preEvaluate();
},
});
}
else
{
cp_probe.preEvaluate();
}
}, 500);
};

Expand Down
Loading

0 comments on commit 571bae5

Please sign in to comment.