![JAR search and dependency download from the Maven repository](/logo.png)
org.ggp.base.util.crypto.CanonicalJSON Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.util.crypto;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import external.JSON.JSONArray;
import external.JSON.JSONException;
import external.JSON.JSONObject;
import external.JSON.JSONString;
public class CanonicalJSON {
/* Right now we only support one canonicalization strategy, which is
* the SIMPLE approach. In the future, we may need to make breaking changes
* to the canonicalization strategy, to support unforeseen situations (e.g.
* edge cases the current canonicalization strategy doesn't handle properly).
* However, we'd still like to be able to canonicalize data using the older
* strategies so that we can e.g. still verify signatures created using the
* older canonicalization strategy. So this class is designed to be able to
* support multiple canonicalization strategies, and the user chooses which
* strategy is used. */
static enum CanonicalizationStrategy {
SIMPLE,
}
/* Helper function to generate canonical strings for JSON strings */
static String getCanonicalForm(String x, CanonicalizationStrategy s) {
try {
return getCanonicalForm(new JSONObject(x), s);
} catch (JSONException e) {
return null;
}
}
/* Main function to generate canonical strings for JSON objects */
static String getCanonicalForm(JSONObject x, CanonicalizationStrategy s) {
if (s == CanonicalizationStrategy.SIMPLE) {
return renderSimpleCanonicalJSON(x);
} else {
throw new RuntimeException("Canonicalization strategy not recognized.");
}
}
/* This should be identical to the standard code to render the JSON object,
* except it forces the keys for maps to be listed in sorted order. */
static String renderSimpleCanonicalJSON(Object x) {
try {
if (x instanceof JSONObject) {
JSONObject theObject = (JSONObject)x;
// Sort the keys
TreeSet t = new TreeSet();
Iterator> i = theObject.keys();
while (i.hasNext()) t.add(i.next().toString());
Iterator keys = t.iterator();
StringBuilder sb = new StringBuilder("{");
while (keys.hasNext()) {
if (sb.length() > 1) {
sb.append(',');
}
Object o = keys.next();
sb.append(JSONObject.quote(o.toString()));
sb.append(':');
sb.append(renderSimpleCanonicalJSON(theObject.get(o.toString())));
}
sb.append('}');
return sb.toString();
} else if (x instanceof JSONArray) {
JSONArray theArray = (JSONArray)x;
StringBuilder sb = new StringBuilder();
sb.append("[");
int len = theArray.length();
for (int i = 0; i < len; i += 1) {
if (i > 0) {
sb.append(",");
}
sb.append(renderSimpleCanonicalJSON(theArray.get(i)));
}
sb.append("]");
return sb.toString();
} else {
if (x == null || x.equals(null)) {
return "null";
}
if (x instanceof JSONString) {
Object object;
try {
object = ((JSONString)x).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
if (object instanceof String) {
return (String)object;
}
throw new JSONException("Bad value from toJSONString: " + object);
}
if (x instanceof Number) {
return JSONObject.numberToString((Number)x);
}
if (x instanceof Boolean || x instanceof JSONObject ||
x instanceof JSONArray) {
return x.toString();
}
if (x instanceof Map) {
return renderSimpleCanonicalJSON(new JSONObject((Map,?>)x)).toString();
}
if (x instanceof Collection) {
return renderSimpleCanonicalJSON(new JSONArray((Collection>)x)).toString();
}
if (x.getClass().isArray()) {
return renderSimpleCanonicalJSON(new JSONArray(x)).toString();
}
return JSONObject.quote(x.toString());
}
} catch (Exception e) {
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy