diff -Nur SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEvent.java SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEvent.java --- SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEvent.java 1970-01-01 01:00:00.000000000 +0100 +++ SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEvent.java 2006-12-06 00:40:46.000000000 +0100 @@ -0,0 +1,50 @@ +package nextapp.echo2.webcontainer; + +import java.util.EventObject; +import java.util.Iterator; +import java.util.Map; + +public class WindowHtmlEvent extends EventObject { + + private Map eventParameters; + private String uri; + + public WindowHtmlEvent(Object source, Map eventParameters, String uri) { + super(source); + this.eventParameters = eventParameters; + this.uri = uri; + } + + public String getUri() { + return uri; + } + + public Map getParameterMap() { + return eventParameters; + } + + public String getParameter(String paramName) { + String[] values = getParameterValues(paramName); + if (values == null || values.length == 0) + return null; + return values[0]; + } + + public String[] getParameterValues(String paramName) { + return (String[]) eventParameters.get(paramName); + } + + public String[] getParameterNames() { + int nameCount = 0; + for (Iterator iter = eventParameters.keySet().iterator(); iter.hasNext();) { + iter.next(); nameCount++; + } + String[] nameArray = new String[nameCount]; + nameCount=0; + for (Iterator iter = eventParameters.keySet().iterator(); iter.hasNext();) { + nameArray[nameCount] = (String)iter.next();; + nameCount++; + } + return nameArray; + } +} diff -Nur SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventListener.java SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventListener.java --- SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventListener.java 1970-01-01 01:00:00.000000000 +0100 +++ SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventListener.java 2006-12-06 00:41:02.000000000 +0100 @@ -0,0 +1,7 @@ +package nextapp.echo2.webcontainer; + +import java.util.EventListener; + +public interface WindowHtmlEventListener extends EventListener { + public void windowHtmlEvent(WindowHtmlEvent windowHtmlEvent); +} diff -Nur SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventMonitor.java SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventMonitor.java --- SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventMonitor.java 1970-01-01 01:00:00.000000000 +0100 +++ SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlEventMonitor.java 2006-12-06 00:41:51.000000000 +0100 @@ -0,0 +1,48 @@ +package nextapp.echo2.webcontainer; + +import java.util.EventListener; + +import nextapp.echo2.app.Component; +import nextapp.echo2.app.event.EventListenerList; +import nextapp.echo2.webcontainer.WindowHtmlEvent; +import nextapp.echo2.webcontainer.WindowHtmlEventListener; +import nextapp.echo2.webcontainer.WindowHtmlService; + +public class WindowHtmlEventMonitor extends Component { + + private EventListenerList listenerList = new EventListenerList(); + + public WindowHtmlEventMonitor() { + setVisible(false); + } + + public void init() { + super.init(); + WindowHtmlService.INSTANCE.register(this); + } + + public void dispose() { + super.dispose(); + WindowHtmlService.INSTANCE.deregister(this); + } + + public void addExternalEventListener(WindowHtmlEventListener l) { + listenerList.addListener(WindowHtmlEventListener.class,l); + } + + public void removeExternalEventListener(WindowHtmlEventListener l) { + listenerList.removeListener(WindowHtmlEventListener.class,l); + } + + public void fireWindowHtmlEvent(WindowHtmlEvent externalEvent) { + EventListener[] listeners = listenerList.getListeners(WindowHtmlEventListener.class); + for (int index = 0; index < listeners.length; ++index) { + ((WindowHtmlEventListener) listeners[index]).windowHtmlEvent(externalEvent); + } + } + + public void setVisible(boolean newValue) { + super.setVisible(false); + } + +} diff -Nur SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlService.java SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlService.java --- SourceCodeOrg/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlService.java 2006-12-06 00:38:45.000000000 +0100 +++ SourceCode/src/webcontainer/java/nextapp/echo2/webcontainer/WindowHtmlService.java 2006-12-06 00:42:56.000000000 +0100 @@ -30,8 +30,15 @@ package nextapp.echo2.webcontainer; import java.io.IOException; +import java.util.Map; +import java.util.HashMap; +import java.util.WeakHashMap; +import java.util.Set; +import java.util.Iterator; +import java.util.Enumeration; import nextapp.echo2.app.ApplicationInstance; +import nextapp.echo2.app.TaskQueueHandle; import nextapp.echo2.webrender.BaseHtmlDocument; import nextapp.echo2.webrender.Connection; import nextapp.echo2.webrender.ContentType; @@ -40,6 +47,8 @@ import nextapp.echo2.webrender.output.CssStyle; import nextapp.echo2.webrender.service.CoreServices; +import javax.servlet.http.HttpServletRequest; + /** * Completely re-renders a browser window. * This is the default service invoked when the user visits an application. @@ -68,36 +77,91 @@ return DO_NOT_CACHE; } - /** - * @see nextapp.echo2.webrender.Service#service(nextapp.echo2.webrender.Connection) - */ - public void service(Connection conn) throws IOException { - ContainerInstance ci = (ContainerInstance) conn.getUserInstance(); - conn.setContentType(ContentType.TEXT_HTML); - - boolean debug = !("false".equals(conn.getServlet().getInitParameter("echo2.debug"))); - - BaseHtmlDocument baseDoc = new BaseHtmlDocument(ROOT_ID); - baseDoc.setGenarator(ApplicationInstance.ID_STRING); - baseDoc.addJavaScriptInclude(ci.getServiceUri(CoreServices.CLIENT_ENGINE)); - - // Add initialization directive. - baseDoc.getBodyElement().setAttribute("onload", "EchoClientEngine.init('" + ci.getServletUri() + "', " - + debug + ");"); - - // Set body element CSS style. - CssStyle cssStyle = new CssStyle(); - cssStyle.setAttribute("position", "absolute"); - cssStyle.setAttribute("font-family", "verdana, arial, helvetica, sans-serif"); - cssStyle.setAttribute("font-size", "10pt"); - cssStyle.setAttribute("height", "100%"); - cssStyle.setAttribute("width", "100%"); - cssStyle.setAttribute("padding", "0px"); - cssStyle.setAttribute("margin", "0px"); - cssStyle.setAttribute("overflow", "hidden"); - baseDoc.getBodyElement().setAttribute("style", cssStyle.renderInline()); - - // Render. - baseDoc.render(conn.getWriter()); - } + /** + * @see nextapp.echo2.webrender.Service#service(nextapp.echo2.webrender.Connection) + */ + public void service(Connection conn) throws IOException { + ContainerInstance ci = (ContainerInstance) conn.getUserInstance(); + conn.setContentType(ContentType.TEXT_HTML); + + ApplicationInstance appInstance = ci.getApplicationInstance(); + if ( appInstance != null ) { + synchronized(this) { + HttpServletRequest request = conn.getRequest(); + Map parameterMap = new HashMap(); + for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) { + String paramName = (String) e.nextElement(); + String[] paramValues = conn.getRequest().getParameterValues(paramName); + parameterMap.put(paramName,paramValues); + } + final WindowHtmlEvent externalEvent = new WindowHtmlEvent(this,parameterMap, request.getRequestURI()); + + // + // create a TaskQueue but only once per app instance. As it is weak + // it will die with the AppInstance and hence so will the TaskQueue + // as its referred to by its AppInstance. + TaskQueueHandle taskQueueHandle = (TaskQueueHandle) weakInstanceQueues.get(appInstance); + if (taskQueueHandle == null) { + taskQueueHandle = appInstance.createTaskQueue(); + weakInstanceQueues.put(appInstance,taskQueueHandle); + } + // + // run through all registed event monitors but only tell the ones + // that belong to the current app instance. + Set set = weakInterestedParties.keySet(); + for (Iterator iter = set.iterator(); iter.hasNext();) { + final WindowHtmlEventMonitor monitor = (WindowHtmlEventMonitor) iter.next(); + + if (appInstance.equals(monitor.getApplicationInstance())) { + Runnable task = new Runnable() { + public void run() { + monitor.fireWindowHtmlEvent(externalEvent); + } + }; + // tell the peer and hence the listeners about the event but in + // a runnable task so that it executes in the main UI thread. + appInstance.enqueueTask(taskQueueHandle,task); + } + } + } + } + + boolean debug = !("false".equals(conn.getServlet().getInitParameter("echo2.debug"))); + + BaseHtmlDocument baseDoc = new BaseHtmlDocument(ROOT_ID); + baseDoc.setGenarator(ApplicationInstance.ID_STRING); + baseDoc.addJavaScriptInclude(ci.getServiceUri(CoreServices.CLIENT_ENGINE)); + + // Add initialization directive. + baseDoc.getBodyElement().setAttribute("onload", "EchoClientEngine.init('" + ci.getServletUri() + "', " + + debug + ");"); + + // Set body element CSS style. + CssStyle cssStyle = new CssStyle(); + cssStyle.setAttribute("position", "absolute"); + cssStyle.setAttribute("font-family", "verdana, arial, helvetica, sans-serif"); + cssStyle.setAttribute("font-size", "10pt"); + cssStyle.setAttribute("height", "100%"); + cssStyle.setAttribute("width", "100%"); + cssStyle.setAttribute("padding", "0px"); + cssStyle.setAttribute("margin", "0px"); + cssStyle.setAttribute("overflow", "hidden"); + baseDoc.getBodyElement().setAttribute("style", cssStyle.renderInline()); + + // Render. + baseDoc.render(conn.getWriter()); + } + + private WeakHashMap weakInterestedParties = new WeakHashMap(); + private WeakHashMap weakInstanceQueues = new WeakHashMap(); + + + public synchronized void register(WindowHtmlEventMonitor monitor) { + weakInterestedParties.put(monitor,null); + } + + public synchronized void deregister(WindowHtmlEventMonitor monitor) { + weakInterestedParties.remove(monitor); + } + }