/* * Copyright 2005 Joe Walker * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.directwebremoting.impl; import java.lang.reflect.Method; import java.util.Map; import org.directwebremoting.ConversionException; import org.directwebremoting.ScriptSession; import org.directwebremoting.WebContext; import org.directwebremoting.WebContextFactory; import org.directwebremoting.extend.CallbackHelper; import org.directwebremoting.extend.ConverterManager; import org.directwebremoting.extend.InboundVariable; import org.directwebremoting.extend.ParameterProperty; import org.directwebremoting.extend.Property; import org.directwebremoting.extend.RealRawData; import org.directwebremoting.ui.Callback; import org.directwebremoting.util.IdGenerator; /** * The default implementation of CallbackHelper * @author Joe Walker [joe at getahead dot ltd dot uk] */ public class DefaultCallbackHelper implements CallbackHelper { /* (non-Javadoc) * @see org.directwebremoting.extend.CallbackHelper#saveCallback(org.directwebremoting.proxy.Callback, java.lang.Class) */ @SuppressWarnings("unchecked") public <T> String saveCallback(Callback<T> callback, Class<T> type) { String key = createUniqueId(); for (ScriptSession session : callback.getScriptSessions()) { // Save the callback itself Map<String, Callback<T>> callbackMap = (Map<String, Callback<T>>) session.getAttribute(KEY_CALLBACK); callbackMap.put(key, callback); session.setAttribute(KEY_CALLBACK, callbackMap); // And save the type of the callback Map<String, Class<T>> typeMap = (Map<String, Class<T>>) session.getAttribute(KEY_TYPE); typeMap.put(key, type); session.setAttribute(KEY_TYPE, typeMap); } return key; } /** * The reverse of {@link CallbackHelper#saveCallback(Callback, Class)} * which executes a {@link Callback} which has been called by the browser */ @SuppressWarnings("unchecked") public static <T> void executeCallback(String key, RealRawData data) throws ConversionException { WebContext webContext = WebContextFactory.get(); ScriptSession session = webContext.getScriptSession(); ConverterManager converterManager = webContext.getContainer().getBean(ConverterManager.class); Map<String, Class<T>> typeMap = (Map<String, Class<T>>) session.getAttribute(KEY_TYPE); Class<T> type = typeMap.remove(key); session.removeAttribute(KEY_TYPE); session.setAttribute(KEY_TYPE, typeMap); try { Method method = Callback.class.getMethod("dataReturned", type); Property property = new ParameterProperty(method, 0); InboundVariable iv = data.getInboundVariable(); Object callbackData = converterManager.convertInbound(type, iv, property); Map<String, Callback<T>> callbackMap = (Map<String, Callback<T>>) session.getAttribute(KEY_TYPE); Callback<T> callback = callbackMap.remove(key); session.removeAttribute(KEY_TYPE); session.setAttribute(KEY_CALLBACK, callbackMap); callback.dataReturned((T) callbackData); } catch (Exception ex) { throw new ConversionException(type, ex); } } /** * Callbacks need a unique ID */ public static String createUniqueId() { return idGenerator.generateId(16); } /** * Callbacks need a unique ID */ private static IdGenerator idGenerator = new IdGenerator(); /** * The key that we use in a script session to store Callbacks */ public static final String KEY_CALLBACK = "org.directwebremoting.callback"; /** * The key that we use in a script session to store Callbacks */ public static final String KEY_TYPE = "org.directwebremoting.type"; }