@SuppressWarnings("unchecked") private static Class<? extends ServiceDocument> getTypeFromKind(String documentKind) { // TODO: how to find class? // Check if kind was registered Class<?> clazz = Utils.getTypeFromKind(documentKind); if (clazz == null) { String className = documentKind.replace(':', '.'); while (true) { try { clazz = Class.forName(className); break; } catch (ClassNotFoundException e) { int i = className.lastIndexOf('.'); if (i == -1) { logger.warning("State type not found for " + documentKind); return null; } // Check if inner class, replace last '.' with '$' StringBuilder sb = new StringBuilder(className); sb.setCharAt(i, '$'); className = sb.toString(); } } // Register kind Utils.registerKind(clazz, documentKind); } return (Class<? extends ServiceDocument>) clazz; }
@Override public ResourceState deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonElement documentKind = json.getAsJsonObject().get("documentKind"); if (documentKind == null) { // deserialize as ResourceState if documentKink is not available Utils.log(ResourceStateDeserializer.class, "deserialize", Level.WARNING, "Json document of type %s does not have a documentKind field", typeOfT.getTypeName()); return Utils.fromJson(json, typeOfT); } Class<?> clazz = Utils.getTypeFromKind(documentKind.getAsString()); if (clazz != null) { return context.deserialize(json, clazz); } else { // deserialize as ResourceState if type is not registered Utils.log(ResourceStateDeserializer.class, "deserialize", Level.WARNING, "Json document of type %s and kind %s does not declare derived deserializer", typeOfT, documentKind.getAsString()); return Utils.fromJson(json, typeOfT); } } }
private static ServiceDocument extractServiceState(Operation getOp, ServiceHost serviceHost) { ServiceDocument userState = QueryFilterUtils.getServiceState(getOp, serviceHost); if (userState == null) { Object rawBody = getOp.getBodyRaw(); Class<?> serviceTypeClass = null; if (rawBody instanceof String) { String kind = Utils.getJsonMapValue(rawBody, ServiceDocument.FIELD_NAME_KIND, String.class); serviceTypeClass = Utils.getTypeFromKind(kind); } else { serviceTypeClass = rawBody.getClass(); } if (serviceTypeClass != null) { userState = (ServiceDocument)Utils.fromJson(rawBody, serviceTypeClass); } } return userState; }
@Test public void registerKind() { String kindBefore = Utils.buildKind(ExampleServiceState.class); String newKind = "e"; Utils.registerKind(ExampleServiceState.class, newKind); String kindAfter = Utils.buildKind(ExampleServiceState.class); assertEquals(newKind, kindAfter); Utils.registerKind(ExampleServiceState.class, kindBefore); kindAfter = Utils.buildKind(ExampleServiceState.class); assertEquals(kindBefore, kindAfter); Class<?> stateClass = Utils.getTypeFromKind(kindAfter); assertEquals(stateClass.getCanonicalName(), ExampleServiceState.class.getCanonicalName()); }
@Test public void registerKind() { String kindBefore = Utils.buildKind(ExampleServiceState.class); String newKind = "e"; Utils.registerKind(ExampleServiceState.class, newKind); String kindAfter = Utils.buildKind(ExampleServiceState.class); assertEquals(newKind, kindAfter); Utils.registerKind(ExampleServiceState.class, kindBefore); kindAfter = Utils.buildKind(ExampleServiceState.class); assertEquals(kindBefore, kindAfter); Class<?> stateClass = Utils.getTypeFromKind(kindAfter); assertEquals(stateClass.getCanonicalName(), ExampleServiceState.class.getCanonicalName()); }