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    }