/** * Optionally tag the {@link JSONObject} with the {@link Class} of the other {@link Object}. * * @param obj whose {@link Class} should be tagged * @param jsonObject that should be tagged * @param isAddClassTag if this is {@code false}, no action will be performed * @return the {@code jsonObject} */ public static JSONObject addClassTag(Object obj, JSONObject jsonObject, boolean isAddClassTag) { return isAddClassTag ? addClassTag(obj, jsonObject) : jsonObject; }
/** * Deserialize a given JSON datatype. The following cases are supported: * <ul> * <li>{@code json} is a (JSON) {@code null} value;</li> * <li>{@code json} is a basic (JSON) datatype;</li> * <li>{@code json} is a {@link Class}-tagged {@link JSONObject} that corresponds to a {@link JsonSerializable};</li> * <li>{@code json} is a {@link JSONArray} with {@link Class}-tagged {@link JSONObject}s that correspond to a * {@link JsonSerializable}s - in this case, the result type is a {@link List}.</li> * </ul> * * @param json the JSON data * @return the deserialization result */ public static Object deserialize(Object json) { if (isJsonNull(json)) return null; else if (isUnconvertedInstance(json)) return json; else if (json instanceof JSONObject) return deserialize((JSONObject) json); else if (json instanceof JSONArray) return deserializeAllAsList((JSONArray) json); throw new SerializationException(String.format("Don't know how to deserialize %s.", json)); }
/** * Try to serialize the given {@link Object}. It must be JSON-compatible or a {@link JsonSerializable}. * * @param obj the {@link Object} to serialize * @param isPolymorph in case a {@link JSONObject} is created, whether it should be tagged with the {@link Class} * of {@code obj} * @return the serialization result * @see #isJsonCompatible(Object) */ public static Object serialize(Object obj, boolean isPolymorph) { if (obj == null) return null; if (isJsonCompatible(obj)) { return obj; } if (obj instanceof JsonSerializable) return serialize((JsonSerializable) obj, isPolymorph); throw new IllegalArgumentException(String.format("Cannot serialize %s.", obj)); }
/** * Deserialize a {@link JSONArray} according to the rules of {@link #deserialize(JSONObject, JsonSerializer)}. * * @param jsonArray the {@link JSONArray} * @param serializer the {@link JsonSerializer} * @return the deserialization product */ @SuppressWarnings("unchecked") public static <T> List<T> deserializeAllAsList(JSONArray jsonArray, JsonSerializer<T> serializer) { List<T> result = new ArrayList<>(jsonArray.length()); for (Object jsonElement : jsonArray) { result.add(isJsonNull(jsonElement) ? null : deserialize((JSONObject) jsonElement, serializer)); } return result; }
@Override public JSONObject serialize(AtomicExecutionGroup aeg) { AtomicExecution.KeyOrLoadSerializer atomicExecutionSerializer = new AtomicExecution.KeyOrLoadSerializer(null, aeg.estimationContext); return new JSONObject() .put("ctx", JsonSerializables.serialize(aeg.estimationContext, false, EstimationContext.defaultSerializer)) .put("platform", JsonSerializables.serialize(aeg.platform, true, Platform.jsonSerializer)) .put("executions", JsonSerializables.serializeAll(aeg.atomicExecutions, false, atomicExecutionSerializer)); }
/** * Serialize the given {@link JsonSerializable}. * * @param serializable the {@link JsonSerializable} to serialize * @param isPolymorph in case a {@link JSONObject} is created, whether it should be tagged with the {@link Class} * of {@code serializable} * @return the serialization result */ public static JSONObject serialize(JsonSerializable serializable, boolean isPolymorph) { return serialize(serializable, isPolymorph, JsonSerializable.uncheckedSerializer); }
/** * Try to serialize the given {@link Object}s. They must be JSON-compatible or a {@link JsonSerializable}s. * * @param collection the {@link Object}s to serialize * @param isPolymorph in case a {@link JSONObject} is created, whether it should be tagged with the {@link Class} * of the according {@link Object} * @return the serialization result * @see #isJsonCompatible(Object) */ public static JSONArray serializeAll(Collection<?> collection, boolean isPolymorph) { if (isJsonNull(collection)) return null; JSONArray jsonArray = new JSONArray(); for (Object obj : collection) { jsonArray.put(serialize(obj, isPolymorph)); } return jsonArray; }
/** * Deserializes an object. * * @param json that should be serialized * @return the deserialized object */ @SuppressWarnings("unchecked") default T deserialize(JSONObject json) { if (JsonSerializables.isJsonNull(json)) return null; try { final Class<?> classTag = JsonSerializables.getClassTag(json); if (classTag == null) { throw new IllegalArgumentException(String.format("Cannot determine class from %s.", json)); } return this.deserialize(json, (Class<? extends T>) classTag); } catch (ClassNotFoundException e) { throw new SerializationException("Could not load class.", e); } }
@Override public AtomicExecutionGroup deserialize(JSONObject json, Class<? extends AtomicExecutionGroup> cls) { return new AtomicExecutionGroup( JsonSerializables.deserialize( json.getJSONObject("ctx"), SimpleEstimationContext.jsonSerializer, SimpleEstimationContext.class ), JsonSerializables.deserialize( json.getJSONObject("platform"), Platform.jsonSerializer ), this.configuration, JsonSerializables.deserializeAllAsList( json.getJSONArray("executions"), new AtomicExecution.KeyOrLoadSerializer(this.configuration, null), AtomicExecution.class ) ); } }
/** * Tag the {@link JSONObject} with the {@link Class} of the other {@link Object}. * * @param obj whose {@link Class} should be tagged * @param jsonObject that should be tagged * @return the {@code jsonObject} */ public static JSONObject addClassTag(Object obj, JSONObject jsonObject) { if (isJsonNull(jsonObject)) return jsonObject; return jsonObject.put("_class", obj.getClass().getCanonicalName()); }
@SuppressWarnings("unused") public static LoadProfile fromJson(JSONObject jsonObject) { return new LoadProfile( JsonSerializables.deserialize(jsonObject.getJSONObject("cpu"), LoadEstimate.class), JsonSerializables.deserialize(jsonObject.getJSONObject("ram"), LoadEstimate.class), JsonSerializables.deserialize(jsonObject.optJSONObject("network"), LoadEstimate.class), JsonSerializables.deserialize(jsonObject.optJSONObject("disk"), LoadEstimate.class), jsonObject.getDouble("utilization"), jsonObject.getLong("overhead") ); } }
/** * Deserialize a {@link JSONArray} according to the rules of {@link #deserialize(JSONObject, Class)}. * * @param jsonArray the {@link JSONArray} * @param cls the {@link Class} of the elements in the {@code jsonArray} * @return the deserialization product */ @SuppressWarnings("unchecked") public static <T> List<T> deserializeAllAsList(JSONArray jsonArray, Class<T> cls) { return deserializeAllAsList(jsonArray, (JsonSerializer<T>) JsonSerializable.uncheckedSerializer(), cls); }
@Override public JSONObject serialize(PartialExecution pe) { return new JSONObject() .put("millis", pe.measuredExecutionTime) .put("lowerCost", pe.lowerCost) .put("upperCost", pe.upperCost) .put("execGroups", JsonSerializables.serializeAll( pe.atomicExecutionGroups, false, new AtomicExecutionGroup.Serializer(this.configuration)) ) .putOpt( "initPlatforms", JsonSerializables.serializeAll(pe.initializedPlatforms, true, Platform.jsonSerializer) ); }
/** * Tells whether the given instance is a JSON datatype. * * @param obj the instance to test * @return whether {@code obj} is a JSON datatype */ public static boolean isJsonCompatible(Object obj) { return isUnconvertedInstance(obj) || obj == JSONObject.NULL || obj instanceof JSONObject || obj instanceof JSONArray; }
/** * Deserialize a {@link Class}-tagged {@link JSONObject} that should correspond to a {@link JsonSerializable}. * * @param jsonObject the {@link JSONObject} * @return the deserialization product */ @SuppressWarnings("unchecked") public static <T> T deserialize(JSONObject jsonObject) { if (isJsonNull(jsonObject)) return null; return deserialize(jsonObject, JsonSerializable.uncheckedSerializer()); }
/** * Serialize the given {@link Object}s using a specific {@link JsonSerializer}. * * @param collection the {@link Object}s to serialize * @param isPolymorph in case a {@link JSONObject} is created, whether it should be tagged with the {@link Class} * of {@code serializable} * @param serializer the {@link JsonSerializer} * @return the serialization result */ public static <T> JSONArray serializeAll(Collection<T> collection, boolean isPolymorph, JsonSerializer<T> serializer) { if (collection == null) return null; JSONArray jsonArray = new JSONArray(); for (T serializable : collection) { jsonArray.put(serialize(serializable, isPolymorph, serializer)); } return jsonArray; }
/** * Read and load the specified {@link Class} in a {@link JSONObject}. * * @param jsonObject that contains the {@link Class} tag * @return the loaded {@link Class} or {@code null} if none exists * @throws ClassNotFoundException if the {@link Class} could not be loaded */ public static Class<?> getClassTag(JSONObject jsonObject) throws ClassNotFoundException { if (isJsonNull(jsonObject) || !jsonObject.has("_class")) return null; final String className = jsonObject.getString("_class"); return Class.forName(className); }
/** * Streams the contents of this instance. * * @return a {@link Stream} of the contained {@link PartialExecution}s * @throws IOException */ public Stream<PartialExecution> stream() throws IOException { IOUtils.closeQuietly(this.writer); this.writer = null; final PartialExecution.Serializer serializer = new PartialExecution.Serializer(this.configuration); return Files.lines(Paths.get(this.repositoryPath), Charset.forName("UTF-8")) .map(line -> { try { return JsonSerializables.deserialize(new JSONObject(line), serializer, PartialExecution.class); } catch (Exception e) { throw new RheemException(String.format("Could not parse \"%s\".", line), e); } }); }
@Override public PartialExecution deserialize(JSONObject json, Class<? extends PartialExecution> cls) { final long measuredExecutionTime = json.getLong("millis"); final double lowerCost = json.optDouble("lowerCost", -1); final double uppserCost = json.optDouble("upperCost", -1); final Collection<AtomicExecutionGroup> atomicExecutionGroups = JsonSerializables.deserializeAllAsList( json.getJSONArray("execGroups"), new AtomicExecutionGroup.Serializer(this.configuration), AtomicExecutionGroup.class ); final Collection<Platform> initializedPlatforms = JsonSerializables.deserializeAllAsList(json.optJSONArray("initPlatforms"), Platform.jsonSerializer); final PartialExecution partialExecution = new PartialExecution( atomicExecutionGroups, measuredExecutionTime, lowerCost, uppserCost ); partialExecution.initializedPlatforms.addAll(initializedPlatforms); return partialExecution; } }
@Override public JSONObject serialize(EstimationContext ctx) { JSONObject doubleProperties = new JSONObject(); for (String key : ctx.getPropertyKeys()) { double value = ctx.getDoubleProperty(key, 0); doubleProperties.put(key, value); } if (doubleProperties.length() == 0) doubleProperties = null; return new JSONObject() .put("inCards", JsonSerializables.serializeAll(Arrays.asList(ctx.getInputCardinalities()), false)) .put("outCards", JsonSerializables.serializeAll(Arrays.asList(ctx.getOutputCardinalities()), false)) .put("executions", ctx.getNumExecutions()) .putOpt("properties", doubleProperties); }