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.export;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import javax.servlet.ServletContext;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.directwebremoting.Hub;
026: import org.directwebremoting.HubFactory;
027: import org.directwebremoting.ScriptBuffer;
028: import org.directwebremoting.ScriptSession;
029: import org.directwebremoting.WebContext;
030: import org.directwebremoting.WebContextFactory;
031: import org.directwebremoting.event.MessageEvent;
032: import org.directwebremoting.event.MessageListener;
033: import org.directwebremoting.extend.CallbackHelper;
034: import org.directwebremoting.extend.ConverterManager;
035: import org.directwebremoting.io.RawData;
036:
037: /**
038: * Various functions exported by DWR to help us with various book-keeping
039: * duties.
040: * @author Joe Walker [joe at getahead dot ltd dot uk]
041: */
042: public class System {
043: /**
044: * A method designed to be called on page load so the client knows about
045: * the http and script sessions. This method doesn't actually do anything
046: * however it does allow DWR's script session checking code to work
047: */
048: public void pageLoaded() {
049: }
050:
051: /**
052: * Call {@link ScriptSession#invalidate()} on the {@link ScriptSession}
053: * that called this method.
054: * Used by the page unloader.
055: */
056: public void pageUnloaded() {
057: WebContext wctx = WebContextFactory.get();
058: ScriptSession scriptSession = wctx.getScriptSession();
059:
060: log.debug("scriptSession.invalidate(): "
061: + scriptSession.getId());
062: scriptSession.invalidate();
063: }
064:
065: /**
066: * Used by reverse ajax proxies to send data back to the server
067: * @param key The unique id under which a callback is registered
068: * @param data The data to decode and pass to the callback
069: */
070: public void activateCallback(String key, RawData data) {
071: try {
072: CallbackHelper.executeCallback(key, data);
073: } catch (Exception ex) {
074: log.error("Failed to marshall data from callback", ex);
075: }
076: }
077:
078: /**
079: * Something has published to the client side 'hub' and we're getting to
080: * know about it.
081: * @param topic The topic that has been published to
082: * @param data The published data
083: */
084: public void publish(String topic, RawData data) {
085: WebContext webContext = WebContextFactory.get();
086: ConverterManager converterManager = webContext.getContainer()
087: .getBean(ConverterManager.class);
088: ServletContext servletContext = webContext.getServletContext();
089: Hub hub = HubFactory.get(servletContext);
090:
091: MessageEvent event = new MessageEvent(hub, converterManager,
092: data);
093: hub.publish(topic, event);
094: }
095:
096: /**
097: * Ensure that the clients know about server publishes
098: * @param topic The topic being subscribed to
099: * @param subscriptionId The ID to pass back to link to client side data
100: */
101: @SuppressWarnings("unchecked")
102: public void subscribe(String topic, String subscriptionId) {
103: WebContext webContext = WebContextFactory.get();
104: ServletContext servletContext = webContext.getServletContext();
105: Hub hub = HubFactory.get(servletContext);
106: final ScriptSession session = webContext.getScriptSession();
107:
108: // Create a subscription block
109: BrowserMessageListener subscription = new BrowserMessageListener(
110: session, topic, subscriptionId);
111:
112: Map<String, BrowserMessageListener> subscriptions = (Map<String, BrowserMessageListener>) session
113: .getAttribute(ATTRIBUTE_SUBSCRIPTIONS);
114: if (subscriptions == null) {
115: subscriptions = new HashMap<String, BrowserMessageListener>();
116: }
117: subscriptions.put(subscriptionId, subscription);
118: session.setAttribute(ATTRIBUTE_SUBSCRIPTIONS, subscriptions);
119:
120: hub.subscribe(subscription.topic, subscription);
121: }
122:
123: /**
124: * Stop notifications of against a subscription id
125: * @param subscriptionId The ID to pass back to link to client side data
126: * @return true iff someone was unsubscribed
127: */
128: @SuppressWarnings("unchecked")
129: public boolean unsubscribe(String subscriptionId) {
130: WebContext webContext = WebContextFactory.get();
131: ServletContext servletContext = webContext.getServletContext();
132: Hub hub = HubFactory.get(servletContext);
133: ScriptSession session = webContext.getScriptSession();
134:
135: Map<String, BrowserMessageListener> subscriptions = (Map<String, BrowserMessageListener>) session
136: .getAttribute(ATTRIBUTE_SUBSCRIPTIONS);
137: BrowserMessageListener subscription = subscriptions
138: .get(subscriptionId);
139:
140: return hub.unsubscribe(subscription.topic, subscription);
141: }
142:
143: /**
144: * A struct to collect the data we need to remember against a subscription
145: */
146: protected class BrowserMessageListener implements MessageListener {
147: /**
148: *
149: */
150: public BrowserMessageListener(ScriptSession session,
151: String topic, String subscriptionId) {
152: this .session = session;
153: this .topic = topic;
154: this .subscriptionId = subscriptionId;
155: }
156:
157: /* (non-Javadoc)
158: * @see org.directwebremoting.event.MessageListener#onMessage(org.directwebremoting.event.MessageEvent)
159: */
160: public void onMessage(MessageEvent message) {
161: ScriptBuffer script = new ScriptBuffer();
162: script.appendCall("dwr.hub._remotePublish", subscriptionId,
163: message.getRawData());
164: session.addScript(script);
165: }
166:
167: protected String topic;
168: protected String subscriptionId;
169: protected ScriptSession session;
170: }
171:
172: /**
173: *
174: */
175: private static final String ATTRIBUTE_SUBSCRIPTIONS = "org.directwebremoting.export.System.subscriptions";
176:
177: /**
178: * The log stream
179: */
180: private static final Log log = LogFactory.getLog(System.class);
181: }
|