001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2012 GRANITE DATA SERVICES S.A.S.
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019 */
020
021 package org.granite.client.tide.impl;
022
023 import java.lang.reflect.ParameterizedType;
024 import java.lang.reflect.Type;
025
026 import org.granite.client.messaging.events.Event;
027 import org.granite.client.messaging.events.IncomingMessageEvent;
028 import org.granite.client.messaging.events.ResultEvent;
029 import org.granite.client.tide.Context;
030 import org.granite.client.tide.server.ComponentListener;
031 import org.granite.client.tide.server.ServerSession;
032 import org.granite.client.tide.server.TideMergeResponder;
033 import org.granite.client.tide.server.TideResponder;
034 import org.granite.client.tide.server.TideResultEvent;
035 import org.granite.tide.invocation.InvocationResult;
036
037 /**
038 * @author William DRAI
039 */
040 public class ResultHandler<T> implements Runnable {
041
042 private final ServerSession serverSession;
043 private final Context sourceContext;
044 private final String componentName;
045 private final String operation;
046 private final Event event;
047 @SuppressWarnings("unused")
048 private final Object info;
049 private final TideResponder<T> tideResponder;
050 private final ComponentListener<T> componentListener;
051 private boolean executed = false;
052
053
054 public ResultHandler(ServerSession serverSession, Context sourceContext, String componentName, String operation,
055 Event event, Object info, TideResponder<T> tideResponder, ComponentListener<T> componentListener) {
056 this.serverSession = serverSession;
057 this.sourceContext = sourceContext;
058 this.componentName = componentName;
059 this.operation = operation;
060 this.event = event;
061 this.info = info;
062 this.tideResponder = tideResponder;
063 this.componentListener = componentListener;
064 }
065
066 @SuppressWarnings("unchecked")
067 public void run() {
068 if (executed)
069 return;
070 executed = true;
071 InvocationResult invocationResult = null;
072 Object result = null;
073 if (event instanceof ResultEvent)
074 result = ((ResultEvent)event).getResult();
075 else if (event instanceof IncomingMessageEvent<?>)
076 result = ((IncomingMessageEvent<?>)event).getMessage();
077
078 if (result instanceof InvocationResult) {
079 invocationResult = (InvocationResult)result;
080 result = invocationResult.getResult();
081 }
082
083 if (tideResponder != null) {
084 for (Type type : tideResponder.getClass().getGenericInterfaces()) {
085 if (type instanceof ParameterizedType && ((ParameterizedType)type).getRawType().equals(TideResponder.class)) {
086 Type expectedReturnType = ((ParameterizedType)type).getActualTypeArguments()[0];
087 result = serverSession.getConverters().convert(result, expectedReturnType);
088 if (invocationResult != null)
089 invocationResult.setResult(result);
090 break;
091 }
092 }
093 }
094
095 // var conversationId:String = null;
096 // if (event.message.headers[Tide.IS_LONG_RUNNING_CONVERSATION_TAG])
097 // conversationId = event.message.headers[Tide.CONVERSATION_TAG];
098 // var wasConversationCreated:Boolean = event.message.headers[Tide.WAS_LONG_RUNNING_CONVERSATION_CREATED_TAG] != null;
099 // var wasConversationEnded:Boolean = event.message.headers[Tide.WAS_LONG_RUNNING_CONVERSATION_ENDED_TAG] != null;
100 //
101 // var context:Context = _contextManager.retrieveContext(sourceContext, conversationId, wasConversationCreated, wasConversationEnded);
102
103 Context context = sourceContext.getContextManager().retrieveContext(sourceContext, null, false, false); // conversationId, wasConversationCreated, wasConversationEnded);
104
105 serverSession.handleResultEvent(event);
106
107 serverSession.handleResult(context, componentName, operation, invocationResult, result,
108 tideResponder instanceof TideMergeResponder<?> ? ((TideMergeResponder<T>)tideResponder).getMergeResultWith() : null);
109 if (invocationResult != null)
110 result = invocationResult.getResult();
111
112 @SuppressWarnings("unused")
113 boolean handled = false;
114 if (tideResponder != null) {
115 TideResultEvent<T> resultEvent = new TideResultEvent<T>(context, serverSession, componentListener, (T)result);
116 tideResponder.result(resultEvent);
117 if (resultEvent.isDefaultPrevented())
118 handled = true;
119 }
120
121 componentListener.setResult((T)result);
122
123 // context.clearData();
124 //
125 // // Should be after event result handling and responder: previous could trigger other remote calls
126 // if (context.isFinished())
127 // context.scheduleDestroy();
128 //
129 // if (!handled && !serverSession.isLogoutInProgress())
130 // context.raiseEvent(Tide.CONTEXT_RESULT, result);
131
132 serverSession.tryLogout();
133 }
134 }