001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.extend;
017:
018: import java.lang.reflect.Method;
019: import java.util.Map;
020:
021: import org.directwebremoting.ScriptSession;
022: import org.directwebremoting.WebContext;
023: import org.directwebremoting.WebContextFactory;
024: import org.directwebremoting.io.RawData;
025: import org.directwebremoting.proxy.Callback;
026: import org.directwebremoting.util.IdGenerator;
027:
028: /**
029: * A class to help with the use of {@link Callback}s
030: * @author Joe Walker [joe at getahead dot ltd dot uk]
031: */
032: public class CallbackHelper {
033: /**
034: * Used by the many proxy classes to record a callback for later calling
035: * @param callback The callback that acts on the type
036: * @param type The type of the data that we are recording
037: * @return A key under which the data is stored
038: */
039: @SuppressWarnings("unchecked")
040: public static <T> String saveCallback(Callback<T> callback,
041: Class<T> type) {
042: String key = createUniqueId();
043:
044: for (ScriptSession session : callback.getScriptSessions()) {
045: // Save the callback itself
046: Map<String, Callback<T>> callbackMap = (Map<String, Callback<T>>) session
047: .getAttribute(KEY_CALLBACK);
048: callbackMap.put(key, callback);
049: session.setAttribute(KEY_CALLBACK, callbackMap);
050:
051: // And save the type of the callback
052: Map<String, Class<T>> typeMap = (Map<String, Class<T>>) session
053: .getAttribute(KEY_TYPE);
054: typeMap.put(key, type);
055: session.setAttribute(KEY_TYPE, typeMap);
056: }
057:
058: return key;
059: }
060:
061: /**
062: * The reverse of {@link #saveCallback(Callback, Class)}
063: * which executes a {@link Callback} which has been
064: * @param key
065: * @param data
066: * @throws MarshallException
067: */
068: @SuppressWarnings("unchecked")
069: public static <T> void executeCallback(String key, RawData data)
070: throws MarshallException {
071: WebContext webContext = WebContextFactory.get();
072: ScriptSession session = webContext.getScriptSession();
073: ConverterManager converterManager = webContext.getContainer()
074: .getBean(ConverterManager.class);
075:
076: Map<String, Class<T>> typeMap = (Map<String, Class<T>>) session
077: .getAttribute(KEY_TYPE);
078: Class<T> type = typeMap.remove(key);
079: session.removeAttribute(KEY_TYPE);
080: session.setAttribute(KEY_TYPE, typeMap);
081:
082: try {
083: Method method = Callback.class.getMethod("dataReturned",
084: type);
085:
086: InboundContext inctx = data.getInboundContext();
087: TypeHintContext incc = new TypeHintContext(
088: converterManager, method, 0);
089: InboundVariable iv = data.getInboundVariable();
090: Object callbackData = converterManager.convertInbound(type,
091: iv, inctx, incc);
092:
093: Map<String, Callback<T>> callbackMap = (Map<String, Callback<T>>) session
094: .getAttribute(KEY_TYPE);
095: Callback<T> callback = callbackMap.remove(key);
096: session.removeAttribute(KEY_TYPE);
097: session.setAttribute(KEY_CALLBACK, callbackMap);
098:
099: callback.dataReturned((T) callbackData);
100: } catch (Exception ex) {
101: throw new MarshallException(type, ex);
102: }
103: }
104:
105: /**
106: * Callbacks need a unique ID
107: */
108: public static String createUniqueId() {
109: return idGenerator.generateId(16);
110: }
111:
112: /**
113: * Callbacks need a unique ID
114: */
115: private static IdGenerator idGenerator = new IdGenerator();
116:
117: /**
118: * The key that we use in a script session to store Callbacks
119: */
120: public static final String KEY_CALLBACK = "org.directwebremoting.callback";
121:
122: /**
123: * The key that we use in a script session to store Callbacks
124: */
125: public static final String KEY_TYPE = "org.directwebremoting.type";
126: }
|