package er.rest.format; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONNull; import net.sf.json.JSONObject; import net.sf.json.JSONSerializer; import net.sf.json.JsonConfig; import er.rest.ERXRestContext; import er.rest.ERXRestRequestNode; import er.rest.ERXRestUtils; /** * ERXJSONRestRequestParser is an implementation of the IERXRestRequestParser interface that supports JSON document * requests. * * @author mschrag */ public class ERXJSONRestParser implements IERXRestParser { public static ERXRestRequestNode createRequestNodeForJSON(String name, JSON json, boolean rootNode, ERXRestFormat.Delegate delegate) { ERXRestRequestNode requestNode = new ERXRestRequestNode(name, rootNode); if (json instanceof JSONNull) { // just leave the value null } else if (json instanceof JSONArray) { requestNode.setArray(true); JSONArray jsonArray = (JSONArray) json; for (Object obj : jsonArray) { if (ERXRestUtils.isPrimitive(obj)) { ERXRestRequestNode primitiveChild = new ERXRestRequestNode(null, obj, false); requestNode.addChild(primitiveChild); if (delegate != null) { delegate.nodeDidParse(primitiveChild); } } else { requestNode.addChild(ERXJSONRestParser.createRequestNodeForJSON(null, (JSON) obj, true, delegate)); } } } else if (json instanceof JSONObject) { JSONObject jsonObject = (JSONObject) json; for (Object key : jsonObject.keySet()) { String strKey = (String) key; Object value = jsonObject.get(key); if (ERXRestUtils.isPrimitive(value)) { ERXRestRequestNode primitiveChild = new ERXRestRequestNode(strKey, value, false); requestNode.addChild(primitiveChild); if (delegate != null) { delegate.nodeDidParse(primitiveChild); } } else { requestNode.addChild(ERXJSONRestParser.createRequestNodeForJSON(strKey, (JSON) value, false, delegate)); } } } else { throw new IllegalArgumentException("Unknown JSON value '" + json + "'."); } if (delegate != null) { delegate.nodeDidParse(requestNode); } return requestNode; } public ERXJSONRestParser() { } protected JsonConfig configWithContext(ERXRestContext context) { return _ERXJSONConfig.createDefaultConfig(context); } @Override public ERXRestRequestNode parseRestRequest(IERXRestRequest request, ERXRestFormat.Delegate delegate, ERXRestContext context) { ERXRestRequestNode rootRequestNode = null; String contentString = request.stringContent(); if (contentString != null) { contentString = contentString.trim(); } if (contentString != null && contentString.length() > 0 && !"undefined".equals(contentString)) { // MS: Support direct updating of primitive type keys -- so if you don't want to // wrap your request in XML, this will allow it // if (!contentStr.trim().startsWith("<")) { // contentStr = "<FakeWrapper>" + contentStr.trim() + "</FakeWrapper>"; // } JSON rootJSON = JSONSerializer.toJSON(contentString, configWithContext(context)); rootRequestNode = createRequestNodeForJSON(null, rootJSON, true, delegate); } else { rootRequestNode = new ERXRestRequestNode(null, true); rootRequestNode.setNull(true); } return rootRequestNode; } }