}
@SuppressWarnings("unchecked")
@Override
public WOResponse handleRequest(WORequest request) {
WOApplication application = WOApplication.application();
application.awake();
try {
WOContext context = application.createContextForRequest(request);
WOResponse response = application.createResponseInContext(context);
Object output;
try {
String inputString = request.contentString();
JSONObject input = new JSONObject(inputString);
String sessionIdKey = WOApplication.application().sessionIdKey();
String sessionId = request.cookieValueForKey(sessionIdKey);
if (sessionId == null) {
ERXMutableURL url = new ERXMutableURL();
url.setQueryParameters(request.queryString());
sessionId = url.queryParameter(sessionIdKey);
if (sessionId == null && input.has(sessionIdKey)) {
sessionId = input.getString(sessionIdKey);
}
}
context._setRequestSessionID(sessionId);
WOSession session = null;
if (context._requestSessionID() != null) {
session = WOApplication.application().restoreSessionWithID(sessionId, context);
}
if (session != null) {
session.awake();
}
try {
JSONComponentCallback componentCallback = null;
WODynamicURL url = request._uriDecomposed();
String requestHandlerPath = url.requestHandlerPath();
JSONRPCBridge jsonBridge;
if (requestHandlerPath != null && requestHandlerPath.length() > 0) {
String componentNameAndInstance = requestHandlerPath;
String componentInstance;
String componentName;
int slashIndex = componentNameAndInstance.indexOf('/');
if (slashIndex == -1) {
componentName = componentNameAndInstance;
componentInstance = null;
}
else {
componentName = componentNameAndInstance.substring(0, slashIndex);
componentInstance = componentNameAndInstance.substring(slashIndex + 1);
}
if (session == null) {
session = context.session();
}
String bridgesKey = (componentInstance == null) ? "_JSONGlobalBridges" : "_JSONInstanceBridges";
Map<String, JSONRPCBridge> componentBridges = (Map<String, JSONRPCBridge>) session.objectForKey(bridgesKey);
if (componentBridges == null) {
int limit = ERXProperties.intForKeyWithDefault((componentInstance == null) ? "er.ajax.json.globalBacktrackCacheSize" : "er.ajax.json.backtrackCacheSize", WOApplication.application().pageCacheSize());
componentBridges = new LRUMap<String, JSONRPCBridge>(limit);
session.setObjectForKey(componentBridges, bridgesKey);
}
jsonBridge = componentBridges.get(componentNameAndInstance);
if (jsonBridge == null) {
Class componentClass = _NSUtilities.classWithName(componentName);
JSONComponent component;
if (JSONComponent.class.isAssignableFrom(componentClass)) {
component = (JSONComponent) _NSUtilities.instantiateObject(componentClass, new Class[] { WOContext.class }, new Object[] { context }, true, false);
}
else {
throw new SecurityException("There is no JSON component named '" + componentName + "'.");
}
jsonBridge = createBridgeForComponent(component, componentName, componentInstance, componentBridges);
}
componentCallback = new JSONComponentCallback(context);
jsonBridge.registerCallback(componentCallback, WOContext.class);
}
else {
jsonBridge = _sharedBridge;
}
try {
output = jsonBridge.call(new Object[] { request, response, context }, input);
}
finally {
if (componentCallback != null) {
jsonBridge.unregisterCallback(componentCallback, WOContext.class);
}
}
if (context._session() != null) {
WOSession contextSession = context._session();
// If this is a new session, then we have to force it to be a cookie session
if (sessionId == null) {
boolean storesIDsInCookies = contextSession.storesIDsInCookies();
try {
contextSession.setStoresIDsInCookies(true);
contextSession._appendCookieToResponse(response);
}
finally {
contextSession.setStoresIDsInCookies(storesIDsInCookies);
}
}
else {
contextSession._appendCookieToResponse(response);
}
}
response.appendContentString(output.toString());
response._finalizeInContext(context);
response.disableClientCaching();
}
finally {
try {
if (session != null) {
session.sleep();
}
}
finally {
if (context._session() != null) {
WOApplication.application().saveSessionForContext(context);
}
}
}
}
catch (NoSuchElementException e) {
e.printStackTrace();
output = new JSONRPCResult(JSONRPCResult.CODE_ERR_NOMETHOD, null, JSONRPCResult.MSG_ERR_NOMETHOD);
}
catch (JSONException e) {
e.printStackTrace();
output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, JSONRPCResult.MSG_ERR_PARSE);
}
catch (Throwable t) {
t.printStackTrace();
output = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, t.getMessage());
}
return response;
}
finally {
application.sleep();
}
}